mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 00:50:40 +00:00
Update multiview test to check shader exported viewport
* This also has code to support the qcom implicit viewport, but we disable that path by default since it would break all the single-viewport tests.
This commit is contained in:
@@ -65,6 +65,32 @@ void main()
|
||||
vertOut.col = vec4(0, 1, 0, 1);
|
||||
}
|
||||
|
||||
)EOSHADER";
|
||||
|
||||
const std::string multiviewViewportVertex = common + R"EOSHADER(
|
||||
|
||||
#extension GL_ARB_shader_viewport_layer_array : require
|
||||
|
||||
layout(location = 0) in vec3 Position;
|
||||
layout(location = 1) in vec4 Color;
|
||||
layout(location = 2) in vec2 UV;
|
||||
|
||||
layout(location = 0) out v2f vertOut;
|
||||
|
||||
void main()
|
||||
{
|
||||
vertOut.pos = vec4(Position.xyz*vec3(1,-1,1), 1);
|
||||
gl_Position = vertOut.pos;
|
||||
vertOut.col = Color;
|
||||
vertOut.uv = vec4(UV.xy, 0, 1);
|
||||
|
||||
gl_ViewportIndex = gl_ViewIndex;
|
||||
if (gl_ViewIndex == 0)
|
||||
vertOut.col = vec4(1, 0, 0, 1);
|
||||
if (gl_ViewIndex == 1)
|
||||
vertOut.col = vec4(0, 1, 0, 1);
|
||||
}
|
||||
|
||||
)EOSHADER";
|
||||
|
||||
const std::string multiViewGeom = common + R"EOSHADER(
|
||||
@@ -128,7 +154,13 @@ void main()
|
||||
void Prepare(int argc, char **argv)
|
||||
{
|
||||
features.geometryShader = VK_TRUE;
|
||||
features.multiViewport = VK_TRUE;
|
||||
devExts.push_back(VK_KHR_MULTIVIEW_EXTENSION_NAME);
|
||||
optDevExts.push_back(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME);
|
||||
|
||||
// this extension is all-or-nothing and prevents us doing any other tests normally with single
|
||||
// viewports
|
||||
// optDevExts.push_back(VK_QCOM_MULTIVIEW_PER_VIEW_VIEWPORTS_EXTENSION_NAME);
|
||||
|
||||
VulkanGraphicsTest::Prepare(argc, argv);
|
||||
|
||||
@@ -143,6 +175,17 @@ void main()
|
||||
geometryTest = multiview.multiviewGeometryShader == VK_TRUE;
|
||||
|
||||
devInfoNext = &multiview;
|
||||
|
||||
static VkPhysicalDeviceMultiviewPerViewViewportsFeaturesQCOM perviewQC = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_VIEWPORTS_FEATURES_QCOM,
|
||||
};
|
||||
|
||||
if(hasExt(VK_QCOM_MULTIVIEW_PER_VIEW_VIEWPORTS_EXTENSION_NAME))
|
||||
{
|
||||
perviewQC.multiviewPerViewViewports = VK_TRUE;
|
||||
perviewQC.pNext = (void *)devInfoNext;
|
||||
devInfoNext = &perviewQC;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
@@ -228,33 +271,72 @@ void main()
|
||||
|
||||
std::vector<std::string> testNames;
|
||||
std::vector<VkPipeline> testPipes;
|
||||
testPipes.push_back(createGraphicsPipeline(pipeCreateInfo));
|
||||
testNames.push_back("Vertex: viewIndex");
|
||||
|
||||
pipeCreateInfo.stages = {
|
||||
CompileShaderModule(VKDefaultVertex, ShaderLang::glsl, ShaderStage::vert, "main"),
|
||||
CompileShaderModule(multiViewPixel, ShaderLang::glsl, ShaderStage::frag, "main"),
|
||||
};
|
||||
testPipes.push_back(createGraphicsPipeline(pipeCreateInfo));
|
||||
testNames.push_back("Fragment: viewIndex");
|
||||
size_t viewportChoosePipe = ~0U;
|
||||
size_t viewportAutoPipe = ~0U;
|
||||
|
||||
if(geometryTest)
|
||||
if(hasExt(VK_QCOM_MULTIVIEW_PER_VIEW_VIEWPORTS_EXTENSION_NAME))
|
||||
{
|
||||
pipeCreateInfo.stages = {
|
||||
CompileShaderModule(multiviewVertex, ShaderLang::glsl, ShaderStage::vert, "main"),
|
||||
CompileShaderModule(VKDefaultPixel, ShaderLang::glsl, ShaderStage::frag, "main"),
|
||||
};
|
||||
|
||||
pipeCreateInfo.viewportState.viewportCount = 2;
|
||||
pipeCreateInfo.viewportState.scissorCount = 2;
|
||||
|
||||
viewportAutoPipe = testPipes.size();
|
||||
|
||||
testPipes.push_back(createGraphicsPipeline(pipeCreateInfo));
|
||||
testNames.push_back("viewportIndex auto");
|
||||
}
|
||||
else
|
||||
{
|
||||
testPipes.push_back(createGraphicsPipeline(pipeCreateInfo));
|
||||
testNames.push_back("Vertex: viewIndex");
|
||||
|
||||
pipeCreateInfo.stages = {
|
||||
CompileShaderModule(VKDefaultVertex, ShaderLang::glsl, ShaderStage::vert, "main"),
|
||||
CompileShaderModule(multiViewPixel, ShaderLang::glsl, ShaderStage::frag, "main"),
|
||||
};
|
||||
testPipes.push_back(createGraphicsPipeline(pipeCreateInfo));
|
||||
testNames.push_back("Fragment: viewIndex");
|
||||
|
||||
if(geometryTest)
|
||||
{
|
||||
pipeCreateInfo.stages = {
|
||||
CompileShaderModule(VKDefaultVertex, ShaderLang::glsl, ShaderStage::vert, "main"),
|
||||
CompileShaderModule(VKDefaultPixel, ShaderLang::glsl, ShaderStage::frag, "main"),
|
||||
CompileShaderModule(multiViewGeom, ShaderLang::glsl, ShaderStage::geom, "main"),
|
||||
};
|
||||
testPipes.push_back(createGraphicsPipeline(pipeCreateInfo));
|
||||
testNames.push_back("Geometry: viewIndex");
|
||||
}
|
||||
|
||||
pipeCreateInfo.stages = {
|
||||
CompileShaderModule(VKDefaultVertex, ShaderLang::glsl, ShaderStage::vert, "main"),
|
||||
CompileShaderModule(VKDefaultPixel, ShaderLang::glsl, ShaderStage::frag, "main"),
|
||||
CompileShaderModule(multiViewGeom, ShaderLang::glsl, ShaderStage::geom, "main"),
|
||||
};
|
||||
testPipes.push_back(createGraphicsPipeline(pipeCreateInfo));
|
||||
testNames.push_back("Geometry: viewIndex");
|
||||
}
|
||||
testNames.push_back("No viewIndex");
|
||||
|
||||
pipeCreateInfo.stages = {
|
||||
CompileShaderModule(VKDefaultVertex, ShaderLang::glsl, ShaderStage::vert, "main"),
|
||||
CompileShaderModule(VKDefaultPixel, ShaderLang::glsl, ShaderStage::frag, "main"),
|
||||
};
|
||||
testPipes.push_back(createGraphicsPipeline(pipeCreateInfo));
|
||||
testNames.push_back("No viewIndex");
|
||||
if(hasExt(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME))
|
||||
{
|
||||
pipeCreateInfo.stages = {
|
||||
CompileShaderModule(multiviewViewportVertex, ShaderLang::glsl, ShaderStage::vert,
|
||||
"main"),
|
||||
CompileShaderModule(VKDefaultPixel, ShaderLang::glsl, ShaderStage::frag, "main"),
|
||||
};
|
||||
|
||||
pipeCreateInfo.viewportState.viewportCount = 2;
|
||||
pipeCreateInfo.viewportState.scissorCount = 2;
|
||||
|
||||
viewportChoosePipe = testPipes.size();
|
||||
|
||||
testPipes.push_back(createGraphicsPipeline(pipeCreateInfo));
|
||||
testNames.push_back("viewportIndex choice");
|
||||
}
|
||||
}
|
||||
|
||||
AllocatedBuffer vb(
|
||||
this,
|
||||
@@ -288,6 +370,38 @@ void main()
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, testPipes[i]);
|
||||
vkCmdSetViewport(cmd, 0, 1, &mainWindow->viewport);
|
||||
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
|
||||
|
||||
if(i == viewportChoosePipe || i == viewportAutoPipe)
|
||||
{
|
||||
VkViewport v = mainWindow->viewport;
|
||||
VkRect2D s = mainWindow->scissor;
|
||||
|
||||
VkViewport vs[2];
|
||||
|
||||
v.width /= 2.0f;
|
||||
vs[0] = v;
|
||||
// vkCmdSetViewport(cmd, 0, 1, &v);
|
||||
v.x += v.width;
|
||||
vs[1] = v;
|
||||
// vkCmdSetViewport(cmd, 1, 1, &v);
|
||||
vkCmdSetViewport(cmd, 0, 2, vs);
|
||||
|
||||
s.extent.width /= 2;
|
||||
s.extent.width -= 150;
|
||||
s.offset.x += 75;
|
||||
s.extent.height -= 200;
|
||||
s.offset.y += 100;
|
||||
|
||||
VkRect2D ss[2];
|
||||
|
||||
ss[0] = s;
|
||||
// vkCmdSetScissor(cmd, 0, 1, &s);
|
||||
s.offset.x += mainWindow->scissor.extent.width / 2;
|
||||
ss[1] = s;
|
||||
// vkCmdSetScissor(cmd, 1, 1, &s);
|
||||
vkCmdSetScissor(cmd, 0, 2, ss);
|
||||
}
|
||||
|
||||
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
|
||||
setMarker(cmd, testNames[i]);
|
||||
vkCmdDraw(cmd, 3, 1, 0, 0);
|
||||
|
||||
@@ -14,7 +14,10 @@ class VK_Multi_View(rdtest.TestCase):
|
||||
|
||||
for test_name in ["Vertex: viewIndex", "Geometry: viewIndex", "Fragment: viewIndex", "No viewIndex"]:
|
||||
rdtest.log.print("Test {}".format(test_name))
|
||||
action: rd.ActionDescription = self.find_action(test_name).next
|
||||
label = self.find_action(test_name)
|
||||
if label is None:
|
||||
continue
|
||||
action = label.next
|
||||
self.controller.SetFrameEvent(action.eventId, True)
|
||||
|
||||
pipe: rd.PipeState = self.controller.GetPipelineState()
|
||||
@@ -45,6 +48,47 @@ class VK_Multi_View(rdtest.TestCase):
|
||||
self.check_debug(vtx, idx, inst, view, postvs)
|
||||
rdtest.log.print(f"View {view} Slice {slice} passed")
|
||||
|
||||
for test_name in ["viewportIndex choice"]:
|
||||
rdtest.log.print("Test {}".format(test_name))
|
||||
label = self.find_action(test_name)
|
||||
if label is None:
|
||||
continue
|
||||
action = label.next
|
||||
self.controller.SetFrameEvent(action.eventId, True)
|
||||
|
||||
pipe: rd.PipeState = self.controller.GetPipelineState()
|
||||
if not pipe.GetShaderReflection(rd.ShaderStage.Pixel).debugInfo.debuggable:
|
||||
raise rdtest.TestFailureException("Test {} shader can not be debugged".format(test_name))
|
||||
|
||||
for view in range(2):
|
||||
if view == 0:
|
||||
x, y = 100, 140
|
||||
else:
|
||||
x, y = 300, 140
|
||||
|
||||
# Debug the pixel shader
|
||||
inputs = rd.DebugPixelInputs()
|
||||
inputs.view = view
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugPixel(x, y, inputs)
|
||||
if trace.debugger is None:
|
||||
self.controller.FreeTrace(trace)
|
||||
raise rdtest.TestFailureException("Test {} view {} did not debug at all".format(test_name, view))
|
||||
|
||||
cycles, variables = self.process_trace(trace)
|
||||
output: rd.SourceVariableMapping = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
|
||||
debugged = self.evaluate_source_var(output, variables)
|
||||
slice = view + 1
|
||||
sub = rd.Subresource(0, slice, 0)
|
||||
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4], sub=sub)
|
||||
self.controller.FreeTrace(trace)
|
||||
|
||||
inst = 0
|
||||
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, instance=inst, view=view)
|
||||
for vtx in range(action.numIndices):
|
||||
idx = vtx
|
||||
self.check_debug(vtx, idx, inst, view, postvs)
|
||||
rdtest.log.print(f"View {view} Slice {slice} passed")
|
||||
|
||||
rdtest.log.success("All tests matched")
|
||||
|
||||
|
||||
@@ -74,7 +118,12 @@ class VK_Multi_View(rdtest.TestCase):
|
||||
"Output {} at vert {} (idx {}) instance {} view {} has different size ({} values) to expectation ({} values)"
|
||||
.format(name, vtx, idx, inst, view, value.columns, len(expect)))
|
||||
|
||||
debugged = value.value.f32v[0:value.columns]
|
||||
if value.type == rd.VarType.SInt:
|
||||
debugged = value.value.s32v[0:value.columns]
|
||||
elif value.type == rd.VarType.UInt:
|
||||
debugged = value.value.u32v[0:value.columns]
|
||||
else:
|
||||
debugged = value.value.f32v[0:value.columns]
|
||||
|
||||
if not rdtest.value_compare(expect, debugged):
|
||||
raise rdtest.TestFailureException(
|
||||
|
||||
Reference in New Issue
Block a user