From b351f069f16b27eeccf89b7e0f1723f3412f171e Mon Sep 17 00:00:00 2001 From: Jaebaek Seo Date: Thu, 29 Nov 2018 15:08:50 -0500 Subject: Vulkan: Split Engine::DoProcessCommands (#120) Split Engine::DoProcessCommands() into DoProcessCommands() and GetFrameBufferInfo() for probing FrameBuffer and split it into DoProcessCommands() and GetDescriptorInfo() for probing SSBO This commit is a part of PR #101 --- src/dawn/engine_dawn.cc | 47 ++++++++++++++++++++++--------------- src/dawn/engine_dawn.h | 9 ++++---- src/dawn/pipeline_info.h | 2 +- src/dawn/pipeline_info_test.cc | 2 +- src/engine.h | 51 +++++++++++++++++++++++++++++++++++++---- src/verifier.cc | 2 +- src/verifier.h | 2 +- src/vkscript/executor.cc | 28 ++++++++++++++++------ src/vkscript/executor_test.cc | 18 ++++++++------- src/vulkan/compute_pipeline.cc | 12 ++++++++++ src/vulkan/compute_pipeline.h | 3 +++ src/vulkan/engine_vulkan.cc | 43 +++++++++++++++++++--------------- src/vulkan/engine_vulkan.h | 9 ++++---- src/vulkan/graphics_pipeline.cc | 4 ---- src/vulkan/graphics_pipeline.h | 2 +- src/vulkan/pipeline.h | 1 + 16 files changed, 161 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/dawn/engine_dawn.cc b/src/dawn/engine_dawn.cc index 159ed10..768e3c2 100644 --- a/src/dawn/engine_dawn.cc +++ b/src/dawn/engine_dawn.cc @@ -324,16 +324,7 @@ Result EngineDawn::DoBuffer(const BufferCommand*) { return Result("Dawn:DoBuffer not implemented"); } -Result EngineDawn::DoProcessCommands(uint32_t* texel_stride, - uint32_t* width, - uint32_t* height, - const void** buf_ptr) { - assert(texel_stride); - // TODO(dneto): Need to pass back a row_stride. - assert(width); - assert(height); - assert(buf_ptr); - +Result EngineDawn::DoProcessCommands() { Result result; // TODO(dneto): How to distinguish the compute case: It won't have a @@ -368,9 +359,9 @@ Result EngineDawn::DoProcessCommands(uint32_t* texel_stride, // Now run the commands. auto command_buffer = command_buffer_builder_.GetResult(); - if (render_pipeline_info_.fb_is_mapped) { + if (render_pipeline_info_.fb_data != nullptr) { fb_buffer.Unmap(); - render_pipeline_info_.fb_is_mapped = false; + render_pipeline_info_.fb_data = nullptr; } queue_.Submit(1, &command_buffer); @@ -379,12 +370,7 @@ Result EngineDawn::DoProcessCommands(uint32_t* texel_stride, DestroyCommandBufferBuilder(); MapResult map = MapBuffer(device_, fb_buffer, render_pipeline_info_.fb_size); - render_pipeline_info_.fb_is_mapped = map.result.IsSuccess(); - - *texel_stride = render_pipeline_info_.fb_texel_stride; - *width = kFramebufferWidth; - *height = kFramebufferHeight; - *buf_ptr = map.data; + render_pipeline_info_.fb_data = map.data; return map.result; } @@ -438,10 +424,33 @@ Result EngineDawn::CreateFramebufferIfNeeded() { render_pipeline_info_.fb_texel_stride = texel_stride; render_pipeline_info_.fb_row_stride = row_stride; render_pipeline_info_.fb_size = size; - render_pipeline_info_.fb_is_mapped = false; + render_pipeline_info_.fb_data = nullptr; } return {}; } +Result EngineDawn::GetFrameBufferInfo(ResourceInfo* info) { + assert(info); + + if (render_pipeline_info_.fb_data == nullptr) + return Result("Dawn: FrameBuffer is not mapped"); + + // TODO(dneto): Need to pass back a row_stride. + info->image_info.texel_stride = render_pipeline_info_.fb_texel_stride; + info->image_info.width = kFramebufferWidth; + info->image_info.height = kFramebufferHeight; + info->image_info.depth = 1U; + info->size_in_bytes = render_pipeline_info_.fb_texel_stride * + kFramebufferWidth * kFramebufferHeight; + info->cpu_memory = render_pipeline_info_.fb_data; + return {}; +} + +Result EngineDawn::GetDescriptorInfo(const uint32_t, + const uint32_t, + ResourceInfo*) { + return Result("Dawn:GetDescriptorInfo not implemented"); +} + } // namespace dawn } // namespace amber diff --git a/src/dawn/engine_dawn.h b/src/dawn/engine_dawn.h index af599bb..8007321 100644 --- a/src/dawn/engine_dawn.h +++ b/src/dawn/engine_dawn.h @@ -63,10 +63,11 @@ class EngineDawn : public Engine { Result DoPatchParameterVertices( const PatchParameterVerticesCommand* cmd) override; Result DoBuffer(const BufferCommand* cmd) override; - Result DoProcessCommands(uint32_t* stride, - uint32_t* width, - uint32_t* height, - const void** buf) override; + Result DoProcessCommands() override; + Result GetFrameBufferInfo(ResourceInfo* info) override; + Result GetDescriptorInfo(const uint32_t descriptor_set, + const uint32_t binding, + ResourceInfo* info) override; private: // Creates a command buffer builder if it doesn't already exist. diff --git a/src/dawn/pipeline_info.h b/src/dawn/pipeline_info.h index 8bb646c..cf4bdb3 100644 --- a/src/dawn/pipeline_info.h +++ b/src/dawn/pipeline_info.h @@ -49,7 +49,7 @@ struct RenderPipelineInfo { uint32_t fb_row_stride = 0; // The number of data bytes in the framebuffer host-side buffer. uint32_t fb_size = 0; - bool fb_is_mapped = false; + const void* fb_data = nullptr; // TODO(dneto): Record index data // TODO(dneto): Record buffer data diff --git a/src/dawn/pipeline_info_test.cc b/src/dawn/pipeline_info_test.cc index 6bc2905..a5e1a1e 100644 --- a/src/dawn/pipeline_info_test.cc +++ b/src/dawn/pipeline_info_test.cc @@ -49,7 +49,7 @@ TEST_F(DawnRenderPipelineInfoTest, DefaultValuesForMembers) { EXPECT_FALSE(static_cast(rpi.fb_buffer)); EXPECT_EQ(0u, rpi.fb_row_stride); EXPECT_EQ(0u, rpi.fb_size); - EXPECT_FALSE(rpi.fb_is_mapped); + EXPECT_EQ(nullptr, rpi.fb_data); } } // namespace diff --git a/src/engine.h b/src/engine.h index f772d27..0d6cb9f 100644 --- a/src/engine.h +++ b/src/engine.h @@ -33,6 +33,34 @@ enum class PipelineType : uint8_t { kGraphics, }; +enum class ResourceInfoType : uint8_t { + kBuffer = 0, + kImage, +}; + +struct ResourceInfo { + ResourceInfoType type = ResourceInfoType::kBuffer; + + struct { + uint32_t texel_stride = 0; // Number of bytes for a single texel. + uint32_t width = 0; + uint32_t height = 0; + uint32_t depth = 0; + } image_info; + + // The size in bytes of Vulkan memory pointed by |cpu_memory|. + // For the case when it is an image resource, |size_in_bytes| must + // be |image_info.width * image_info.height * image_info.depth * + // image_info.texel_stride|. + size_t size_in_bytes = 0; + + // If the primitive type of resource is the same with the type + // of actual data, the alignment must be properly determined by + // Vulkan's internal memory allocation. In these cases, script + // writers can assume that there is no alignment issues. + const void* cpu_memory = nullptr; +}; + class Engine { public: static std::unique_ptr Create(EngineType type); @@ -104,11 +132,24 @@ class Engine { // This covers both Vulkan buffers and images. virtual Result DoBuffer(const BufferCommand* cmd) = 0; - // Run all queued commands and copy result data to the host. - virtual Result DoProcessCommands(uint32_t* stride, - uint32_t* width, - uint32_t* height, - const void** buf) = 0; + // Run all queued commands and copy frame buffer data to the host + // if graphics pipeline. + virtual Result DoProcessCommands() = 0; + + // Get stride, width, height, and memory pointer of frame buffer. + // This is only valid if the buffer of framebuffer is mapped into + // the host address space. In particular, if we have run + // DoProcessCommands() and since then no graphics pipeline drawing + // commands have occurred e.g., DoClear, DoDrawArrays, DoDrawRect. + virtual Result GetFrameBufferInfo(ResourceInfo* info) = 0; + + // Copy the contents of the resource bound to the given descriptor + // and get the resource information e.g., size for buffer, width, + // height, depth for image of descriptor given as |descriptor_set| + // and |binding|. + virtual Result GetDescriptorInfo(const uint32_t descriptor_set, + const uint32_t binding, + ResourceInfo* info) = 0; protected: Engine(); diff --git a/src/verifier.cc b/src/verifier.cc index aac2b78..c36923d 100644 --- a/src/verifier.cc +++ b/src/verifier.cc @@ -114,7 +114,7 @@ Result Verifier::Probe(const ProbeCommand* command, return {}; } -Result Verifier::ProbeSSBO(const ProbeSSBOCommand*) { +Result Verifier::ProbeSSBO(const ProbeSSBOCommand*, size_t, const void*) { return Result("Verifier::ProbeSSBO Not Implemented"); } diff --git a/src/verifier.h b/src/verifier.h index c410d32..40610a9 100644 --- a/src/verifier.h +++ b/src/verifier.h @@ -30,7 +30,7 @@ class Verifier { uint32_t frame_width, uint32_t frame_height, const void* buf); - Result ProbeSSBO(const ProbeSSBOCommand*); + Result ProbeSSBO(const ProbeSSBOCommand*, size_t, const void*); }; } // namespace amber diff --git a/src/vkscript/executor.cc b/src/vkscript/executor.cc index ae2d43b..147eb5e 100644 --- a/src/vkscript/executor.cc +++ b/src/vkscript/executor.cc @@ -106,18 +106,32 @@ Result Executor::Execute(Engine* engine, const amber::Script* src_script) { for (const auto& cmd : node->AsTest()->GetCommands()) { if (cmd->IsProbe()) { - const void* buf = nullptr; - uint32_t width = 0; - uint32_t height = 0; - uint32_t stride = 0; - r = engine->DoProcessCommands(&stride, &width, &height, &buf); + ResourceInfo info; + r = engine->GetFrameBufferInfo(&info); if (!r.IsSuccess()) return r; - r = verifier_.Probe(cmd->AsProbe(), stride, width, height, buf); + r = engine->DoProcessCommands(); + if (!r.IsSuccess()) + return r; + + r = verifier_.Probe(cmd->AsProbe(), info.image_info.texel_stride, + info.image_info.width, info.image_info.height, + info.cpu_memory); } else if (cmd->IsProbeSSBO()) { - r = verifier_.ProbeSSBO(cmd->AsProbeSSBO()); + auto probe_ssbo = cmd->AsProbeSSBO(); + ResourceInfo info; + r = engine->GetDescriptorInfo(probe_ssbo->GetDescriptorSet(), + probe_ssbo->GetBinding(), &info); + if (!r.IsSuccess()) + return r; + + r = engine->DoProcessCommands(); + if (!r.IsSuccess()) + return r; + r = verifier_.ProbeSSBO(probe_ssbo, info.size_in_bytes, + info.cpu_memory); } else if (cmd->IsClear()) { r = engine->DoClear(cmd->AsClear()); } else if (cmd->IsClearColor()) { diff --git a/src/vkscript/executor_test.cc b/src/vkscript/executor_test.cc index 0872f9e..c177348 100644 --- a/src/vkscript/executor_test.cc +++ b/src/vkscript/executor_test.cc @@ -195,10 +195,11 @@ class EngineStub : public Engine { return {}; } - Result DoProcessCommands(uint32_t*, - uint32_t*, - uint32_t*, - const void**) override { + Result DoProcessCommands() override { return {}; } + Result GetFrameBufferInfo(ResourceInfo*) override { return {}; } + Result GetDescriptorInfo(const uint32_t, + const uint32_t, + ResourceInfo*) override { return {}; } @@ -287,10 +288,11 @@ class EngineCountingStub : public Engine { return {}; } Result DoBuffer(const BufferCommand*) override { return {}; } - Result DoProcessCommands(uint32_t*, - uint32_t*, - uint32_t*, - const void**) override { + Result DoProcessCommands() override { return {}; } + Result GetFrameBufferInfo(ResourceInfo*) override { return {}; } + Result GetDescriptorInfo(const uint32_t, + const uint32_t, + ResourceInfo*) override { return {}; } diff --git a/src/vulkan/compute_pipeline.cc b/src/vulkan/compute_pipeline.cc index bfba88e..a4f94f6 100644 --- a/src/vulkan/compute_pipeline.cc +++ b/src/vulkan/compute_pipeline.cc @@ -81,5 +81,17 @@ Result ComputePipeline::Compute(uint32_t x, uint32_t y, uint32_t z) { return {}; } +Result ComputePipeline::ProcessCommands() { + Result r = command_->BeginIfNotInRecording(); + if (!r.IsSuccess()) + return r; + + r = command_->End(); + if (!r.IsSuccess()) + return r; + + return command_->SubmitAndReset(GetFenceTimeout()); +} + } // namespace vulkan } // namespace amber diff --git a/src/vulkan/compute_pipeline.h b/src/vulkan/compute_pipeline.h index ddbc39d..ccbd1be 100644 --- a/src/vulkan/compute_pipeline.h +++ b/src/vulkan/compute_pipeline.h @@ -37,6 +37,9 @@ class ComputePipeline : public Pipeline { Result Compute(uint32_t x, uint32_t y, uint32_t z); + // Pipeline + Result ProcessCommands() override; + private: Result CreateVkComputePipeline(); }; diff --git a/src/vulkan/engine_vulkan.cc b/src/vulkan/engine_vulkan.cc index d407ab7..bdcd786 100644 --- a/src/vulkan/engine_vulkan.cc +++ b/src/vulkan/engine_vulkan.cc @@ -272,28 +272,35 @@ Result EngineVulkan::DoPatchParameterVertices( return Result("Vulkan::DoPatch Not Implemented"); } -Result EngineVulkan::DoProcessCommands(uint32_t* stride, - uint32_t* width, - uint32_t* height, - const void** buf) { - assert(width); - assert(height); - assert(stride); - assert(buf); +Result EngineVulkan::DoProcessCommands() { + return pipeline_->ProcessCommands(); +} - if (!pipeline_->IsGraphics()) - return Result("Vulkan::ProcessCommands for Non-Graphics Pipeline"); +Result EngineVulkan::GetFrameBufferInfo(ResourceInfo* info) { + assert(info); - auto graphics = pipeline_->AsGraphics(); - Result r = graphics->ProcessCommands(); + if (!pipeline_->IsGraphics()) + return Result("Vulkan::GetFrameBufferInfo for Non-Graphics Pipeline"); + + const auto graphics = pipeline_->AsGraphics(); + const auto frame = graphics->GetFrame(); + auto bytes_per_texel = VkFormatToByteSize(graphics->GetColorFormat()); + info->type = ResourceInfoType::kImage; + info->image_info.width = frame->GetWidth(); + info->image_info.height = frame->GetHeight(); + info->image_info.depth = 1U; + info->image_info.texel_stride = bytes_per_texel; + info->size_in_bytes = + frame->GetWidth() * frame->GetHeight() * bytes_per_texel; + info->cpu_memory = frame->GetColorBufferPtr(); - auto frame = graphics->GetFrame(); - *width = frame->GetWidth(); - *height = frame->GetHeight(); - *stride = VkFormatToByteSize(graphics->GetColorFormat()); - *buf = frame->GetColorBufferPtr(); + return {}; +} - return r; +Result EngineVulkan::GetDescriptorInfo(const uint32_t, + const uint32_t, + ResourceInfo*) { + return Result("EngineVulkan::GetDescriptorInfo not implemented"); } Result EngineVulkan::DoBuffer(const BufferCommand* command) { diff --git a/src/vulkan/engine_vulkan.h b/src/vulkan/engine_vulkan.h index e4fd4fa..d9f82f2 100644 --- a/src/vulkan/engine_vulkan.h +++ b/src/vulkan/engine_vulkan.h @@ -56,10 +56,11 @@ class EngineVulkan : public Engine { Result DoPatchParameterVertices( const PatchParameterVerticesCommand* cmd) override; Result DoBuffer(const BufferCommand* cmd) override; - Result DoProcessCommands(uint32_t* stride, - uint32_t* width, - uint32_t* height, - const void** buf) override; + Result DoProcessCommands() override; + Result GetFrameBufferInfo(ResourceInfo* info) override; + Result GetDescriptorInfo(const uint32_t descriptor_set, + const uint32_t binding, + ResourceInfo* info) override; private: Result InitDeviceAndCreateCommand(); diff --git a/src/vulkan/graphics_pipeline.cc b/src/vulkan/graphics_pipeline.cc index f330e8c..c9c9eed 100644 --- a/src/vulkan/graphics_pipeline.cc +++ b/src/vulkan/graphics_pipeline.cc @@ -528,10 +528,6 @@ Result GraphicsPipeline::ProcessCommands() { void GraphicsPipeline::Shutdown() { DeactivateRenderPassIfNeeded(); - Result r = command_->End(); - if (r.IsSuccess()) - command_->SubmitAndReset(GetFenceTimeout()); - Pipeline::Shutdown(); frame_->Shutdown(); vkDestroyRenderPass(device_, render_pass_, nullptr); diff --git a/src/vulkan/graphics_pipeline.h b/src/vulkan/graphics_pipeline.h index d9c2ef8..110d944 100644 --- a/src/vulkan/graphics_pipeline.h +++ b/src/vulkan/graphics_pipeline.h @@ -58,7 +58,6 @@ class GraphicsPipeline : public Pipeline { VkImageAspectFlags aspect); VkFormat GetColorFormat() const { return color_format_; } VkFormat GetDepthStencilFormat() const { return depth_stencil_format_; } - Result ProcessCommands(); Result SetClearColor(float r, float g, float b, float a); Result SetClearStencil(uint32_t stencil); @@ -70,6 +69,7 @@ class GraphicsPipeline : public Pipeline { // Pipeline void Shutdown() override; + Result ProcessCommands() override; private: enum class RenderPassState : uint8_t { diff --git a/src/vulkan/pipeline.h b/src/vulkan/pipeline.h index 0b806bf..8b56391 100644 --- a/src/vulkan/pipeline.h +++ b/src/vulkan/pipeline.h @@ -46,6 +46,7 @@ class Pipeline { Result AddDescriptor(const BufferCommand*); virtual void Shutdown(); + virtual Result ProcessCommands() = 0; protected: Pipeline( -- cgit v1.2.3