1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-27 04:54:15 +01:00

[d3d11] Implement direct draw batching

Not super useful without backend support though.
This commit is contained in:
Philip Rebohle 2025-02-21 14:16:34 +01:00 committed by Philip Rebohle
parent fc3d3ae331
commit 7815b6942d
3 changed files with 95 additions and 34 deletions

View File

@ -14,6 +14,8 @@ namespace dxvk {
None, None,
DrawIndirect, DrawIndirect,
DrawIndirectIndexed, DrawIndirectIndexed,
Draw,
DrawIndexed,
}; };

View File

@ -1037,14 +1037,13 @@ namespace dxvk {
UINT StartVertexLocation) { UINT StartVertexLocation) {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
if (unlikely(HasDirtyGraphicsBindings())) VkDrawIndirectCommand draw = { };
ApplyDirtyGraphicsBindings(); draw.vertexCount = VertexCount;
draw.instanceCount = 1u;
draw.firstVertex = StartVertexLocation;
draw.firstInstance = 0u;
EmitCs([=] (DxvkContext* ctx) { BatchDraw(draw);
ctx->draw(
VertexCount, 1,
StartVertexLocation, 0);
});
} }
@ -1055,15 +1054,14 @@ namespace dxvk {
INT BaseVertexLocation) { INT BaseVertexLocation) {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
if (unlikely(HasDirtyGraphicsBindings())) VkDrawIndexedIndirectCommand draw = { };
ApplyDirtyGraphicsBindings(); draw.indexCount = IndexCount;
draw.instanceCount = 1u;
draw.firstIndex = StartIndexLocation;
draw.vertexOffset = BaseVertexLocation;
draw.firstInstance = 0u;
EmitCs([=] (DxvkContext* ctx) { BatchDrawIndexed(draw);
ctx->drawIndexed(
IndexCount, 1,
StartIndexLocation,
BaseVertexLocation, 0);
});
} }
@ -1075,16 +1073,13 @@ namespace dxvk {
UINT StartInstanceLocation) { UINT StartInstanceLocation) {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
if (unlikely(HasDirtyGraphicsBindings())) VkDrawIndirectCommand draw = { };
ApplyDirtyGraphicsBindings(); draw.vertexCount = VertexCountPerInstance;
draw.instanceCount = InstanceCount;
draw.firstVertex = StartVertexLocation;
draw.firstInstance = StartInstanceLocation;
EmitCs([=] (DxvkContext* ctx) { BatchDraw(draw);
ctx->draw(
VertexCountPerInstance,
InstanceCount,
StartVertexLocation,
StartInstanceLocation);
});
} }
@ -1097,17 +1092,14 @@ namespace dxvk {
UINT StartInstanceLocation) { UINT StartInstanceLocation) {
D3D10DeviceLock lock = LockContext(); D3D10DeviceLock lock = LockContext();
if (unlikely(HasDirtyGraphicsBindings())) VkDrawIndexedIndirectCommand draw = { };
ApplyDirtyGraphicsBindings(); draw.indexCount = IndexCountPerInstance;
draw.instanceCount = InstanceCount;
draw.firstIndex = StartIndexLocation;
draw.vertexOffset = BaseVertexLocation;
draw.firstInstance = StartInstanceLocation;
EmitCs([=] (DxvkContext* ctx) { BatchDrawIndexed(draw);
ctx->drawIndexed(
IndexCountPerInstance,
InstanceCount,
StartIndexLocation,
BaseVertexLocation,
StartInstanceLocation);
});
} }
@ -3568,6 +3560,67 @@ namespace dxvk {
} }
template<typename ContextType>
void D3D11CommonContext<ContextType>::BatchDraw(
const VkDrawIndirectCommand& draw) {
if (unlikely(HasDirtyGraphicsBindings()))
ApplyDirtyGraphicsBindings();
// Batch consecutive draws if there are no state changes
if (m_csDataType == D3D11CmdType::Draw) {
auto* drawInfo = m_csChunk->pushData(m_csData, 1u);
if (likely(drawInfo)) {
new (drawInfo) VkDrawIndirectCommand(draw);
return;
}
}
EmitCsCmd<VkDrawIndirectCommand>(D3D11CmdType::Draw, 1u,
[] (DxvkContext* ctx, const VkDrawIndirectCommand* draws, size_t count) {
for (size_t i = 0; i < count; i++) {
ctx->draw(draws[i].vertexCount,
draws[i].instanceCount,
draws[i].firstVertex,
draws[i].firstInstance);
}
});
new (m_csData->first()) VkDrawIndirectCommand(draw);
}
template<typename ContextType>
void D3D11CommonContext<ContextType>::BatchDrawIndexed(
const VkDrawIndexedIndirectCommand& draw) {
if (unlikely(HasDirtyGraphicsBindings()))
ApplyDirtyGraphicsBindings();
// Batch consecutive draws if there are no state changes
if (m_csDataType == D3D11CmdType::DrawIndexed) {
auto* drawInfo = m_csChunk->pushData(m_csData, 1u);
if (likely(drawInfo)) {
new (drawInfo) VkDrawIndexedIndirectCommand(draw);
return;
}
}
EmitCsCmd<VkDrawIndexedIndirectCommand>(D3D11CmdType::DrawIndexed, 1u,
[] (DxvkContext* ctx, const VkDrawIndexedIndirectCommand* draws, size_t count) {
for (size_t i = 0; i < count; i++) {
ctx->drawIndexed(draws[i].indexCount,
draws[i].instanceCount,
draws[i].firstIndex,
draws[i].vertexOffset,
draws[i].firstInstance);
}
});
new (m_csData->first()) VkDrawIndexedIndirectCommand(draw);
}
template<typename ContextType> template<typename ContextType>
template<DxbcProgramType ShaderStage> template<DxbcProgramType ShaderStage>
void D3D11CommonContext<ContextType>::BindShader( void D3D11CommonContext<ContextType>::BindShader(

View File

@ -848,6 +848,12 @@ namespace dxvk {
void ApplyViewportState(); void ApplyViewportState();
void BatchDraw(
const VkDrawIndirectCommand& draw);
void BatchDrawIndexed(
const VkDrawIndexedIndirectCommand& draw);
template<DxbcProgramType ShaderStage> template<DxbcProgramType ShaderStage>
void BindShader( void BindShader(
const D3D11CommonShader* pShaderModule); const D3D11CommonShader* pShaderModule);