| 26 | }; |
| 27 | |
| 28 | TEST_F(PositiveGpuAVShaderObject, RestoreUserPushConstants) { |
| 29 | TEST_DESCRIPTION("Test that user supplied push constants are correctly restored. One graphics pipeline, indirect draw."); |
| 30 | InitBasicShaderObject(); |
| 31 | AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); |
| 32 | AddRequiredFeature(vkt::Feature::bufferDeviceAddress); |
| 33 | RETURN_IF_SKIP(InitGpuAvFramework()); |
| 34 | RETURN_IF_SKIP(InitState()); |
| 35 | InitDynamicRenderTarget(); |
| 36 | |
| 37 | vkt::Buffer indirect_draw_parameters_buffer(*m_device, sizeof(VkDrawIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, |
| 38 | kHostVisibleMemProps); |
| 39 | auto& indirect_draw_parameters = *static_cast<VkDrawIndirectCommand*>(indirect_draw_parameters_buffer.Memory().Map()); |
| 40 | indirect_draw_parameters.vertexCount = 3; |
| 41 | indirect_draw_parameters.instanceCount = 1; |
| 42 | indirect_draw_parameters.firstVertex = 0; |
| 43 | indirect_draw_parameters.firstInstance = 0; |
| 44 | |
| 45 | constexpr int32_t int_count = 16; |
| 46 | vkt::Buffer storage_buffer(*m_device, int_count * sizeof(int32_t), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, vkt::device_address); |
| 47 | |
| 48 | // Use different push constant ranges for vertex and fragment shader. |
| 49 | // The underlying storage buffer is the same. |
| 50 | // Vertex shader will fill the first 8 integers, fragment shader the other 8 |
| 51 | struct PushConstants { |
| 52 | // Vertex shader |
| 53 | VkDeviceAddress storage_buffer_ptr_1; |
| 54 | int32_t integers_1[int_count / 2]; |
| 55 | // Fragment shader |
| 56 | VkDeviceAddress storage_buffer_ptr_2; |
| 57 | int32_t integers_2[int_count / 2]; |
| 58 | } push_constants; |
| 59 | |
| 60 | push_constants.storage_buffer_ptr_1 = storage_buffer.Address(); |
| 61 | push_constants.storage_buffer_ptr_2 = storage_buffer.Address() + sizeof(int32_t) * (int_count / 2); |
| 62 | for (int32_t i = 0; i < int_count / 2; ++i) { |
| 63 | push_constants.integers_1[i] = i; |
| 64 | push_constants.integers_2[i] = (int_count / 2) + i; |
| 65 | } |
| 66 | |
| 67 | constexpr uint32_t shader_pcr_byte_size = uint32_t(sizeof(VkDeviceAddress)) + uint32_t(sizeof(int32_t)) * (int_count / 2); |
| 68 | std::array<VkPushConstantRange, 2> push_constant_ranges = {{ |
| 69 | {VK_SHADER_STAGE_VERTEX_BIT, 0, shader_pcr_byte_size}, |
| 70 | {VK_SHADER_STAGE_FRAGMENT_BIT, shader_pcr_byte_size, shader_pcr_byte_size}, |
| 71 | }}; |
| 72 | VkPipelineLayoutCreateInfo plci = vku::InitStructHelper(); |
| 73 | plci.pushConstantRangeCount = size32(push_constant_ranges); |
| 74 | plci.pPushConstantRanges = push_constant_ranges.data(); |
| 75 | vkt::PipelineLayout pipeline_layout(*m_device, plci); |
| 76 | |
| 77 | const char* vs_source = R"glsl( |
| 78 | #version 450 |
| 79 | #extension GL_EXT_buffer_reference : enable |
| 80 | |
| 81 | layout(buffer_reference, std430, buffer_reference_align = 16) buffer MyPtrType { |
| 82 | int out_array[8]; |
| 83 | }; |
| 84 | |
| 85 | layout(push_constant) uniform PushConstants { |
nothing calls this directly
no test coverage detected