mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-12 17:51:02 +00:00
Make overlays interact consistently with viewport/scissor
* We also add a red/green display to the viewport and scissor overlay to show pixels that fail the scissor test.
This commit is contained in:
@@ -357,6 +357,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
{
|
||||
origdesc.CullMode = D3D11_CULL_BACK;
|
||||
origdesc.FrontCounterClockwise = FALSE;
|
||||
origdesc.ScissorEnable = FALSE;
|
||||
}
|
||||
|
||||
SAFE_RELEASE(rs);
|
||||
@@ -372,7 +373,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP;
|
||||
rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
|
||||
rdesc.DepthClipEnable = FALSE;
|
||||
rdesc.ScissorEnable = FALSE;
|
||||
rdesc.ScissorEnable = origdesc.ScissorEnable;
|
||||
rdesc.MultisampleEnable = FALSE;
|
||||
rdesc.AntialiasedLineEnable = FALSE;
|
||||
|
||||
@@ -422,27 +423,22 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
}
|
||||
else if(overlay == DebugOverlay::ViewportScissor)
|
||||
{
|
||||
m_pImmediateContext->VSSetShader(m_Overlay.FullscreenVS, NULL, 0);
|
||||
m_pImmediateContext->HSSetShader(NULL, NULL, 0);
|
||||
m_pImmediateContext->DSSetShader(NULL, NULL, 0);
|
||||
m_pImmediateContext->GSSetShader(NULL, NULL, 0);
|
||||
m_pImmediateContext->PSSetShader(m_General.CheckerboardPS, NULL, 0);
|
||||
m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
m_pImmediateContext->IASetInputLayout(NULL);
|
||||
m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff);
|
||||
m_pImmediateContext->PSSetShader(m_General.FixedColPS, NULL, 0);
|
||||
|
||||
D3D11_RASTERIZER_DESC origdesc;
|
||||
D3D11_RASTERIZER_DESC origdesc = {};
|
||||
|
||||
{
|
||||
ID3D11RasterizerState *rs = NULL;
|
||||
ID3D11RasterizerState *origRS = NULL;
|
||||
|
||||
m_pImmediateContext->RSGetState(&rs);
|
||||
m_pImmediateContext->RSGetState(&origRS);
|
||||
|
||||
if(rs)
|
||||
rs->GetDesc(&origdesc);
|
||||
if(origRS)
|
||||
origRS->GetDesc(&origdesc);
|
||||
else
|
||||
origdesc.ScissorEnable = FALSE;
|
||||
|
||||
SAFE_RELEASE(rs);
|
||||
SAFE_RELEASE(origRS);
|
||||
}
|
||||
|
||||
dsDesc.DepthEnable = FALSE;
|
||||
@@ -456,8 +452,71 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
return m_Overlay.resourceId;
|
||||
}
|
||||
|
||||
ID3D11RasterizerState *rs = NULL;
|
||||
ID3D11RasterizerState *rsScissorOn = NULL;
|
||||
{
|
||||
D3D11_RASTERIZER_DESC rdesc;
|
||||
|
||||
rdesc.FillMode = D3D11_FILL_SOLID;
|
||||
rdesc.CullMode = D3D11_CULL_NONE;
|
||||
rdesc.FrontCounterClockwise = FALSE;
|
||||
rdesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS;
|
||||
rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP;
|
||||
rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
|
||||
rdesc.DepthClipEnable = FALSE;
|
||||
rdesc.ScissorEnable = FALSE;
|
||||
rdesc.MultisampleEnable = FALSE;
|
||||
rdesc.AntialiasedLineEnable = FALSE;
|
||||
|
||||
hr = m_pDevice->CreateRasterizerState(&rdesc, &rs);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create drawcall rast state HRESULT: %s", ToStr(hr).c_str());
|
||||
return m_Overlay.resourceId;
|
||||
}
|
||||
|
||||
rdesc.ScissorEnable = TRUE;
|
||||
|
||||
hr = m_pDevice->CreateRasterizerState(&rdesc, &rsScissorOn);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create drawcall rast state HRESULT: %s", ToStr(hr).c_str());
|
||||
return m_Overlay.resourceId;
|
||||
}
|
||||
}
|
||||
|
||||
float clearColour[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
m_pImmediateContext->ClearRenderTargetView(rtv, clearColour);
|
||||
|
||||
m_pImmediateContext->RSSetState(rs);
|
||||
m_pImmediateContext->OMSetDepthStencilState(os, 0);
|
||||
|
||||
float overlayConsts[] = {1.0f, 0.0f, 0.0f, 1.0f};
|
||||
ID3D11Buffer *buf = GetDebugManager()->MakeCBuffer(overlayConsts, sizeof(overlayConsts));
|
||||
|
||||
m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf);
|
||||
|
||||
m_pDevice->ReplayLog(0, eventId, eReplay_OnlyDraw);
|
||||
|
||||
overlayConsts[0] = 0.0f;
|
||||
overlayConsts[1] = 1.0f;
|
||||
|
||||
buf = GetDebugManager()->MakeCBuffer(overlayConsts, sizeof(overlayConsts));
|
||||
|
||||
m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf);
|
||||
|
||||
m_pImmediateContext->RSSetState(rsScissorOn);
|
||||
|
||||
m_pDevice->ReplayLog(0, eventId, eReplay_OnlyDraw);
|
||||
|
||||
m_pImmediateContext->VSSetShader(m_Overlay.FullscreenVS, NULL, 0);
|
||||
m_pImmediateContext->HSSetShader(NULL, NULL, 0);
|
||||
m_pImmediateContext->DSSetShader(NULL, NULL, 0);
|
||||
m_pImmediateContext->GSSetShader(NULL, NULL, 0);
|
||||
m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
m_pImmediateContext->IASetInputLayout(NULL);
|
||||
m_pImmediateContext->PSSetShader(m_General.CheckerboardPS, NULL, 0);
|
||||
|
||||
D3D11_BLEND_DESC blendDesc;
|
||||
RDCEraseEl(blendDesc);
|
||||
|
||||
@@ -478,32 +537,6 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
float blendwhite[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
m_pImmediateContext->OMSetBlendState(bs, blendwhite, 0xffffffff);
|
||||
|
||||
ID3D11RasterizerState *rs = NULL;
|
||||
{
|
||||
D3D11_RASTERIZER_DESC rdesc;
|
||||
|
||||
rdesc.FillMode = D3D11_FILL_SOLID;
|
||||
rdesc.CullMode = D3D11_CULL_NONE;
|
||||
rdesc.FrontCounterClockwise = FALSE;
|
||||
rdesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS;
|
||||
rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP;
|
||||
rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
|
||||
rdesc.DepthClipEnable = FALSE;
|
||||
rdesc.ScissorEnable = FALSE;
|
||||
rdesc.MultisampleEnable = FALSE;
|
||||
rdesc.AntialiasedLineEnable = FALSE;
|
||||
|
||||
hr = m_pDevice->CreateRasterizerState(&rdesc, &rs);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create drawcall rast state HRESULT: %s", ToStr(hr).c_str());
|
||||
return m_Overlay.resourceId;
|
||||
}
|
||||
}
|
||||
|
||||
float clearColour[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
m_pImmediateContext->ClearRenderTargetView(rtv, clearColour);
|
||||
|
||||
m_pImmediateContext->RSSetState(rs);
|
||||
|
||||
CheckerboardCBuffer pixelData = {0};
|
||||
@@ -517,13 +550,13 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
|
||||
// set primary/secondary to the same to 'disable' checkerboard
|
||||
pixelData.PrimaryColor = pixelData.SecondaryColor = Vec4f(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
pixelData.InnerColor = Vec4f(0.2f, 0.2f, 0.9f, 0.7f);
|
||||
pixelData.InnerColor = Vec4f(0.2f, 0.2f, 0.9f, 0.4f);
|
||||
|
||||
// set viewport rect
|
||||
pixelData.RectPosition = Vec2f(views[0].TopLeftX, views[0].TopLeftY);
|
||||
pixelData.RectSize = Vec2f(views[0].Width, views[0].Height);
|
||||
|
||||
ID3D11Buffer *buf = GetDebugManager()->MakeCBuffer(&pixelData, sizeof(pixelData));
|
||||
buf = GetDebugManager()->MakeCBuffer(&pixelData, sizeof(pixelData));
|
||||
|
||||
m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf);
|
||||
|
||||
@@ -565,6 +598,7 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
|
||||
SAFE_RELEASE(os);
|
||||
SAFE_RELEASE(rs);
|
||||
SAFE_RELEASE(rsScissorOn);
|
||||
SAFE_RELEASE(bs);
|
||||
}
|
||||
else if(overlay == DebugOverlay::Wireframe)
|
||||
@@ -1116,6 +1150,10 @@ ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff);
|
||||
m_pImmediateContext->RSSetState(m_General.RasterState);
|
||||
|
||||
D3D11_VIEWPORT view = {0.0f, 0.0f, (float)realTexDesc.Width, (float)realTexDesc.Height,
|
||||
0.0f, 1.0f};
|
||||
m_pImmediateContext->RSSetViewports(1, &view);
|
||||
|
||||
float clearColour[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
m_pImmediateContext->ClearRenderTargetView(rtv, clearColour);
|
||||
|
||||
|
||||
@@ -442,7 +442,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
D3D12_RENDER_TARGET_VIEW_DESC rtDesc = {};
|
||||
rtDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||
|
||||
ID3D12GraphicsCommandList *list = m_pDevice->GetNewList();
|
||||
ID3D12GraphicsCommandListX *list = m_pDevice->GetNewList();
|
||||
|
||||
// clear all mips and all slices first
|
||||
for(UINT mip = 0; mip < overlayTexDesc.MipLevels; mip++)
|
||||
@@ -563,6 +563,9 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
rs.rts[0] = *GetWrapped(rtv);
|
||||
RDCEraseEl(rs.dsv);
|
||||
|
||||
for(D3D12_RECT &r : rs.scissors)
|
||||
r = {0, 0, 32768, 32768};
|
||||
|
||||
m_pDevice->ReplayLog(0, eventId, eReplay_OnlyDraw);
|
||||
|
||||
rs = prev;
|
||||
@@ -844,12 +847,102 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
{
|
||||
if(pipe && pipe->IsGraphics() && !rs.views.empty())
|
||||
{
|
||||
D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC psoDesc;
|
||||
pipe->Fill(psoDesc);
|
||||
|
||||
bool dxil =
|
||||
DXBC::DXBCContainer::CheckForDXIL(psoDesc.VS.pShaderBytecode, psoDesc.VS.BytecodeLength);
|
||||
|
||||
ID3DBlob *red = m_pDevice->GetShaderCache()->MakeFixedColShader(D3D12ShaderCache::RED, dxil);
|
||||
ID3DBlob *green =
|
||||
m_pDevice->GetShaderCache()->MakeFixedColShader(D3D12ShaderCache::GREEN, dxil);
|
||||
|
||||
psoDesc.DepthStencilState.DepthEnable = FALSE;
|
||||
psoDesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO;
|
||||
psoDesc.DepthStencilState.StencilEnable = FALSE;
|
||||
|
||||
psoDesc.BlendState.AlphaToCoverageEnable = FALSE;
|
||||
psoDesc.BlendState.IndependentBlendEnable = FALSE;
|
||||
psoDesc.BlendState.RenderTarget[0].BlendEnable = FALSE;
|
||||
psoDesc.BlendState.RenderTarget[0].RenderTargetWriteMask = 0xf;
|
||||
psoDesc.BlendState.RenderTarget[0].LogicOpEnable = FALSE;
|
||||
RDCEraseEl(psoDesc.RTVFormats.RTFormats);
|
||||
psoDesc.RTVFormats.RTFormats[0] = DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||
psoDesc.RTVFormats.NumRenderTargets = 1;
|
||||
psoDesc.SampleMask = ~0U;
|
||||
psoDesc.SampleDesc.Count = RDCMAX(1U, psoDesc.SampleDesc.Count);
|
||||
psoDesc.DSVFormat = DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
psoDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
|
||||
psoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
|
||||
psoDesc.RasterizerState.FrontCounterClockwise = FALSE;
|
||||
psoDesc.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
|
||||
psoDesc.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
|
||||
psoDesc.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
|
||||
psoDesc.RasterizerState.DepthClipEnable = FALSE;
|
||||
psoDesc.RasterizerState.MultisampleEnable = FALSE;
|
||||
psoDesc.RasterizerState.AntialiasedLineEnable = FALSE;
|
||||
|
||||
psoDesc.PS.pShaderBytecode = red->GetBufferPointer();
|
||||
psoDesc.PS.BytecodeLength = red->GetBufferSize();
|
||||
|
||||
ID3D12PipelineState *redPSO = NULL;
|
||||
HRESULT hr = m_pDevice->CreatePipeState(psoDesc, &redPSO);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create overlay pso HRESULT: %s", ToStr(hr).c_str());
|
||||
SAFE_RELEASE(red);
|
||||
SAFE_RELEASE(redPSO);
|
||||
SAFE_RELEASE(green);
|
||||
return m_Overlay.resourceId;
|
||||
}
|
||||
|
||||
psoDesc.PS.pShaderBytecode = green->GetBufferPointer();
|
||||
psoDesc.PS.BytecodeLength = green->GetBufferSize();
|
||||
|
||||
ID3D12PipelineState *greenPSO = NULL;
|
||||
hr = m_pDevice->CreatePipeState(psoDesc, &greenPSO);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to create overlay pso HRESULT: %s", ToStr(hr).c_str());
|
||||
SAFE_RELEASE(red);
|
||||
SAFE_RELEASE(redPSO);
|
||||
SAFE_RELEASE(green);
|
||||
SAFE_RELEASE(greenPSO);
|
||||
return m_Overlay.resourceId;
|
||||
}
|
||||
|
||||
list->Close();
|
||||
list = NULL;
|
||||
|
||||
D3D12_RECT scissor = {0, 0, 16384, 16384};
|
||||
|
||||
D3D12RenderState prev = rs;
|
||||
|
||||
rs.rts = {*GetWrapped(rtv)};
|
||||
|
||||
for(D3D12_RECT &s : rs.scissors)
|
||||
s = scissor;
|
||||
|
||||
rs.pipe = GetResID(redPSO);
|
||||
m_pDevice->ReplayLog(0, eventId, eReplay_OnlyDraw);
|
||||
|
||||
rs.scissors = prev.scissors;
|
||||
|
||||
rs.pipe = GetResID(greenPSO);
|
||||
m_pDevice->ReplayLog(0, eventId, eReplay_OnlyDraw);
|
||||
|
||||
rs = prev;
|
||||
|
||||
list = m_pDevice->GetNewList();
|
||||
|
||||
rs.ApplyState(m_pDevice, list);
|
||||
|
||||
list->OMSetRenderTargets(1, &rtv, TRUE, NULL);
|
||||
|
||||
D3D12_VIEWPORT viewport = rs.views[0];
|
||||
list->RSSetViewports(1, &viewport);
|
||||
|
||||
D3D12_RECT scissor = {0, 0, 16384, 16384};
|
||||
list->RSSetScissorRects(1, &scissor);
|
||||
|
||||
list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
@@ -866,7 +959,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
|
||||
// set primary/secondary to the same to 'disable' checkerboard
|
||||
pixelData.PrimaryColor = pixelData.SecondaryColor = Vec4f(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
pixelData.InnerColor = Vec4f(0.2f, 0.2f, 0.9f, 0.7f);
|
||||
pixelData.InnerColor = Vec4f(0.2f, 0.2f, 0.9f, 0.4f);
|
||||
|
||||
// set viewport rect
|
||||
pixelData.RectPosition = Vec2f(viewport.TopLeftX, viewport.TopLeftY);
|
||||
@@ -905,6 +998,17 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
list->SetGraphicsRootConstantBufferView(0, scissorCB);
|
||||
|
||||
list->DrawInstanced(3, 1, 0, 0);
|
||||
|
||||
list->Close();
|
||||
list = NULL;
|
||||
|
||||
m_pDevice->ExecuteLists();
|
||||
m_pDevice->FlushLists();
|
||||
|
||||
SAFE_RELEASE(red);
|
||||
SAFE_RELEASE(redPSO);
|
||||
SAFE_RELEASE(green);
|
||||
SAFE_RELEASE(greenPSO);
|
||||
}
|
||||
}
|
||||
else if(overlay == DebugOverlay::TriangleSizeDraw || overlay == DebugOverlay::TriangleSizePass)
|
||||
@@ -937,8 +1041,6 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
list = NULL;
|
||||
|
||||
m_pDevice->ReplayLog(0, events[0], eReplay_WithoutDraw);
|
||||
|
||||
list = m_pDevice->GetNewList();
|
||||
}
|
||||
|
||||
pipe = m_pDevice->GetResourceManager()->GetCurrentAs<WrappedID3D12PipelineState>(rs.pipe);
|
||||
@@ -996,40 +1098,40 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
vertexData.ModelViewProj = Matrix4f::Identity();
|
||||
vertexData.SpriteSize = Vec2f();
|
||||
|
||||
Vec4f viewport;
|
||||
|
||||
if(!rs.views.empty())
|
||||
viewport = Vec4f(rs.views[0].Width, rs.views[0].Height);
|
||||
|
||||
if(rs.dsv.GetResResourceId() != ResourceId())
|
||||
{
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE tmpdsv = GetDebugManager()->GetTempDescriptor(rs.dsv);
|
||||
list->OMSetRenderTargets(1, &rtv, TRUE, &tmpdsv);
|
||||
}
|
||||
else
|
||||
{
|
||||
list->OMSetRenderTargets(1, &rtv, TRUE, NULL);
|
||||
}
|
||||
|
||||
if(!rs.views.empty())
|
||||
list->RSSetViewports(1, &rs.views[0]);
|
||||
|
||||
D3D12_RECT scissor = {0, 0, 16384, 16384};
|
||||
list->RSSetScissorRects(1, &scissor);
|
||||
|
||||
list->OMSetStencilRef(rs.stencilRef);
|
||||
list->OMSetBlendFactor(rs.blendFactor);
|
||||
|
||||
list->SetGraphicsRootSignature(GetDebugManager()->GetMeshRootSig());
|
||||
|
||||
list->SetGraphicsRootConstantBufferView(
|
||||
0, GetDebugManager()->UploadConstants(&vertexData, sizeof(vertexData)));
|
||||
list->SetGraphicsRootConstantBufferView(
|
||||
1, GetDebugManager()->UploadConstants(&viewport, sizeof(viewport)));
|
||||
list->SetGraphicsRoot32BitConstants(2, 4, &viewport.x, 0);
|
||||
D3D12RenderState::SignatureElement vertexElem(eRootCBV, ResourceId(), 0);
|
||||
WrappedID3D12Resource1::GetResIDFromAddr(
|
||||
GetDebugManager()->UploadConstants(&vertexData, sizeof(vertexData)), vertexElem.id,
|
||||
vertexElem.offset);
|
||||
|
||||
for(size_t i = 0; i < events.size(); i++)
|
||||
{
|
||||
D3D12RenderState prevState = rs;
|
||||
|
||||
Vec4f viewport;
|
||||
|
||||
if(!rs.views.empty())
|
||||
viewport = Vec4f(rs.views[0].Width, rs.views[0].Height);
|
||||
|
||||
D3D12RenderState::SignatureElement viewportElem(eRootCBV, ResourceId(), 0);
|
||||
WrappedID3D12Resource1::GetResIDFromAddr(
|
||||
GetDebugManager()->UploadConstants(&viewport, sizeof(viewport)), viewportElem.id,
|
||||
viewportElem.offset);
|
||||
|
||||
D3D12RenderState::SignatureElement viewportConstElem(eRootConst, ResourceId(), 0);
|
||||
viewportConstElem.SetConstants(4, &viewport, 0);
|
||||
|
||||
rs.graphics.rootsig = GetResID(GetDebugManager()->GetMeshRootSig());
|
||||
rs.graphics.sigelems = {
|
||||
vertexElem, viewportElem, viewportConstElem,
|
||||
};
|
||||
|
||||
rs.rts = {*(D3D12Descriptor *)rtv.ptr};
|
||||
|
||||
if(list == NULL)
|
||||
list = m_pDevice->GetNewList();
|
||||
|
||||
rs.ApplyState(m_pDevice, list);
|
||||
|
||||
const DrawcallDescription *draw = m_pDevice->GetDrawcall(events[i]);
|
||||
|
||||
for(uint32_t inst = 0; draw && inst < RDCMAX(1U, draw->numInstances); inst++)
|
||||
@@ -1097,10 +1199,20 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list->Close();
|
||||
list = NULL;
|
||||
list->Close();
|
||||
list = NULL;
|
||||
|
||||
rs = prevState;
|
||||
|
||||
if(overlay == DebugOverlay::TriangleSizePass)
|
||||
{
|
||||
m_pDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw);
|
||||
|
||||
if(i + 1 < events.size())
|
||||
m_pDevice->ReplayLog(events[i], events[i + 1], eReplay_WithoutDraw);
|
||||
}
|
||||
}
|
||||
|
||||
m_pDevice->ExecuteLists();
|
||||
m_pDevice->FlushLists();
|
||||
@@ -1220,8 +1332,9 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
|
||||
|
||||
list->OMSetRenderTargets(1, &rtv, TRUE, NULL);
|
||||
|
||||
if(!rs.views.empty())
|
||||
list->RSSetViewports(1, &rs.views[0]);
|
||||
D3D12_VIEWPORT view = {0.0f, 0.0f, (float)resourceDesc.Width, (float)resourceDesc.Height,
|
||||
0.0f, 1.0f};
|
||||
list->RSSetViewports(1, &view);
|
||||
|
||||
D3D12_RECT scissor = {0, 0, 16384, 16384};
|
||||
list->RSSetScissorRects(1, &scissor);
|
||||
|
||||
@@ -548,7 +548,6 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
// clear all mips first
|
||||
drv.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
drv.glDisable(eGL_BLEND);
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
drv.glDepthMask(GL_FALSE);
|
||||
drv.glDisable(eGL_CULL_FACE);
|
||||
drv.glDisable(eGL_DEPTH_TEST);
|
||||
@@ -563,6 +562,8 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
|
||||
drv.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.overlayFBO);
|
||||
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
|
||||
// clear the overlay texture to black
|
||||
{
|
||||
GLfloat black[4] = {};
|
||||
@@ -597,7 +598,6 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
// the program's state.
|
||||
drv.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
drv.glDisable(eGL_BLEND);
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
drv.glDepthMask(GL_FALSE);
|
||||
drv.glDisable(eGL_CULL_FACE);
|
||||
drv.glDisable(eGL_DEPTH_TEST);
|
||||
@@ -609,6 +609,24 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
drv.glEnable(eGL_DEPTH_CLAMP);
|
||||
}
|
||||
|
||||
if(HasExt[ARB_viewport_array])
|
||||
{
|
||||
for(size_t s = 0; s < ARRAY_COUNT(rs.Scissors); s++)
|
||||
{
|
||||
if(rs.Scissors[s].enabled)
|
||||
drv.glEnablei(eGL_SCISSOR_TEST, (GLuint)s);
|
||||
else
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, (GLuint)s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rs.Scissors[0].enabled)
|
||||
drv.glEnable(eGL_SCISSOR_TEST);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
if(overlay == DebugOverlay::NaN || overlay == DebugOverlay::Clipping)
|
||||
{
|
||||
// just need the basic texture
|
||||
@@ -617,6 +635,11 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
}
|
||||
else if(overlay == DebugOverlay::Drawcall)
|
||||
{
|
||||
if(HasExt[ARB_viewport_array])
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
|
||||
float black[] = {0.0f, 0.0f, 0.0f, 0.5f};
|
||||
drv.glClearBufferfv(eGL_COLOR, 0, black);
|
||||
|
||||
@@ -727,6 +750,41 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
float col[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
drv.glClearBufferfv(eGL_COLOR, 0, col);
|
||||
|
||||
if(HasExt[ARB_viewport_array])
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
|
||||
col[0] = 1.0f;
|
||||
col[1] = 0.0f;
|
||||
col[3] = 1.0f;
|
||||
|
||||
drv.glProgramUniform4fv(DebugData.overlayProg, overlayFixedColLocation, 1, col);
|
||||
|
||||
ReplayLog(eventId, eReplay_OnlyDraw);
|
||||
|
||||
if(HasExt[ARB_viewport_array])
|
||||
{
|
||||
if(rs.Scissors[0].enabled)
|
||||
drv.glEnablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rs.Scissors[0].enabled)
|
||||
drv.glEnable(eGL_SCISSOR_TEST);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
col[0] = 0.0f;
|
||||
col[1] = 1.0f;
|
||||
|
||||
drv.glProgramUniform4fv(DebugData.overlayProg, overlayFixedColLocation, 1, col);
|
||||
|
||||
ReplayLog(eventId, eReplay_OnlyDraw);
|
||||
|
||||
// don't need to use the existing program at all!
|
||||
drv.glUseProgram(DebugData.checkerProg);
|
||||
drv.glBindProgramPipeline(0);
|
||||
@@ -775,7 +833,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
|
||||
// set primary/secondary to the same to 'disable' checkerboard
|
||||
cdata->PrimaryColor = cdata->SecondaryColor = Vec4f(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
cdata->InnerColor = Vec4f(0.2f, 0.2f, 0.9f, 0.7f);
|
||||
cdata->InnerColor = Vec4f(0.2f, 0.2f, 0.9f, 0.4f);
|
||||
|
||||
// set viewport rect
|
||||
cdata->RectPosition = Vec2f(rs.Viewports[0].x, rs.Viewports[0].y);
|
||||
@@ -820,9 +878,29 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
}
|
||||
else if(overlay == DebugOverlay::Depth || overlay == DebugOverlay::Stencil)
|
||||
{
|
||||
if(HasExt[ARB_viewport_array])
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
|
||||
float backCol[] = {0.0f, 1.0f, 0.0f, 0.0f};
|
||||
drv.glClearBufferfv(eGL_COLOR, 0, backCol);
|
||||
|
||||
if(HasExt[ARB_viewport_array])
|
||||
{
|
||||
if(rs.Scissors[0].enabled)
|
||||
drv.glEnablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rs.Scissors[0].enabled)
|
||||
drv.glEnable(eGL_SCISSOR_TEST);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
float red[] = {1.0f, 0.0f, 0.0f, 1.0f};
|
||||
drv.glProgramUniform4fv(DebugData.overlayProg, overlayFixedColLocation, 1, red);
|
||||
|
||||
@@ -1091,9 +1169,29 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
}
|
||||
else if(overlay == DebugOverlay::BackfaceCull)
|
||||
{
|
||||
if(HasExt[ARB_viewport_array])
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
|
||||
float col[] = {0.0f, 1.0f, 0.0f, 0.0f};
|
||||
drv.glClearBufferfv(eGL_COLOR, 0, col);
|
||||
|
||||
if(HasExt[ARB_viewport_array])
|
||||
{
|
||||
if(rs.Scissors[0].enabled)
|
||||
drv.glEnablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rs.Scissors[0].enabled)
|
||||
drv.glEnable(eGL_SCISSOR_TEST);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
col[0] = 1.0f;
|
||||
col[1] = 0.0f;
|
||||
col[3] = 1.0f;
|
||||
@@ -1116,9 +1214,32 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
}
|
||||
else if(overlay == DebugOverlay::ClearBeforeDraw || overlay == DebugOverlay::ClearBeforePass)
|
||||
{
|
||||
if(HasExt[ARB_viewport_array])
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
|
||||
float col[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
drv.glClearBufferfv(eGL_COLOR, 0, col);
|
||||
|
||||
if(HasExt[ARB_viewport_array])
|
||||
{
|
||||
for(size_t s = 0; s < ARRAY_COUNT(rs.Scissors); s++)
|
||||
{
|
||||
if(rs.Scissors[s].enabled)
|
||||
drv.glEnablei(eGL_SCISSOR_TEST, (GLuint)s);
|
||||
else
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, (GLuint)s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rs.Scissors[0].enabled)
|
||||
drv.glEnable(eGL_SCISSOR_TEST);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
rdcarray<uint32_t> events = passEvents;
|
||||
|
||||
if(overlay == DebugOverlay::ClearBeforeDraw)
|
||||
@@ -1138,9 +1259,32 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
rs.ApplyState(&drv);
|
||||
}
|
||||
|
||||
GLboolean scissor = HasExt[ARB_viewport_array] ? GL.glIsEnabledi(eGL_SCISSOR_TEST, 0)
|
||||
: GL.glIsEnabled(eGL_SCISSOR_TEST);
|
||||
|
||||
if(HasExt[ARB_viewport_array])
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
drv.glClearBufferfv(eGL_COLOR, i, &clearCol.x);
|
||||
|
||||
if(HasExt[ARB_viewport_array])
|
||||
{
|
||||
if(scissor == GL_TRUE)
|
||||
drv.glEnablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(scissor == GL_TRUE)
|
||||
drv.glEnable(eGL_SCISSOR_TEST);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
// Try to clear depth as well, to help debug shadow rendering
|
||||
if(IsDepthStencilFormat(texDetails.internalFormat))
|
||||
{
|
||||
@@ -1172,9 +1316,32 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
{
|
||||
SCOPED_TIMER("Triangle Size");
|
||||
|
||||
if(HasExt[ARB_viewport_array])
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
|
||||
float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
drv.glClearBufferfv(eGL_COLOR, 0, black);
|
||||
|
||||
if(HasExt[ARB_viewport_array])
|
||||
{
|
||||
for(size_t s = 0; s < ARRAY_COUNT(rs.Scissors); s++)
|
||||
{
|
||||
if(rs.Scissors[s].enabled)
|
||||
drv.glEnablei(eGL_SCISSOR_TEST, (GLuint)s);
|
||||
else
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, (GLuint)s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rs.Scissors[0].enabled)
|
||||
drv.glEnable(eGL_SCISSOR_TEST);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
MeshUBOData uboParams = {};
|
||||
uboParams.homogenousInput = 1;
|
||||
uboParams.invProj = Matrix4f::Identity();
|
||||
@@ -1568,6 +1735,11 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
|
||||
{
|
||||
SCOPED_TIMER("Quad Overdraw");
|
||||
|
||||
if(HasExt[ARB_viewport_array])
|
||||
drv.glDisablei(eGL_SCISSOR_TEST, 0);
|
||||
else
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
|
||||
float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
drv.glClearBufferfv(eGL_COLOR, 0, black);
|
||||
|
||||
|
||||
@@ -935,14 +935,17 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
att->colorWriteMask = 0xf;
|
||||
}
|
||||
|
||||
// set scissors to max
|
||||
for(size_t i = 0; i < pipeCreateInfo.pViewportState->scissorCount; i++)
|
||||
// set scissors to max for drawcall
|
||||
if(overlay == DebugOverlay::Drawcall)
|
||||
{
|
||||
VkRect2D &sc = (VkRect2D &)pipeCreateInfo.pViewportState->pScissors[i];
|
||||
sc.offset.x = 0;
|
||||
sc.offset.y = 0;
|
||||
sc.extent.width = 16384;
|
||||
sc.extent.height = 16384;
|
||||
for(size_t i = 0; i < pipeCreateInfo.pViewportState->scissorCount; i++)
|
||||
{
|
||||
VkRect2D &sc = (VkRect2D &)pipeCreateInfo.pViewportState->pScissors[i];
|
||||
sc.offset.x = 0;
|
||||
sc.offset.y = 0;
|
||||
sc.extent.width = 16384;
|
||||
sc.extent.height = 16384;
|
||||
}
|
||||
}
|
||||
|
||||
// set our renderpass and shader
|
||||
@@ -992,12 +995,15 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe);
|
||||
|
||||
// set dynamic scissors in case pipeline was using them
|
||||
for(size_t i = 0; i < m_pDriver->m_RenderState.scissors.size(); i++)
|
||||
if(overlay == DebugOverlay::Drawcall)
|
||||
{
|
||||
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
|
||||
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
|
||||
m_pDriver->m_RenderState.scissors[i].extent.width = 16384;
|
||||
m_pDriver->m_RenderState.scissors[i].extent.height = 16384;
|
||||
for(size_t i = 0; i < m_pDriver->m_RenderState.scissors.size(); i++)
|
||||
{
|
||||
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
|
||||
m_pDriver->m_RenderState.scissors[i].offset.y = 0;
|
||||
m_pDriver->m_RenderState.scissors[i].extent.width = 16384;
|
||||
m_pDriver->m_RenderState.scissors[i].extent.height = 16384;
|
||||
}
|
||||
}
|
||||
|
||||
if(overlay == DebugOverlay::Wireframe)
|
||||
@@ -1051,7 +1057,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
{
|
||||
// clear the whole image to opaque black. We'll overwite the render area with transparent black
|
||||
// before rendering the viewport/scissors
|
||||
float black[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
NULL,
|
||||
@@ -1077,6 +1083,138 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
|
||||
black[3] = 0.0f;
|
||||
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
float highlightCol[] = {1.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
// backup state
|
||||
VulkanRenderState prevstate = m_pDriver->m_RenderState;
|
||||
|
||||
// make patched shader
|
||||
VkShaderModule mod[2] = {0};
|
||||
VkPipeline pipe[2] = {0};
|
||||
|
||||
// first shader, no culling, writes red
|
||||
GetDebugManager()->PatchFixedColShader(mod[0], highlightCol);
|
||||
|
||||
highlightCol[0] = 0.0f;
|
||||
highlightCol[1] = 1.0f;
|
||||
|
||||
// second shader, normal culling, writes green
|
||||
GetDebugManager()->PatchFixedColShader(mod[1], highlightCol);
|
||||
|
||||
// make patched pipeline
|
||||
VkGraphicsPipelineCreateInfo pipeCreateInfo;
|
||||
|
||||
m_pDriver->GetShaderCache()->MakeGraphicsPipelineInfo(pipeCreateInfo,
|
||||
prevstate.graphics.pipeline);
|
||||
|
||||
// disable all tests possible
|
||||
VkPipelineDepthStencilStateCreateInfo *ds =
|
||||
(VkPipelineDepthStencilStateCreateInfo *)pipeCreateInfo.pDepthStencilState;
|
||||
ds->depthTestEnable = false;
|
||||
ds->depthWriteEnable = false;
|
||||
ds->stencilTestEnable = false;
|
||||
ds->depthBoundsTestEnable = false;
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo *rs =
|
||||
(VkPipelineRasterizationStateCreateInfo *)pipeCreateInfo.pRasterizationState;
|
||||
rs->cullMode = VK_CULL_MODE_NONE; // first render without any culling
|
||||
rs->rasterizerDiscardEnable = false;
|
||||
|
||||
if(m_pDriver->GetDeviceEnabledFeatures().depthClamp)
|
||||
rs->depthClampEnable = true;
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo *cb =
|
||||
(VkPipelineColorBlendStateCreateInfo *)pipeCreateInfo.pColorBlendState;
|
||||
cb->logicOpEnable = false;
|
||||
cb->attachmentCount = 1; // only one colour attachment
|
||||
for(uint32_t i = 0; i < cb->attachmentCount; i++)
|
||||
{
|
||||
VkPipelineColorBlendAttachmentState *att =
|
||||
(VkPipelineColorBlendAttachmentState *)&cb->pAttachments[i];
|
||||
att->blendEnable = false;
|
||||
att->colorWriteMask = 0xf;
|
||||
}
|
||||
|
||||
// set our renderpass and shader
|
||||
pipeCreateInfo.renderPass = m_Overlay.NoDepthRP;
|
||||
pipeCreateInfo.subpass = 0;
|
||||
|
||||
VkPipelineShaderStageCreateInfo *fragShader = NULL;
|
||||
|
||||
for(uint32_t i = 0; i < pipeCreateInfo.stageCount; i++)
|
||||
{
|
||||
VkPipelineShaderStageCreateInfo &sh =
|
||||
(VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[i];
|
||||
if(sh.stage == VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||
{
|
||||
sh.module = mod[0];
|
||||
sh.pName = "main";
|
||||
fragShader = &sh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(fragShader == NULL)
|
||||
{
|
||||
// we know this is safe because it's pointing to a static array that's
|
||||
// big enough for all shaders
|
||||
|
||||
VkPipelineShaderStageCreateInfo &sh =
|
||||
(VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[pipeCreateInfo.stageCount++];
|
||||
sh.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
sh.pNext = NULL;
|
||||
sh.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
sh.module = mod[0];
|
||||
sh.pName = "main";
|
||||
sh.pSpecializationInfo = NULL;
|
||||
|
||||
fragShader = &sh;
|
||||
}
|
||||
|
||||
vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL,
|
||||
&pipe[0]);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
fragShader->module = mod[1];
|
||||
|
||||
vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL,
|
||||
&pipe[1]);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
// modify state
|
||||
m_pDriver->m_RenderState.renderPass = GetResID(m_Overlay.NoDepthRP);
|
||||
m_pDriver->m_RenderState.subpass = 0;
|
||||
m_pDriver->m_RenderState.SetFramebuffer(m_pDriver, GetResID(m_Overlay.NoDepthFB));
|
||||
|
||||
m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[0]);
|
||||
m_pDriver->m_RenderState.scissors = prevstate.scissors;
|
||||
|
||||
for(VkRect2D &sc : m_pDriver->m_RenderState.scissors)
|
||||
{
|
||||
sc.offset.x = 0;
|
||||
sc.offset.y = 0;
|
||||
sc.extent.width = 16384;
|
||||
sc.extent.height = 16384;
|
||||
}
|
||||
|
||||
m_pDriver->ReplayLog(0, eventId, eReplay_OnlyDraw);
|
||||
|
||||
m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[1]);
|
||||
m_pDriver->m_RenderState.scissors = prevstate.scissors;
|
||||
|
||||
m_pDriver->ReplayLog(0, eventId, eReplay_OnlyDraw);
|
||||
|
||||
// restore state
|
||||
m_pDriver->m_RenderState = prevstate;
|
||||
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
|
||||
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
{
|
||||
VkClearValue clearval = {};
|
||||
VkRenderPassBeginInfo rpbegin = {
|
||||
@@ -1090,23 +1228,6 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
};
|
||||
vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
VkClearRect rect = {
|
||||
{
|
||||
{
|
||||
m_pDriver->m_RenderState.renderArea.offset.x,
|
||||
m_pDriver->m_RenderState.renderArea.offset.y,
|
||||
},
|
||||
{
|
||||
m_pDriver->m_RenderState.renderArea.extent.width,
|
||||
m_pDriver->m_RenderState.renderArea.extent.height,
|
||||
},
|
||||
},
|
||||
0,
|
||||
1,
|
||||
};
|
||||
VkClearAttachment blackclear = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {}};
|
||||
vt->CmdClearAttachments(Unwrap(cmd), 1, &blackclear, 1, &rect);
|
||||
|
||||
VkViewport viewport = m_pDriver->m_RenderState.views[0];
|
||||
vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport);
|
||||
|
||||
@@ -1119,7 +1240,7 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
|
||||
// set primary/secondary to the same to 'disable' checkerboard
|
||||
ubo->PrimaryColor = ubo->SecondaryColor = Vec4f(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
ubo->InnerColor = Vec4f(0.2f, 0.2f, 0.9f, 0.7f);
|
||||
ubo->InnerColor = Vec4f(0.2f, 0.2f, 0.9f, 0.4f);
|
||||
|
||||
// set viewport rect
|
||||
ubo->RectPosition = Vec2f(viewport.x, viewport.y);
|
||||
@@ -1185,6 +1306,24 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
|
||||
vt->CmdEndRenderPass(Unwrap(cmd));
|
||||
}
|
||||
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
// submit & flush so that we don't have to keep pipeline around for a while
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
|
||||
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
m_pDriver->vkDestroyPipeline(m_Device, pipe[i], NULL);
|
||||
m_pDriver->vkDestroyShaderModule(m_Device, mod[i], NULL);
|
||||
}
|
||||
}
|
||||
else if(overlay == DebugOverlay::BackfaceCull)
|
||||
{
|
||||
@@ -1267,16 +1406,6 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
att->colorWriteMask = 0xf;
|
||||
}
|
||||
|
||||
// set scissors to max
|
||||
for(size_t i = 0; i < pipeCreateInfo.pViewportState->scissorCount; i++)
|
||||
{
|
||||
VkRect2D &sc = (VkRect2D &)pipeCreateInfo.pViewportState->pScissors[i];
|
||||
sc.offset.x = 0;
|
||||
sc.offset.y = 0;
|
||||
sc.extent.width = 16384;
|
||||
sc.extent.height = 16384;
|
||||
}
|
||||
|
||||
// set our renderpass and shader
|
||||
pipeCreateInfo.renderPass = m_Overlay.NoDepthRP;
|
||||
pipeCreateInfo.subpass = 0;
|
||||
@@ -1334,15 +1463,6 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
|
||||
m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[0]);
|
||||
|
||||
// set dynamic scissors in case pipeline was using them
|
||||
for(size_t i = 0; i < m_pDriver->m_RenderState.scissors.size(); i++)
|
||||
{
|
||||
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
|
||||
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
|
||||
m_pDriver->m_RenderState.scissors[i].extent.width = 16384;
|
||||
m_pDriver->m_RenderState.scissors[i].extent.height = 16384;
|
||||
}
|
||||
|
||||
m_pDriver->ReplayLog(0, eventId, eReplay_OnlyDraw);
|
||||
|
||||
m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[1]);
|
||||
@@ -1544,16 +1664,6 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
att->colorWriteMask = 0xf;
|
||||
}
|
||||
|
||||
// set scissors to max
|
||||
for(size_t i = 0; i < pipeCreateInfo.pViewportState->scissorCount; i++)
|
||||
{
|
||||
VkRect2D &sc = (VkRect2D &)pipeCreateInfo.pViewportState->pScissors[i];
|
||||
sc.offset.x = 0;
|
||||
sc.offset.y = 0;
|
||||
sc.extent.width = 16384;
|
||||
sc.extent.height = 16384;
|
||||
}
|
||||
|
||||
// subpass 0 in either render pass
|
||||
pipeCreateInfo.subpass = 0;
|
||||
|
||||
@@ -1631,15 +1741,6 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
|
||||
m_pDriver->m_RenderState.graphics.pipeline = GetResID(failpipe);
|
||||
|
||||
// set dynamic scissors in case pipeline was using them
|
||||
for(size_t i = 0; i < m_pDriver->m_RenderState.scissors.size(); i++)
|
||||
{
|
||||
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
|
||||
m_pDriver->m_RenderState.scissors[i].offset.x = 0;
|
||||
m_pDriver->m_RenderState.scissors[i].extent.width = 16384;
|
||||
m_pDriver->m_RenderState.scissors[i].extent.height = 16384;
|
||||
}
|
||||
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
@@ -2372,33 +2473,25 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
|
||||
std::map<PipeKey, VkPipeline> pipes;
|
||||
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
|
||||
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
VkClearValue clearval = {};
|
||||
VkRenderPassBeginInfo rpbegin = {
|
||||
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
NULL,
|
||||
Unwrap(RP),
|
||||
Unwrap(FB),
|
||||
{{0, 0}, m_Overlay.ImageDim},
|
||||
1,
|
||||
&clearval,
|
||||
};
|
||||
vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
VkViewport viewport = {0.0f,
|
||||
0.0f,
|
||||
(float)RDCMAX(1U, m_Overlay.ImageDim.width >> sub.mip),
|
||||
(float)RDCMAX(1U, m_Overlay.ImageDim.height >> sub.mip),
|
||||
0.0f,
|
||||
1.0f};
|
||||
vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport);
|
||||
|
||||
for(size_t i = 0; i < events.size(); i++)
|
||||
{
|
||||
cmd = m_pDriver->GetNextCmd();
|
||||
|
||||
vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
VkClearValue clearval = {};
|
||||
VkRenderPassBeginInfo rpbegin = {
|
||||
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
NULL,
|
||||
Unwrap(RP),
|
||||
Unwrap(FB),
|
||||
{{0, 0}, m_Overlay.ImageDim},
|
||||
1,
|
||||
&clearval,
|
||||
};
|
||||
vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
const DrawcallDescription *draw = m_pDriver->GetDrawcall(events[i]);
|
||||
|
||||
for(uint32_t inst = 0; draw && inst < RDCMAX(1U, draw->numInstances); inst++)
|
||||
@@ -2567,13 +2660,21 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, D
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vt->CmdEndRenderPass(Unwrap(cmd));
|
||||
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
if(overlay == DebugOverlay::TriangleSizePass)
|
||||
{
|
||||
m_pDriver->ReplayLog(events[i], events[i], eReplay_OnlyDraw);
|
||||
|
||||
if(i + 1 < events.size())
|
||||
m_pDriver->ReplayLog(events[i], events[i + 1], eReplay_WithoutDraw);
|
||||
}
|
||||
}
|
||||
|
||||
vt->CmdEndRenderPass(Unwrap(cmd));
|
||||
|
||||
vkr = vt->EndCommandBuffer(Unwrap(cmd));
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
m_pDriver->SubmitCmds();
|
||||
m_pDriver->FlushQ();
|
||||
|
||||
|
||||
@@ -110,6 +110,12 @@ float4 main() : SV_Target0
|
||||
{Vec3f(0.0f, 0.7f, 0.5f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
|
||||
{Vec3f(0.0f, 0.725f, 0.5f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(0.0f, 1.0f)},
|
||||
{Vec3f(0.025f, 0.7f, 0.5f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(1.0f, 0.0f)},
|
||||
|
||||
// this triangle deliberately goes out of the viewport, it will test viewport & scissor
|
||||
// clipping
|
||||
{Vec3f(-1.3f, -1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(0.0f, 0.0f)},
|
||||
{Vec3f(0.0f, 1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(0.0f, 1.0f)},
|
||||
{Vec3f(1.3f, -1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(1.0f, 0.0f)},
|
||||
};
|
||||
|
||||
ID3D11BufferPtr vb = MakeBuffer().Vertex().Data(VBData);
|
||||
@@ -188,6 +194,11 @@ float4 main() : SV_Target0
|
||||
depth.DepthFunc = D3D11_COMPARISON_ALWAYS;
|
||||
SetDepthState(depth);
|
||||
|
||||
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);
|
||||
|
||||
RSSetViewport({5.0f, 5.0f, float(screenWidth) / 4.0f - 10.0f,
|
||||
|
||||
@@ -105,6 +105,12 @@ float4 main() : SV_Target0
|
||||
{Vec3f(0.0f, 0.7f, 0.5f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
|
||||
{Vec3f(0.0f, 0.725f, 0.5f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(0.0f, 1.0f)},
|
||||
{Vec3f(0.025f, 0.7f, 0.5f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(1.0f, 0.0f)},
|
||||
|
||||
// this triangle deliberately goes out of the viewport, it will test viewport & scissor
|
||||
// clipping
|
||||
{Vec3f(-1.3f, -1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(0.0f, 0.0f)},
|
||||
{Vec3f(0.0f, 1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(0.0f, 1.0f)},
|
||||
{Vec3f(1.3f, -1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(1.0f, 0.0f)},
|
||||
};
|
||||
|
||||
ID3D12ResourcePtr vb = MakeBuffer().Data(VBData);
|
||||
@@ -204,6 +210,13 @@ float4 main() : SV_Target0
|
||||
cmd->SetPipelineState(pipe);
|
||||
cmd->DrawInstanced(24, 1, 9, 0);
|
||||
|
||||
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);
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE subrtv = MakeRTV(subtex)
|
||||
.Format(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB)
|
||||
.FirstSlice(2)
|
||||
|
||||
@@ -153,6 +153,12 @@ void main()
|
||||
{Vec3f(0.0f, 0.7f, 0.0f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
|
||||
{Vec3f(0.0f, 0.725f, 0.0f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(0.0f, 1.0f)},
|
||||
{Vec3f(0.025f, 0.7f, 0.0f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(1.0f, 0.0f)},
|
||||
|
||||
// this triangle deliberately goes out of the viewport, it will test viewport & scissor
|
||||
// clipping
|
||||
{Vec3f(-1.3f, -1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(0.0f, 0.0f)},
|
||||
{Vec3f(0.0f, 1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(0.0f, 1.0f)},
|
||||
{Vec3f(1.3f, -1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(1.0f, 0.0f)},
|
||||
};
|
||||
|
||||
GLuint vb = MakeBuffer();
|
||||
@@ -256,6 +262,14 @@ void main()
|
||||
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);
|
||||
|
||||
glScissor(0, 0, screenWidth, screenHeight);
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight,
|
||||
|
||||
@@ -157,6 +157,12 @@ void main()
|
||||
{Vec3f(0.0f, -0.7f, 0.5f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
|
||||
{Vec3f(0.0f, -0.725f, 0.5f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(0.0f, 1.0f)},
|
||||
{Vec3f(0.025f, -0.7f, 0.5f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(1.0f, 0.0f)},
|
||||
|
||||
// this triangle deliberately goes out of the viewport, it will test viewport & scissor
|
||||
// clipping
|
||||
{Vec3f(-1.3f, 1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(0.0f, 0.0f)},
|
||||
{Vec3f(0.0f, -1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(0.0f, 1.0f)},
|
||||
{Vec3f(1.3f, 1.3f, 0.95f), Vec4f(0.1f, 0.1f, 0.5f, 1.0f), Vec2f(1.0f, 0.0f)},
|
||||
};
|
||||
|
||||
// negate y if we're using negative viewport height
|
||||
@@ -336,6 +342,19 @@ void main()
|
||||
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;
|
||||
@@ -352,7 +371,7 @@ void main()
|
||||
v.height = -v.height;
|
||||
}
|
||||
|
||||
VkRect2D s = mainWindow->scissor;
|
||||
s = mainWindow->scissor;
|
||||
s.extent.width /= 4;
|
||||
s.extent.height /= 4;
|
||||
|
||||
|
||||
@@ -224,10 +224,14 @@ class Overlay_Test(rdtest.TestCase):
|
||||
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.7, 0.2*0.7, 0.9*0.7, 0.7*0.7], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 350, 50, [0.2*0.7, 0.2*0.7, 0.9*0.7, 0.7*0.7], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 50, 250, [0.2*0.7, 0.2*0.7, 0.9*0.7, 0.7*0.7], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 350, 250, [0.2*0.7, 0.2*0.7, 0.9*0.7, 0.7*0.7], eps=eps)
|
||||
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)
|
||||
@@ -364,7 +368,116 @@ class Overlay_Test(rdtest.TestCase):
|
||||
|
||||
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)
|
||||
|
||||
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 viewport draw".format(str(overlay)))
|
||||
|
||||
tex.overlay = overlay
|
||||
out.SetTextureDisplay(tex)
|
||||
|
||||
out.Display()
|
||||
|
||||
eps = 1.0 / 256.0
|
||||
|
||||
overlay_id: rd.ResourceId = out.GetDebugOverlayTexID()
|
||||
|
||||
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)
|
||||
self.check_pixel_value(overlay_id, 50, 50, [0.8, 0.1, 0.8, 1.0], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 50, 10, [0.8, 0.1, 0.8, 1.0], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 85, 85, [0.8, 0.1, 0.8, 1.0], eps=eps)
|
||||
|
||||
self.check_pixel_value(overlay_id, 50, 5, [0.0, 0.0, 0.0, 0.5], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 95, 85, [0.0, 0.0, 0.0, 0.5], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 80, 30, [0.0, 0.0, 0.0, 0.5], 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
|
||||
|
||||
found = False
|
||||
|
||||
for delta in range(0, 5):
|
||||
try:
|
||||
self.check_pixel_value(overlay_id, 30 + delta, 32, [200.0 / 255.0, 1.0, 0.0, 1.0], eps=eps)
|
||||
found = True
|
||||
break
|
||||
except rdtest.TestFailureException:
|
||||
pass
|
||||
|
||||
if not found:
|
||||
raise rdtest.TestFailureException("Couldn't find wireframe within scissor")
|
||||
|
||||
found = False
|
||||
|
||||
for delta in range(0, 5):
|
||||
try:
|
||||
self.check_pixel_value(overlay_id, 34 + delta, 22, [200.0 / 255.0, 1.0, 0.0, 1.0], eps=eps)
|
||||
found = True
|
||||
break
|
||||
except rdtest.TestFailureException:
|
||||
pass
|
||||
|
||||
if found:
|
||||
raise rdtest.TestFailureException("Found wireframe outside of scissor")
|
||||
elif overlay == rd.DebugOverlay.Depth or overlay == rd.DebugOverlay.Stencil or overlay == rd.DebugOverlay.BackfaceCull:
|
||||
self.check_pixel_value(overlay_id, 50, 25, [0.0, 1.0, 0.0, 1.0], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 50, 75, [0.0, 1.0, 0.0, 1.0], eps=eps)
|
||||
|
||||
self.check_pixel_value(overlay_id, 50, 20, [0.0, 1.0, 0.0, 0.0], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 50, 80, [0.0, 1.0, 0.0, 0.0], eps=eps)
|
||||
elif overlay == rd.DebugOverlay.ViewportScissor:
|
||||
# Inside viewport and scissor, passing triangle
|
||||
self.check_pixel_value(overlay_id, 50, 50,
|
||||
[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)
|
||||
|
||||
# Inside viewport and outside scissor
|
||||
self.check_pixel_value(overlay_id, 50, 80,
|
||||
[1.0 * 0.6 + 0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 1.0 * 0.6 + 0.4 * 0.4], eps=eps)
|
||||
elif overlay == rd.DebugOverlay.QuadOverdrawDraw:
|
||||
self.check_pixel_value(overlay_id, 50, 50, [1.0, 1.0, 1.0, 1.0], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 50, 15, [0.0, 0.0, 0.0, 0.0], eps=eps)
|
||||
elif overlay == rd.DebugOverlay.QuadOverdrawPass:
|
||||
self.check_pixel_value(overlay_id, 50, 50, [1.0, 1.0, 1.0, 1.0], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 50, 15, [0.0, 0.0, 0.0, 0.0], eps=eps)
|
||||
|
||||
self.check_pixel_value(overlay_id, 200, 270, [1.0, 1.0, 1.0, 1.0], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 200, 280, [0.0, 0.0, 0.0, 0.0], eps=eps)
|
||||
elif overlay == rd.DebugOverlay.TriangleSizeDraw:
|
||||
eps = 1.0
|
||||
|
||||
self.check_pixel_value(overlay_id, 50, 50, [5408.0, 5408.0, 5408.0, 1.0], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 50, 15, [0.0, 0.0, 0.0, 0.0], eps=eps)
|
||||
elif overlay == rd.DebugOverlay.TriangleSizePass:
|
||||
eps = 1.0
|
||||
|
||||
self.check_pixel_value(overlay_id, 50, 50, [5408.0, 5408.0, 5408.0, 1.0], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 50, 15, [0.0, 0.0, 0.0, 0.0], eps=eps)
|
||||
|
||||
self.check_pixel_value(overlay_id, 200, 270, [43072.0, 43072.0, 43072.0, 1.0], eps=eps)
|
||||
self.check_pixel_value(overlay_id, 200, 280, [0.0, 0.0, 0.0, 0.0], eps=eps)
|
||||
|
||||
rdtest.log.success("Picked pixels are as expected for {}".format(str(overlay)))
|
||||
|
||||
rdtest.log.success("Overlays are as expected around viewport/scissor behaviour")
|
||||
|
||||
# Now check clear-before-X by hand, for colour and for depth
|
||||
self.controller.SetFrameEvent(test_marker.next.eventId, True)
|
||||
|
||||
depth_tex: rd.ResourceId = pipe.GetDepthTarget().resourceId
|
||||
|
||||
@@ -535,14 +648,18 @@ class Overlay_Test(rdtest.TestCase):
|
||||
self.check_pixel_value(overlay_id, 70 >> shift, 34 >> shift, [1.0, 0.0, 0.0, 1.0], sub=sub)
|
||||
self.check_pixel_value(overlay_id, 70 >> shift, 20 >> shift, [0.0, 1.0, 0.0, 0.0], sub=sub)
|
||||
elif overlay == rd.DebugOverlay.ViewportScissor:
|
||||
self.check_pixel_value(overlay_id, 20 >> shift, 15 >> shift,
|
||||
[0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 0.4 * 0.4], sub=sub, eps=eps)
|
||||
self.check_pixel_value(overlay_id, 80 >> shift, 15 >> shift,
|
||||
[0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 0.4 * 0.4], sub=sub, eps=eps)
|
||||
self.check_pixel_value(overlay_id, 20 >> shift, 60 >> shift,
|
||||
[0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 0.4 * 0.4], sub=sub, eps=eps)
|
||||
self.check_pixel_value(overlay_id, 80 >> shift, 60 >> shift,
|
||||
[0.2 * 0.4, 0.2 * 0.4, 0.9 * 0.4, 0.4 * 0.4], sub=sub, eps=eps)
|
||||
|
||||
self.check_pixel_value(overlay_id, 50 >> shift, 36 >> shift,
|
||||
[0.2 * 0.7, 0.2 * 0.7, 0.9 * 0.7, 0.7 * 0.7], sub=sub, eps=eps)
|
||||
self.check_pixel_value(overlay_id, 30 >> shift, 36 >> shift,
|
||||
[0.2 * 0.7, 0.2 * 0.7, 0.9 * 0.7, 0.7 * 0.7], sub=sub, eps=eps)
|
||||
self.check_pixel_value(overlay_id, 70 >> shift, 34 >> shift,
|
||||
[0.2 * 0.7, 0.2 * 0.7, 0.9 * 0.7, 0.7 * 0.7], sub=sub, eps=eps)
|
||||
self.check_pixel_value(overlay_id, 70 >> shift, 20 >> shift,
|
||||
[0.2 * 0.7, 0.2 * 0.7, 0.9 * 0.7, 0.7 * 0.7], sub=sub, eps=eps)
|
||||
[0.2 * 0.4, 1.0 * 0.6 + 0.2 * 0.4, 0.9 * 0.4, 1.0 * 0.6 + 0.4 * 0.4],
|
||||
sub=sub, eps=eps)
|
||||
|
||||
if mip == 2:
|
||||
self.check_pixel_value(overlay_id, 6, 6, [0.1, 0.1, 0.1, 1.0], sub=sub, eps=eps)
|
||||
|
||||
@@ -382,6 +382,9 @@ class TestCase:
|
||||
save_data = rd.TextureSave()
|
||||
save_data.resourceId = tex
|
||||
save_data.destType = rd.FileType.PNG
|
||||
save_data.slice.sliceIndex = sub.slice
|
||||
save_data.mip = sub.mip
|
||||
save_data.sample.sampleIndex = sub.sample
|
||||
|
||||
img_path = util.get_tmp_path('output.png')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user