Support advanced cbuffer layouts

* This includes 8/16/64-bit integers, 16-bit/64-bit floats, and scalar block
  packing
This commit is contained in:
baldurk
2019-02-07 15:23:06 +00:00
parent 134cdfd09b
commit fbb6b23b23
22 changed files with 1075 additions and 117 deletions
+1
View File
@@ -198,6 +198,7 @@
<ClCompile Include="vk\vk_indirect.cpp" />
<ClCompile Include="vk\vk_overlay_test.cpp" />
<ClCompile Include="vk\vk_sample_locations.cpp" />
<ClCompile Include="vk\vk_adv_cbuffer_zoo.cpp" />
<ClCompile Include="vk\vk_secondary_cmdbuf.cpp" />
<ClCompile Include="vk\vk_video_textures.cpp" />
<ClCompile Include="vk\vk_vs_max_desc_set.cpp" />
+3
View File
@@ -252,6 +252,9 @@
<ClCompile Include="vk\vk_discard_rects.cpp">
<Filter>Vulkan\demos</Filter>
</ClCompile>
<ClCompile Include="vk\vk_adv_cbuffer_zoo.cpp">
<Filter>Vulkan\demos</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="D3D11">
+399
View File
@@ -0,0 +1,399 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2018-2019 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "vk_test.h"
struct vec2
{
float x, y;
};
struct vec3
{
float x, y, z;
};
struct i8vec4
{
int8_t x, y, z, w;
};
struct i8vec2
{
int8_t x, y;
};
struct i16vec4
{
int16_t x, y, z, w;
};
struct i16vec3
{
int16_t x, y, z;
};
struct i16vec2
{
int16_t x, y;
};
struct mat2x3
{
float m[2 * 3];
};
// Block memory layout
struct S
{
float a;
vec2 b;
double c;
float d;
vec3 e;
float f;
};
struct S8
{
int8_t a;
i8vec4 b;
i8vec2 c[4];
};
struct S16
{
uint16_t a;
i16vec4 b;
i16vec2 c[4];
int8_t d;
};
struct UBO
{
float a;
vec2 b;
vec3 c;
float d[2];
mat2x3 e;
mat2x3 f[2];
float g;
S h;
S i[2];
// i8vec4 pad1;
int8_t j;
S8 k;
S8 l[2];
int8_t m;
S16 n;
uint8_t o;
S16 p[2];
uint64_t q;
int64_t r;
uint16_t s;
int8_t test;
};
struct VK_Adv_CBuffer_Zoo : VulkanGraphicsTest
{
static constexpr const char *Description =
"Tests VK_EXT_scalar_block_layout as well as 8-bit/16-bit storage "
"to ensure we correctly handle all types of offset and type.";
std::string common = R"EOSHADER(
#version 460 core
#extension GL_EXT_scalar_block_layout : require
#extension GL_EXT_shader_16bit_storage : require
#extension GL_EXT_shader_8bit_storage : require
#extension GL_ARB_gpu_shader_int64 : require
#extension GL_EXT_shader_explicit_arithmetic_types : require
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require
struct v2f
{
vec4 pos;
vec4 col;
vec4 uv;
};
)EOSHADER";
const std::string vertex = R"EOSHADER(
layout(location = 0) in vec3 Position;
layout(location = 1) in vec4 Color;
layout(location = 2) in vec2 UV;
layout(location = 0) out v2f vertOut;
// Block memory layout
struct S
{
float a; // offset 0
vec2 b; // offset 4
double c; // offset 16
float d; // offset 24
vec3 e; // offset 28
float f; // offset 40
// size = 44, align = 8
};
struct S8
{
int8_t a; // offset 0
i8vec4 b; // offset 1
i8vec2 c[4]; // offset 5
// size = 13, align = 1
};
struct S16
{
uint16_t a; // offset 0
i16vec4 b; // offset 2
i16vec2 c[4]; // offset 10
int8_t d; // offset 26
// size = 27, align = 2
};
layout(column_major, scalar) uniform B1
{
float a; // offset = 0
vec2 b; // offset = 4
vec3 c; // offset = 12
float d[2]; // offset = 24
mat2x3 e; // offset = 32, takes 24 bytes, matrixstride = 12
mat2x3 f[2]; // offset = 56, takes 48 bytes, matrixstride = 12, arraystride = 24
float g; // offset = 104
S h; // offset = 112 (aligned to multiple of 8)
S i[2]; // offset = 160 (aligned to multiple of 8) stride = 48
i8vec4 pad1; // offset = 252 C pads after array here - not required in GLSL scalar packing
int8_t j; // offset = 256
S8 k; // offset = 257 (aligned to multiple of 1)
S8 l[2]; // offset = 270 (aligned to multiple of 1) stride = 13
int8_t m; // offset = 296
S16 n; // offset = 298 (aligned to multiple of 2)
int8_t pad2; // offset = 325 C pads after struct here - not required in GLSL scalar packing
uint8_t o; // offset = 326
S16 p[2]; // offset = 328 (aligned to multiple of 2) stride = 28
int8_t pad3; // offset = 383 C pads after struct here - not required in GLSL scalar packing
uint64_t q; // offset = 384
int64_t r; // offset = 392
float16_t s; // offset = 400
int8_t test; // offset = 402
};
void main()
{
vertOut.pos = vec4(Position.xyz*vec3(1,-1,1), 1);
gl_Position = vertOut.pos;
vertOut.uv = vec4(UV.xy, 0, 1);
vertOut.col = vec4(1,0,0,0);
if(int(test) == 42)
vertOut.col = vec4(0,1,0,0);
}
)EOSHADER";
const std::string pixel = R"EOSHADER(
layout(location = 0) in v2f vertIn;
layout(location = 0, index = 0) out vec4 Color;
void main()
{
Color = vertIn.col;
}
)EOSHADER";
int main(int argc, char **argv)
{
instExts.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
devExts.push_back(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
devExts.push_back(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME);
devExts.push_back(VK_KHR_16BIT_STORAGE_EXTENSION_NAME);
devExts.push_back(VK_KHR_8BIT_STORAGE_EXTENSION_NAME);
VkPhysicalDevice16BitStorageFeaturesKHR _16bitFeatures = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR,
};
VkPhysicalDevice16BitStorageFeaturesKHR _8bitFeatures = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR,
};
_16bitFeatures.uniformAndStorageBuffer16BitAccess = VK_TRUE;
_8bitFeatures.uniformAndStorageBuffer16BitAccess = VK_TRUE;
devInfoNext = &_8bitFeatures;
_8bitFeatures.pNext = &_16bitFeatures;
features.shaderFloat64 = true;
features.shaderInt16 = true;
features.shaderInt64 = true;
// initialise, create window, create context, etc
if(!Init(argc, argv))
return 3;
_16bitFeatures.uniformAndStorageBuffer16BitAccess = VK_FALSE;
_8bitFeatures.uniformAndStorageBuffer16BitAccess = VK_FALSE;
vkGetPhysicalDeviceFeatures2KHR(phys, vkh::PhysicalDeviceFeatures2KHR().next(&_16bitFeatures));
vkGetPhysicalDeviceFeatures2KHR(phys, vkh::PhysicalDeviceFeatures2KHR().next(&_8bitFeatures));
// a bit late, but...
TEST_ASSERT(_16bitFeatures.uniformAndStorageBuffer16BitAccess &&
_8bitFeatures.uniformAndStorageBuffer16BitAccess,
"8-bit or 16-bit uniform storage not available");
VkDescriptorSetLayout setlayout = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({
{0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT},
}));
VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo({setlayout}));
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = swapRenderPass;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
vkh::vertexAttr(0, 0, DefaultA2V, pos), vkh::vertexAttr(1, 0, DefaultA2V, col),
vkh::vertexAttr(2, 0, DefaultA2V, uv),
};
pipeCreateInfo.stages = {
CompileShaderModule(common + vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
CompileShaderModule(common + pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
};
VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);
AllocatedBuffer vb(
allocator, vkh::BufferCreateInfo(sizeof(DefaultTri), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
vb.upload(DefaultTri);
UBO cbufferdata = {};
// this value is checked by the shader to ensure everything has aligned just so.
cbufferdata.test = 42;
// set some other values that we can inspect ourselves manually
cbufferdata.a = 1.0f;
cbufferdata.b.x = 2.0f;
cbufferdata.c.y = 3.0f;
cbufferdata.d[0] = 4.0f;
cbufferdata.d[1] = 5.0f;
cbufferdata.e.m[0] = 6.0f;
cbufferdata.e.m[1] = 7.0f;
cbufferdata.e.m[3] = 999.0f;
cbufferdata.f[0].m[0] = 8.0f;
cbufferdata.f[0].m[1] = 9.0f;
cbufferdata.f[0].m[3] = 999.0f;
cbufferdata.f[1].m[0] = 10.0f;
cbufferdata.f[1].m[1] = 11.0f;
cbufferdata.f[1].m[3] = 999.0f;
cbufferdata.g = 12.0f;
cbufferdata.h.c = 13.0;
cbufferdata.h.d = 14.0f;
cbufferdata.i[0].c = 15.0;
cbufferdata.i[1].d = 16.0f;
cbufferdata.j = 17;
cbufferdata.k.c[1].y = 18;
cbufferdata.l[0].a = 19;
cbufferdata.l[0].c[1].y = 20;
cbufferdata.l[1].a = 21;
cbufferdata.l[1].c[0].y = 22;
cbufferdata.m = -23;
cbufferdata.n.a = 65524;
cbufferdata.n.b.w = -2424;
cbufferdata.n.d = 25;
cbufferdata.o = 226;
cbufferdata.p[0].b.z = 2727;
cbufferdata.p[0].d = 28;
cbufferdata.p[1].b.w = 2929;
cbufferdata.q = 30303030303030ULL;
cbufferdata.r = -31313131313131LL;
cbufferdata.s = 19472; // 16.25f
AllocatedBuffer cb(
allocator, vkh::BufferCreateInfo(sizeof(cbufferdata), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
VK_BUFFER_USAGE_TRANSFER_DST_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));
cb.upload(&cbufferdata, sizeof(cbufferdata));
VkDescriptorSet descset = allocateDescriptorSet(setlayout);
vkh::updateDescriptorSets(
device, {
vkh::WriteDescriptorSet(descset, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
{vkh::DescriptorBufferInfo(cb.buffer)}),
});
while(Running())
{
VkCommandBuffer cmd = GetCommandBuffer();
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
VkImage swapimg =
StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
vkh::ClearColorValue(0.4f, 0.5f, 0.6f, 1.0f), 1,
vkh::ImageSubresourceRange());
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor,
{vkh::ClearValue(0.0f, 0.0f, 0.0f, 1.0f)}),
VK_SUBPASS_CONTENTS_INLINE);
vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, {descset}, {});
vkCmdSetViewport(cmd, 0, 1, &viewport);
vkCmdSetScissor(cmd, 0, 1, &scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
vkCmdDraw(cmd, 3, 1, 0, 0);
vkCmdEndRenderPass(cmd);
FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
vkEndCommandBuffer(cmd);
Submit(0, 1, {cmd});
Present();
}
return 0;
}
};
REGISTER_TEST(VK_Adv_CBuffer_Zoo);
+17
View File
@@ -283,6 +283,23 @@ struct PhysicalDeviceProperties2KHR : public VkPhysicalDeviceProperties2KHR
operator VkPhysicalDeviceProperties2KHR *() { return this; }
};
struct PhysicalDeviceFeatures2KHR : public VkPhysicalDeviceFeatures2KHR
{
PhysicalDeviceFeatures2KHR()
{
sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
pNext = NULL;
}
PhysicalDeviceFeatures2KHR &next(void *next)
{
this->pNext = next;
return *this;
}
operator VkPhysicalDeviceFeatures2KHR *() { return this; }
};
struct SemaphoreCreateInfo : public VkSemaphoreCreateInfo
{
SemaphoreCreateInfo() : VkSemaphoreCreateInfo()
+21 -4
View File
@@ -33,7 +33,7 @@ class ShaderVariableCheck:
def type(self, type_: rd.VarType):
if self.var.type != type_:
raise TestFailureException("Variable {} type mismatch, expected {} but got {}"
.format(self.var.name, type_, self.var.type))
.format(self.var.name, str(type_), str(self.var.type)))
return self
@@ -44,9 +44,26 @@ class ShaderVariableCheck:
raise TestFailureException("Float variable {} value mismatch, expected {} but got {}"
.format(self.var.name, value_, self.var.value.fv[0:count]))
else:
if self.var.value.iv[0:count] != value_:
raise TestFailureException("Int variable {} value mismatch, expected {} but got {}"
.format(self.var.name, value_, self.var.value.iv[0:count]))
# hack - check signed and unsigned values
if self.var.value.iv[0:count] != value_ and self.var.value.uv[0:count] != value_:
raise TestFailureException("Int variable {} value mismatch, expected {} but got {} / {}"
.format(self.var.name, value_, self.var.value.iv[0:count],
self.var.value.uv[0:count]))
return self
def longvalue(self, value_: list):
count = len(value_)
if isinstance(value_[0], float):
if self.var.value.dv[0:count] != value_:
raise TestFailureException("Float variable {} value mismatch, expected {} but got {}"
.format(self.var.name, value_, self.var.value.dv[0:count]))
else:
# hack - check signed and unsigned values
if self.var.value.s64v[0:count] != value_ and self.var.value.u64v[0:count] != value_:
raise TestFailureException("Int variable {} value mismatch, expected {} but got {} / {}"
.format(self.var.name, value_, self.var.value.s64v[0:count],
self.var.value.u64v[0:count]))
return self
@@ -0,0 +1,247 @@
import rdtest
import renderdoc as rd
class VK_Adv_CBuffer_Zoo(rdtest.TestCase):
def get_capture(self):
return rdtest.run_and_capture("demos_x64", "VK_Adv_CBuffer_Zoo", 5)
def check_capture(self):
draw = self.find_draw("Draw")
self.check(draw is not None)
self.controller.SetFrameEvent(draw.eventId, False)
# Make an output so we can pick pixels
out: rd.ReplayOutput = self.controller.CreateOutput(rd.CreateHeadlessWindowingData(), rd.ReplayOutputType.Texture)
self.check(out is not None)
out.SetDimensions(100, 100)
pipe: rd.PipeState = self.controller.GetPipelineState()
stage = rd.ShaderStage.Vertex
cbuf: rd.BoundCBuffer = pipe.GetConstantBuffer(stage, 0, 0)
var_check = rdtest.ConstantBufferChecker(
self.controller.GetCBufferVariableContents(pipe.GetShader(stage),
pipe.GetShaderEntryPoint(stage), 0,
cbuf.resourceId, cbuf.byteOffset))
# For more detailed reference for the below checks, see the commented definition of the cbuffer
# in the shader source code in the demo itself
# float a;
var_check.check('a').cols(1).rows(1).type(rd.VarType.Float).value([1.0])
# vec2 b;
var_check.check('b').cols(2).rows(1).type(rd.VarType.Float).value([2.0, 0.0])
# vec3 c;
var_check.check('c').cols(3).rows(1).type(rd.VarType.Float).value([0.0, 3.0])
# float d[2];
var_check.check('d').cols(0).rows(0).arraySize(2).members({
0: lambda x: x.cols(1).rows(1).type(rd.VarType.Float).value([4.0]),
1: lambda x: x.cols(1).rows(1).type(rd.VarType.Float).value([5.0]),
})
# mat2x3 e;
var_check.check('e').cols(2).rows(3).column_major().type(rd.VarType.Float).value([6.0, 999.0,
7.0, 0.0,
0.0, 0.0])
# mat2x3 f[2];
var_check.check('f').cols(0).rows(0).arraySize(2).members({
0: lambda x: x.cols(2).rows(3).column_major().type(rd.VarType.Float).value([8.0, 999.0,
9.0, 0.0,
0.0, 0.0]),
1: lambda x: x.cols(2).rows(3).column_major().type(rd.VarType.Float).value([10.0, 999.0,
11.0, 0.0,
0.0, 0.0]),
})
# float g;
var_check.check('g').cols(1).rows(1).type(rd.VarType.Float).value([12.0])
# struct S
# {
# float a;
# vec2 b;
# double c;
# float d;
# vec3 e;
# float f;
# };
# S h;
var_check.check('h').cols(0).rows(0).structSize(6).members({
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
'b': lambda x: x.cols(2).rows(1).type(rd.VarType.Float ).value([0.0]),
'c': lambda x: x.cols(1).rows(1).type(rd.VarType.Double).longvalue([13.0]),
'd': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([14.0]),
'e': lambda x: x.cols(3).rows(1).type(rd.VarType.Float ).value([0.0]),
'f': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
})
# S i[2];
var_check.check('i').cols(0).rows(0).arraySize(2).members({
0: lambda x: x.cols(0).rows(0).structSize(6).members({
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
'b': lambda x: x.cols(2).rows(1).type(rd.VarType.Float ).value([0.0]),
'c': lambda x: x.cols(1).rows(1).type(rd.VarType.Double).longvalue([15.0]),
'd': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
'e': lambda x: x.cols(3).rows(1).type(rd.VarType.Float ).value([0.0]),
'f': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
}),
1: lambda x: x.cols(0).rows(0).structSize(6).members({
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
'b': lambda x: x.cols(2).rows(1).type(rd.VarType.Float ).value([0.0]),
'c': lambda x: x.cols(1).rows(1).type(rd.VarType.Double).longvalue([0.0]),
'd': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([16.0]),
'e': lambda x: x.cols(3).rows(1).type(rd.VarType.Float ).value([0.0]),
'f': lambda x: x.cols(1).rows(1).type(rd.VarType.Float ).value([0.0]),
}),
})
# i8vec4 pad1;
var_check.check('pad1')
# int8_t j;
var_check.check('j').cols(1).rows(1).type(rd.VarType.SByte).value([17])
# struct S8
# {
# int8_t a;
# i8vec4 b;
# i8vec2 c[4];
# };
# S8 k;
var_check.check('k').cols(0).rows(0).structSize(3).members({
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.SByte).value([0]),
'b': lambda x: x.cols(4).rows(1).type(rd.VarType.SByte).value([0, 0, 0, 0]),
'c': lambda x: x.cols(0).rows(0).arraySize(4).members({
0: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
1: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 18]),
2: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
3: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
}),
})
# S8 l[2];
var_check.check('l').cols(0).rows(0).arraySize(2).members({
0: lambda x: x.cols(0).rows(0).structSize(3).members({
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.SByte).value([19]),
'b': lambda x: x.cols(4).rows(1).type(rd.VarType.SByte).value([0, 0, 0, 0]),
'c': lambda x: x.cols(0).rows(0).arraySize(4).members({
0: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
1: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 20]),
2: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
3: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
}),
}),
1: lambda x: x.cols(0).rows(0).structSize(3).members({
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.SByte).value([21]),
'b': lambda x: x.cols(4).rows(1).type(rd.VarType.SByte).value([0, 0, 0, 0]),
'c': lambda x: x.cols(0).rows(0).arraySize(4).members({
0: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 22]),
1: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
2: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
3: lambda x: x.cols(2).rows(1).type(rd.VarType.SByte).value([0, 0]),
}),
})
})
# int8_t m;
var_check.check('m').cols(1).rows(1).type(rd.VarType.SByte).value([-23])
# struct S16
# {
# uint16_t a;
# i16vec4 b;
# i16vec2 c[4];
# int8_t d;
# };
# S16 n;
var_check.check('n').cols(0).rows(0).structSize(4).members({
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.UShort).value([65524]),
'b': lambda x: x.cols(4).rows(1).type(rd.VarType.SShort).value([0, 0, 0, -2424]),
'c': lambda x: x.cols(0).rows(0).arraySize(4).members({
0: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
1: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
2: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
3: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
}),
'd': lambda x: x.cols(1).rows(1).type(rd.VarType.SByte).value([25]),
})
# i8vec4 pad2;
var_check.check('pad2')
# uint8_t o;
var_check.check('o').cols(1).rows(1).type(rd.VarType.UByte).value([226])
# S16 p[2];
var_check.check('p').cols(0).rows(0).arraySize(2).members({
0: lambda x: x.cols(0).rows(0).structSize(4).members({
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.UShort).value([0]),
'b': lambda x: x.cols(4).rows(1).type(rd.VarType.SShort).value([0, 0, 2727, 0]),
'c': lambda x: x.cols(0).rows(0).arraySize(4).members({
0: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
1: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
2: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
3: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
}),
'd': lambda x: x.cols(1).rows(1).type(rd.VarType.SByte).value([28]),
}),
1: lambda x: x.cols(0).rows(0).structSize(4).members({
'a': lambda x: x.cols(1).rows(1).type(rd.VarType.UShort).value([0]),
'b': lambda x: x.cols(4).rows(1).type(rd.VarType.SShort).value([0, 0, 0, 2929]),
'c': lambda x: x.cols(0).rows(0).arraySize(4).members({
0: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
1: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
2: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
3: lambda x: x.cols(2).rows(1).type(rd.VarType.SShort).value([0, 0]),
}),
'd': lambda x: x.cols(1).rows(1).type(rd.VarType.SByte).value([0]),
})
})
# i8vec4 pad3;
var_check.check('pad3')
# uint64_t q;
var_check.check('q').cols(1).rows(1).type(rd.VarType.ULong).longvalue([30303030303030])
# int64_t r;
var_check.check('r').cols(1).rows(1).type(rd.VarType.SLong).longvalue([-31313131313131])
# half s;
var_check.check('s').cols(1).rows(1).type(rd.VarType.Half).value([16.25])
# int8_t test;
var_check.check('test').cols(1).rows(1).type(rd.VarType.SByte).value([42])
var_check.done()
rdtest.log.success("CBuffer variables are as expected")
tex = rd.TextureDisplay()
tex.resourceId = pipe.GetOutputTargets()[0].resourceId
out.SetTextureDisplay(tex)
texdetails = self.get_texture(tex.resourceId)
picked: rd.PixelValue = out.PickPixel(tex.resourceId, False,
int(texdetails.width / 2), int(texdetails.height / 2), 0, 0, 0)
# We just output green from the shader when the value is as expected
if not rdtest.value_compare(picked.floatValue, [0.0, 1.0, 0.0, 0.0]):
raise rdtest.TestFailureException("Picked value {} doesn't match expectation".format(picked.floatValue))
rdtest.log.success("Picked value is as expected")
out.Shutdown()