Fix AoS output in mesh viewer being incorrect with mesh shaders

* This would generally only come up with gl_PerVertex, and was hidden before
  because gl_Position is the first member. It likely would also reproduce if a
  user had a struct output from the mesh shader.
This commit is contained in:
baldurk
2026-03-16 15:12:30 +00:00
parent 4f3fc2f0ff
commit aebb1f90ee
3 changed files with 82 additions and 3 deletions
@@ -1284,9 +1284,13 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
// move to the inner struct if this is an array of structs - e.g. for arrayed shader outputs
const DataType *structType = &baseType;
bool arrayOfStructsBase = false;
if(structType->type == DataType::ArrayType &&
dataTypes[structType->InnerType()].type == DataType::StructType)
{
structType = &dataTypes[structType->InnerType()];
arrayOfStructsBase = true;
}
// if this is a struct variable then either all members must be builtins, or none of them, as
// per the SPIR-V Decoration rules:
@@ -1339,6 +1343,8 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
SPIRVInterfaceAccess patch;
patch.accessChain = {i};
if(arrayOfStructsBase)
patch.accessChain.insert(0, 0);
uint32_t dummy = 0;
AddSignatureParameter(isInput, stage, global.id, structType->id, dummy, patch,
+51 -2
View File
@@ -174,6 +174,42 @@ void main()
}
}
)EOSHADER";
std::string point_mesh = R"EOSHADER(
#version 460
#extension GL_EXT_mesh_shader : require
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(points, max_vertices = 2, max_primitives = 2) out;
layout(location = 0) out vec4 outColor[];
void main()
{
uint primCount = 2;
uint vertexCount = 1 * primCount;
SetMeshOutputsEXT(vertexCount, primCount);
for (uint i = 0; i < primCount; ++i)
{
uint vertIdx = i * 1;
uint tri = i + 2 * gl_WorkGroupID.x;
vec4 org = vec4(0.21, 0.0, 0.0, 0.0) * tri;
uint vert0 = 0 + vertIdx;
gl_MeshVerticesEXT[vert0].gl_Position = vec4(-0.4, -0.4, 0.0, 1.0) + org;
gl_MeshVerticesEXT[vert0].gl_PointSize = 20.0f;
outColor[vert0] = vec4(0.0, 1.0, 0.0, 1.0);
gl_PrimitivePointIndicesEXT[i] = vert0;
}
}
)EOSHADER";
std::string pixel = R"EOSHADER(
@@ -244,8 +280,8 @@ void main()
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = mainWindow->rp;
VkPipeline pipelines[2];
int countTasks[2];
VkPipeline pipelines[3];
int countTasks[3];
pipeCreateInfo.stages = {
CompileShaderModule(simple_mesh, ShaderLang::glsl, ShaderStage::mesh, "main", {},
@@ -275,6 +311,19 @@ void main()
pipelines[1] = createGraphicsPipeline(vkPipeCreateInfo);
countTasks[1] = 1;
pipeCreateInfo.stages = {
CompileShaderModule(point_mesh, ShaderLang::glsl, ShaderStage::mesh, "main", {},
SPIRVTarget::vulkan12),
CompileShaderModule(pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
};
vkPipeCreateInfo = pipeCreateInfo;
vkPipeCreateInfo->pVertexInputState = NULL;
vkPipeCreateInfo->pInputAssemblyState = NULL;
pipelines[2] = createGraphicsPipeline(vkPipeCreateInfo);
countTasks[2] = 3;
while(Running())
{
VkCommandBuffer cmd = GetCommandBuffer();
+25 -1
View File
@@ -69,7 +69,7 @@ class VK_Mesh_Shader(rdtest.TestCase):
y -= 100
action = action.next
name = f"Amplification Shader with Local Payload EID:{action.eventId}"
name = f"Task Shader with Local Payload EID:{action.eventId}"
rdtest.log.begin_section(name)
self.controller.SetFrameEvent(action.eventId, False)
@@ -84,3 +84,27 @@ class VK_Mesh_Shader(rdtest.TestCase):
self.check_mesh_data(postms_ref, postms_data)
self.check_debug_pixel(x, y)
rdtest.log.end_section(name)
name = f"Mesh Shader with Points output"
with rdtest.log.auto_section(name):
action = action.next
self.controller.SetFrameEvent(action.eventId, False)
x = 290
y = 90
color = [0.0, 1.0, 0.0, 1.0]
postms_ref = {}
for i in range(6):
postms_ref[i] = {
'vtx': i,
'idx': i,
'gl_Position': [-0.4+0.21*i, -0.4, 0.0, 1.0],
'gl_PointSize': 20.0,
'outColor': color,
}
postms_data = self.get_postvs(action, rd.MeshDataStage.MeshOut, 0, action.numIndices)
self.check_mesh_data(postms_ref, postms_data)
self.check_debug_pixel(x, y)
rdtest.log.end_section(name)