From 76e9bc066b289f8569d334e878b251371bbfa9dc Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Tue, 26 Feb 2019 15:02:18 +0000 Subject: [PATCH] Plumb PipelineLayouts down to SpirvRoutine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This initializes arrays to hold the descriptor sets in the routine. Nothing uses this yet. Bug: b/126330097 Change-Id: If052d0b93e62e4f32e88ed02f9bc21f4203587f5 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/25553 Reviewed-by: Alexis Hétu Reviewed-by: Nicolas Capens Tested-by: Ben Clayton --- src/Device/Context.cpp | 2 ++ src/Device/Context.hpp | 5 ++++- src/Device/PixelProcessor.cpp | 2 +- src/Device/VertexProcessor.cpp | 2 +- src/Pipeline/PixelProgram.hpp | 7 +++++-- src/Pipeline/PixelRoutine.cpp | 8 ++++++-- src/Pipeline/PixelRoutine.hpp | 4 +++- src/Pipeline/SpirvShader.cpp | 7 +++++++ src/Pipeline/SpirvShader.hpp | 17 +++++++++++++++-- src/Pipeline/VertexProgram.cpp | 7 +++++-- src/Pipeline/VertexProgram.hpp | 5 ++++- src/Pipeline/VertexRoutine.cpp | 8 ++++++-- src/Pipeline/VertexRoutine.hpp | 10 +++++++++- src/Vulkan/VkDescriptorSetLayout.cpp | 8 ++++++++ src/Vulkan/VkDescriptorSetLayout.hpp | 1 + src/Vulkan/VkPipeline.cpp | 8 ++++++++ src/Vulkan/VkPipeline.hpp | 9 +++++++++ src/Vulkan/VkPipelineLayout.cpp | 11 +++++++++++ src/Vulkan/VkPipelineLayout.hpp | 3 +++ 19 files changed, 108 insertions(+), 16 deletions(-) diff --git a/src/Device/Context.cpp b/src/Device/Context.cpp index face9e450154d..53a77721c8182 100644 --- a/src/Device/Context.cpp +++ b/src/Device/Context.cpp @@ -218,6 +218,8 @@ namespace sw colorWriteMask[i] = 0x0000000F; } + pipelineLayout = nullptr; + pixelShader = nullptr; vertexShader = nullptr; diff --git a/src/Device/Context.hpp b/src/Device/Context.hpp index db14e8c0020e0..6be2017e5a6a5 100644 --- a/src/Device/Context.hpp +++ b/src/Device/Context.hpp @@ -24,7 +24,8 @@ namespace vk { class ImageView; -}; + class PipelineLayout; +} // namespace vk namespace sw { @@ -198,6 +199,8 @@ namespace sw vk::ImageView *stencilBuffer; unsigned int stencilBufferLayer; + vk::PipelineLayout const *pipelineLayout; + // Shaders const SpirvShader *pixelShader; const SpirvShader *vertexShader; diff --git a/src/Device/PixelProcessor.cpp b/src/Device/PixelProcessor.cpp index cc52c87d35268..811a265f91b49 100644 --- a/src/Device/PixelProcessor.cpp +++ b/src/Device/PixelProcessor.cpp @@ -449,7 +449,7 @@ namespace sw if(!routine) { - QuadRasterizer *generator = new PixelProgram(state, context->pixelShader); + QuadRasterizer *generator = new PixelProgram(state, context->pipelineLayout, context->pixelShader); generator->generate(); routine = (*generator)("PixelRoutine_%0.8X", state.shaderID); delete generator; diff --git a/src/Device/VertexProcessor.cpp b/src/Device/VertexProcessor.cpp index 065e7c01f2239..21ab83f61e996 100644 --- a/src/Device/VertexProcessor.cpp +++ b/src/Device/VertexProcessor.cpp @@ -129,7 +129,7 @@ namespace sw if(!routine) // Create one { - VertexRoutine *generator = new VertexProgram(state, context->vertexShader); + VertexRoutine *generator = new VertexProgram(state, context->pipelineLayout, context->vertexShader); generator->generate(); routine = (*generator)("VertexRoutine_%0.8X", state.shaderID); delete generator; diff --git a/src/Pipeline/PixelProgram.hpp b/src/Pipeline/PixelProgram.hpp index 295941874b3f4..71c46df5915d5 100644 --- a/src/Pipeline/PixelProgram.hpp +++ b/src/Pipeline/PixelProgram.hpp @@ -23,8 +23,11 @@ namespace sw class PixelProgram : public PixelRoutine { public: - PixelProgram(const PixelProcessor::State &state, SpirvShader const *spirvShader) : - PixelRoutine(state, spirvShader) + PixelProgram( + const PixelProcessor::State &state, + vk::PipelineLayout const *pipelineLayout, + SpirvShader const *spirvShader) : + PixelRoutine(state, pipelineLayout, spirvShader) { } diff --git a/src/Pipeline/PixelRoutine.cpp b/src/Pipeline/PixelRoutine.cpp index ce32f32f6ba44..fd6a85c0aaa0e 100644 --- a/src/Pipeline/PixelRoutine.cpp +++ b/src/Pipeline/PixelRoutine.cpp @@ -29,8 +29,12 @@ namespace sw extern bool exactColorRounding; extern bool forceClearRegisters; - PixelRoutine::PixelRoutine(const PixelProcessor::State &state, SpirvShader const *spirvShader) - : QuadRasterizer(state, spirvShader) /* addressing */ + PixelRoutine::PixelRoutine( + const PixelProcessor::State &state, + vk::PipelineLayout const *pipelineLayout, + SpirvShader const *spirvShader) + : QuadRasterizer(state, spirvShader), + routine(pipelineLayout) { spirvShader->emitProlog(&routine); diff --git a/src/Pipeline/PixelRoutine.hpp b/src/Pipeline/PixelRoutine.hpp index a2b2b6ef8a180..7b8f78053c462 100644 --- a/src/Pipeline/PixelRoutine.hpp +++ b/src/Pipeline/PixelRoutine.hpp @@ -25,7 +25,9 @@ namespace sw class PixelRoutine : public sw::QuadRasterizer, public ShaderCore { public: - PixelRoutine(const PixelProcessor::State &state, SpirvShader const *spirvShader); + PixelRoutine(const PixelProcessor::State &state, + vk::PipelineLayout const *pipelineLayout, + SpirvShader const *spirvShader); virtual ~PixelRoutine(); diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp index 77d3393e4d720..d3c0061007706 100644 --- a/src/Pipeline/SpirvShader.cpp +++ b/src/Pipeline/SpirvShader.cpp @@ -16,6 +16,7 @@ #include "SpirvShader.hpp" #include "System/Math.hpp" #include "Vulkan/VkDebug.hpp" +#include "Vulkan/VkPipelineLayout.hpp" #include "Device/Config.hpp" namespace sw @@ -1437,4 +1438,10 @@ namespace sw } } } + + SpirvRoutine::SpirvRoutine(vk::PipelineLayout const *pipelineLayout) : + pipelineLayout(pipelineLayout) + { + } + } diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp index ecac7a71269d8..76400c0ae2433 100644 --- a/src/Pipeline/SpirvShader.hpp +++ b/src/Pipeline/SpirvShader.hpp @@ -15,11 +15,13 @@ #ifndef sw_SpirvShader_hpp #define sw_SpirvShader_hpp -#include "System/Types.hpp" -#include "Vulkan/VkDebug.hpp" #include "ShaderCore.hpp" #include "SpirvID.hpp" +#include "System/Types.hpp" +#include "Vulkan/VkDebug.hpp" +#include "Vulkan/VkConfig.h" +#include #include #include #include @@ -30,6 +32,11 @@ #include #include +namespace vk +{ + class PipelineLayout; +} // namespace vk + namespace sw { // Forward declarations. @@ -412,8 +419,12 @@ namespace sw class SpirvRoutine { public: + SpirvRoutine(vk::PipelineLayout const *pipelineLayout); + using Value = Array; + vk::PipelineLayout const * const pipelineLayout; + std::unordered_map lvalues; std::unordered_map intermediates; @@ -421,6 +432,8 @@ namespace sw Value inputs = Value{MAX_INTERFACE_COMPONENTS}; Value outputs = Value{MAX_INTERFACE_COMPONENTS}; + std::array, vk::MAX_BOUND_DESCRIPTOR_SETS> descriptorSets; + void createLvalue(SpirvShader::ObjectID id, uint32_t size) { lvalues.emplace(id, Value(size)); diff --git a/src/Pipeline/VertexProgram.cpp b/src/Pipeline/VertexProgram.cpp index 56eb4ced59e72..182e7bdf0901c 100644 --- a/src/Pipeline/VertexProgram.cpp +++ b/src/Pipeline/VertexProgram.cpp @@ -22,8 +22,11 @@ namespace sw { - VertexProgram::VertexProgram(const VertexProcessor::State &state, SpirvShader const *spirvShader) - : VertexRoutine(state, spirvShader) + VertexProgram::VertexProgram( + const VertexProcessor::State &state, + vk::PipelineLayout const *pipelineLayout, + SpirvShader const *spirvShader) + : VertexRoutine(state, pipelineLayout, spirvShader) { ifDepth = 0; loopRepDepth = 0; diff --git a/src/Pipeline/VertexProgram.hpp b/src/Pipeline/VertexProgram.hpp index 358ed5f64e1fd..5fe12526aefc2 100644 --- a/src/Pipeline/VertexProgram.hpp +++ b/src/Pipeline/VertexProgram.hpp @@ -29,7 +29,10 @@ namespace sw class VertexProgram : public VertexRoutine, public ShaderCore { public: - VertexProgram(const VertexProcessor::State &state, SpirvShader const *spirvShader); + VertexProgram( + const VertexProcessor::State &state, + vk::PipelineLayout const *pipelineLayout, + SpirvShader const *spirvShader); virtual ~VertexProgram(); diff --git a/src/Pipeline/VertexRoutine.cpp b/src/Pipeline/VertexRoutine.cpp index c4e5db5b1d221..df2c8133e4e64 100644 --- a/src/Pipeline/VertexRoutine.cpp +++ b/src/Pipeline/VertexRoutine.cpp @@ -24,8 +24,12 @@ namespace sw { - VertexRoutine::VertexRoutine(const VertexProcessor::State &state, SpirvShader const *spirvShader) - : state(state), + VertexRoutine::VertexRoutine( + const VertexProcessor::State &state, + vk::PipelineLayout const *pipelineLayout, + SpirvShader const *spirvShader) + : routine(pipelineLayout), + state(state), spirvShader(spirvShader) { spirvShader->emitProlog(&routine); diff --git a/src/Pipeline/VertexRoutine.hpp b/src/Pipeline/VertexRoutine.hpp index 943e5601d322f..757fc51c6b388 100644 --- a/src/Pipeline/VertexRoutine.hpp +++ b/src/Pipeline/VertexRoutine.hpp @@ -20,6 +20,11 @@ #include "ShaderCore.hpp" #include "SpirvShader.hpp" +namespace vk +{ + class PipelineLayout; +} // namespace vk + namespace sw { class VertexRoutinePrototype : public Function, Pointer, Pointer, Pointer)> @@ -38,7 +43,10 @@ namespace sw class VertexRoutine : public VertexRoutinePrototype { public: - VertexRoutine(const VertexProcessor::State &state, SpirvShader const *spirvShader); + VertexRoutine( + const VertexProcessor::State &state, + vk::PipelineLayout const *pipelineLayout, + SpirvShader const *spirvShader); virtual ~VertexRoutine(); void generate(); diff --git a/src/Vulkan/VkDescriptorSetLayout.cpp b/src/Vulkan/VkDescriptorSetLayout.cpp index d07e27be04c1c..14f43a87c6bcb 100644 --- a/src/Vulkan/VkDescriptorSetLayout.cpp +++ b/src/Vulkan/VkDescriptorSetLayout.cpp @@ -13,6 +13,8 @@ // limitations under the License. #include "VkDescriptorSetLayout.hpp" +#include "System/Types.hpp" + #include #include @@ -176,6 +178,12 @@ void DescriptorSetLayout::initialize(VkDescriptorSet vkDescriptorSet) } } +size_t DescriptorSetLayout::getBindingOffset(uint32_t binding) const +{ + uint32_t index = getBindingIndex(binding); + return bindingOffsets[index] + OFFSET(DescriptorSet, data[0]); +} + uint8_t* DescriptorSetLayout::getOffsetPointer(VkDescriptorSet descriptorSet, uint32_t binding, uint32_t arrayElement, uint32_t count, size_t* typeSize) const { uint32_t index = getBindingIndex(binding); diff --git a/src/Vulkan/VkDescriptorSetLayout.hpp b/src/Vulkan/VkDescriptorSetLayout.hpp index 627c9ab5d0785..d332c28c6b552 100644 --- a/src/Vulkan/VkDescriptorSetLayout.hpp +++ b/src/Vulkan/VkDescriptorSetLayout.hpp @@ -35,6 +35,7 @@ class DescriptorSetLayout : public Objectlayout)) { if((pCreateInfo->flags != 0) || (pCreateInfo->stageCount != 2) || @@ -230,6 +234,9 @@ GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn UNIMPLEMENTED(); } + // Context must always have a PipelineLayout set. + context.pipelineLayout = layout; + // Temporary in-binding-order representation of buffer strides, to be consumed below // when considering attributes. TODO: unfuse buffers from attributes in backend, is old GL model. uint32_t bufferStrides[MAX_VERTEX_INPUT_BINDINGS]; @@ -499,6 +506,7 @@ const sw::Color& GraphicsPipeline::getBlendConstants() const } ComputePipeline::ComputePipeline(const VkComputePipelineCreateInfo* pCreateInfo, void* mem) + : Pipeline(Cast(pCreateInfo->layout)) { } diff --git a/src/Vulkan/VkPipeline.hpp b/src/Vulkan/VkPipeline.hpp index 039b33e9ee3ad..7b4d59142793e 100644 --- a/src/Vulkan/VkPipeline.hpp +++ b/src/Vulkan/VkPipeline.hpp @@ -23,9 +23,13 @@ namespace sw { class SpirvShader; } namespace vk { +class PipelineLayout; + class Pipeline { public: + Pipeline(PipelineLayout const *layout); + operator VkPipeline() { return reinterpret_cast(this); @@ -40,6 +44,11 @@ class Pipeline #ifndef NDEBUG virtual VkPipelineBindPoint bindPoint() const = 0; #endif + + PipelineLayout const * getLayout() const { return layout; } + +protected: + PipelineLayout const *layout = nullptr; }; class GraphicsPipeline : public Pipeline, public ObjectBase diff --git a/src/Vulkan/VkPipelineLayout.cpp b/src/Vulkan/VkPipelineLayout.cpp index 1daea01cc1df3..fcc6c662b9625 100644 --- a/src/Vulkan/VkPipelineLayout.cpp +++ b/src/Vulkan/VkPipelineLayout.cpp @@ -44,4 +44,15 @@ size_t PipelineLayout::ComputeRequiredAllocationSize(const VkPipelineLayoutCreat (pCreateInfo->pushConstantRangeCount * sizeof(VkPushConstantRange)); } +size_t PipelineLayout::getNumDescriptorSets() const +{ + return setLayoutCount; +} + +size_t PipelineLayout::getBindingOffset(size_t descriptorSet, size_t binding) const +{ + ASSERT(descriptorSet < setLayoutCount); + return setLayouts[descriptorSet]->getBindingOffset(binding); +} + } // namespace vk diff --git a/src/Vulkan/VkPipelineLayout.hpp b/src/Vulkan/VkPipelineLayout.hpp index fe9d5282da81f..5723317184aa8 100644 --- a/src/Vulkan/VkPipelineLayout.hpp +++ b/src/Vulkan/VkPipelineLayout.hpp @@ -29,6 +29,9 @@ class PipelineLayout : public Object static size_t ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo* pCreateInfo); + size_t getNumDescriptorSets() const; + size_t getBindingOffset(size_t descriptorSet, size_t binding) const; + private: uint32_t setLayoutCount = 0; DescriptorSetLayout** setLayouts = nullptr;