diff --git a/util/test/demos/vk/vk_robustness2.cpp b/util/test/demos/vk/vk_robustness2.cpp index 11e278c3b..c7f0d9c12 100644 --- a/util/test/demos/vk/vk_robustness2.cpp +++ b/util/test/demos/vk/vk_robustness2.cpp @@ -87,6 +87,18 @@ layout(set = 0, binding = 12, std430) buffer storebuftype layout(set = 0, binding = 13, rgba32f) uniform coherent image2D storeImage; +layout(set = 1, binding = 5) uniform sampler2D linearSampledImage2; + +layout(set = 1, binding = 10, std140) uniform constsbuf2 +{ + vec4 data; +} cbuf2; + +layout(set = 1, binding = 20, std140) uniform constsbuf3 +{ + vec4 data; +} cbuf3; + layout(location = 0) in v2f vertIn; @@ -96,7 +108,9 @@ void main() { imageStore(oobImage, push.coord.xy, vec4(1,2,3,4)); oobbuf.arr[push.coord.z] = vec4(1,2,3,4); - Color = vertIn.col + storebuf.arr[0] + imageLoad(storeImage, ivec2(0, 0)) + texture(linearSampledImage, vec2(0, 0)); + Color = vertIn.col + storebuf.arr[0] + imageLoad(storeImage, ivec2(0, 0)) + texture(linearSampledImage, vec2(0, 0)) + + texture(linearSampledImage2, vec2(0, 0)) + cbuf.data + cbuf2.data + cbuf3.data + + vec4(0,1,0,1); } )EOSHADER"; @@ -110,6 +124,8 @@ void main() // require descriptor indexing devExts.push_back(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME); + optDevExts.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + features.robustBufferAccess = VK_TRUE; features.fragmentStoresAndAtomics = VK_TRUE; @@ -133,6 +149,8 @@ void main() if(!Init()) return 3; + bool KHR_push_descriptor = hasExt(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + VkDescriptorSetLayout setlayout = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({ {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, {3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, @@ -143,11 +161,32 @@ void main() {13, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, })); - VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo( - {setlayout}, - { - vkh::PushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4i)), - })); + VkPipelineLayout layout; + + if(KHR_push_descriptor) + { + VkDescriptorSetLayout pushlayout = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo( + { + {5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, + {10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, + {20, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, + }, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)); + + layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo( + {setlayout, pushlayout}, + { + vkh::PushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4i)), + })); + } + else + { + layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo( + {setlayout}, + { + vkh::PushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4i)), + })); + } vkh::GraphicsPipelineCreateInfo pipeCreateInfo; @@ -236,13 +275,37 @@ void main() Vec4i push = {}; if(robustnessFeatures.robustBufferAccess2) + { push.z = 1000000; + setMarker(cmd, "robustBufferAccess2"); + } + if(robustnessFeatures.robustImageAccess2) + { push.x = push.y = 1000000; + setMarker(cmd, "robustImageAccess2"); + } vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, {descset}, {}); vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4i), &push); + if(KHR_push_descriptor) + { + vkCmdPushDescriptorSetKHR( + cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, 1, + vkh::WriteDescriptorSet( + VK_NULL_HANDLE, 5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + {vkh::DescriptorImageInfo(VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED, pointsampler)})); + vkCmdPushDescriptorSetKHR( + cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, 1, + vkh::WriteDescriptorSet(VK_NULL_HANDLE, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + {vkh::DescriptorBufferInfo(VK_NULL_HANDLE)})); + vkCmdPushDescriptorSetKHR( + cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 1, 1, + vkh::WriteDescriptorSet(VK_NULL_HANDLE, 20, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + {vkh::DescriptorBufferInfo(VK_NULL_HANDLE)})); + } + vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe); vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport); vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor); diff --git a/util/test/tests/Vulkan/VK_Robustness2.py b/util/test/tests/Vulkan/VK_Robustness2.py new file mode 100644 index 000000000..3bb28425f --- /dev/null +++ b/util/test/tests/Vulkan/VK_Robustness2.py @@ -0,0 +1,101 @@ +import renderdoc as rd +import rdtest + + +class VK_Robustness2(rdtest.TestCase): + demos_test_name = 'VK_Robustness2' + + def check_capture(self): + draw: rd.DrawcallDescription = self.find_draw('vkCmdDraw') + + self.controller.SetFrameEvent(draw.eventId, True) + + self.check_triangle() + + rdtest.log.success('Triangle is rendered correctly') + + vsin_ref = { + 0: { + 'vtx': 0, + 'idx': 0, + 'Position': [-0.5, -0.5, 0.0], + 'Color': None, + 'UV': None, + }, + 1: { + 'vtx': 1, + 'idx': 1, + 'Position': [0.0, 0.5, 0.0], + 'Color': None, + 'UV': None, + }, + 2: { + 'vtx': 2, + 'idx': 2, + 'Position': [0.5, -0.5, 0.0], + 'Color': None, + 'UV': None, + }, + } + + self.check_mesh_data(vsin_ref, self.get_vsin(draw)) + + rdtest.log.success('Mesh input data is correct, including unbound VB') + + postvs_data = self.get_postvs(draw, rd.MeshDataStage.VSOut, 0, draw.numIndices) + + postvs_ref = { + 0: { + 'vtx': 0, + 'idx': 0, + 'gl_PerVertex_var.gl_Position': [-0.5, 0.5, 0.0, 1.0], + 'vertOut.pos': [-0.5, 0.5, 0.0, 1.0], + 'vertOut.col': [0.0, 0.0, 0.0, 0.0], + 'vertOut.uv': [0.0, 0.0, 0.0, 1.0], + }, + 1: { + 'vtx': 1, + 'idx': 1, + 'gl_PerVertex_var.gl_Position': [0.0, -0.5, 0.0, 1.0], + 'vertOut.pos': [0.0, -0.5, 0.0, 1.0], + 'vertOut.col': [0.0, 0.0, 0.0, 0.0], + 'vertOut.uv': [0.0, 0.0, 0.0, 1.0], + }, + 2: { + 'vtx': 2, + 'idx': 2, + 'gl_PerVertex_var.gl_Position': [0.5, 0.5, 0.0, 1.0], + 'vertOut.pos': [0.5, 0.5, 0.0, 1.0], + 'vertOut.col': [0.0, 0.0, 0.0, 0.0], + 'vertOut.uv': [0.0, 0.0, 0.0, 1.0], + }, + } + + self.check_mesh_data(postvs_ref, postvs_data) + + rdtest.log.success('Mesh output data is correct, including unbound VB') + + pipe = self.controller.GetPipelineState() + refl = pipe.GetShaderReflection(rd.ShaderStage.Fragment) + mapping = pipe.GetBindpointMapping(rd.ShaderStage.Fragment) + + for i, cb in enumerate(refl.constantBlocks): + cbuf = pipe.GetConstantBuffer(rd.ShaderStage.Fragment, i, 0) + + var_check = rdtest.ConstantBufferChecker( + self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(), + pipe.GetShader(rd.ShaderStage.Fragment), refl.entryPoint, i, + cbuf.resourceId, cbuf.byteOffset, cbuf.byteSize)) + + if cb.bufferBacked: + var_check.check('data').type(rd.VarType.Float).rows(1).cols(4).value([0.0, 0.0, 0.0, 0.0]) + else: + val = [0, 0, 0, 0] + if self.find_draw('robustBufferAccess2') is not None: + val[2] = 1000000 + if self.find_draw('robustImageAccess2') is not None: + val[0] = val[1] = 1000000 + var_check.check('coord').type(rd.VarType.SInt).rows(1).cols(4).value(val) + + rdtest.log.success('CBuffer {} at bindpoint {}.{}[0] contains the correct contents' + .format(cb.name, mapping.constantBlocks[i].bindset, mapping.constantBlocks[i].bind))