From c42d55f61c1476f3f6cb425d7c81a62c035f6dc7 Mon Sep 17 00:00:00 2001 From: Peter Gal Date: Mon, 31 Aug 2015 15:05:57 +0200 Subject: [PATCH] ShaderRenderCase: Add methods for specifying custom vertex input attributes --- .../shaderrendercase/vktShaderRenderCase.cpp | 209 +++++++++++---------- .../shaderrendercase/vktShaderRenderCase.hpp | 24 ++- .../shaderrendercase/vktShaderRenderCaseTests.cpp | 16 +- 3 files changed, 138 insertions(+), 111 deletions(-) diff --git a/external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCase.cpp b/external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCase.cpp index 3cb9736..23e1d4a 100644 --- a/external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCase.cpp +++ b/external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCase.cpp @@ -64,15 +64,6 @@ static const int MAX_RENDER_WIDTH = 128; static const int MAX_RENDER_HEIGHT = 112; static const tcu::Vec4 DEFAULT_CLEAR_COLOR = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f); - -struct BaseVertexAttributes -{ - Vec4 position; - Vec4 coord; //!< Near-unit coordinates, roughly [-2.0 .. 2.0]. - Vec4 unitCoord; //!< Positive-only coordinates [0.0 .. 1.5]. - float one; -}; - // QuadGrid. class QuadGrid @@ -90,8 +81,10 @@ public: // TODO: //const vector& getTextures (void) const { return m_textures; } - const BaseVertexAttributes* getBaseAttributes (void) const { return &m_baseAttribs[0]; } - deUint32 getBaseAttributesSize (void) const { return (deUint32)(m_numVertices * sizeof(BaseVertexAttributes)); } + const Vec4* getPositions (void) const { return &m_positions[0]; } + const float* getAttribOne (void) const { return &m_attribOne[0]; } + const Vec4* getCoords (void) const { return &m_coords[0]; } + const Vec4* getUnitCoords (void) const { return &m_unitCoords[0]; } const Vec4* getUserAttrib (int attribNdx) const { return &m_userAttribs[attribNdx][0]; } const deUint16* getIndices (void) const { return &m_indices[0]; } @@ -112,7 +105,10 @@ private: // vector m_textures; vector m_screenPos; - vector m_baseAttribs; + vector m_positions; + vector m_coords; //!< Near-unit coordinates, roughly [-2.0 .. 2.0]. + vector m_unitCoords; //!< Positive-only coordinates [0.0 .. 1.5]. + vector m_attribOne; vector m_userAttribs[ShaderEvalContext::MAX_TEXTURES]; vector m_indices; }; @@ -129,8 +125,11 @@ QuadGrid::QuadGrid (int gridSize, int width, int height, const Vec4& constCoords Vec4 viewportScale = Vec4((float)width, (float)height, 0.0f, 0.0f); // Compute vertices. - m_baseAttribs.resize(m_numVertices); m_screenPos.resize(m_numVertices); + m_positions.resize(m_numVertices); + m_coords.resize(m_numVertices); + m_unitCoords.resize(m_numVertices); + m_attribOne.resize(m_numVertices); // User attributes. for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_userAttribs); i++) @@ -145,10 +144,10 @@ QuadGrid::QuadGrid (int gridSize, int width, int height, const Vec4& constCoords float fy = 2.0f * sy - 1.0f; int vtxNdx = ((y * (gridSize+1)) + x); - m_baseAttribs[vtxNdx].position = Vec4(fx, fy, 0.0f, 1.0f); - m_baseAttribs[vtxNdx].coord = getCoords(sx, sy); - m_baseAttribs[vtxNdx].unitCoord= getUnitCoords(sx, sy); - m_baseAttribs[vtxNdx].one = 1.0f; + m_positions[vtxNdx] = Vec4(fx, fy, 0.0f, 1.0f); + m_coords[vtxNdx] = getCoords(sx, sy); + m_unitCoords[vtxNdx] = getUnitCoords(sx, sy); + m_attribOne[vtxNdx] = 1.0f; m_screenPos[vtxNdx] = Vec4(sx, sy, 0.0f, 1.0f) * viewportScale; @@ -293,7 +292,7 @@ void ShaderEvaluator::evaluate (ShaderEvalContext& ctx) // ShaderRenderCaseInstance. -ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context, const string& name, bool isVertexCase, ShaderEvaluator& evaluator, UniformSetupFunc uniformFunc) +ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context, const string& name, bool isVertexCase, ShaderEvaluator& evaluator, UniformSetupFunc uniformFunc, AttributeSetupFunc attribFunc) : vkt::TestInstance(context) , m_clearColor(DEFAULT_CLEAR_COLOR) , memAlloc(m_context.getDeviceInterface(), m_context.getDevice(), getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())) @@ -301,6 +300,7 @@ ShaderRenderCaseInstance::ShaderRenderCaseInstance (Context& context, const stri , m_isVertexCase(isVertexCase) , m_evaluator(evaluator) , m_uniformFunc(uniformFunc) + , m_attribFunc(attribFunc) , m_renderSize(100, 100) , m_colorFormat(VK_FORMAT_R8G8B8A8_UNORM) { @@ -384,6 +384,62 @@ void ShaderRenderCaseInstance::setupUniformData (deUint32 size, void* dataPtr) } +void ShaderRenderCaseInstance::addAttribute (deUint32 bindingLocation, vk::VkFormat format, deUint32 sizePerElement, deUint32 count, const void* dataPtr) +{ + // Add binding specification + const deUint32 binding = (deUint32)m_vertexBindingDescription.size(); + const VkVertexInputBindingDescription bindingDescription = + { + binding, + sizePerElement, + VK_VERTEX_INPUT_STEP_RATE_VERTEX + }; + + m_vertexBindingDescription.push_back(bindingDescription); + + // Add location and format specification + const VkVertexInputAttributeDescription attributeDescription = + { + bindingLocation, // deUint32 location; + binding, // deUint32 binding; + format, // VkFormat format; + 0u, // deUint32 offsetInBytes; + }; + + m_vertexattributeDescription.push_back(attributeDescription); + + // Upload data to buffer + const VkDevice vkDevice = m_context.getDevice(); + const DeviceInterface& vk = m_context.getDeviceInterface(); + const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); + + const VkDeviceSize inputSize = sizePerElement * count; + const VkBufferCreateInfo vertexBufferParams = + { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + inputSize, // VkDeviceSize size; + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; + 0u, // VkBufferCreateFlags flags; + VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; + 1u, // deUint32 queueFamilyCount; + &queueFamilyIndex // const deUint32* pQueueFamilyIndices; + }; + + Move buffer = createBuffer(vk, vkDevice, &vertexBufferParams); + de::MovePtr alloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); + + VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, alloc->getMemory(), 0)); + + void* bufferPtr; + VK_CHECK(vk.mapMemory(vkDevice, alloc->getMemory(), 0, inputSize, 0, &bufferPtr)); + deMemcpy(bufferPtr, dataPtr, inputSize); + VK_CHECK(vk.unmapMemory(vkDevice, alloc->getMemory())); + + m_vertexBuffers.push_back(buffer.disown()); + m_vertexBufferAllocs.push_back(alloc.release()); +} + void ShaderRenderCaseInstance::addUniform (deUint32 bindingLocation, VkDescriptorType descriptorType, float data) { m_descriptorSetLayoutBuilder.addSingleBinding(descriptorType, VK_SHADER_STAGE_VERTEX_BIT); @@ -450,10 +506,20 @@ tcu::IVec2 ShaderRenderCaseInstance::getViewportSize (void) const de::min(m_renderSize.y(), MAX_RENDER_HEIGHT)); } -void ShaderRenderCaseInstance::setupDefaultInputs (void) +void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid) { - // TODO!! - // SetupUniforms: map unifrom ids and set the values + /* Configuration of the vertex input attributes: + a_position is at location 0 + a_coords is at location 1 + a_unitCoords is at location 2 + a_one is at location 3 + + User attributes starts from at the location 4. + */ + addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(Vec4), quadGrid.getNumVertices(), quadGrid.getPositions()); + addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(Vec4), quadGrid.getNumVertices(), quadGrid.getCoords()); + addAttribute(2u, VK_FORMAT_R32G32B32A32_SFLOAT, sizeof(Vec4), quadGrid.getNumVertices(), quadGrid.getUnitCoords()); + addAttribute(3u, VK_FORMAT_R32_SFLOAT, sizeof(float), quadGrid.getNumVertices(), quadGrid.getAttribOne()); } void ShaderRenderCaseInstance::render (Surface& result, const QuadGrid& quadGrid) @@ -668,63 +734,22 @@ void ShaderRenderCaseInstance::render (Surface& result, const QuadGrid& quadGrid } }; - // TODO: adapt input parameters!!! - const VkVertexInputBindingDescription vertexInputBindingDescription[] = - { - { - 0u, // deUint32 binding; - sizeof(BaseVertexAttributes), // deUint32 strideInBytes; - VK_VERTEX_INPUT_STEP_RATE_VERTEX // VkVertexInputStepRate stepRate; - } - }; - const deUint32 numberOfBindings = DE_LENGTH_OF_ARRAY(vertexInputBindingDescription); - - // TODO adapt input attribute locations!!! - /* Configuration of the vertex input attributes: - a_position is at location 0 - a_coords is at location 1 - a_unitCoords is at location 2 - a_one is at location 3 - - User attributes starts from at the location 4 and ends at the location 6. - */ - const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = - { - { - 0u, // deUint32 location; - 0u, // deUint32 binding; - VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; - DE_OFFSET_OF(BaseVertexAttributes, position) // deUint32 offsetInBytes; - }, - { - 1u, // deUint32 location; - 0u, // deUint32 binding; - VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; - DE_OFFSET_OF(BaseVertexAttributes, coord) // deUint32 offsetInBytes; - }, - { - 2u, // deUint32 location; - 0u, // deUint32 binding; - VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; - DE_OFFSET_OF(BaseVertexAttributes, unitCoord) // deUint32 offsetInBytes; - }, - { - 3u, // deUint32 location; - 0u, // deUint32 binding; - VK_FORMAT_R32_SFLOAT, // VkFormat format; - DE_OFFSET_OF(BaseVertexAttributes, one) // deUint32 offsetInBytes; - } - }; + // Add base attributes + setupDefaultInputs(quadGrid); + + // Add test case specific attributes + if (m_attribFunc) + m_attribFunc(*this, quadGrid.getNumVertices()); + - const deUint32 numberOfAttributes = DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions); const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; - numberOfBindings, // deUint32 bindingCount; - vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; - numberOfAttributes, // deUint32 attributeCount; - vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; + (deUint32)m_vertexBindingDescription.size(), // deUint32 bindingCount; + &m_vertexBindingDescription[0], // const VkVertexInputBindingDescription* pVertexBindingDescriptions; + (deUint32)m_vertexattributeDescription.size(), // deUint32 attributeCount; + &m_vertexattributeDescription[0], // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; }; const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = @@ -854,33 +879,6 @@ void ShaderRenderCaseInstance::render (Surface& result, const QuadGrid& quadGrid m_colorBlendState = createDynamicColorBlendState(vk, vkDevice, &colorBlendStateParams); } - // Create vertex buffer - { - // TODO: upload all inputs - const VkBufferCreateInfo vertexBufferParams = - { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - quadGrid.getBaseAttributesSize(), // VkDeviceSize size; - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; - 0u, // VkBufferCreateFlags flags; - VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; - 1u, // deUint32 queueFamilyCount; - &queueFamilyIndex // const deUint32* pQueueFamilyIndices; - }; - - m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); - m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible); - - VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), 0)); - - // Load vertices into vertex buffer - void* bufferPtr; - VK_CHECK(vk.mapMemory(vkDevice, m_vertexBufferAlloc->getMemory(), 0, quadGrid.getBaseAttributesSize(), 0, &bufferPtr)); - deMemcpy(bufferPtr, quadGrid.getBaseAttributes(), quadGrid.getBaseAttributesSize()); - VK_CHECK(vk.unmapMemory(vkDevice, m_vertexBufferAlloc->getMemory())); - } - // Create vertex indices buffer { const VkDeviceSize indiceBufferSize = quadGrid.getNumTriangles() * 3 * sizeof(deUint16); @@ -972,10 +970,13 @@ void ShaderRenderCaseInstance::render (Surface& result, const QuadGrid& quadGrid vk.cmdBindIndexBuffer(*m_cmdBuffer, *m_indiceBuffer, 0, VK_INDEX_TYPE_UINT16); - const VkDeviceSize vertexBindingOffset = 0; - vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBindingOffset); - //vk.cmdDraw(*m_cmdBuffer, 0, 3 /*quadGrid.getNumVertices()*/, 0, 1); - //vk.cmdDraw(*m_cmdBuffer, 0, quadGrid.getNumVertices(), 0, 1); + const deUint32 numberOfVertexAttributes = (deUint32)m_vertexBuffers.size(); + std::vector offsets; + + for (deUint32 i = 0; i < numberOfVertexAttributes; i++) + offsets.push_back(0); + + vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, numberOfVertexAttributes, &m_vertexBuffers[0], &offsets[0]); vk.cmdDrawIndexed(*m_cmdBuffer, 0, quadGrid.getNumTriangles() * 3, 0, 0, 1); vk.cmdEndRenderPass(*m_cmdBuffer); diff --git a/external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCase.hpp b/external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCase.hpp index e63df11..4dddaa2 100644 --- a/external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCase.hpp +++ b/external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCase.hpp @@ -142,6 +142,7 @@ private: class ShaderRenderCaseInstance; typedef void (*UniformSetupFunc) (ShaderRenderCaseInstance& instance); +typedef void (*AttributeSetupFunc) (ShaderRenderCaseInstance& instance, deUint32 numVertices); template class ShaderRenderCase : public vkt::TestCase @@ -152,11 +153,13 @@ public: const std::string& description, bool isVertexCase, ShaderEvalFunc evalFunc, - UniformSetupFunc uniformFunc) + UniformSetupFunc uniformFunc, + AttributeSetupFunc attribFunc) : vkt::TestCase(testCtx, name, description) , m_isVertexCase(isVertexCase) , m_evaluator(new ShaderEvaluator(evalFunc)) , m_uniformFunc(uniformFunc) + , m_attribFunc(attribFunc) {} ShaderRenderCase (tcu::TestContext& testCtx, @@ -164,11 +167,13 @@ public: const std::string& description, bool isVertexCase, ShaderEvaluator* evaluator, - UniformSetupFunc uniformFunc) + UniformSetupFunc uniformFunc, + AttributeSetupFunc attribFunc) : vkt::TestCase(testCtx, name, description) , m_isVertexCase(isVertexCase) , m_evaluator(evaluator) , m_uniformFunc(uniformFunc) + , m_attribFunc(attribFunc) {} @@ -179,7 +184,7 @@ public: programCollection.add(m_name + "_frag") << glu::FragmentSource(m_fragShaderSource); } - virtual TestInstance* createInstance (Context& context) const { return new Instance(context, m_name, m_isVertexCase, *m_evaluator, m_uniformFunc); } + virtual TestInstance* createInstance (Context& context) const { return new Instance(context, m_name, m_isVertexCase, *m_evaluator, m_uniformFunc, m_attribFunc); } protected: std::string m_vertShaderSource; @@ -189,6 +194,7 @@ private: bool m_isVertexCase; ShaderEvaluator* m_evaluator; UniformSetupFunc m_uniformFunc; + AttributeSetupFunc m_attribFunc; }; @@ -198,10 +204,12 @@ private: class ShaderRenderCaseInstance : public vkt::TestInstance { public: - ShaderRenderCaseInstance (Context& context, const std::string& name, bool isVertexCase, ShaderEvaluator& evaluator, UniformSetupFunc uniformFunc); + ShaderRenderCaseInstance (Context& context, const std::string& name, bool isVertexCase, ShaderEvaluator& evaluator, UniformSetupFunc uniformFunc, AttributeSetupFunc attribFunc); virtual ~ShaderRenderCaseInstance (void); virtual tcu::TestStatus iterate (void); + void addAttribute (deUint32 bindingLocation, vk::VkFormat, deUint32 sizePerElement, deUint32 count, const void* data); + void addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, float data); void addUniform (deUint32 bindingLocation, vk::VkDescriptorType descriptorType, tcu::Vec4 data); @@ -220,7 +228,7 @@ protected: private: void setupUniformData (deUint32 size, void* dataPtr); - void setupDefaultInputs (void); + void setupDefaultInputs (const QuadGrid& quadGrid); void render (tcu::Surface& result, const QuadGrid& quadGrid); void computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid); @@ -231,6 +239,7 @@ private: bool m_isVertexCase; ShaderEvaluator& m_evaluator; UniformSetupFunc m_uniformFunc; + AttributeSetupFunc m_attribFunc; const tcu::IVec2 m_renderSize; const vk::VkFormat m_colorFormat; @@ -278,6 +287,11 @@ private: std::vector m_uniformBufferAllocs; std::vector m_uniformBufferViews; std::vector m_uniformDescriptorInfos; + + std::vector m_vertexBindingDescription; + std::vector m_vertexattributeDescription; + std::vector m_vertexBuffers; + std::vector m_vertexBufferAllocs; }; diff --git a/external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCaseTests.cpp b/external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCaseTests.cpp index 323d3dc..6d85450 100644 --- a/external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCaseTests.cpp +++ b/external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCaseTests.cpp @@ -22,6 +22,17 @@ void dummy_uniforms (ShaderRenderCaseInstance& instance) instance.addUniform(2u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, tcu::Vec4(1, 0.5f, 1.0f, 0.5f)); } +void dummy_attributes (ShaderRenderCaseInstance& instance, deUint32 numVertices) +{ + std::vector data; + data.resize(numVertices); + for(int i = 0; i < numVertices; i++) + data[i] = 1.0; + + instance.addAttribute(4u, vk::VK_FORMAT_R32_SFLOAT, sizeof(float), numVertices, &data[0]); +} + + class DummyShaderRenderCaseInstance; class DummyTestRenderCase : public ShaderRenderCase @@ -34,7 +45,7 @@ public: ShaderEvalFunc evalFunc, std::string vertexShader, std::string fragmentShader) - : ShaderRenderCase(testCtx, name, description, isVertexCase, evalFunc, dummy_uniforms) + : ShaderRenderCase(testCtx, name, description, isVertexCase, evalFunc, dummy_uniforms, dummy_attributes) { m_vertShaderSource = vertexShader; m_fragShaderSource = fragmentShader; @@ -53,6 +64,7 @@ tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx) "layout(location = 1) in highp vec4 a_coords;\n" "layout(location = 2) in highp vec4 a_unitCoords;\n" "layout(location = 3) in mediump float a_one;\n" + "layout(location = 4) in mediump float a_in1;\n" "layout (set=0, binding=0) uniform buf {\n" " float item;\n" @@ -67,7 +79,7 @@ tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx) "};\n" "out mediump vec4 v_color;\n" - "void main (void) { gl_Position = a_position; v_color = vec4(a_coords.xyz, item3.x); }\n"; + "void main (void) { gl_Position = a_position; v_color = vec4(a_coords.xyz, a_in1); }\n"; std::string base_fragment = "#version 300 es\n" "layout(location = 0) out lowp vec4 o_color;\n" -- 2.7.4