From 4329e26efd719623a4456bf7e94ef407734555eb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mika=20Isoj=C3=A4rvi?= Date: Fri, 9 Sep 2016 12:55:14 -0700 Subject: [PATCH] Add fragment storage images to pipeline barrier tests Change-Id: I34614de9bbc6ac567ba5a0faab1fc78c7b6375ca --- .../memory/vktMemoryPipelineBarrierTests.cpp | 281 ++++++++++++++++++--- 1 file changed, 251 insertions(+), 30 deletions(-) diff --git a/external/vulkancts/modules/vulkan/memory/vktMemoryPipelineBarrierTests.cpp b/external/vulkancts/modules/vulkan/memory/vktMemoryPipelineBarrierTests.cpp index 9014808..d57574d 100644 --- a/external/vulkancts/modules/vulkan/memory/vktMemoryPipelineBarrierTests.cpp +++ b/external/vulkancts/modules/vulkan/memory/vktMemoryPipelineBarrierTests.cpp @@ -66,6 +66,7 @@ using std::set; using std::pair; using tcu::IVec2; +using tcu::UVec2; using tcu::UVec4; using tcu::Vec4; using tcu::ConstPixelBufferAccess; @@ -5924,12 +5925,12 @@ public: RenderVertexSampledImage (void) {} ~RenderVertexSampledImage (void); - const char* getName (void) const { return "RenderVertexSampledImage"; } - void logPrepare (TestLog&, size_t) const; - void logSubmit (TestLog&, size_t) const; - void prepare (PrepareRenderPassContext&); - void submit (SubmitContext& context); - void verify (VerifyRenderPassContext&, size_t); + const char* getName (void) const { return "RenderVertexSampledImage"; } + void logPrepare (TestLog&, size_t) const; + void logSubmit (TestLog&, size_t) const; + void prepare (PrepareRenderPassContext&); + void submit (SubmitContext& context); + void verify (VerifyRenderPassContext&, size_t); private: PipelineResources m_resources; @@ -6985,6 +6986,185 @@ void RenderFragmentStorageTexelBuffer::verify (VerifyRenderPassContext& context, } } +class RenderFragmentStorageImage : public RenderPassCommand +{ +public: + RenderFragmentStorageImage (void) {} + ~RenderFragmentStorageImage (void); + + const char* getName (void) const { return "RenderFragmentStorageImage"; } + void logPrepare (TestLog&, size_t) const; + void logSubmit (TestLog&, size_t) const; + void prepare (PrepareRenderPassContext&); + void submit (SubmitContext& context); + void verify (VerifyRenderPassContext&, size_t); + +private: + PipelineResources m_resources; + vk::Move m_descriptorPool; + vk::Move m_descriptorSet; + vk::Move m_imageView; +}; + +RenderFragmentStorageImage::~RenderFragmentStorageImage (void) +{ +} + +void RenderFragmentStorageImage::logPrepare (TestLog& log, size_t commandIndex) const +{ + log << TestLog::Message << commandIndex << ":" << getName() << " Create pipeline for render storage image." << TestLog::EndMessage; +} + +void RenderFragmentStorageImage::logSubmit (TestLog& log, size_t commandIndex) const +{ + log << TestLog::Message << commandIndex << ":" << getName() << " Render using storage image." << TestLog::EndMessage; +} + +void RenderFragmentStorageImage::prepare (PrepareRenderPassContext& context) +{ + const vk::DeviceInterface& vkd = context.getContext().getDeviceInterface(); + const vk::VkDevice device = context.getContext().getDevice(); + const vk::VkRenderPass renderPass = context.getRenderPass(); + const deUint32 subpass = 0; + const vk::Unique vertexShaderModule (vk::createShaderModule(vkd, device, context.getBinaryCollection().get("render-quad.vert"), 0)); + const vk::Unique fragmentShaderModule (vk::createShaderModule(vkd, device, context.getBinaryCollection().get("storage-image.frag"), 0)); + vector bindings; + + { + const vk::VkDescriptorSetLayoutBinding binding = + { + 0u, + vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + 1, + vk::VK_SHADER_STAGE_FRAGMENT_BIT, + DE_NULL + }; + + bindings.push_back(binding); + } + + createPipelineWithResources(vkd, device, renderPass, subpass, *vertexShaderModule, *fragmentShaderModule, context.getTargetWidth(), context.getTargetHeight(), + vector(), vector(), bindings, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 0u, DE_NULL, m_resources); + + { + const vk::VkDescriptorPoolSize poolSizes = + { + vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + 1 + }; + const vk::VkDescriptorPoolCreateInfo createInfo = + { + vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + DE_NULL, + vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, + + 1u, + 1u, + &poolSizes, + }; + + m_descriptorPool = vk::createDescriptorPool(vkd, device, &createInfo); + } + + { + const vk::VkDescriptorSetLayout layout = *m_resources.descriptorSetLayout; + const vk::VkDescriptorSetAllocateInfo allocateInfo = + { + vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + DE_NULL, + + *m_descriptorPool, + 1, + &layout + }; + + m_descriptorSet = vk::allocateDescriptorSet(vkd, device, &allocateInfo); + + { + const vk::VkImageViewCreateInfo createInfo = + { + vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + DE_NULL, + 0u, + + context.getImage(), + vk::VK_IMAGE_VIEW_TYPE_2D, + vk::VK_FORMAT_R8G8B8A8_UNORM, + vk::makeComponentMappingRGBA(), + { + vk::VK_IMAGE_ASPECT_COLOR_BIT, + 0u, + 1u, + 0u, + 1u + } + }; + + m_imageView = vk::createImageView(vkd, device, &createInfo); + } + + { + const vk::VkDescriptorImageInfo imageInfo = + { + 0, + *m_imageView, + vk::VK_IMAGE_LAYOUT_GENERAL + }; + const vk::VkWriteDescriptorSet write = + { + vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + DE_NULL, + *m_descriptorSet, + 0u, + 0u, + 1u, + vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + &imageInfo, + DE_NULL, + DE_NULL, + }; + + vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL); + } + } +} + +void RenderFragmentStorageImage::submit (SubmitContext& context) +{ + const vk::DeviceInterface& vkd = context.getContext().getDeviceInterface(); + const vk::VkCommandBuffer commandBuffer = context.getCommandBuffer(); + + vkd.cmdBindPipeline(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipeline); + + vkd.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_resources.pipelineLayout, 0u, 1u, &(*m_descriptorSet), 0u, DE_NULL); + vkd.cmdDraw(commandBuffer, 6, 1, 0, 0); +} + +void RenderFragmentStorageImage::verify (VerifyRenderPassContext& context, size_t) +{ + const UVec2 size = UVec2(context.getReferenceImage().getWidth(), context.getReferenceImage().getHeight()); + const deUint32 valuesPerPixel = de::max(1u, (size.x() * size.y()) / (256u * 256u)); + + for (int y = 0; y < context.getReferenceTarget().getSize().y(); y++) + for (int x = 0; x < context.getReferenceTarget().getSize().x(); x++) + { + UVec4 value = UVec4(x, y, 0u, 0u); + + for (deUint32 i = 0; i < valuesPerPixel; i++) + { + const UVec2 pos = UVec2(value.z() * 256u + (value.x() ^ value.z()), value.w() * 256u + (value.y() ^ value.w())); + const Vec4 floatValue = context.getReferenceImage().getAccess().getPixel(pos.x() % size.x(), pos.y() % size.y()); + + value = UVec4((deUint32)(floatValue.x() * 255.0f), + (deUint32)(floatValue.y() * 255.0f), + (deUint32)(floatValue.z() * 255.0f), + (deUint32)(floatValue.w() * 255.0f)); + + } + context.getReferenceTarget().getAccess().setPixel(value.asFloat() / Vec4(255.0f), x, y); + } +} + enum Op { OP_MAP, @@ -7059,6 +7239,8 @@ enum Op OP_RENDER_FRAGMENT_STORAGE_TEXEL_BUFFER, OP_RENDER_VERTEX_STORAGE_IMAGE, + OP_RENDER_FRAGMENT_STORAGE_IMAGE, + OP_RENDER_VERTEX_SAMPLED_IMAGE, }; @@ -7956,10 +8138,13 @@ void getAvailableOps (const State& state, bool supportsBuffers, bool supportsIma if ((usage & USAGE_STORAGE_IMAGE) != 0 && state.imageDefined && state.hasBoundImageMemory - && (state.imageLayout == vk::VK_IMAGE_LAYOUT_GENERAL) - && state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT)) + && (state.imageLayout == vk::VK_IMAGE_LAYOUT_GENERAL)) { - ops.push_back(OP_RENDER_VERTEX_STORAGE_IMAGE); + if (state.cache.isValid(vk::VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT)) + ops.push_back(OP_RENDER_VERTEX_STORAGE_IMAGE); + + if (state.cache.isValid(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT)) + ops.push_back(OP_RENDER_FRAGMENT_STORAGE_IMAGE); } if ((usage & USAGE_SAMPLED_IMAGE) != 0 @@ -8330,6 +8515,15 @@ void applyOp (State& state, const Memory& memory, Op op, Usage usage) break; } + case OP_RENDER_FRAGMENT_STORAGE_IMAGE: + { + DE_ASSERT(state.stage == STAGE_RENDER_PASS); + + state.renderPassIsEmpty = false; + state.cache.perform(vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_ACCESS_SHADER_READ_BIT); + break; + } + case OP_RENDER_VERTEX_STORAGE_IMAGE: case OP_RENDER_VERTEX_SAMPLED_IMAGE: { @@ -8525,6 +8719,8 @@ de::MovePtr createRenderPassCommand (de::Random&, case OP_RENDER_FRAGMENT_STORAGE_TEXEL_BUFFER: return de::MovePtr(new RenderFragmentStorageTexelBuffer()); case OP_RENDER_VERTEX_STORAGE_IMAGE: return de::MovePtr(new RenderVertexStorageImage()); + case OP_RENDER_FRAGMENT_STORAGE_IMAGE: return de::MovePtr(new RenderFragmentStorageImage()); + case OP_RENDER_VERTEX_SAMPLED_IMAGE: return de::MovePtr(new RenderVertexSampledImage()); default: @@ -9321,28 +9517,53 @@ struct AddPrograms if (config.usage & USAGE_STORAGE_IMAGE) { - // Vertex storage image - const char* const vertexShader = - "#version 450\n" - "highp float;\n" - "layout(set=0, binding=0, rgba8) uniform image2D u_image;\n" - "out gl_PerVertex {\n" - "\tvec4 gl_Position;\n" - "\tfloat gl_PointSize;\n" - "};\n" - "void main (void) {\n" - "\tgl_PointSize = 1.0;\n" - "\thighp vec4 val = imageLoad(u_image, ivec2((gl_VertexIndex / 2) / imageSize(u_image).x, (gl_VertexIndex / 2) % imageSize(u_image).x));\n" - "\thighp vec2 pos;\n" - "\tif (gl_VertexIndex % 2 == 0)\n" - "\t\tpos = val.xy;\n" - "\telse\n" - "\t\tpos = val.zw;\n" - "\tgl_Position = vec4(1.998 * pos - vec2(0.999), 0.0, 1.0);\n" - "}\n"; + { + // Vertex storage image + const char* const vertexShader = + "#version 450\n" + "highp float;\n" + "layout(set=0, binding=0, rgba8) uniform image2D u_image;\n" + "out gl_PerVertex {\n" + "\tvec4 gl_Position;\n" + "\tfloat gl_PointSize;\n" + "};\n" + "void main (void) {\n" + "\tgl_PointSize = 1.0;\n" + "\thighp vec4 val = imageLoad(u_image, ivec2((gl_VertexIndex / 2) / imageSize(u_image).x, (gl_VertexIndex / 2) % imageSize(u_image).x));\n" + "\thighp vec2 pos;\n" + "\tif (gl_VertexIndex % 2 == 0)\n" + "\t\tpos = val.xy;\n" + "\telse\n" + "\t\tpos = val.zw;\n" + "\tgl_Position = vec4(1.998 * pos - vec2(0.999), 0.0, 1.0);\n" + "}\n"; - sources.glslSources.add("storage-image.vert") - << glu::VertexSource(vertexShader); + sources.glslSources.add("storage-image.vert") + << glu::VertexSource(vertexShader); + } + { + // Fragment storage image + const char* const fragmentShader = + "#version 450\n" + "#extension GL_EXT_texture_buffer : require\n" + "highp float;\n" + "layout(set=0, binding=0, rgba8) uniform image2D u_image;\n" + "layout(location = 0) out highp vec4 o_color;\n" + "void main (void) {\n" + "\thighp uvec2 size = uvec2(imageSize(u_image).x, imageSize(u_image).y);\n" + "\thighp uint valuesPerPixel = max(1u, (size.x * size.y) / (256u * 256u));\n" + "\thighp uvec4 value = uvec4(uint(gl_FragCoord.x), uint(gl_FragCoord.y), 0u, 0u);\n" + "\tfor (uint i = 0u; i < valuesPerPixel; i++)\n" + "\t{\n" + "\t\thighp vec4 floatValue = imageLoad(u_image, ivec2(int((value.z * 256u + (value.x ^ value.z)) % size.x), int((value.w * 256u + (value.y ^ value.w)) % size.y)));\n" + "\t\tvalue = uvec4(uint(floatValue.x * 255.0), uint(floatValue.y * 255.0), uint(floatValue.z * 255.0), uint(floatValue.w * 255.0));\n" + "\t}\n" + "\to_color = vec4(value) / vec4(255.0);\n" + "}\n"; + + sources.glslSources.add("storage-image.frag") + << glu::FragmentSource(fragmentShader); + } } if (config.usage & USAGE_SAMPLED_IMAGE) -- 2.7.4