End stream-out queries in ClearState(). Closes #1412

* Also add tests of stream-out and DrawAuto()
This commit is contained in:
baldurk
2019-06-12 19:07:22 +01:00
parent 48cdc00b7f
commit 88189e316f
5 changed files with 153 additions and 6 deletions
@@ -6427,6 +6427,20 @@ bool WrappedID3D11DeviceContext::Serialise_ClearState(SerialiserType &ser)
{
if(IsReplayingAndReading())
{
// end stream-out queries for outgoing targets
for(UINT b = 0; b < D3D11_SO_STREAM_COUNT; b++)
{
ID3D11Buffer *buf = m_CurrentPipelineState->SO.Buffers[b];
if(buf)
{
ResourceId id = GetIDForResource(buf);
m_pRealContext->End(m_StreamOutCounters[id].query);
m_StreamOutCounters[id].running = false;
}
}
m_CurrentPipelineState->Clear();
m_pRealContext->ClearState();
VerifyState();
@@ -6454,6 +6468,20 @@ void WrappedID3D11DeviceContext::ClearState()
m_ContextRecord->AddChunk(scope.Get());
}
// end stream-out queries for outgoing targets
for(UINT b = 0; b < D3D11_SO_STREAM_COUNT; b++)
{
ID3D11Buffer *buf = m_CurrentPipelineState->SO.Buffers[b];
if(buf)
{
ResourceId id = GetIDForResource(buf);
m_pRealContext->End(m_StreamOutCounters[id].query);
m_StreamOutCounters[id].running = false;
}
}
m_CurrentPipelineState->Clear();
VerifyState();
}
@@ -24,7 +24,7 @@
#include "d3d11_test.h"
TEST(D3D11_StreamOut, D3D11GraphicsTest)
TEST(D3D11_Stream_Out, D3D11GraphicsTest)
{
static constexpr const char *Description = "Test using D3D11's streamout feature";
@@ -74,9 +74,25 @@ TEST(D3D11_StreamOut, D3D11GraphicsTest)
ID3D11BufferPtr vb = MakeBuffer().Vertex().Data(DefaultTri);
ID3D11BufferPtr so[2] = {
MakeBuffer().StreamOut().Size(2048), MakeBuffer().StreamOut().Size(2048),
MakeBuffer().StreamOut().Vertex().Size(2048), MakeBuffer().StreamOut().Vertex().Size(2048),
};
D3D11_INPUT_ELEMENT_DESC layoutdesc[] = {
{
"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0,
},
{
"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_VERTEX_DATA, 0,
},
{
"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0,
},
};
ID3D11InputLayoutPtr streamoutLayout;
CHECK_HR(dev->CreateInputLayout(layoutdesc, ARRAY_COUNT(layoutdesc), vsblob->GetBufferPointer(),
vsblob->GetBufferSize(), &streamoutLayout));
while(Running())
{
ctx->ClearState();
@@ -124,6 +140,51 @@ TEST(D3D11_StreamOut, D3D11GraphicsTest)
ctx->Draw(3, 0);
ctx->UpdateSubresource(so[0], 0, NULL, empty, 2048, 2048);
ctx->UpdateSubresource(so[1], 0, NULL, empty, 2048, 2048);
// test DrawAuto()
RSSetViewport({0.0f, 0.0f, (float)screenWidth, (float)screenHeight, 0.0f, 1.0f});
// draw with streamout and explicitly unbind
ctx->SOSetTargets(2, bufs, offs);
ctx->Draw(3, 0);
ctx->SOSetTargets(0, NULL, NULL);
RSSetViewport({0.0f, 0.0f, (float)screenWidth / 4.0f, (float)screenHeight / 4.0f, 0.0f, 1.0f});
ctx->IASetVertexBuffers(0, 2, bufs, &strides[0], offs);
ctx->IASetInputLayout(streamoutLayout);
ctx->DrawAuto();
RSSetViewport({0.0f, 0.0f, (float)screenWidth, (float)screenHeight, 0.0f, 1.0f});
ID3D11Buffer *emptyBuf[2] = {};
ctx->IASetVertexBuffers(0, 2, emptyBuf, &strides[0], offs);
IASetVertexBuffer(vb, sizeof(DefaultA2V), 0);
ctx->IASetInputLayout(defaultLayout);
// draw with streamout and clear state
ctx->SOSetTargets(2, bufs, offs);
ctx->DrawInstanced(3, 2, 0, 0);
ctx->ClearState();
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->VSSetShader(vs, NULL, 0);
ctx->GSSetShader(gs, NULL, 0);
ctx->PSSetShader(ps, NULL, 0);
ctx->OMSetRenderTargets(1, &bbRTV.GetInterfacePtr(), NULL);
RSSetViewport({screenWidth / 4.0f, 0.0f, (float)screenWidth / 4.0f,
(float)screenHeight / 4.0f, 0.0f, 1.0f});
ctx->IASetVertexBuffers(0, 2, bufs, &strides[0], offs);
ctx->IASetInputLayout(streamoutLayout);
ctx->DrawAuto();
Present();
}
+1 -1
View File
@@ -145,7 +145,7 @@
<ClCompile Include="d3d11\d3d11_saturate.cpp" />
<ClCompile Include="d3d11\d3d11_simple_dispatch.cpp" />
<ClCompile Include="d3d11\d3d11_simple_triangle.cpp" />
<ClCompile Include="d3d11\d3d11_streamout.cpp" />
<ClCompile Include="d3d11\d3d11_stream_out.cpp" />
<ClCompile Include="d3d11\d3d11_stripped_shaders.cpp" />
<ClCompile Include="d3d11\d3d11_structured_buffer_misaligned_dirty.cpp" />
<ClCompile Include="d3d11\d3d11_structured_buffer_nested.cpp" />
+3 -3
View File
@@ -70,9 +70,6 @@
<ClCompile Include="gl\gl_vao_0.cpp">
<Filter>OpenGL\demos</Filter>
</ClCompile>
<ClCompile Include="d3d11\d3d11_streamout.cpp">
<Filter>D3D11\demos</Filter>
</ClCompile>
<ClCompile Include="d3d11\d3d11_texture_3d.cpp">
<Filter>D3D11\demos</Filter>
</ClCompile>
@@ -309,6 +306,9 @@
<ClCompile Include="vk\vk_image_layouts.cpp">
<Filter>Vulkan\demos</Filter>
</ClCompile>
<ClCompile Include="d3d11\d3d11_stream_out.cpp">
<Filter>D3D11\demos</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="D3D11">
+58
View File
@@ -0,0 +1,58 @@
import rdtest
import struct
import renderdoc as rd
class D3D11_Stream_Out(rdtest.TestCase):
demos_test_name = 'D3D11_Stream_Out'
def check_capture(self):
draw = self.find_draw("Draw")
self.check(draw is not None)
self.controller.SetFrameEvent(draw.eventId, False)
pipe: rd.PipeState = self.controller.GetPipelineState()
# Get the input data as our reference
# First draw should have data at offset 0. First buffer has positions, second has colors (with doubled stride)
vsin = self.get_vsin(draw)
pos = [(*v['POSITION'], 1.0) for v in vsin]
col = [v['COLOR'] for v in vsin]
d3d11pipe: rd.D3D11State = self.controller.GetD3D11PipelineState()
so: rd.D3D11StreamOut = d3d11pipe.streamOut
so_bytes = self.controller.GetBufferData(so.outputs[0].resourceId, so.outputs[0].byteOffset, 0)
for i,p in enumerate(pos):
so_p = struct.unpack_from("4f", so_bytes, 0 + 4*4*i)
if not rdtest.value_compare(p, so_p):
raise rdtest.TestFailureException("Streamed-out position {} doesn't match expected {}".format(so_p, p))
so_bytes = self.controller.GetBufferData(so.outputs[1].resourceId, so.outputs[1].byteOffset, 0)
for i,c in enumerate(col):
so_c = struct.unpack_from("4f", so_bytes, 0 + 8*4*i)
if not rdtest.value_compare(c, so_c):
raise rdtest.TestFailureException("Streamed-out color {} doesn't match expected {}".format(so_c, c))
draw_auto = self.find_draw("DrawAuto", draw.eventId)
# First draw should be 3 vertices
if not rdtest.value_compare(draw_auto.numIndices, 3):
raise rdtest.TestFailureException("First DrawAuto() draws {} vertices".format(draw_auto.numIndices))
draw_auto = self.find_draw("DrawAuto", draw_auto.eventId+1)
# Second draw should be 6 vertices (3 vertices, instanced twice
if not rdtest.value_compare(draw_auto.numIndices, 6):
raise rdtest.TestFailureException("Second DrawAuto() draws {} vertices".format(draw_auto.numIndices))
if not rdtest.value_compare(draw_auto.numInstances, 1):
raise rdtest.TestFailureException("Second DrawAuto() draws {} instances".format(draw_auto.numInstances))
rdtest.log.success("First draw stream-out data is correct")