Add MSAA case to overlay tests

This commit is contained in:
baldurk
2020-10-22 14:11:01 +01:00
parent d503363279
commit 3f8fb1e1b6
5 changed files with 704 additions and 506 deletions
+67 -42
View File
@@ -124,6 +124,23 @@ float4 main() : SV_Target0
MakeTexture(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, screenWidth, screenHeight).DSV();
ID3D11DepthStencilViewPtr dsv = MakeDSV(depthtex);
UINT numQuals = 0;
dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 4, &numQuals);
// when there's more than one quality, use a non-zero just to be awkward.
ID3D11Texture2DPtr msaatex =
MakeTexture(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, screenWidth, screenHeight)
.RTV()
.Multisampled(4, numQuals > 1 ? 1 : 0);
ID3D11RenderTargetViewPtr msaartv = MakeRTV(msaatex);
dev->CheckMultisampleQualityLevels(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 4, &numQuals);
ID3D11Texture2DPtr msaadepthtex =
MakeTexture(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, screenWidth, screenHeight)
.DSV()
.Multisampled(4, numQuals > 1 ? 1 : 0);
ID3D11DepthStencilViewPtr msaadsv = MakeDSV(msaadepthtex);
ID3D11Texture2DPtr subtex =
MakeTexture(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, screenWidth, screenHeight).RTV().Array(5).Mips(4);
ID3D11RenderTargetViewPtr subrtv =
@@ -140,64 +157,72 @@ float4 main() : SV_Target0
ctx->VSSetShader(vs, NULL, 0);
ctx->PSSetShader(ps, NULL, 0);
D3D11_DEPTH_STENCIL_DESC depth = GetDepthState();
for(ID3D11RenderTargetViewPtr rtv : {bbRTV, msaartv})
{
D3D11_DEPTH_STENCIL_DESC depth = GetDepthState();
depth.StencilEnable = FALSE;
depth.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
depth.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
depth.StencilEnable = FALSE;
depth.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
depth.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
SetDepthState(depth);
SetStencilRef(0x55);
SetDepthState(depth);
SetStencilRef(0x55);
D3D11_RASTERIZER_DESC raster = GetRasterState();
D3D11_RASTERIZER_DESC raster = GetRasterState();
raster.ScissorEnable = TRUE;
raster.ScissorEnable = TRUE;
SetRasterState(raster);
SetRasterState(raster);
RSSetViewport(
{10.0f, 10.0f, (float)screenWidth - 20.0f, (float)screenHeight - 20.0f, 0.0f, 1.0f});
RSSetScissor({0, 0, screenWidth, screenHeight});
RSSetViewport(
{10.0f, 10.0f, (float)screenWidth - 20.0f, (float)screenHeight - 20.0f, 0.0f, 1.0f});
RSSetScissor({0, 0, screenWidth, screenHeight});
ctx->OMSetRenderTargets(1, &bbRTV.GetInterfacePtr(), dsv);
ID3D11DepthStencilViewPtr curDSV = rtv == msaartv ? msaadsv : dsv;
ClearRenderTargetView(bbRTV, {0.2f, 0.2f, 0.2f, 1.0f});
ctx->ClearDepthStencilView(dsv, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
ctx->OMSetRenderTargets(1, &rtv.GetInterfacePtr(), curDSV);
// draw the setup triangles
ClearRenderTargetView(rtv, {0.2f, 0.2f, 0.2f, 1.0f});
ctx->ClearDepthStencilView(curDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
// 1: write depth
depth.DepthFunc = D3D11_COMPARISON_ALWAYS;
SetDepthState(depth);
ctx->Draw(3, 0);
// draw the setup triangles
// 2: write stencil
depth.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
depth.StencilEnable = TRUE;
SetDepthState(depth);
ctx->Draw(3, 3);
// 1: write depth
depth.DepthFunc = D3D11_COMPARISON_ALWAYS;
SetDepthState(depth);
ctx->Draw(3, 0);
// 3: write background
depth.StencilEnable = FALSE;
SetDepthState(depth);
ctx->Draw(3, 6);
// 2: write stencil
depth.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
depth.StencilEnable = TRUE;
SetDepthState(depth);
ctx->Draw(3, 3);
// add a marker so we can easily locate this draw
setMarker("Test Begin");
// 3: write background
depth.StencilEnable = FALSE;
SetDepthState(depth);
ctx->Draw(3, 6);
depth.StencilEnable = TRUE;
depth.FrontFace.StencilFunc = D3D11_COMPARISON_GREATER;
SetDepthState(depth);
ctx->Draw(24, 9);
// add a marker so we can easily locate this draw
setMarker(rtv == msaartv ? "MSAA Test" : "Normal Test");
depth.StencilEnable = FALSE;
depth.DepthFunc = D3D11_COMPARISON_ALWAYS;
SetDepthState(depth);
depth.StencilEnable = TRUE;
depth.FrontFace.StencilFunc = D3D11_COMPARISON_GREATER;
SetDepthState(depth);
ctx->Draw(24, 9);
setMarker("Viewport Test");
RSSetViewport({10.0f, 10.0f, 80.0f, 80.0f, 0.0f, 1.0f});
RSSetScissor({24, 24, 76, 76});
ctx->Draw(3, 33);
depth.StencilEnable = FALSE;
depth.DepthFunc = D3D11_COMPARISON_ALWAYS;
SetDepthState(depth);
if(rtv == bbRTV)
{
setMarker("Viewport Test");
RSSetViewport({10.0f, 10.0f, 80.0f, 80.0f, 0.0f, 1.0f});
RSSetScissor({24, 24, 76, 76});
ctx->Draw(3, 33);
}
}
ctx->PSSetShader(whiteps, NULL, 0);
+84 -32
View File
@@ -117,6 +117,21 @@ float4 main() : SV_Target0
ID3D12RootSignaturePtr sig = MakeSig({});
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS qualData = {};
qualData.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
qualData.SampleCount = 4;
dev->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &qualData, sizeof(qualData));
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS qualData2 = {};
qualData2.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
qualData2.SampleCount = 4;
dev->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &qualData2, sizeof(qualData2));
UINT qual = std::min(qualData.NumQualityLevels, qualData2.NumQualityLevels) > 1 ? 1 : 0;
DXGI_SAMPLE_DESC noMSAA = {1, 0};
DXGI_SAMPLE_DESC yesMSAA = {4, qual};
D3D12PSOCreator creator = MakePSO().RootSig(sig).InputLayout().VS(vsblob).PS(psblob).DSV(
DXGI_FORMAT_D32_FLOAT_S8X24_UINT);
@@ -136,23 +151,41 @@ float4 main() : SV_Target0
creator.GraphicsDesc.DepthStencilState.StencilWriteMask = 0xff;
creator.GraphicsDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
ID3D12PipelineStatePtr depthWritePipe = creator;
ID3D12PipelineStatePtr depthWritePipe[2];
creator.GraphicsDesc.SampleDesc = noMSAA;
depthWritePipe[0] = creator;
creator.GraphicsDesc.SampleDesc = yesMSAA;
depthWritePipe[1] = creator;
creator.GraphicsDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;
creator.GraphicsDesc.DepthStencilState.StencilEnable = TRUE;
ID3D12PipelineStatePtr stencilWritePipe = creator;
ID3D12PipelineStatePtr stencilWritePipe[2];
creator.GraphicsDesc.SampleDesc = noMSAA;
stencilWritePipe[0] = creator;
creator.GraphicsDesc.SampleDesc = yesMSAA;
stencilWritePipe[1] = creator;
creator.GraphicsDesc.DepthStencilState.StencilEnable = FALSE;
ID3D12PipelineStatePtr backgroundPipe = creator;
ID3D12PipelineStatePtr backgroundPipe[2];
creator.GraphicsDesc.SampleDesc = noMSAA;
backgroundPipe[0] = creator;
creator.GraphicsDesc.SampleDesc = yesMSAA;
backgroundPipe[1] = creator;
creator.GraphicsDesc.DepthStencilState.StencilEnable = TRUE;
creator.GraphicsDesc.DepthStencilState.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_GREATER;
ID3D12PipelineStatePtr pipe = creator;
ID3D12PipelineStatePtr pipe[2];
creator.GraphicsDesc.SampleDesc = noMSAA;
pipe[0] = creator;
creator.GraphicsDesc.SampleDesc = yesMSAA;
pipe[1] = creator;
creator.GraphicsDesc.DepthStencilState.StencilEnable = FALSE;
creator.GraphicsDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
creator.PS(whitepsblob);
creator.DSV(DXGI_FORMAT_UNKNOWN);
creator.GraphicsDesc.SampleDesc = noMSAA;
ID3D12PipelineStatePtr whitepipe = creator;
ResourceBarrier(vb, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
@@ -167,6 +200,18 @@ float4 main() : SV_Target0
.Mips(4)
.InitialState(D3D12_RESOURCE_STATE_RENDER_TARGET);
ID3D12ResourcePtr msaadsv =
MakeTexture(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, screenWidth, screenHeight)
.DSV()
.Multisampled(4, qual)
.InitialState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
ID3D12ResourcePtr msaatex =
MakeTexture(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, screenWidth, screenHeight)
.RTV()
.Multisampled(4, qual)
.InitialState(D3D12_RESOURCE_STATE_RENDER_TARGET);
while(Running())
{
ID3D12GraphicsCommandListPtr cmd = GetCommandBuffer();
@@ -175,47 +220,54 @@ float4 main() : SV_Target0
ID3D12ResourcePtr bb = StartUsingBackbuffer(cmd, D3D12_RESOURCE_STATE_RENDER_TARGET);
D3D12_CPU_DESCRIPTOR_HANDLE rtv =
MakeRTV(bb).Format(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB).CreateCPU(0);
for(bool is_msaa : {false, true})
{
D3D12_CPU_DESCRIPTOR_HANDLE rtv =
MakeRTV(is_msaa ? msaatex : bb).Format(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB).CreateCPU(0);
cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
IASetVertexBuffer(cmd, vb, sizeof(DefaultA2V), 0);
cmd->SetGraphicsRootSignature(sig);
IASetVertexBuffer(cmd, vb, sizeof(DefaultA2V), 0);
cmd->SetGraphicsRootSignature(sig);
RSSetViewport(
cmd, {10.0f, 10.0f, (float)screenWidth - 20.0f, (float)screenHeight - 20.0f, 0.0f, 1.0f});
RSSetScissorRect(cmd, {0, 0, screenWidth, screenHeight});
RSSetViewport(cmd, {10.0f, 10.0f, (float)screenWidth - 20.0f, (float)screenHeight - 20.0f,
0.0f, 1.0f});
RSSetScissorRect(cmd, {0, 0, screenWidth, screenHeight});
OMSetRenderTargets(cmd, {rtv}, MakeDSV(dsv).CreateCPU(0));
OMSetRenderTargets(cmd, {rtv}, MakeDSV(is_msaa ? msaadsv : dsv).CreateCPU(0));
ClearRenderTargetView(cmd, rtv, {0.2f, 0.2f, 0.2f, 1.0f});
ClearDepthStencilView(cmd, dsv, D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 0);
ClearRenderTargetView(cmd, rtv, {0.2f, 0.2f, 0.2f, 1.0f});
ClearDepthStencilView(cmd, is_msaa ? msaadsv : dsv,
D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 0);
cmd->OMSetStencilRef(0x55);
cmd->OMSetStencilRef(0x55);
// draw the setup triangles
cmd->SetPipelineState(depthWritePipe);
cmd->DrawInstanced(3, 1, 0, 0);
// draw the setup triangles
cmd->SetPipelineState(depthWritePipe[is_msaa ? 1 : 0]);
cmd->DrawInstanced(3, 1, 0, 0);
cmd->SetPipelineState(stencilWritePipe);
cmd->DrawInstanced(3, 1, 3, 0);
cmd->SetPipelineState(stencilWritePipe[is_msaa ? 1 : 0]);
cmd->DrawInstanced(3, 1, 3, 0);
cmd->SetPipelineState(backgroundPipe);
cmd->DrawInstanced(3, 1, 6, 0);
cmd->SetPipelineState(backgroundPipe[is_msaa ? 1 : 0]);
cmd->DrawInstanced(3, 1, 6, 0);
// add a marker so we can easily locate this draw
setMarker(cmd, "Test Begin");
// add a marker so we can easily locate this draw
setMarker(cmd, is_msaa ? "MSAA Test" : "Normal Test");
cmd->SetPipelineState(pipe);
cmd->DrawInstanced(24, 1, 9, 0);
cmd->SetPipelineState(pipe[is_msaa ? 1 : 0]);
cmd->DrawInstanced(24, 1, 9, 0);
setMarker(cmd, "Viewport Test");
if(!is_msaa)
{
setMarker(cmd, "Viewport Test");
RSSetViewport(cmd, {10.0f, 10.0f, 80.0f, 80.0f, 0.0f, 1.0f});
RSSetScissorRect(cmd, {24, 24, 76, 76});
cmd->SetPipelineState(backgroundPipe);
cmd->DrawInstanced(3, 1, 33, 0);
RSSetViewport(cmd, {10.0f, 10.0f, 80.0f, 80.0f, 0.0f, 1.0f});
RSSetScissorRect(cmd, {24, 24, 76, 76});
cmd->SetPipelineState(backgroundPipe[0]);
cmd->DrawInstanced(3, 1, 33, 0);
}
}
D3D12_CPU_DESCRIPTOR_HANDLE subrtv = MakeRTV(subtex)
.Format(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB)
+58 -37
View File
@@ -181,7 +181,7 @@ void main()
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
// Color render texture
GLuint attachments[] = {MakeTexture(), MakeTexture(), MakeTexture()};
GLuint attachments[] = {MakeTexture(), MakeTexture(), MakeTexture(), MakeTexture()};
glBindTexture(GL_TEXTURE_2D, attachments[0]);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_SRGB8_ALPHA8, screenWidth, screenHeight);
@@ -192,6 +192,21 @@ void main()
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
attachments[1], 0);
GLuint msaafbo = MakeFBO();
glBindFramebuffer(GL_FRAMEBUFFER, msaafbo);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, attachments[2]);
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_SRGB8_ALPHA8, screenWidth,
screenHeight, GL_TRUE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
attachments[2], 0);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, attachments[3]);
glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_DEPTH24_STENCIL8, screenWidth,
screenHeight, GL_TRUE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
attachments[3], 0);
GLuint subtex = MakeTexture();
glBindTexture(GL_TEXTURE_2D_ARRAY, subtex);
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 4, GL_SRGB8_ALPHA8, screenWidth, screenHeight, 5);
@@ -223,52 +238,58 @@ void main()
glUseProgram(program);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
for(GLuint fb : {fbo, msaafbo})
{
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
glDisable(GL_DEPTH_CLAMP);
glDisable(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 0x55, 0xff);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
glDisable(GL_DEPTH_CLAMP);
glDisable(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_ALWAYS, 0x55, 0xff);
glViewport(10, 10, GLsizei(screenWidth) - 20, GLsizei(screenHeight) - 20);
glScissor(0, 0, screenWidth, screenHeight);
glViewport(10, 10, GLsizei(screenWidth) - 20, GLsizei(screenHeight) - 20);
glScissor(0, 0, screenWidth, screenHeight);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
float col[] = {0.2f, 0.2f, 0.2f, 1.0f};
glClearBufferfv(GL_COLOR, 0, col);
glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
float col[] = {0.2f, 0.2f, 0.2f, 1.0f};
glClearBufferfv(GL_COLOR, 0, col);
glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);
// 1: write depth
glDepthFunc(GL_ALWAYS);
glDrawArrays(GL_TRIANGLES, 0, 3);
// 1: write depth
glDepthFunc(GL_ALWAYS);
glDrawArrays(GL_TRIANGLES, 0, 3);
// 2: write stencil
glDepthFunc(GL_LEQUAL);
glEnable(GL_STENCIL_TEST);
glDrawArrays(GL_TRIANGLES, 3, 3);
// 2: write stencil
glDepthFunc(GL_LEQUAL);
glEnable(GL_STENCIL_TEST);
glDrawArrays(GL_TRIANGLES, 3, 3);
// 3: write background
glDisable(GL_STENCIL_TEST);
glDrawArrays(GL_TRIANGLES, 6, 3);
// 3: write background
glDisable(GL_STENCIL_TEST);
glDrawArrays(GL_TRIANGLES, 6, 3);
// add a marker so we can easily locate this draw
setMarker("Test Begin");
// add a marker so we can easily locate this draw
setMarker(fb == msaafbo ? "MSAA Test" : "Normal Test");
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_GREATER, 0x55, 0xff);
glDrawArrays(GL_TRIANGLES, 9, 24);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_GREATER, 0x55, 0xff);
glDrawArrays(GL_TRIANGLES, 9, 24);
setMarker("Viewport Test");
glDisable(GL_STENCIL_TEST);
glViewport(10, screenHeight - 90, 80, 80);
glScissor(24, screenHeight - 76, 52, 52);
glDrawArrays(GL_TRIANGLES, 33, 3);
if(fb != msaafbo)
{
setMarker("Viewport Test");
glDisable(GL_STENCIL_TEST);
glViewport(10, screenHeight - 90, 80, 80);
glScissor(24, screenHeight - 76, 52, 52);
glDrawArrays(GL_TRIANGLES, 33, 3);
}
glScissor(0, 0, screenWidth, screenHeight);
glScissor(0, 0, screenWidth, screenHeight);
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+126 -61
View File
@@ -206,6 +206,17 @@ void main()
VkRenderPass renderPass = createRenderPass(renderPassCreateInfo);
renderPassCreateInfo.attachments[0].samples = VK_SAMPLE_COUNT_4_BIT;
renderPassCreateInfo.attachments[1].samples = VK_SAMPLE_COUNT_4_BIT;
VkRenderPass msaaRP = createRenderPass(renderPassCreateInfo);
renderPassCreateInfo.attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
renderPassCreateInfo.attachments.pop_back();
renderPassCreateInfo.subpasses[0].pDepthStencilAttachment = NULL;
VkRenderPass subrp = createRenderPass(renderPassCreateInfo);
// create framebuffers using swapchain images and DS image
std::vector<VkFramebuffer> fbs;
fbs.resize(mainWindow->GetCount());
@@ -218,7 +229,6 @@ void main()
vkh::GraphicsPipelineCreateInfo pipeCreateInfo;
pipeCreateInfo.layout = layout;
pipeCreateInfo.renderPass = renderPass;
pipeCreateInfo.vertexInputState.vertexBindingDescriptions = {vkh::vertexBind(0, DefaultA2V)};
pipeCreateInfo.vertexInputState.vertexAttributeDescriptions = {
@@ -245,26 +255,46 @@ void main()
pipeCreateInfo.depthStencilState.back = pipeCreateInfo.depthStencilState.front;
pipeCreateInfo.depthStencilState.depthCompareOp = VK_COMPARE_OP_ALWAYS;
VkPipeline depthWritePipe = createGraphicsPipeline(pipeCreateInfo);
VkPipeline depthWritePipe[2];
pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
pipeCreateInfo.renderPass = renderPass;
depthWritePipe[0] = createGraphicsPipeline(pipeCreateInfo);
pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
pipeCreateInfo.renderPass = msaaRP;
depthWritePipe[1] = createGraphicsPipeline(pipeCreateInfo);
pipeCreateInfo.depthStencilState.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
pipeCreateInfo.depthStencilState.stencilTestEnable = VK_TRUE;
VkPipeline stencilWritePipe = createGraphicsPipeline(pipeCreateInfo);
VkPipeline stencilWritePipe[2];
pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
pipeCreateInfo.renderPass = renderPass;
stencilWritePipe[0] = createGraphicsPipeline(pipeCreateInfo);
pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
pipeCreateInfo.renderPass = msaaRP;
stencilWritePipe[1] = createGraphicsPipeline(pipeCreateInfo);
pipeCreateInfo.depthStencilState.stencilTestEnable = VK_FALSE;
VkPipeline backgroundPipe = createGraphicsPipeline(pipeCreateInfo);
VkPipeline backgroundPipe[2];
pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
pipeCreateInfo.renderPass = renderPass;
backgroundPipe[0] = createGraphicsPipeline(pipeCreateInfo);
pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
pipeCreateInfo.renderPass = msaaRP;
backgroundPipe[1] = createGraphicsPipeline(pipeCreateInfo);
pipeCreateInfo.depthStencilState.stencilTestEnable = VK_TRUE;
pipeCreateInfo.depthStencilState.front.compareOp = VK_COMPARE_OP_GREATER;
VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);
renderPassCreateInfo.attachments.pop_back();
renderPassCreateInfo.subpasses[0].pDepthStencilAttachment = NULL;
VkRenderPass subrp = createRenderPass(renderPassCreateInfo);
VkPipeline pipe[2];
pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
pipeCreateInfo.renderPass = renderPass;
pipe[0] = createGraphicsPipeline(pipeCreateInfo);
pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
pipeCreateInfo.renderPass = msaaRP;
pipe[1] = createGraphicsPipeline(pipeCreateInfo);
pipeCreateInfo.stages[1] =
CompileShaderModule(whitepixel, ShaderLang::glsl, ShaderStage::frag, "main");
pipeCreateInfo.multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
pipeCreateInfo.renderPass = subrp;
pipeCreateInfo.depthStencilState.stencilTestEnable = VK_FALSE;
pipeCreateInfo.depthStencilState.depthCompareOp = VK_COMPARE_OP_ALWAYS;
@@ -294,6 +324,31 @@ void main()
{mainWindow->scissor.extent.width / 8, mainWindow->scissor.extent.height / 8})),
};
AllocatedImage msaaimg(
this, vkh::ImageCreateInfo(mainWindow->scissor.extent.width,
mainWindow->scissor.extent.height, 0, mainWindow->format,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 1, 1, VK_SAMPLE_COUNT_4_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
AllocatedImage msaadepthimg(
this, vkh::ImageCreateInfo(
mainWindow->scissor.extent.width, mainWindow->scissor.extent.height, 0,
VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 1, 1,
VK_SAMPLE_COUNT_4_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
VkImageView msaaRTV = createImageView(
vkh::ImageViewCreateInfo(msaaimg.image, VK_IMAGE_VIEW_TYPE_2D, mainWindow->format));
VkImageView msaaDSV = createImageView(vkh::ImageViewCreateInfo(
msaadepthimg.image, VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D32_SFLOAT_S8_UINT, {},
vkh::ImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)));
VkFramebuffer msaaFB = createFramebuffer(vkh::FramebufferCreateInfo(
msaaRP, {msaaRTV, msaaDSV},
{mainWindow->scissor.extent.width, mainWindow->scissor.extent.height}));
(void)msaaFB;
while(Running())
{
VkCommandBuffer cmd = GetCommandBuffer();
@@ -302,61 +357,71 @@ void main()
StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
VkViewport v = mainWindow->viewport;
v.x += 10.0f;
v.y += 10.0f;
v.width -= 20.0f;
v.height -= 20.0f;
VkViewport v;
VkRect2D s;
// if we're using KHR_maintenance1, check that negative viewport height is handled
if(KHR_maintenance1)
for(bool is_msaa : {false, true})
{
v.y += v.height;
v.height = -v.height;
v = mainWindow->viewport;
v.x += 10.0f;
v.y += 10.0f;
v.width -= 20.0f;
v.height -= 20.0f;
// if we're using KHR_maintenance1, check that negative viewport height is handled
if(KHR_maintenance1)
{
v.y += v.height;
v.height = -v.height;
}
vkCmdSetViewport(cmd, 0, 1, &v);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdBeginRenderPass(
cmd, vkh::RenderPassBeginInfo(
is_msaa ? msaaRP : renderPass, is_msaa ? msaaFB : fbs[mainWindow->imgIndex],
mainWindow->scissor,
{vkh::ClearValue(0.2f, 0.2f, 0.2f, 1.0f), vkh::ClearValue(1.0f, 0)}),
VK_SUBPASS_CONTENTS_INLINE);
// draw the setup triangles
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, depthWritePipe[is_msaa ? 1 : 0]);
vkCmdDraw(cmd, 3, 1, 0, 0);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, stencilWritePipe[is_msaa ? 1 : 0]);
vkCmdDraw(cmd, 3, 1, 3, 0);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, backgroundPipe[is_msaa ? 1 : 0]);
vkCmdDraw(cmd, 3, 1, 6, 0);
// add a marker so we can easily locate this draw
setMarker(cmd, is_msaa ? "MSAA Test" : "Normal Test");
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe[is_msaa ? 1 : 0]);
vkCmdDraw(cmd, 24, 1, 9, 0);
if(!is_msaa)
{
setMarker(cmd, "Viewport Test");
v = {10.0f, 10.0f, 80.0f, 80.0f, 0.0f, 1.0f};
if(KHR_maintenance1)
{
v.y += v.height;
v.height = -v.height;
}
s = {{24, 24}, {52, 52}};
vkCmdSetViewport(cmd, 0, 1, &v);
vkCmdSetScissor(cmd, 0, 1, &s);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, backgroundPipe[0]);
vkCmdDraw(cmd, 3, 1, 33, 0);
}
vkCmdEndRenderPass(cmd);
}
vkCmdSetViewport(cmd, 0, 1, &v);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkh::cmdBindVertexBuffers(cmd, 0, {vb.buffer}, {0});
vkCmdBeginRenderPass(cmd,
vkh::RenderPassBeginInfo(
renderPass, fbs[mainWindow->imgIndex], mainWindow->scissor,
{vkh::ClearValue(0.2f, 0.2f, 0.2f, 1.0f), vkh::ClearValue(1.0f, 0)}),
VK_SUBPASS_CONTENTS_INLINE);
// draw the setup triangles
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, depthWritePipe);
vkCmdDraw(cmd, 3, 1, 0, 0);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, stencilWritePipe);
vkCmdDraw(cmd, 3, 1, 3, 0);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, backgroundPipe);
vkCmdDraw(cmd, 3, 1, 6, 0);
// add a marker so we can easily locate this draw
setMarker(cmd, "Test Begin");
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
vkCmdDraw(cmd, 24, 1, 9, 0);
setMarker(cmd, "Viewport Test");
v = {10.0f, 10.0f, 80.0f, 80.0f, 0.0f, 1.0f};
if(KHR_maintenance1)
{
v.y += v.height;
v.height = -v.height;
}
VkRect2D s = {{24, 24}, {52, 52}};
vkCmdSetViewport(cmd, 0, 1, &v);
vkCmdSetScissor(cmd, 0, 1, &s);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, backgroundPipe);
vkCmdDraw(cmd, 3, 1, 33, 0);
vkCmdEndRenderPass(cmd);
v = mainWindow->viewport;
v.width /= 4.0f;
v.height /= 4.0f;
+369 -334
View File
@@ -14,365 +14,391 @@ class Overlay_Test(rdtest.TestCase):
self.check(out is not None)
test_marker: rd.DrawcallDescription = self.find_draw("Test")
self.controller.SetFrameEvent(test_marker.next.eventId, True)
pipe: rd.PipeState = self.controller.GetPipelineState()
col_tex: rd.ResourceId = pipe.GetOutputTargets()[0].resourceId
tex = rd.TextureDisplay()
tex.resourceId = col_tex
api: rd.GraphicsAPI = self.controller.GetAPIProperties().pipelineType
# Check the actual output is as expected first.
# Background around the outside
self.check_pixel_value(col_tex, 0.1, 0.1, [0.2, 0.2, 0.2, 1.0])
self.check_pixel_value(col_tex, 0.8, 0.1, [0.2, 0.2, 0.2, 1.0])
self.check_pixel_value(col_tex, 0.5, 0.95, [0.2, 0.2, 0.2, 1.0])
# Large dark grey triangle
self.check_pixel_value(col_tex, 0.5, 0.1, [0.1, 0.1, 0.1, 1.0])
self.check_pixel_value(col_tex, 0.5, 0.9, [0.1, 0.1, 0.1, 1.0])
self.check_pixel_value(col_tex, 0.2, 0.9, [0.1, 0.1, 0.1, 1.0])
self.check_pixel_value(col_tex, 0.8, 0.9, [0.1, 0.1, 0.1, 1.0])
# Red upper half triangle
self.check_pixel_value(col_tex, 0.3, 0.4, [1.0, 0.0, 0.0, 1.0])
# Blue lower half triangle
self.check_pixel_value(col_tex, 0.3, 0.6, [0.0, 0.0, 1.0, 1.0])
# Floating clipped triangle
self.check_pixel_value(col_tex, 335, 140, [0.0, 0.0, 0.0, 1.0])
self.check_pixel_value(col_tex, 340, 140, [0.2, 0.2, 0.2, 1.0])
# Triangle size triangles
self.check_pixel_value(col_tex, 200, 51, [1.0, 0.5, 1.0, 1.0])
self.check_pixel_value(col_tex, 200, 65, [1.0, 1.0, 0.0, 1.0])
self.check_pixel_value(col_tex, 200, 79, [0.0, 1.0, 1.0, 1.0])
self.check_pixel_value(col_tex, 200, 93, [0.0, 1.0, 0.0, 1.0])
for overlay in rd.DebugOverlay:
if overlay == rd.DebugOverlay.NoOverlay:
continue
# These overlays are just displaymodes really, not actually separate overlays
if overlay == rd.DebugOverlay.NaN or overlay == rd.DebugOverlay.Clipping:
continue
# We'll test the clear-before-X overlays seperately, for both colour and depth
if overlay == rd.DebugOverlay.ClearBeforeDraw or overlay == rd.DebugOverlay.ClearBeforePass:
continue
rdtest.log.print("Checking overlay {} in main draw".format(str(overlay)))
tex.overlay = overlay
out.SetTextureDisplay(tex)
out.Display()
eps = 1.0 / 256.0
overlay_id: rd.ResourceId = out.GetDebugOverlayTexID()
# We test a few key spots:
# 4 points along the left side of the big triangle, above/in/below its intersection with the tri behind
# 4 points outside all triangles
# The overlap between the big tri and the bottom tri, and between it and the right backface culled tri
# The bottom tri's part that sticks out
# The two parts of the backface culled tri that stick out
# The depth clipped tri, in and out of clipping
# The 4 triangle size test triangles
if overlay == rd.DebugOverlay.Drawcall:
self.check_pixel_value(overlay_id, 150, 90, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 0.0, 0.0, 0.5], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [0.0, 0.0, 0.0, 0.5], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 0.0, 0.0, 0.5], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [0.0, 0.0, 0.0, 0.5], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 135, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 340, 145, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [0.8, 0.1, 0.8, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.Wireframe:
# Wireframe we only test a limited set to avoid hitting implementation variations of line raster
# We also have to fudge a little because the lines might land on adjacent pixels
x = 142
picked: rd.PixelValue = self.controller.PickPixel(overlay_id, x, 150, rd.Subresource(), rd.CompType.Typeless)
if picked.floatValue[3] == 0.0:
x = 141
self.check_pixel_value(overlay_id, x, 90, [200.0/255.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, x, 130, [200.0/255.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, x, 160, [200.0/255.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, x, 200, [200.0/255.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [200.0/255.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [200.0/255.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [200.0/255.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [200.0/255.0, 1.0, 0.0, 0.0], eps=eps)
y = 149
picked: rd.PixelValue = self.controller.PickPixel(overlay_id, 325, y, rd.Subresource(), rd.CompType.Typeless)
if picked.floatValue[3] == 0.0:
y = 150
self.check_pixel_value(overlay_id, 325, y, [200.0/255.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 340, y, [200.0/255.0, 1.0, 0.0, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.Depth:
self.check_pixel_value(overlay_id, 150, 90, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Intersection with lesser depth - depth fail
self.check_pixel_value(overlay_id, 150, 160, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Backface culled triangle
self.check_pixel_value(overlay_id, 285, 135, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Depth clipped part of tri
self.check_pixel_value(overlay_id, 340, 145, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [0.0, 1.0, 0.0, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.Stencil:
self.check_pixel_value(overlay_id, 150, 90, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Intersection with different stencil - stencil fail
self.check_pixel_value(overlay_id, 150, 130, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Backface culled triangle
self.check_pixel_value(overlay_id, 285, 135, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Depth clipped part of tri
self.check_pixel_value(overlay_id, 340, 145, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [0.0, 1.0, 0.0, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.BackfaceCull:
self.check_pixel_value(overlay_id, 150, 90, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Backface culled triangle
self.check_pixel_value(overlay_id, 285, 135, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 340, 145, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [0.0, 1.0, 0.0, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.ViewportScissor:
# Inside viewport
self.check_pixel_value(overlay_id, 50, 50, [0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 0.4 * 0.4], eps=eps)
self.check_pixel_value(overlay_id, 350, 50, [0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 0.4 * 0.4], eps=eps)
self.check_pixel_value(overlay_id, 50, 250, [0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 0.4 * 0.4], eps=eps)
self.check_pixel_value(overlay_id, 350, 250, [0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 0.4 * 0.4], eps=eps)
# Passing triangle inside the viewport
self.check_pixel_value(overlay_id, 200, 150,
[0.2 * 0.4, 1.0 * 0.6 + 0.2 * 0.4, 0.9 * 0.4, 1.0 * 0.6 + 0.4 * 0.4], eps=eps)
# Viewport border
self.check_pixel_value(overlay_id, 12, 12, [0.1, 0.1, 0.1, 1.0], eps=eps)
# Outside viewport (not on scissor border)
self.check_pixel_value(overlay_id, 6, 6, [0.0, 0.0, 0.0, 0.0], eps=eps)
# Scissor border
self.check_pixel_value(overlay_id, 0, 0, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 20, 0, [0.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 40, 0, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 60, 0, [0.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 60, 0, [0.0, 0.0, 0.0, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.QuadOverdrawDraw:
self.check_pixel_value(overlay_id, 150, 90, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 135, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 340, 145, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [1.0, 1.0, 1.0, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.QuadOverdrawPass:
self.check_pixel_value(overlay_id, 150, 90, [1.0, 1.0, 1.0, 1.0], eps=eps)
# Do an extra tap here where we overlap with the extreme-background largest triangle, to show that
# overdraw
self.check_pixel_value(overlay_id, 150, 100, [2.0, 2.0, 2.0, 2.0], eps=eps)
for is_msaa in [False, True]:
if is_msaa:
test_marker: rd.DrawcallDescription = self.find_draw("MSAA Test")
else:
test_marker: rd.DrawcallDescription = self.find_draw("Normal Test")
self.controller.SetFrameEvent(test_marker.next.eventId, True)
pipe: rd.PipeState = self.controller.GetPipelineState()
col_tex: rd.ResourceId = pipe.GetOutputTargets()[0].resourceId
tex = rd.TextureDisplay()
tex.resourceId = col_tex
tex.subresource.sample = 0
# Background around the outside
self.check_pixel_value(col_tex, 0.1, 0.1, [0.2, 0.2, 0.2, 1.0])
self.check_pixel_value(col_tex, 0.8, 0.1, [0.2, 0.2, 0.2, 1.0])
self.check_pixel_value(col_tex, 0.5, 0.95, [0.2, 0.2, 0.2, 1.0])
# Large dark grey triangle
self.check_pixel_value(col_tex, 0.5, 0.1, [0.1, 0.1, 0.1, 1.0])
self.check_pixel_value(col_tex, 0.5, 0.9, [0.1, 0.1, 0.1, 1.0])
self.check_pixel_value(col_tex, 0.2, 0.9, [0.1, 0.1, 0.1, 1.0])
self.check_pixel_value(col_tex, 0.8, 0.9, [0.1, 0.1, 0.1, 1.0])
# Red upper half triangle
self.check_pixel_value(col_tex, 0.3, 0.4, [1.0, 0.0, 0.0, 1.0])
# Blue lower half triangle
self.check_pixel_value(col_tex, 0.3, 0.6, [0.0, 0.0, 1.0, 1.0])
# Floating clipped triangle
self.check_pixel_value(col_tex, 335, 140, [0.0, 0.0, 0.0, 1.0])
self.check_pixel_value(col_tex, 340, 140, [0.2, 0.2, 0.2, 1.0])
# Triangle size triangles
self.check_pixel_value(col_tex, 200, 51, [1.0, 0.5, 1.0, 1.0])
self.check_pixel_value(col_tex, 200, 65, [1.0, 1.0, 0.0, 1.0])
self.check_pixel_value(col_tex, 200, 79, [0.0, 1.0, 1.0, 1.0])
self.check_pixel_value(col_tex, 200, 93, [0.0, 1.0, 0.0, 1.0])
for overlay in rd.DebugOverlay:
if overlay == rd.DebugOverlay.NoOverlay:
continue
# These overlays are just displaymodes really, not actually separate overlays
if overlay == rd.DebugOverlay.NaN or overlay == rd.DebugOverlay.Clipping:
continue
# We'll test the clear-before-X overlays seperately, for both colour and depth
if overlay == rd.DebugOverlay.ClearBeforeDraw or overlay == rd.DebugOverlay.ClearBeforePass:
continue
rdtest.log.print("Checking overlay {} in {} main draw".format("MSAA" if is_msaa else "normal", str(overlay)))
tex.overlay = overlay
out.SetTextureDisplay(tex)
out.Display()
eps = 1.0 / 256.0
overlay_id: rd.ResourceId = out.GetDebugOverlayTexID()
# We test a few key spots:
# 4 points along the left side of the big triangle, above/in/below its intersection with the tri behind
# 4 points outside all triangles
# The overlap between the big tri and the bottom tri, and between it and the right backface culled tri
# The bottom tri's part that sticks out
# The two parts of the backface culled tri that stick out
# The depth clipped tri, in and out of clipping
# The 4 triangle size test triangles
if overlay == rd.DebugOverlay.Drawcall:
self.check_pixel_value(overlay_id, 150, 90, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 0.0, 0.0, 0.5], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [0.0, 0.0, 0.0, 0.5], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 0.0, 0.0, 0.5], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [0.0, 0.0, 0.0, 0.5], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 135, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 340, 145, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [0.8, 0.1, 0.8, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [0.8, 0.1, 0.8, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.Wireframe:
# Wireframe we only test a limited set to avoid hitting implementation variations of line raster
# We also have to fudge a little because the lines might land on adjacent pixels
# Also to be safe we don't run this test on MSAA
if not is_msaa:
x = 142
picked: rd.PixelValue = self.controller.PickPixel(overlay_id, x, 150, rd.Subresource(), rd.CompType.Typeless)
if picked.floatValue[3] == 0.0:
x = 141
picked: rd.PixelValue = self.controller.PickPixel(overlay_id, x, 150, rd.Subresource(), rd.CompType.Typeless)
self.check_pixel_value(overlay_id, x, 90, [200.0/255.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, x, 130, [200.0/255.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, x, 160, [200.0/255.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, x, 200, [200.0/255.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [200.0/255.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [200.0/255.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [200.0/255.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [200.0/255.0, 1.0, 0.0, 0.0], eps=eps)
y = 149
picked: rd.PixelValue = self.controller.PickPixel(overlay_id, 325, y, rd.Subresource(), rd.CompType.Typeless)
if picked.floatValue[3] == 0.0:
y = 150
self.check_pixel_value(overlay_id, 325, y, [200.0/255.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 340, y, [200.0/255.0, 1.0, 0.0, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.Depth:
self.check_pixel_value(overlay_id, 150, 90, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Intersection with lesser depth - depth fail
self.check_pixel_value(overlay_id, 150, 160, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Backface culled triangle
self.check_pixel_value(overlay_id, 285, 135, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Depth clipped part of tri
self.check_pixel_value(overlay_id, 340, 145, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [0.0, 1.0, 0.0, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.Stencil:
self.check_pixel_value(overlay_id, 150, 90, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Intersection with different stencil - stencil fail
self.check_pixel_value(overlay_id, 150, 130, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Backface culled triangle
self.check_pixel_value(overlay_id, 285, 135, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Depth clipped part of tri
self.check_pixel_value(overlay_id, 340, 145, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [0.0, 1.0, 0.0, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.BackfaceCull:
self.check_pixel_value(overlay_id, 150, 90, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [0.0, 1.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [0.0, 1.0, 0.0, 1.0], eps=eps)
# Backface culled triangle
self.check_pixel_value(overlay_id, 285, 135, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [1.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 340, 145, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [0.0, 1.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [0.0, 1.0, 0.0, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.ViewportScissor:
# Inside viewport
self.check_pixel_value(overlay_id, 50, 50, [0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 0.4 * 0.4], eps=eps)
self.check_pixel_value(overlay_id, 350, 50, [0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 0.4 * 0.4], eps=eps)
self.check_pixel_value(overlay_id, 50, 250, [0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 0.4 * 0.4], eps=eps)
self.check_pixel_value(overlay_id, 350, 250, [0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 0.4 * 0.4], eps=eps)
# Passing triangle inside the viewport
self.check_pixel_value(overlay_id, 200, 150,
[0.2 * 0.4, 1.0 * 0.6 + 0.2 * 0.4, 0.9 * 0.4, 1.0 * 0.6 + 0.4 * 0.4], eps=eps)
# Viewport border
self.check_pixel_value(overlay_id, 12, 12, [0.1, 0.1, 0.1, 1.0], eps=eps)
# Outside viewport (not on scissor border)
self.check_pixel_value(overlay_id, 6, 6, [0.0, 0.0, 0.0, 0.0], eps=eps)
# Scissor border
self.check_pixel_value(overlay_id, 0, 0, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 20, 0, [0.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 40, 0, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 60, 0, [0.0, 0.0, 0.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 60, 0, [0.0, 0.0, 0.0, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.QuadOverdrawDraw:
# This would require extreme command buffer patching to de-MSAA the framebuffer and renderpass
if api == rd.GraphicsAPI.Vulkan and is_msaa:
rdtest.log.print("Quad overdraw not currently supported on MSAA on Vulkan")
continue
self.check_pixel_value(overlay_id, 150, 90, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 135, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 340, 145, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [1.0, 1.0, 1.0, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.QuadOverdrawPass:
# This would require extreme command buffer patching to de-MSAA the framebuffer and renderpass
if api == rd.GraphicsAPI.Vulkan and is_msaa:
rdtest.log.print("Quad overdraw not currently supported on MSAA on Vulkan")
continue
self.check_pixel_value(overlay_id, 150, 90, [1.0, 1.0, 1.0, 1.0], eps=eps)
# Do an extra tap here where we overlap with the extreme-background largest triangle, to show that
# overdraw
self.check_pixel_value(overlay_id, 150, 100, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [2.0, 2.0, 2.0, 2.0], eps=eps)
# Two of these have overdraw from the pass due to the large background triangle
self.check_pixel_value(overlay_id, 125, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [3.0, 3.0, 3.0, 3.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 135, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [2.0, 2.0, 2.0, 2.0], eps=eps)
# Two of these have overdraw from the pass due to the large background triangle
self.check_pixel_value(overlay_id, 125, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [3.0, 3.0, 3.0, 3.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 135, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 340, 145, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [1.0, 1.0, 1.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 340, 145, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [2.0, 2.0, 2.0, 2.0], eps=eps)
elif overlay == rd.DebugOverlay.TriangleSizeDraw:
eps = 1.0
self.check_pixel_value(overlay_id, 150, 90, [10632.0, 10632.0, 10632.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [10632.0, 10632.0, 10632.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [2.0, 2.0, 2.0, 2.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [2.0, 2.0, 2.0, 2.0], eps=eps)
elif overlay == rd.DebugOverlay.TriangleSizeDraw:
eps = 1.0
self.check_pixel_value(overlay_id, 220, 175, [2128.0, 2128.0, 2128.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [10632.0, 10632.0, 10632.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 90, [10632.0, 10632.0, 10632.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [10632.0, 10632.0, 10632.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [2128.0, 2128.0, 2128.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [2128.0, 2128.0, 2128.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [10632.0, 10632.0, 10632.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [2128.0, 2128.0, 2128.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 135, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 135, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [531.0, 531.0, 531.0, 531.0], eps=eps)
self.check_pixel_value(overlay_id, 340, 145, [0.0, 0.0, 0.0, 0.0], eps=eps)
eps = 0.01
self.check_pixel_value(overlay_id, 330, 145, [531.0, 531.0, 531.0, 531.0], eps=eps)
self.check_pixel_value(overlay_id, 340, 145, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [8.305, 8.305, 8.305, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [5.316, 5.316, 5.316, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [3.0, 3.0, 3.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [1.33, 1.33, 1.33, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.TriangleSizePass:
eps = 1.0
eps = 0.01
self.check_pixel_value(overlay_id, 150, 90, [10632.0, 10632.0, 10632.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [3324.0, 3324.0, 3324.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [3324.0, 3324.0, 3324.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [10632.0, 10632.0, 10632.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [8.305, 8.305, 8.305, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [5.316, 5.316, 5.316, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [3.0, 3.0, 3.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [1.33, 1.33, 1.33, 1.0], eps=eps)
elif overlay == rd.DebugOverlay.TriangleSizePass:
eps = 1.0
self.check_pixel_value(overlay_id, 125, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [43072.0, 43072.0, 43072.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [43072.0, 43072.0, 43072.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 90, [10632.0, 10632.0, 10632.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 130, [3324.0, 3324.0, 3324.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 160, [3324.0, 3324.0, 3324.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 150, 200, [10632.0, 10632.0, 10632.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [2128.0, 2128.0, 2128.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [10632.0, 10632.0, 10632.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 125, 250, [43072.0, 43072.0, 43072.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 60, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 250, [43072.0, 43072.0, 43072.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [2128.0, 2128.0, 2128.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 175, [2128.0, 2128.0, 2128.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 250, 150, [10632.0, 10632.0, 10632.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 135, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [43072.0, 43072.0, 43072.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 220, 190, [2128.0, 2128.0, 2128.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 330, 145, [531.0, 531.0, 531.0, 531.0], eps=eps)
self.check_pixel_value(overlay_id, 340, 145, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 135, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 285, 165, [43072.0, 43072.0, 43072.0, 1.0], eps=eps)
eps = 0.01
self.check_pixel_value(overlay_id, 330, 145, [531.0, 531.0, 531.0, 531.0], eps=eps)
self.check_pixel_value(overlay_id, 340, 145, [0.0, 0.0, 0.0, 0.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 51, [8.305, 8.305, 8.305, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [5.316, 5.316, 5.316, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [3.0, 3.0, 3.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [1.33, 1.33, 1.33, 1.0], eps=eps)
eps = 0.01
rdtest.log.success("Picked pixels are as expected for {}".format(str(overlay)))
self.check_pixel_value(overlay_id, 200, 51, [8.305, 8.305, 8.305, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 65, [5.316, 5.316, 5.316, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 79, [3.0, 3.0, 3.0, 1.0], eps=eps)
self.check_pixel_value(overlay_id, 200, 93, [1.33, 1.33, 1.33, 1.0], eps=eps)
rdtest.log.success("Picked pixels are as expected for {}".format(str(overlay)))
rdtest.log.success("All normal overlays are as expected")
if is_msaa:
rdtest.log.success("All MSAA overlays are as expected")
else:
rdtest.log.success("All normal overlays are as expected")
# Check the viewport overlay especially
view_marker: rd.DrawcallDescription = self.find_draw("Viewport Test")
self.controller.SetFrameEvent(view_marker.next.eventId, True)
pipe: rd.PipeState = self.controller.GetPipelineState()
col_tex: rd.ResourceId = pipe.GetOutputTargets()[0].resourceId
for overlay in rd.DebugOverlay:
if overlay == rd.DebugOverlay.NoOverlay:
continue
@@ -387,6 +413,7 @@ class Overlay_Test(rdtest.TestCase):
rdtest.log.print("Checking overlay {} in viewport draw".format(str(overlay)))
tex.resourceId = col_tex
tex.overlay = overlay
out.SetTextureDisplay(tex)
@@ -396,6 +423,12 @@ class Overlay_Test(rdtest.TestCase):
overlay_id: rd.ResourceId = out.GetDebugOverlayTexID()
save_data = rd.TextureSave()
save_data.resourceId = overlay_id
save_data.destType = rd.FileType.PNG
self.controller.SaveTexture(save_data, rdtest.get_tmp_path('overlay.png'))
if overlay == rd.DebugOverlay.Drawcall:
# The drawcall overlay will show up outside the scissor region
self.check_pixel_value(overlay_id, 50, 85, [0.8, 0.1, 0.8, 1.0], eps=eps)
@@ -476,6 +509,8 @@ class Overlay_Test(rdtest.TestCase):
rdtest.log.success("Overlays are as expected around viewport/scissor behaviour")
test_marker: rd.DrawcallDescription = self.find_draw("Normal Test")
# Now check clear-before-X by hand, for colour and for depth
self.controller.SetFrameEvent(test_marker.next.eventId, True)