mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-23 23:16:31 +00:00
Extend D3D12_Execute_Indirect: add tests with a count buffer
- MaxCount: 1024 CountBuf: 5 - MaxCount: 1 CountBuf: 7 - MaxCount: 0 CountBuf: 11
This commit is contained in:
@@ -415,24 +415,28 @@ void main(uint3 gid : SV_GroupID)
|
||||
ID3D12PipelineStatePtr patchpso2 =
|
||||
MakePSO().RootSig(patchsig).InputLayout(layout).VS(vsblob).PS(psblob);
|
||||
|
||||
struct PatchArgs3
|
||||
D3D12_DRAW_ARGUMENTS singleDraw;
|
||||
singleDraw.VertexCountPerInstance = 3;
|
||||
singleDraw.InstanceCount = 1024;
|
||||
singleDraw.StartInstanceLocation = 0;
|
||||
singleDraw.StartVertexLocation = 6;
|
||||
|
||||
ID3D12ResourcePtr patchArgBuf3 = MakeBuffer().Upload().Size(sizeof(singleDraw)).Data(&singleDraw);
|
||||
|
||||
const uint32_t maxCountDraws = 1024;
|
||||
D3D12_DRAW_ARGUMENTS countSingleDraws[maxCountDraws];
|
||||
for(uint32_t i = 0; i < maxCountDraws; ++i)
|
||||
{
|
||||
D3D12_DRAW_ARGUMENTS draw;
|
||||
} patchargs3;
|
||||
countSingleDraws[i].VertexCountPerInstance = 3;
|
||||
countSingleDraws[i].InstanceCount = i + 1;
|
||||
countSingleDraws[i].StartInstanceLocation = 0;
|
||||
countSingleDraws[i].StartVertexLocation = (9 + (i * 3)) % 18;
|
||||
}
|
||||
ID3D12ResourcePtr countSingleDrawsArgBuf =
|
||||
MakeBuffer().Size(sizeof(countSingleDraws)).Data(&countSingleDraws);
|
||||
|
||||
patchargs3.draw.VertexCountPerInstance = 3;
|
||||
patchargs3.draw.InstanceCount = 1024;
|
||||
patchargs3.draw.StartInstanceLocation = 0;
|
||||
patchargs3.draw.StartVertexLocation = 6;
|
||||
|
||||
std::vector<char> patchArgsData3;
|
||||
patchArgsData3.resize(sizeof(PatchArgs3));
|
||||
|
||||
char *ptr3 = patchArgsData3.data();
|
||||
patchArgsData3.resize(sizeof(PatchArgs3));
|
||||
memcpy(ptr3, &patchargs3.draw, sizeof(D3D12_DRAW_ARGUMENTS));
|
||||
ID3D12ResourcePtr patchArgBuf3 =
|
||||
MakeBuffer().Upload().Size((UINT)patchArgsData3.size()).Data(patchArgsData3.data());
|
||||
uint32_t counts[] = {0, 5, 7, 11};
|
||||
ID3D12ResourcePtr countBuf = MakeBuffer().Data(counts);
|
||||
|
||||
ID3D12PipelineStatePtr patchpso3 =
|
||||
MakePSO().RootSig(patchsig).InputLayout(layout).VS(vsblob).PS(psblob);
|
||||
@@ -710,6 +714,42 @@ void main(uint3 gid : SV_GroupID)
|
||||
}
|
||||
popMarker(cmd);
|
||||
|
||||
pushMarker(cmd, "Count Buffer Draws");
|
||||
{
|
||||
cmd->SetPipelineState(patchpso3);
|
||||
cmd->SetGraphicsRootSignature(patchsig);
|
||||
cmd->SetDescriptorHeaps(1, &m_CBVUAVSRV.GetInterfacePtr());
|
||||
cmd->SetGraphicsRootDescriptorTable(5, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
|
||||
cmd->SetGraphicsRootConstantBufferView(0, cbv->GetGPUVirtualAddress() + 256);
|
||||
cmd->SetGraphicsRootShaderResourceView(1, srv->GetGPUVirtualAddress() + 256);
|
||||
cmd->SetGraphicsRootUnorderedAccessView(2, uav->GetGPUVirtualAddress() + 256);
|
||||
D3D12_VERTEX_BUFFER_VIEW view;
|
||||
view.BufferLocation = vb->GetGPUVirtualAddress();
|
||||
view.SizeInBytes = sizeof(tris);
|
||||
view.StrideInBytes = sizeof(A2V);
|
||||
cmd->IASetVertexBuffers(0, 1, &view);
|
||||
|
||||
RSSetViewport(cmd, {viewXY.x, viewXY.y, sqSize, sqSize, 0.0f, 1.0f});
|
||||
RSSetScissorRect(cmd, {0, 0, screenWidth, screenHeight});
|
||||
|
||||
OMSetRenderTargets(cmd, {rtv}, {});
|
||||
|
||||
cmd->SetGraphicsRoot32BitConstants(3, 4, baseConstData, 0);
|
||||
|
||||
setMarker(cmd, "MaxCount: 1024 CountBuf: 5");
|
||||
cmd->ExecuteIndirect(plainArgSig, maxCountDraws, countSingleDrawsArgBuf, 0, countBuf, 4);
|
||||
NextTest();
|
||||
setMarker(cmd, "MaxCount: 1 CountBuf: 7");
|
||||
RSSetViewport(cmd, {viewXY.x, viewXY.y, sqSize, sqSize, 0.0f, 1.0f});
|
||||
cmd->ExecuteIndirect(plainArgSig, 1, countSingleDrawsArgBuf, 0, countBuf, 8);
|
||||
NextTest();
|
||||
setMarker(cmd, "MaxCount: 0 CountBuf: 11");
|
||||
RSSetViewport(cmd, {viewXY.x, viewXY.y, sqSize, sqSize, 0.0f, 1.0f});
|
||||
cmd->ExecuteIndirect(plainArgSig, 0, countSingleDrawsArgBuf, 0, countBuf, 12);
|
||||
NextTest();
|
||||
}
|
||||
popMarker(cmd);
|
||||
|
||||
pushMarker(cmd, "Two Single Draws");
|
||||
{
|
||||
cmd->SetPipelineState(patchpso3);
|
||||
|
||||
@@ -65,145 +65,144 @@ class D3D12_Execute_Indirect(rdtest.TestCase):
|
||||
rdtest.log.success("rootConsts is as expected")
|
||||
|
||||
def check_capture(self):
|
||||
action = self.find_action("EI without Root Signature");
|
||||
self.controller.SetFrameEvent(action.eventId, False)
|
||||
action = self.find_action("IndirectDraw", action.eventId)
|
||||
for drawNum in range(3):
|
||||
self.controller.SetFrameEvent(action.eventId + drawNum, False)
|
||||
pipe = self.controller.GetPipelineState()
|
||||
if len(pipe.GetOutputTargets()) != 1:
|
||||
raise rdtest.TestFailureException(
|
||||
f"With event {action.eventId + drawNum} selected we should have one output target but there is {len(pipe.GetOutputTargets())}")
|
||||
self.check_pixel_history_succeeds(285, 110)
|
||||
if drawNum == 0:
|
||||
self.check_overlays(action.eventId, 285, 110)
|
||||
rdtest.log.success("Draw without Root Signature replayed correctly");
|
||||
with rdtest.log.auto_section('EI without Root Signature'):
|
||||
action = self.find_action("EI without Root Signature");
|
||||
self.controller.SetFrameEvent(action.eventId, False)
|
||||
action = self.find_action("IndirectDraw", action.eventId)
|
||||
for drawNum in range(3):
|
||||
self.controller.SetFrameEvent(action.eventId + drawNum, False)
|
||||
pipe = self.controller.GetPipelineState()
|
||||
if len(pipe.GetOutputTargets()) != 1:
|
||||
raise rdtest.TestFailureException(
|
||||
f"With event {action.eventId + drawNum} selected we should have one output target but there is {len(pipe.GetOutputTargets())}")
|
||||
self.check_pixel_history_succeeds(285, 110)
|
||||
if drawNum == 0:
|
||||
self.check_overlays(action.eventId, 285, 110)
|
||||
|
||||
from_eid = self.find_action("Multiple draws").eventId
|
||||
ei_eid = self.find_action("ExecuteIndirect", from_eid).eventId
|
||||
self.controller.SetFrameEvent(ei_eid - 1, False)
|
||||
self.check_root_consts([10.0, 9.0, 8.0, 7.0])
|
||||
viewX = 0
|
||||
viewY = 0
|
||||
sqSize = 300 / 4
|
||||
viewW = sqSize
|
||||
viewH = sqSize
|
||||
for i in range(8):
|
||||
action = self.find_action("IndirectDraw", from_eid)
|
||||
eid = action.eventId
|
||||
self.controller.SetFrameEvent(eid, False)
|
||||
self.check_root_consts([123.0, 9.0, 8.0, 7.0])
|
||||
with rdtest.log.auto_section('Multiple draws'):
|
||||
from_eid = self.find_action("Multiple draws").eventId
|
||||
ei_eid = self.find_action("ExecuteIndirect", from_eid).eventId
|
||||
self.controller.SetFrameEvent(ei_eid - 1, False)
|
||||
self.check_root_consts([10.0, 9.0, 8.0, 7.0])
|
||||
viewX = 0
|
||||
viewY = 0
|
||||
sqSize = 300 / 4
|
||||
viewW = sqSize
|
||||
viewH = sqSize
|
||||
for i in range(8):
|
||||
action = self.find_action("IndirectDraw", from_eid)
|
||||
eid = action.eventId
|
||||
self.controller.SetFrameEvent(eid, False)
|
||||
self.check_root_consts([123.0, 9.0, 8.0, 7.0])
|
||||
|
||||
# Should be a green triangle in the centre of the screen on a black background
|
||||
# Should be a green triangle in the centre of the screen on a black background
|
||||
self.check_triangle(back=[0.0, 0.0, 0.0, 1.0], vp=[viewX, viewY, viewW, viewH])
|
||||
|
||||
vsin_ref = {
|
||||
0: {
|
||||
'vtx': 0,
|
||||
'idx': 0,
|
||||
'POSITION': [-0.5, -0.5, 0.0, 0.0],
|
||||
'COLOR': [0.0, 1.0, 0.0, 1.0],
|
||||
},
|
||||
1: {
|
||||
'vtx': 1,
|
||||
'idx': 1,
|
||||
'POSITION': [0.0, 0.5, 0.0, 0.0],
|
||||
'COLOR': [0.0, 1.0, 0.0, 1.0],
|
||||
},
|
||||
2: {
|
||||
'vtx': 2,
|
||||
'idx': 2,
|
||||
'POSITION': [0.5, -0.5, 0.0, 0.0],
|
||||
'COLOR': [0.0, 1.0, 0.0, 1.0],
|
||||
},
|
||||
}
|
||||
self.check_mesh_data(vsin_ref, self.get_vsin(action))
|
||||
postvs_data = self.get_postvs(action, rd.MeshDataStage.VSOut, 0, action.numIndices)
|
||||
postvs_ref = {
|
||||
0: {
|
||||
'vtx': 0,
|
||||
'idx': 0,
|
||||
'SV_POSITION': [-0.5, -0.5, 0.0, 1.0],
|
||||
'COLOR': [0.0, 1.0, 0.0, 1.0],
|
||||
},
|
||||
1: {
|
||||
'vtx': 1,
|
||||
'idx': 1,
|
||||
'SV_POSITION': [0.0, 0.5, 0.0, 1.0],
|
||||
'COLOR': [0.0, 1.0, 0.0, 1.0],
|
||||
},
|
||||
2: {
|
||||
'vtx': 2,
|
||||
'idx': 2,
|
||||
'SV_POSITION': [0.5, -0.5, 0.0, 1.0],
|
||||
'COLOR': [0.0, 1.0, 0.0, 1.0],
|
||||
},
|
||||
}
|
||||
self.check_mesh_data(postvs_ref, postvs_data)
|
||||
|
||||
x = int(viewX + viewW/2)
|
||||
y = int(viewY + viewH/2)
|
||||
self.check_pixel_history_succeeds(x,y)
|
||||
self.check_overlays(eid, x,y)
|
||||
|
||||
from_eid = eid + 1
|
||||
|
||||
pipe = self.controller.GetPipelineState()
|
||||
|
||||
vbs = pipe.GetVBuffers()
|
||||
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Vertex)
|
||||
rw = pipe.GetReadWriteResources(rd.ShaderStage.Vertex)
|
||||
self.check(vbs[0].resourceId != rd.ResourceId())
|
||||
self.check(ro[0].descriptor.resource != rd.ResourceId())
|
||||
self.check(rw[0].descriptor.resource != rd.ResourceId())
|
||||
self.check(pipe.GetConstantBlock(rd.ShaderStage.Vertex, 0, 0).descriptor.resource != rd.ResourceId())
|
||||
|
||||
viewX += sqSize
|
||||
if viewX + sqSize >= 400:
|
||||
viewX = 0
|
||||
viewY += sqSize
|
||||
|
||||
with rdtest.log.auto_section('State is reset after execute'):
|
||||
viewX = 0
|
||||
viewY = 0
|
||||
action = self.find_action("Post draw")
|
||||
self.controller.SetFrameEvent(action.eventId, False)
|
||||
|
||||
# triangle should still be visible
|
||||
self.check_triangle(back=[0.0, 0.0, 0.0, 1.0], vp=[viewX, viewY, viewW, viewH])
|
||||
|
||||
vsin_ref = {
|
||||
0: {
|
||||
'vtx': 0,
|
||||
'idx': 0,
|
||||
'POSITION': [-0.5, -0.5, 0.0, 0.0],
|
||||
'COLOR': [0.0, 1.0, 0.0, 1.0],
|
||||
},
|
||||
1: {
|
||||
'vtx': 1,
|
||||
'idx': 1,
|
||||
'POSITION': [0.0, 0.5, 0.0, 0.0],
|
||||
'COLOR': [0.0, 1.0, 0.0, 1.0],
|
||||
},
|
||||
2: {
|
||||
'vtx': 2,
|
||||
'idx': 2,
|
||||
'POSITION': [0.5, -0.5, 0.0, 0.0],
|
||||
'COLOR': [0.0, 1.0, 0.0, 1.0],
|
||||
},
|
||||
}
|
||||
self.check_mesh_data(vsin_ref, self.get_vsin(action))
|
||||
postvs_data = self.get_postvs(action, rd.MeshDataStage.VSOut, 0, action.numIndices)
|
||||
postvs_ref = {
|
||||
0: {
|
||||
'vtx': 0,
|
||||
'idx': 0,
|
||||
'SV_POSITION': [-0.5, -0.5, 0.0, 1.0],
|
||||
'COLOR': [0.0, 1.0, 0.0, 1.0],
|
||||
},
|
||||
1: {
|
||||
'vtx': 1,
|
||||
'idx': 1,
|
||||
'SV_POSITION': [0.0, 0.5, 0.0, 1.0],
|
||||
'COLOR': [0.0, 1.0, 0.0, 1.0],
|
||||
},
|
||||
2: {
|
||||
'vtx': 2,
|
||||
'idx': 2,
|
||||
'SV_POSITION': [0.5, -0.5, 0.0, 1.0],
|
||||
'COLOR': [0.0, 1.0, 0.0, 1.0],
|
||||
},
|
||||
}
|
||||
self.check_mesh_data(postvs_ref, postvs_data)
|
||||
|
||||
x = int(viewX + viewW/2)
|
||||
y = int(viewY + viewH/2)
|
||||
self.check_pixel_history_succeeds(x,y)
|
||||
self.check_overlays(eid, x,y)
|
||||
|
||||
from_eid = eid + 1
|
||||
|
||||
# but state should be reset
|
||||
pipe = self.controller.GetPipelineState()
|
||||
|
||||
vbs = pipe.GetVBuffers()
|
||||
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Vertex)
|
||||
rw = pipe.GetReadWriteResources(rd.ShaderStage.Vertex)
|
||||
self.check(vbs[0].resourceId != rd.ResourceId())
|
||||
self.check(ro[0].descriptor.resource != rd.ResourceId())
|
||||
self.check(rw[0].descriptor.resource != rd.ResourceId())
|
||||
self.check(pipe.GetConstantBlock(rd.ShaderStage.Vertex, 0, 0).descriptor.resource != rd.ResourceId())
|
||||
|
||||
viewX += sqSize
|
||||
if viewX + sqSize >= 400:
|
||||
viewX = 0
|
||||
viewY += sqSize
|
||||
|
||||
viewX = 0
|
||||
viewY = 0
|
||||
action = self.find_action("Post draw")
|
||||
self.controller.SetFrameEvent(action.eventId, False)
|
||||
|
||||
# triangle should still be visible
|
||||
self.check_triangle(back=[0.0, 0.0, 0.0, 1.0], vp=[viewX, viewY, viewW, viewH])
|
||||
|
||||
# but state should be reset
|
||||
pipe = self.controller.GetPipelineState()
|
||||
|
||||
vbs = pipe.GetVBuffers()
|
||||
ro = pipe.GetReadOnlyResources(rd.ShaderStage.Vertex)
|
||||
rw = pipe.GetReadWriteResources(rd.ShaderStage.Vertex)
|
||||
self.check(len(vbs) == 0 or vbs[0].resourceId == rd.ResourceId())
|
||||
self.check(len(ro) == 0 or ro[0].descriptor.resource == rd.ResourceId())
|
||||
self.check(len(rw) == 0 or rw[0].descriptor.resource == rd.ResourceId())
|
||||
self.check(pipe.GetConstantBlock(rd.ShaderStage.Vertex, 0, 0).descriptor.resource == rd.ResourceId())
|
||||
|
||||
rdtest.log.success("State is reset after execute")
|
||||
self.check(len(vbs) == 0 or vbs[0].resourceId == rd.ResourceId())
|
||||
self.check(len(ro) == 0 or ro[0].descriptor.resource == rd.ResourceId())
|
||||
self.check(len(rw) == 0 or rw[0].descriptor.resource == rd.ResourceId())
|
||||
self.check(pipe.GetConstantBlock(rd.ShaderStage.Vertex, 0, 0).descriptor.resource == rd.ResourceId())
|
||||
|
||||
self.check_pixel_history_succeeds(185, 50)
|
||||
|
||||
action = self.find_action("Post Single dispatch")
|
||||
self.controller.SetFrameEvent(action.eventId, False)
|
||||
with rdtest.log.auto_section('Dispatch buffer output is correct'):
|
||||
action = self.find_action("Post Single dispatch")
|
||||
self.controller.SetFrameEvent(action.eventId, False)
|
||||
|
||||
pipe = self.controller.GetPipelineState()
|
||||
rw = pipe.GetReadWriteResources(rd.ShaderStage.Compute)
|
||||
pipe = self.controller.GetPipelineState()
|
||||
rw = pipe.GetReadWriteResources(rd.ShaderStage.Compute)
|
||||
|
||||
for z in range(10):
|
||||
for y in range(30):
|
||||
for x in range(12):
|
||||
idx = z*30*12+y*12+x
|
||||
value = struct.unpack_from('4f', self.controller.GetBufferData(rw[0].descriptor.resource, 16*idx, 16))
|
||||
expect = [float(x), float(y), float(z), float(idx)]
|
||||
for z in range(10):
|
||||
for y in range(30):
|
||||
for x in range(12):
|
||||
idx = z*30*12+y*12+x
|
||||
value = struct.unpack_from('4f', self.controller.GetBufferData(rw[0].descriptor.resource, 16*idx, 16))
|
||||
expect = [float(x), float(y), float(z), float(idx)]
|
||||
|
||||
if not rdtest.value_compare(expect, value):
|
||||
raise rdtest.TestFailureException(
|
||||
"buffer at {},{},{}: {} doesn't match expected {}".format(x, y, z, value, expect))
|
||||
|
||||
rdtest.log.success("Dispatch buffer output is correct")
|
||||
if not rdtest.value_compare(expect, value):
|
||||
raise rdtest.TestFailureException(
|
||||
"buffer at {},{},{}: {} doesn't match expected {}".format(x, y, z, value, expect))
|
||||
|
||||
self.check_pixel_history_succeeds(185, 50)
|
||||
|
||||
@@ -214,129 +213,173 @@ class D3D12_Execute_Indirect(rdtest.TestCase):
|
||||
# time we replay it should be self-consistent - after selecting the 4th draw then eactly 4 draws should appear.
|
||||
# And of course no exploding polys!
|
||||
|
||||
action = self.find_action("Custom order draw")
|
||||
action = self.find_action("IndirectDraw", action.eventId)
|
||||
with rdtest.log.auto_section('Custom order draw'):
|
||||
action = self.find_action("Custom order draw")
|
||||
action = self.find_action("IndirectDraw", action.eventId)
|
||||
|
||||
drawPoints = [
|
||||
(310, 78),
|
||||
(338, 78),
|
||||
(367, 78),
|
||||
drawPoints = [
|
||||
(310, 78),
|
||||
(338, 78),
|
||||
(367, 78),
|
||||
|
||||
(310, 107),
|
||||
(367, 107),
|
||||
(310, 107),
|
||||
(367, 107),
|
||||
|
||||
(310, 135),
|
||||
(338, 135),
|
||||
(367, 135),
|
||||
]
|
||||
(310, 135),
|
||||
(338, 135),
|
||||
(367, 135),
|
||||
]
|
||||
|
||||
sdfile = self.controller.GetStructuredFile()
|
||||
sdfile = self.controller.GetStructuredFile()
|
||||
|
||||
# do N passes since it will be unpredictable
|
||||
for passNum in range(50):
|
||||
for drawNum in range(8):
|
||||
# do N passes since it will be unpredictable
|
||||
for passNum in range(50):
|
||||
for drawNum in range(8):
|
||||
self.controller.SetFrameEvent(action.eventId + drawNum, False)
|
||||
|
||||
pipe = self.controller.GetPipelineState()
|
||||
out = pipe.GetOutputTargets()[0].resource
|
||||
|
||||
count = 0
|
||||
draws = []
|
||||
for i, p in enumerate(drawPoints):
|
||||
picked = self.controller.PickPixel(out, p[0], p[1], rd.Subresource(), rd.CompType.UNorm)
|
||||
if rdtest.value_compare(picked.floatValue, [0.0, 1.0, 0.0, 1.0]):
|
||||
count += 1
|
||||
draws += [i]
|
||||
|
||||
if not rdtest.value_compare(drawNum + 1, count):
|
||||
raise rdtest.TestFailureException(
|
||||
"With {} selected we should have {} draws, but counted {} draws".format(action.GetName(sdfile),
|
||||
drawNum + 1, count))
|
||||
|
||||
rdtest.log.print("With draw #{} selected we saw draws {} active".format(drawNum, str(draws)))
|
||||
|
||||
# the exploded verts are calibrated to render as purple. We don't handle the case where exploding polys
|
||||
# reference vertices from other draws, but this _should_ not happen as we leave a large margin between
|
||||
# each draw's segments
|
||||
|
||||
data = self.controller.GetTextureData(out, rd.Subresource(0, 0, 0))
|
||||
tex = self.get_texture(out)
|
||||
rdtest.log.print("{} - {} {} ".format(len(data), tex.width, tex.height))
|
||||
pixels = [struct.unpack_from("4B", data, 4 * p) for p in range(int(tex.width * tex.height))]
|
||||
unique_pixels = list(set(pixels))
|
||||
|
||||
if (255, 0, 255, 255) in unique_pixels:
|
||||
raise rdtest.TestFailureException(
|
||||
"Detected an exploded polygon with {} selected".format(action.GetName(sdfile)))
|
||||
|
||||
self.check_pixel_history_succeeds(185, 50)
|
||||
|
||||
rdtest.log.success(f"Pass {passNum} of unordered draw was correct")
|
||||
|
||||
# This does not draw anything but its argument buffer is fully used with no spare bytes
|
||||
# Iterate over every draw and check the replay has valid output target
|
||||
with rdtest.log.auto_section('Fully used argument buffer with multiple draws replayed'):
|
||||
action = self.find_action("Full Arg Buffer")
|
||||
action = self.find_action("IndirectDraw", action.eventId)
|
||||
for drawNum in range(3):
|
||||
self.controller.SetFrameEvent(action.eventId + drawNum, False)
|
||||
|
||||
pipe = self.controller.GetPipelineState()
|
||||
out = pipe.GetOutputTargets()[0].resource
|
||||
|
||||
count = 0
|
||||
draws = []
|
||||
for i, p in enumerate(drawPoints):
|
||||
picked = self.controller.PickPixel(out, p[0], p[1], rd.Subresource(), rd.CompType.UNorm)
|
||||
if rdtest.value_compare(picked.floatValue, [0.0, 1.0, 0.0, 1.0]):
|
||||
count += 1
|
||||
draws += [i]
|
||||
|
||||
if not rdtest.value_compare(drawNum + 1, count):
|
||||
if len(pipe.GetOutputTargets()) != 1:
|
||||
raise rdtest.TestFailureException(
|
||||
"With {} selected we should have {} draws, but counted {} draws".format(action.GetName(sdfile),
|
||||
drawNum + 1, count))
|
||||
|
||||
rdtest.log.print("With draw #{} selected we saw draws {} active".format(drawNum, str(draws)))
|
||||
|
||||
# the exploded verts are calibrated to render as purple. We don't handle the case where exploding polys
|
||||
# reference vertices from other draws, but this _should_ not happen as we leave a large margin between
|
||||
# each draw's segments
|
||||
|
||||
data = self.controller.GetTextureData(out, rd.Subresource(0, 0, 0))
|
||||
tex = self.get_texture(out)
|
||||
rdtest.log.print("{} - {} {} ".format(len(data), tex.width, tex.height))
|
||||
pixels = [struct.unpack_from("4B", data, 4 * p) for p in range(int(tex.width * tex.height))]
|
||||
unique_pixels = list(set(pixels))
|
||||
|
||||
if (255, 0, 255, 255) in unique_pixels:
|
||||
raise rdtest.TestFailureException(
|
||||
"Detected an exploded polygon with {} selected".format(action.GetName(sdfile)))
|
||||
|
||||
f"With event {action.eventId + drawNum} selected we should have one output target but there is {len(pipe.GetOutputTargets())}")
|
||||
self.check_pixel_history_succeeds(185, 50)
|
||||
|
||||
rdtest.log.success(f"Pass {passNum} of unordered draw was correct")
|
||||
|
||||
# This does not draw anything but its argument buffer is fully used with no spare bytes
|
||||
# Iterate over every draw and check the replay has valid output target
|
||||
action = self.find_action("Full Arg Buffer")
|
||||
action = self.find_action("IndirectDraw", action.eventId)
|
||||
for drawNum in range(3):
|
||||
self.controller.SetFrameEvent(action.eventId + drawNum, False)
|
||||
pipe = self.controller.GetPipelineState()
|
||||
if len(pipe.GetOutputTargets()) != 1:
|
||||
raise rdtest.TestFailureException(
|
||||
f"With event {action.eventId + drawNum} selected we should have one output target but there is {len(pipe.GetOutputTargets())}")
|
||||
self.check_pixel_history_succeeds(185, 50)
|
||||
rdtest.log.success("Fully used argument buffer with multiple draws replayed")
|
||||
|
||||
# This does not draw anything but its argument buffer is fully used with no spare bytes
|
||||
# Iterate over every draw and check the replay has valid output target
|
||||
action = self.find_action("Full Arg Buffer: State + Draw")
|
||||
action = self.find_action("IndirectDraw", action.eventId)
|
||||
for drawNum in range(3):
|
||||
eid = action.eventId
|
||||
self.controller.SetFrameEvent(eid, False)
|
||||
pipe = self.controller.GetPipelineState()
|
||||
if len(pipe.GetOutputTargets()) != 1:
|
||||
raise rdtest.TestFailureException(
|
||||
f"With event {eid} selected we should have one output target but there is {len(pipe.GetOutputTargets())}")
|
||||
x = 100
|
||||
y = 210 - drawNum * 20
|
||||
self.check_overlays(eid, x, y)
|
||||
self.check_pixel_history_succeeds(x, 210)
|
||||
if drawNum > 0:
|
||||
self.check_pixel_history_succeeds(x, 190)
|
||||
if drawNum > 1:
|
||||
self.check_pixel_history_succeeds(x, 170)
|
||||
action = action.next
|
||||
rdtest.log.success("Fully used argument buffer with multiple states + draws replayed")
|
||||
|
||||
for drawNum in range(2):
|
||||
action = self.find_action("Two Single Draws")
|
||||
with rdtest.log.auto_section('Fully used argument buffer with multiple states + draws replayed'):
|
||||
action = self.find_action("Full Arg Buffer: State + Draw")
|
||||
action = self.find_action("IndirectDraw", action.eventId)
|
||||
if drawNum == 1:
|
||||
action = self.find_action("IndirectDraw", action.eventId+1)
|
||||
for drawNum in range(3):
|
||||
eid = action.eventId
|
||||
self.controller.SetFrameEvent(eid, False)
|
||||
pipe = self.controller.GetPipelineState()
|
||||
if len(pipe.GetOutputTargets()) != 1:
|
||||
raise rdtest.TestFailureException(
|
||||
f"With event {eid} selected we should have one output target but there is {len(pipe.GetOutputTargets())}")
|
||||
x = 100
|
||||
y = 210 - drawNum * 20
|
||||
self.check_overlays(eid, x, y)
|
||||
self.check_pixel_history_succeeds(x, 210)
|
||||
if drawNum > 0:
|
||||
self.check_pixel_history_succeeds(x, 190)
|
||||
if drawNum > 1:
|
||||
self.check_pixel_history_succeeds(x, 170)
|
||||
action = action.next
|
||||
|
||||
eid = action.eventId
|
||||
self.controller.SetFrameEvent(action.eventId, False)
|
||||
pipe = self.controller.GetPipelineState()
|
||||
if len(pipe.GetOutputTargets()) != 1:
|
||||
raise rdtest.TestFailureException(
|
||||
f"With event {action.eventId} selected we should have one output target but there is {len(pipe.GetOutputTargets())}")
|
||||
x = 200 + 80 * drawNum
|
||||
y = 205
|
||||
self.check_pixel_history_succeeds(x, y)
|
||||
self.check_overlays(eid, x, y)
|
||||
with rdtest.log.auto_section('Checking Count Buffer Draws'):
|
||||
base = self.find_action("Count Buffer Draws")
|
||||
tests = [
|
||||
("MaxCount: 1024 CountBuf: 5", 5, 170),
|
||||
("MaxCount: 1 CountBuf: 7", 1, 250),
|
||||
("MaxCount: 0 CountBuf: 11", 0, 0)
|
||||
]
|
||||
for test in tests:
|
||||
marker = test[0]
|
||||
expectedDraws = test[1]
|
||||
xpos = test[2]
|
||||
with rdtest.log.auto_section(f'Checking "{marker}"'):
|
||||
markerAction = self.find_action(marker, base.eventId);
|
||||
executeAction = self.find_action("ExecuteIndirect", markerAction.eventId);
|
||||
# Exclude the ExecuteIndirect end marker
|
||||
countDraws = len(executeAction.children) - 1
|
||||
self.check_eq(countDraws, expectedDraws)
|
||||
action = self.find_action("IndirectDraw", executeAction.eventId)
|
||||
for drawNum in range(countDraws):
|
||||
eid = action.eventId
|
||||
self.controller.SetFrameEvent(eid, False)
|
||||
pipe = self.controller.GetPipelineState()
|
||||
if len(pipe.GetOutputTargets()) != 1:
|
||||
raise rdtest.TestFailureException(
|
||||
f"With event {eid} selected we should have one output target but there is {len(pipe.GetOutputTargets())}")
|
||||
x = xpos
|
||||
y = 210 - drawNum * 20
|
||||
if drawNum > 2:
|
||||
x = xpos + 30
|
||||
y = 165 + (drawNum - 3) * 20
|
||||
|
||||
overlay = rd.DebugOverlay.QuadOverdrawPass
|
||||
tex = rd.TextureDisplay()
|
||||
col_tex: rd.ResourceId = pipe.GetOutputTargets()[0].resource
|
||||
tex.resourceId = col_tex
|
||||
tex.overlay = overlay
|
||||
tex.subresource.sample = 0
|
||||
self.check_overlays(eid, x, y)
|
||||
self.check_pixel_history_succeeds(xpos, 210)
|
||||
if drawNum > 0:
|
||||
self.check_pixel_history_succeeds(xpos, 190)
|
||||
if drawNum > 1:
|
||||
self.check_pixel_history_succeeds(xpos, 170)
|
||||
if drawNum > 2:
|
||||
self.check_pixel_history_succeeds(x, 165)
|
||||
if drawNum > 3:
|
||||
self.check_pixel_history_succeeds(x, 185)
|
||||
action = action.next
|
||||
|
||||
out: rd.ReplayOutput = self.controller.CreateOutput(rd.CreateHeadlessWindowingData(100, 100), rd.ReplayOutputType.Texture)
|
||||
out.SetTextureDisplay(tex)
|
||||
out.Display()
|
||||
out.Shutdown()
|
||||
rdtest.log.success("Two Single Draws QuadOverdraw (Pass) replayed correctly");
|
||||
with rdtest.log.auto_section('Two Single Draws QuadOverdraw (Pass) replayed correctly'):
|
||||
for drawNum in range(2):
|
||||
action = self.find_action("Two Single Draws")
|
||||
action = self.find_action("IndirectDraw", action.eventId)
|
||||
if drawNum == 1:
|
||||
action = self.find_action("IndirectDraw", action.eventId+1)
|
||||
|
||||
eid = action.eventId
|
||||
self.controller.SetFrameEvent(action.eventId, False)
|
||||
pipe = self.controller.GetPipelineState()
|
||||
if len(pipe.GetOutputTargets()) != 1:
|
||||
raise rdtest.TestFailureException(
|
||||
f"With event {action.eventId} selected we should have one output target but there is {len(pipe.GetOutputTargets())}")
|
||||
x = 50 + 80 * drawNum
|
||||
y = 275
|
||||
self.check_pixel_history_succeeds(x, y)
|
||||
self.check_overlays(eid, x, y)
|
||||
|
||||
overlay = rd.DebugOverlay.QuadOverdrawPass
|
||||
tex = rd.TextureDisplay()
|
||||
col_tex: rd.ResourceId = pipe.GetOutputTargets()[0].resource
|
||||
tex.resourceId = col_tex
|
||||
tex.overlay = overlay
|
||||
tex.subresource.sample = 0
|
||||
|
||||
out: rd.ReplayOutput = self.controller.CreateOutput(rd.CreateHeadlessWindowingData(100, 100), rd.ReplayOutputType.Texture)
|
||||
out.SetTextureDisplay(tex)
|
||||
out.Display()
|
||||
out.Shutdown()
|
||||
|
||||
with rdtest.log.auto_section('Checking All Overlays'):
|
||||
for eid in range(self.get_first_action().eventId, self.get_last_action().eventId + 1):
|
||||
|
||||
Reference in New Issue
Block a user