diff --git a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp index b2eda1270..f34a0acab 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_container.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_container.cpp @@ -436,7 +436,7 @@ CBufferVariableType DXBCContainer::ParseRDEFType(RDEFHeader *h, char *chunkConte v.type = ParseRDEFType(h, chunkContents, members[j].typeOffset); v.descriptor.offset = members[j].memberOffset; - ret.descriptor.bytesize += v.type.descriptor.bytesize; + ret.descriptor.bytesize = v.descriptor.offset + v.type.descriptor.bytesize; // N/A v.descriptor.flags = 0; @@ -456,14 +456,25 @@ CBufferVariableType DXBCContainer::ParseRDEFType(RDEFHeader *h, char *chunkConte // matrices take up a full vector for each column or row depending which is major, regardless of // the other dimension if(ret.descriptor.varClass == CLASS_MATRIX_COLUMNS) + { ret.descriptor.bytesize = TypeByteSize(ret.descriptor.type) * ret.descriptor.cols * 4 * RDCMAX(1U, ret.descriptor.elements); + } else if(ret.descriptor.varClass == CLASS_MATRIX_ROWS) + { ret.descriptor.bytesize = TypeByteSize(ret.descriptor.type) * ret.descriptor.rows * 4 * RDCMAX(1U, ret.descriptor.elements); + } else - ret.descriptor.bytesize = TypeByteSize(ret.descriptor.type) * ret.descriptor.rows * - ret.descriptor.cols * RDCMAX(1U, ret.descriptor.elements); + { + // arrays also take up a full vector for each element + if(ret.descriptor.elements > 1) + ret.descriptor.bytesize = + TypeByteSize(ret.descriptor.type) * 4 * RDCMAX(1U, ret.descriptor.elements); + else + ret.descriptor.bytesize = + TypeByteSize(ret.descriptor.type) * ret.descriptor.rows * ret.descriptor.cols; + } } m_Variables[typeOffset] = ret; diff --git a/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp b/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp index a2ab56c7b..a34df4ec2 100644 --- a/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp +++ b/util/test/demos/d3d11/d3d11_cbuffer_zoo.cpp @@ -36,6 +36,17 @@ struct float3_1 { float3 a; float b; }; struct nested { float3_1 a; float4 b[4]; float3_1 c[4]; }; +struct nested_with_padding +{ + float a; // 0, <1, 2, 3> + float4 b; // {4, 5, 6, 7} + float c; // 8, <9, 10, 11> + float3 d[4]; // [0]: {12, 13, 14}, <15> + // [1]: {16, 17, 18}, <19> + // [2]: {20, 21, 22}, <23> + // [3]: {24, 25, 26}, <27> +}; + cbuffer consts : register(b0) { // dummy* entries are just to 'reset' packing to avoid pollution between tests @@ -225,8 +236,10 @@ cbuffer consts : register(b0) // <434, 438> // <435, 439> // } + + nested_with_padding ak[2]; // 440 - 467, 468 - 495 - float4 test; // {440, 441, 442, 443} + float4 test; // {496, 497, 498, 499} }; 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 549b770af..36cb8405c 100644 --- a/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp +++ b/util/test/demos/d3d12/d3d12_cbuffer_zoo.cpp @@ -36,6 +36,17 @@ struct float3_1 { float3 a; float b; }; struct nested { float3_1 a; float4 b[4]; float3_1 c[4]; }; +struct nested_with_padding +{ + float a; // 0, <1, 2, 3> + float4 b; // {4, 5, 6, 7} + float c; // 8, <9, 10, 11> + float3 d[4]; // [0]: {12, 13, 14}, <15> + // [1]: {16, 17, 18}, <19> + // [2]: {20, 21, 22}, <23> + // [3]: {24, 25, 26}, <27> +}; + cbuffer consts : register(b0) { // dummy* entries are just to 'reset' packing to avoid pollution between tests @@ -225,8 +236,10 @@ cbuffer consts : register(b0) // <434, 438> // <435, 439> // } + + nested_with_padding ak[2]; // 440 - 467, 468 - 495 - float4 test; // {440, 441, 442, 443} + float4 test; // {496, 497, 498, 499} }; // 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 31ffd029f..94792d5d0 100644 --- a/util/test/demos/gl/gl_cbuffer_zoo.cpp +++ b/util/test/demos/gl/gl_cbuffer_zoo.cpp @@ -71,6 +71,17 @@ struct vec3_1 { vec3 a; float b; }; struct nested { vec3_1 a; vec4 b[4]; vec3_1 c[4]; }; +struct nested_with_padding +{ + float a; // 0, <1, 2, 3> + vec4 b; // {4, 5, 6, 7} + float c; // 8, <9, 10, 11> + vec3 d[4]; // [0]: {12, 13, 14}, <15> + // [1]: {16, 17, 18}, <19> + // [2]: {20, 21, 22}, <23> + // [3]: {24, 25, 26}, <27> +}; + layout(binding = 0, std140) uniform constsbuf { // dummy* entries are just to 'reset' packing to avoid pollution between tests @@ -257,14 +268,16 @@ layout(binding = 0, std140) uniform constsbuf // <435, 439> // } - vec4 test; // {440, 441, 442, 443} + nested_with_padding ak[2]; // 440 - 467, 468 - 495 + + vec4 test; // {496, 497, 498, 499} // 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] = {444, 445, 446, 447} - // [0][0][1] = {448, 449, 450, 451} - // [0][1][0] = {452, ..., ..., ...} + vec4 multiarray2[4][3][2]; // [0][0][0] = {500, 501, 502, 503} + // [0][0][1] = {504, 505, 506, 507} + // [0][1][0] = {508, ..., ..., ...} // [0][1][1] = {..., ..., ..., ...} // [0][2][0] = {..., ..., ..., ...} // [0][2][1] = {..., ..., ..., ...} @@ -335,9 +348,9 @@ void main() GLuint program = MakeProgram(common + vertex, common + pixel); - Vec4f cbufferdata[684]; + Vec4f cbufferdata[1024]; - for(int i = 0; i < 684; i++) + for(int i = 0; i < 1024; i++) cbufferdata[i] = Vec4f(float(i * 4 + 0), float(i * 4 + 1), float(i * 4 + 2), float(i * 4 + 3)); GLuint cb = MakeBuffer(); diff --git a/util/test/demos/vk/vk_cbuffer_zoo.cpp b/util/test/demos/vk/vk_cbuffer_zoo.cpp index cf94854dc..9c0ff07d6 100644 --- a/util/test/demos/vk/vk_cbuffer_zoo.cpp +++ b/util/test/demos/vk/vk_cbuffer_zoo.cpp @@ -70,6 +70,17 @@ struct vec3_1 { vec3 a; float b; }; struct nested { vec3_1 a; vec4 b[4]; vec3_1 c[4]; }; +struct nested_with_padding +{ + float a; // 0, <1, 2, 3> + vec4 b; // {4, 5, 6, 7} + float c; // 8, <9, 10, 11> + vec3 d[4]; // [0]: {12, 13, 14}, <15> + // [1]: {16, 17, 18}, <19> + // [2]: {20, 21, 22}, <23> + // [3]: {24, 25, 26}, <27> +}; + layout(set = 0, binding = 0, std140) uniform constsbuf { // dummy* entries are just to 'reset' packing to avoid pollution between tests @@ -256,7 +267,9 @@ layout(set = 0, binding = 0, std140) uniform constsbuf // <435, 439> // } - vec4 test; // {440, 441, 442, 443} + nested_with_padding ak[2]; // 440 - 467, 468 - 495 + + vec4 test; // {496, 497, 498, 499} }; layout (constant_id = 0) const int A = 10; @@ -276,6 +289,17 @@ struct float3_1 { float3 a; float b; }; struct nested { float3_1 a; float4 b[4]; float3_1 c[4]; }; +struct nested_with_padding +{ + float a; // 0, <1, 2, 3> + float4 b; // {4, 5, 6, 7} + float c; // 8, <9, 10, 11> + float3 d[4]; // [0]: {12, 13, 14}, <15> + // [1]: {16, 17, 18}, <19> + // [2]: {20, 21, 22}, <23> + // [3]: {24, 25, 26}, <27> +}; + layout(set = 0, binding = 0) cbuffer consts { // dummy* entries are just to 'reset' packing to avoid pollution between tests @@ -471,8 +495,10 @@ layout(set = 0, binding = 0) cbuffer consts // <434, 438> // <435, 439> // } + + nested_with_padding ak[2]; // 440 - 467, 468 - 495 - float4 test; // {440, 441, 442, 443} + float4 test; // {496, 497, 498, 499} }; 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 9e369e619..f855e0542 100644 --- a/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py +++ b/util/test/tests/D3D11/D3D11_CBuffer_Zoo.py @@ -300,13 +300,48 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase): 433.0, 437.0]), }) + # struct nested_with_padding + # { + # float a; // float3 padding + # float4 b; + # float c; // float3 padding + # float3 d[4]; // float padding after each one + # }; + # nested_with_padding ak[2]; + var_check.check('ak').rows(0).cols(0).arraySize(2).members({ + # ak[0] + 0: lambda s: s.rows(0).cols(0).structSize(4).members({ + 'a': lambda y: y.rows(1).cols(1).value([440.0]), + 'b': lambda y: y.rows(1).cols(4).value([444.0, 445.0, 446.0, 447.0]), + 'c': lambda y: y.rows(1).cols(1).value([448.0]), + 'd': lambda x: x.rows(0).cols(0).arraySize(4).members({ + 0: lambda z: z.rows(1).cols(3).value([452.0, 453.0, 454.0]), + 1: lambda z: z.rows(1).cols(3).value([456.0, 457.0, 458.0]), + 2: lambda z: z.rows(1).cols(3).value([460.0, 461.0, 462.0]), + 3: lambda z: z.rows(1).cols(3).value([464.0, 465.0, 466.0]), + }), + }), + # ak[1] + 1: lambda s: s.rows(0).cols(0).structSize(4).members({ + 'a': lambda y: y.rows(1).cols(1).value([468.0]), + 'b': lambda y: y.rows(1).cols(4).value([472.0, 473.0, 474.0, 475.0]), + 'c': lambda y: y.rows(1).cols(1).value([476.0]), + 'd': lambda x: x.rows(0).cols(0).arraySize(4).members({ + 0: lambda z: z.rows(1).cols(3).value([480.0, 481.0, 482.0]), + 1: lambda z: z.rows(1).cols(3).value([484.0, 485.0, 486.0]), + 2: lambda z: z.rows(1).cols(3).value([488.0, 489.0, 490.0]), + 3: lambda z: z.rows(1).cols(3).value([492.0, 493.0, 494.0]), + }), + }), + }) + # float4 test; - var_check.check('test').rows(1).cols(4).value([440.0, 441.0, 442.0, 443.0]) + var_check.check('test').rows(1).cols(4).value([496.0, 497.0, 498.0, 499.0]) var_check.done() rdtest.log.success("CBuffer variables are as expected") - self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [440.1, 441.0, 442.0, 443.0]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [496.1, 497.0, 498.0, 499.0]) rdtest.log.success("Picked value is as expected") diff --git a/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py b/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py index ab3a0a6e3..33dc6a9fe 100644 --- a/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py +++ b/util/test/tests/D3D12/D3D12_CBuffer_Zoo.py @@ -322,14 +322,49 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase): 433.0, 437.0]), }) + # struct nested_with_padding + # { + # float a; // float3 padding + # float4 b; + # float c; // float3 padding + # float3 d[4]; // float padding after each one + # }; + # nested_with_padding ak[2]; + var_check.check('ak').rows(0).cols(0).arraySize(2).members({ + # ak[0] + 0: lambda s: s.rows(0).cols(0).structSize(4).members({ + 'a': lambda y: y.rows(1).cols(1).value([440.0]), + 'b': lambda y: y.rows(1).cols(4).value([444.0, 445.0, 446.0, 447.0]), + 'c': lambda y: y.rows(1).cols(1).value([448.0]), + 'd': lambda x: x.rows(0).cols(0).arraySize(4).members({ + 0: lambda z: z.rows(1).cols(3).value([452.0, 453.0, 454.0]), + 1: lambda z: z.rows(1).cols(3).value([456.0, 457.0, 458.0]), + 2: lambda z: z.rows(1).cols(3).value([460.0, 461.0, 462.0]), + 3: lambda z: z.rows(1).cols(3).value([464.0, 465.0, 466.0]), + }), + }), + # ak[1] + 1: lambda s: s.rows(0).cols(0).structSize(4).members({ + 'a': lambda y: y.rows(1).cols(1).value([468.0]), + 'b': lambda y: y.rows(1).cols(4).value([472.0, 473.0, 474.0, 475.0]), + 'c': lambda y: y.rows(1).cols(1).value([476.0]), + 'd': lambda x: x.rows(0).cols(0).arraySize(4).members({ + 0: lambda z: z.rows(1).cols(3).value([480.0, 481.0, 482.0]), + 1: lambda z: z.rows(1).cols(3).value([484.0, 485.0, 486.0]), + 2: lambda z: z.rows(1).cols(3).value([488.0, 489.0, 490.0]), + 3: lambda z: z.rows(1).cols(3).value([492.0, 493.0, 494.0]), + }), + }), + }) + # float4 test; - var_check.check('test').rows(1).cols(4).value([440.0, 441.0, 442.0, 443.0]) + var_check.check('test').rows(1).cols(4).value([496.0, 497.0, 498.0, 499.0]) var_check.done() rdtest.log.success("CBuffer variables are as expected") - self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [440.1, 441.0, 442.0, 443.0]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [496.1, 497.0, 498.0, 499.0]) rdtest.log.success("Picked value is as expected") diff --git a/util/test/tests/GL/GL_CBuffer_Zoo.py b/util/test/tests/GL/GL_CBuffer_Zoo.py index 77afd4555..5f7e9b700 100644 --- a/util/test/tests/GL/GL_CBuffer_Zoo.py +++ b/util/test/tests/GL/GL_CBuffer_Zoo.py @@ -285,11 +285,46 @@ class GL_CBuffer_Zoo(rdtest.TestCase): 433.0, 437.0]), }) + # struct nested_with_padding + # { + # float a; // vec3 padding + # vec4 b; + # float c; // vec3 padding + # vec3 d[4]; // float padding after each one + # }; + # nested_with_padding ak[2]; + var_check.check('ak').rows(0).cols(0).arraySize(2).members({ + # ak[0] + 0: lambda s: s.rows(0).cols(0).structSize(4).members({ + 'a': lambda y: y.rows(1).cols(1).value([440.0]), + 'b': lambda y: y.rows(1).cols(4).value([444.0, 445.0, 446.0, 447.0]), + 'c': lambda y: y.rows(1).cols(1).value([448.0]), + 'd': lambda x: x.rows(0).cols(0).arraySize(4).members({ + 0: lambda z: z.rows(1).cols(3).value([452.0, 453.0, 454.0]), + 1: lambda z: z.rows(1).cols(3).value([456.0, 457.0, 458.0]), + 2: lambda z: z.rows(1).cols(3).value([460.0, 461.0, 462.0]), + 3: lambda z: z.rows(1).cols(3).value([464.0, 465.0, 466.0]), + }), + }), + # ak[1] + 1: lambda s: s.rows(0).cols(0).structSize(4).members({ + 'a': lambda y: y.rows(1).cols(1).value([468.0]), + 'b': lambda y: y.rows(1).cols(4).value([472.0, 473.0, 474.0, 475.0]), + 'c': lambda y: y.rows(1).cols(1).value([476.0]), + 'd': lambda x: x.rows(0).cols(0).arraySize(4).members({ + 0: lambda z: z.rows(1).cols(3).value([480.0, 481.0, 482.0]), + 1: lambda z: z.rows(1).cols(3).value([484.0, 485.0, 486.0]), + 2: lambda z: z.rows(1).cols(3).value([488.0, 489.0, 490.0]), + 3: lambda z: z.rows(1).cols(3).value([492.0, 493.0, 494.0]), + }), + }), + }) + # vec4 test; - var_check.check('test').rows(1).cols(4).value([440.0, 441.0, 442.0, 443.0]) + var_check.check('test').rows(1).cols(4).value([496.0, 497.0, 498.0, 499.0]) # to save duplicating if this array changes, we calculate out from the start, as the array is tightly packed - base = 444.0 + base = 500.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)] @@ -357,7 +392,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, [440.1, 441.0, 442.0, 443.0]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [496.1, 497.0, 498.0, 499.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 ee58d87fd..dc8957faa 100644 --- a/util/test/tests/Vulkan/VK_CBuffer_Zoo.py +++ b/util/test/tests/Vulkan/VK_CBuffer_Zoo.py @@ -292,14 +292,49 @@ class VK_CBuffer_Zoo(rdtest.TestCase): 433.0, 437.0]), }) + # struct nested_with_padding + # { + # float a; // vec3 padding + # vec4 b; + # float c; // vec3 padding + # vec3 d[4]; // float padding after each one + # }; + # nested_with_padding ak[2]; + var_check.check('ak').rows(0).cols(0).arraySize(2).members({ + # ak[0] + 0: lambda s: s.rows(0).cols(0).structSize(4).members({ + 'a': lambda y: y.rows(1).cols(1).value([440.0]), + 'b': lambda y: y.rows(1).cols(4).value([444.0, 445.0, 446.0, 447.0]), + 'c': lambda y: y.rows(1).cols(1).value([448.0]), + 'd': lambda x: x.rows(0).cols(0).arraySize(4).members({ + 0: lambda z: z.rows(1).cols(3).value([452.0, 453.0, 454.0]), + 1: lambda z: z.rows(1).cols(3).value([456.0, 457.0, 458.0]), + 2: lambda z: z.rows(1).cols(3).value([460.0, 461.0, 462.0]), + 3: lambda z: z.rows(1).cols(3).value([464.0, 465.0, 466.0]), + }), + }), + # ak[1] + 1: lambda s: s.rows(0).cols(0).structSize(4).members({ + 'a': lambda y: y.rows(1).cols(1).value([468.0]), + 'b': lambda y: y.rows(1).cols(4).value([472.0, 473.0, 474.0, 475.0]), + 'c': lambda y: y.rows(1).cols(1).value([476.0]), + 'd': lambda x: x.rows(0).cols(0).arraySize(4).members({ + 0: lambda z: z.rows(1).cols(3).value([480.0, 481.0, 482.0]), + 1: lambda z: z.rows(1).cols(3).value([484.0, 485.0, 486.0]), + 2: lambda z: z.rows(1).cols(3).value([488.0, 489.0, 490.0]), + 3: lambda z: z.rows(1).cols(3).value([492.0, 493.0, 494.0]), + }), + }), + }) + # vec4 test; - var_check.check('test').rows(1).cols(4).value([440.0, 441.0, 442.0, 443.0]) + var_check.check('test').rows(1).cols(4).value([496.0, 497.0, 498.0, 499.0]) var_check.done() rdtest.log.success("GLSL CBuffer variables are as expected") - self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [440.1, 441.0, 442.0, 443.0]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [496.1, 497.0, 498.0, 499.0]) rdtest.log.success("GLSL picked value is as expected") @@ -634,13 +669,48 @@ class VK_CBuffer_Zoo(rdtest.TestCase): 436.0, 437.0]), }) + # struct nested_with_padding + # { + # float a; // float3 padding + # float4 b; + # float c; // float3 padding + # float3 d[4]; // float padding after each one + # }; + # nested_with_padding ak[2]; + var_check.check('ak').rows(0).cols(0).arraySize(2).members({ + # ak[0] + 0: lambda s: s.rows(0).cols(0).structSize(4).members({ + 'a': lambda y: y.rows(1).cols(1).value([440.0]), + 'b': lambda y: y.rows(1).cols(4).value([444.0, 445.0, 446.0, 447.0]), + 'c': lambda y: y.rows(1).cols(1).value([448.0]), + 'd': lambda x: x.rows(0).cols(0).arraySize(4).members({ + 0: lambda z: z.rows(1).cols(3).value([452.0, 453.0, 454.0]), + 1: lambda z: z.rows(1).cols(3).value([456.0, 457.0, 458.0]), + 2: lambda z: z.rows(1).cols(3).value([460.0, 461.0, 462.0]), + 3: lambda z: z.rows(1).cols(3).value([464.0, 465.0, 466.0]), + }), + }), + # ak[1] + 1: lambda s: s.rows(0).cols(0).structSize(4).members({ + 'a': lambda y: y.rows(1).cols(1).value([468.0]), + 'b': lambda y: y.rows(1).cols(4).value([472.0, 473.0, 474.0, 475.0]), + 'c': lambda y: y.rows(1).cols(1).value([476.0]), + 'd': lambda x: x.rows(0).cols(0).arraySize(4).members({ + 0: lambda z: z.rows(1).cols(3).value([480.0, 481.0, 482.0]), + 1: lambda z: z.rows(1).cols(3).value([484.0, 485.0, 486.0]), + 2: lambda z: z.rows(1).cols(3).value([488.0, 489.0, 490.0]), + 3: lambda z: z.rows(1).cols(3).value([492.0, 493.0, 494.0]), + }), + }), + }) + # float4 test; - var_check.check('test').rows(1).cols(4).value([440.0, 441.0, 442.0, 443.0]) + var_check.check('test').rows(1).cols(4).value([496.0, 497.0, 498.0, 499.0]) var_check.done() rdtest.log.success("HLSL CBuffer variables are as expected") - self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [440.1, 441.0, 442.0, 443.0]) + self.check_pixel_value(pipe.GetOutputTargets()[0].resourceId, 0.5, 0.5, [496.1, 497.0, 498.0, 499.0]) rdtest.log.success("HLSL picked value is as expected")