diff --git a/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp b/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp index 488c12ae4..58c77cdad 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp @@ -66,7 +66,7 @@ static ShaderVariableType MakeShaderVariableType(DXBC::CBufferVariableType type) { uint32_t stride = type.descriptor.bytesize / RDCMAX(1U, type.descriptor.elements); RDCASSERTMSG("Stride is too large for uint16_t", stride <= 0xffff); - ret.descriptor.arrayByteStride = RDCMIN(stride, 0xffffu) & 0xffff; + ret.descriptor.arrayByteStride = AlignUp16(RDCMIN(stride, 0xffffu) & 0xffff); ret.descriptor.rows = ret.descriptor.columns = 0; } diff --git a/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp b/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp index 27a970829..d20aa6fdb 100644 --- a/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp +++ b/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp @@ -60,6 +60,12 @@ struct nested_with_empty float2 c; // 4, 5, <6, 7> }; +struct misaligned_struct +{ + float4 a; + float2 b; +}; + cbuffer consts : register(b0) { // dummy* entries are just to 'reset' packing to avoid pollution between tests @@ -268,7 +274,16 @@ cbuffer consts : register(b0) nested_with_empty nested_empty; // empty struct will take up a float4 - float4 test; // {520, 521, 522, 523} + misaligned_struct ao[2]; // [0] = { + // .a = { 520, 521, 522, 523 } + // .b = { 524, 525 } <526, 527> + // } + // [1] = { + // .a = { 528, 529, 530, 531 } + // .b = { 532, 533 } <534, 535> + // } + + float4 test; // {536, 537, 538, 539} }; float4 main() : SV_Target0 diff --git a/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp b/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp index a19bb3ae6..0b3f7d3e2 100644 --- a/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp +++ b/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp @@ -60,6 +60,12 @@ struct nested_with_empty float2 c; // 4, 5, <6, 7> }; +struct misaligned_struct +{ + float4 a; + float2 b; +}; + cbuffer consts : register(b7) { // dummy* entries are just to 'reset' packing to avoid pollution between tests @@ -268,7 +274,16 @@ cbuffer consts : register(b7) nested_with_empty nested_empty; // empty struct will take up a float4 - float4 test; // {520, 521, 522, 523} + misaligned_struct ao[2]; // [0] = { + // .a = { 520, 521, 522, 523 } + // .b = { 524, 525 } <526, 527> + // } + // [1] = { + // .a = { 528, 529, 530, 531 } + // .b = { 532, 533 } <534, 535> + // } + + float4 test; // {536, 537, 538, 539} }; // this comes from root signature constants diff --git a/util/test/demos/gl/gl_cbuffer_zoo.cpp b/util/test/demos/gl/gl_cbuffer_zoo.cpp index 463cd64e9..76ec94818 100644 --- a/util/test/demos/gl/gl_cbuffer_zoo.cpp +++ b/util/test/demos/gl/gl_cbuffer_zoo.cpp @@ -84,6 +84,12 @@ struct nested_with_padding // [3]: {24, 25, 26}, <27> }; +struct misaligned_struct +{ + vec4 a; + vec2 b; +}; + layout(binding = 0, std140) uniform constsbuf { // dummy* entries are just to 'reset' packing to avoid pollution between tests @@ -284,12 +290,21 @@ layout(binding = 0, std140) uniform constsbuf vec4 dummy13[2]; // empty structs on D3D - vec4 test; // {520, 521, 522, 523} + misaligned_struct ao[2]; // [0] = { + // .a = { 520, 521, 522, 523 } + // .b = { 524, 525 } <526, 527> + // } + // [1] = { + // .a = { 528, 529, 530, 531 } + // .b = { 532, 533 } <534, 535> + // } + + vec4 test; // {536, 537, 538, 539} // because GL has worse handling of multidimensional arrays than other APIs, we add an extra test // here with more than 2 dimensions - vec4 multiarray2[4][3][2]; // [0][0][0] = {524, 525, 526, ...} + vec4 multiarray2[4][3][2]; // [0][0][0] = {540, 541, 542, ...} // [0][0][1] = {..., ..., ..., ...} // [0][1][0] = {..., ..., ..., ...} // [0][1][1] = {..., ..., ..., ...} diff --git a/util/test/demos/vk/vk_cbuffer_zoo.cpp b/util/test/demos/vk/vk_cbuffer_zoo.cpp index 47a0bc2e5..fe5f10ad8 100644 --- a/util/test/demos/vk/vk_cbuffer_zoo.cpp +++ b/util/test/demos/vk/vk_cbuffer_zoo.cpp @@ -83,6 +83,12 @@ struct nested_with_padding // [3]: {24, 25, 26}, <27> }; +struct misaligned_struct +{ + vec4 a; + vec2 b; +}; + layout(set = 0, binding = 0, std140) uniform constsbuf { // dummy* entries are just to 'reset' packing to avoid pollution between tests @@ -283,7 +289,16 @@ layout(set = 0, binding = 0, std140) uniform constsbuf vec4 dummy13[2]; // empty structs on D3D - vec4 test; // {520, 521, 522, 523} + misaligned_struct ao[2]; // [0] = { + // .a = { 520, 521, 522, 523 } + // .b = { 524, 525 } <526, 527> + // } + // [1] = { + // .a = { 528, 529, 530, 531 } + // .b = { 532, 533 } <534, 535> + // } + + vec4 test; // {536, 537, 538, 539} }; layout (constant_id = 0) const int A = 10; @@ -316,6 +331,12 @@ struct nested_with_padding // [3]: {24, 25, 26}, <27> }; +struct misaligned_struct +{ + float4 a; + float2 b; +}; + layout(set = 0, binding = 0) cbuffer consts { // dummy* entries are just to 'reset' packing to avoid pollution between tests @@ -526,7 +547,16 @@ layout(set = 0, binding = 0) cbuffer consts float4 dummy15[2]; // empty structs on D3D - float4 test; // {520, 521, 522, 523} + misaligned_struct ao[2]; // [0] = { + // .a = { 520, 521, 522, 523 } + // .b = { 524, 525 } <526, 527> + // } + // [1] = { + // .a = { 528, 529, 530, 531 } + // .b = { 532, 533 } <534, 535> + // } + + float4 test; // {536, 537, 538, 539} }; float4 main() : SV_Target0 diff --git a/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py b/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py index ed615254e..825336395 100644 --- a/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py +++ b/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py @@ -69,16 +69,16 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase): debugged = self.evaluate_source_var(output, variables) - if not rdtest.util.value_compare(debugged.value.fv[0:4], [520.1, 521.0, 522.0, 523.0]): + if not rdtest.util.value_compare(debugged.value.fv[0:4], [536.1, 537.0, 538.0, 539.0]): raise rdtest.TestFailureException( "Debugged output {} did not match expected {}".format( - debugged.value.fv[0:4], [520.1, 521.0, 522.0, 523.0])) + debugged.value.fv[0:4], [536.1, 537.0, 538.0, 539.0])) rdtest.log.success("Debugged output matched as expected") self.controller.FreeTrace(trace) - self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [520.1, 521.0, 522.0, 523.0]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [536.1, 537.0, 538.0, 539.0]) rdtest.log.success("Picked value is as expected") @@ -426,7 +426,20 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase): 'c': lambda y: y.rows(1).cols(2).value([516.0, 517.0]), }) + # misaligned_struct ao[2]; + var_check.check('ao').rows(0).cols(0).arraySize(2).members({ + # ao[0] + 0: lambda s: s.rows(0).cols(0).structSize(2).members({ + 'a': lambda y: y.rows(1).cols(4).value([520.0, 521.0, 522.0, 523.0]), + 'b': lambda y: y.rows(1).cols(2).value([524.0, 525.0]), + }), + 1: lambda s: s.rows(0).cols(0).structSize(2).members({ + 'a': lambda y: y.rows(1).cols(4).value([528.0, 529.0, 530.0, 531.0]), + 'b': lambda y: y.rows(1).cols(2).value([532.0, 533.0]), + }), + }) + # float4 test; - var_check.check('test').rows(1).cols(4).value([520.0, 521.0, 522.0, 523.0]) + var_check.check('test').rows(1).cols(4).value([536.0, 537.0, 538.0, 539.0]) var_check.done() diff --git a/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py b/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py index 2db95819b..a24f217cc 100644 --- a/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py +++ b/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py @@ -110,16 +110,16 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase): debugged = self.evaluate_source_var(output, variables) - if not rdtest.util.value_compare(debugged.value.fv[0:4], [520.1, 521.0, 522.0, 523.0]): + if not rdtest.util.value_compare(debugged.value.fv[0:4], [536.1, 537.0, 538.0, 539.0]): raise rdtest.TestFailureException( "Debugged output {} did not match expected {}".format( - debugged.value.fv[0:4], [520.1, 521.0, 522.0, 523.0])) + debugged.value.fv[0:4], [536.1, 537.0, 538.0, 539.0])) rdtest.log.success("Debugged output matched as expected") self.controller.FreeTrace(trace) - self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [520.1, 521.0, 522.0, 523.0]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [536.1, 537.0, 538.0, 539.0]) rdtest.log.success("Picked value is as expected") @@ -467,8 +467,21 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase): 'c': lambda y: y.rows(1).cols(2).value([516.0, 517.0]), }) + # misaligned_struct ao[2]; + var_check.check('ao').rows(0).cols(0).arraySize(2).members({ + # ao[0] + 0: lambda s: s.rows(0).cols(0).structSize(2).members({ + 'a': lambda y: y.rows(1).cols(4).value([520.0, 521.0, 522.0, 523.0]), + 'b': lambda y: y.rows(1).cols(2).value([524.0, 525.0]), + }), + 1: lambda s: s.rows(0).cols(0).structSize(2).members({ + 'a': lambda y: y.rows(1).cols(4).value([528.0, 529.0, 530.0, 531.0]), + 'b': lambda y: y.rows(1).cols(2).value([532.0, 533.0]), + }), + }) + # float4 test; - var_check.check('test').rows(1).cols(4).value([520.0, 521.0, 522.0, 523.0]) + var_check.check('test').rows(1).cols(4).value([536.0, 537.0, 538.0, 539.0]) var_check.done() diff --git a/util/test/tests/GL/GL_CBuffer_Zoo.py b/util/test/tests/GL/GL_CBuffer_Zoo.py index c3b39afa5..063a1809e 100644 --- a/util/test/tests/GL/GL_CBuffer_Zoo.py +++ b/util/test/tests/GL/GL_CBuffer_Zoo.py @@ -342,11 +342,24 @@ class GL_CBuffer_Zoo(rdtest.TestCase): # float4 dummy13[2]; var_check.check('dummy13') + # misaligned_struct ao[2]; + var_check.check('ao').rows(0).cols(0).arraySize(2).members({ + # ao[0] + 0: lambda s: s.rows(0).cols(0).structSize(2).members({ + 'a': lambda y: y.rows(1).cols(4).value([520.0, 521.0, 522.0, 523.0]), + 'b': lambda y: y.rows(1).cols(2).value([524.0, 525.0]), + }), + 1: lambda s: s.rows(0).cols(0).structSize(2).members({ + 'a': lambda y: y.rows(1).cols(4).value([528.0, 529.0, 530.0, 531.0]), + 'b': lambda y: y.rows(1).cols(2).value([532.0, 533.0]), + }), + }) + # float4 test; - var_check.check('test').rows(1).cols(4).value([520.0, 521.0, 522.0, 523.0]) + var_check.check('test').rows(1).cols(4).value([536.0, 537.0, 538.0, 539.0]) # to save duplicating if this array changes, we calculate out from the start, as the array is tightly packed - base = 524.0 + base = 540.0 exp_vals = lambda wi,yi,xi: [base + wi * 24.0 + yi * 8.0 + xi * 4.0 + c * 1.0 for c in range(0,4)] @@ -414,7 +427,7 @@ class GL_CBuffer_Zoo(rdtest.TestCase): rdtest.log.success("CBuffer variables are as expected") - self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [520.1, 521.0, 522.0, 523.0]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [536.1, 537.0, 538.0, 539.0]) rdtest.log.success("Picked value is as expected") diff --git a/util/test/tests/Vulkan/VK_CBuffer_Zoo.py b/util/test/tests/Vulkan/VK_CBuffer_Zoo.py index 591ced6bc..b8e9fcc48 100644 --- a/util/test/tests/Vulkan/VK_CBuffer_Zoo.py +++ b/util/test/tests/Vulkan/VK_CBuffer_Zoo.py @@ -36,7 +36,7 @@ class VK_CBuffer_Zoo(rdtest.TestCase): rdtest.log.success("GLSL CBuffer variables are as expected") - self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [520.1, 521.0, 522.0, 523.0]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [536.1, 537.0, 538.0, 539.0]) rdtest.log.success("GLSL picked value is as expected") @@ -92,7 +92,7 @@ class VK_CBuffer_Zoo(rdtest.TestCase): rdtest.log.success("HLSL CBuffer variables are as expected") - self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [520.1, 521.0, 522.0, 523.0]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [536.1, 537.0, 538.0, 539.0]) rdtest.log.success("HLSL picked value is as expected") @@ -416,8 +416,21 @@ class VK_CBuffer_Zoo(rdtest.TestCase): # float4 dummy13[2]; var_check.check('dummy13') + # misaligned_struct ao[2]; + var_check.check('ao').rows(0).cols(0).arraySize(2).members({ + # ao[0] + 0: lambda s: s.rows(0).cols(0).structSize(2).members({ + 'a': lambda y: y.rows(1).cols(4).value([520.0, 521.0, 522.0, 523.0]), + 'b': lambda y: y.rows(1).cols(2).value([524.0, 525.0]), + }), + 1: lambda s: s.rows(0).cols(0).structSize(2).members({ + 'a': lambda y: y.rows(1).cols(4).value([528.0, 529.0, 530.0, 531.0]), + 'b': lambda y: y.rows(1).cols(2).value([532.0, 533.0]), + }), + }) + # float4 test; - var_check.check('test').rows(1).cols(4).value([520.0, 521.0, 522.0, 523.0]) + var_check.check('test').rows(1).cols(4).value([536.0, 537.0, 538.0, 539.0]) var_check.done() @@ -762,8 +775,21 @@ class VK_CBuffer_Zoo(rdtest.TestCase): # float4 dummy15[2]; var_check.check('dummy15') + # misaligned_struct ao[2]; + var_check.check('ao').rows(0).cols(0).arraySize(2).members({ + # ao[0] + 0: lambda s: s.rows(0).cols(0).structSize(2).members({ + 'a': lambda y: y.rows(1).cols(4).value([520.0, 521.0, 522.0, 523.0]), + 'b': lambda y: y.rows(1).cols(2).value([524.0, 525.0]), + }), + 1: lambda s: s.rows(0).cols(0).structSize(2).members({ + 'a': lambda y: y.rows(1).cols(4).value([528.0, 529.0, 530.0, 531.0]), + 'b': lambda y: y.rows(1).cols(2).value([532.0, 533.0]), + }), + }) + # float4 test; - var_check.check('test').rows(1).cols(4).value([520.0, 521.0, 522.0, 523.0]) + var_check.check('test').rows(1).cols(4).value([536.0, 537.0, 538.0, 539.0]) var_check.done()