D3D12: Add IndexBufferTracker
Setting an index buffer is dependent on getting the index format from the pipeline. This adds a tracker to lazily apply the index format before a draw call if it changes. Bug: dawn:201 Change-Id: I83c87cc950bf6c93637dd14765c340c97b461061 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/11001 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
8e37315012
commit
f35420dfca
|
@ -448,6 +448,36 @@ namespace dawn_native { namespace d3d12 {
|
||||||
std::array<D3D12_VERTEX_BUFFER_VIEW, kMaxVertexBuffers> mD3D12BufferViews = {};
|
std::array<D3D12_VERTEX_BUFFER_VIEW, kMaxVertexBuffers> mD3D12BufferViews = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IndexBufferTracker {
|
||||||
|
public:
|
||||||
|
void OnSetIndexBuffer(Buffer* buffer, uint64_t offset) {
|
||||||
|
mD3D12BufferView.BufferLocation = buffer->GetVA() + offset;
|
||||||
|
mD3D12BufferView.SizeInBytes = buffer->GetSize() - offset;
|
||||||
|
|
||||||
|
// We don't need to dirty the state unless BufferLocation or SizeInBytes
|
||||||
|
// change, but most of the time this will always be the case.
|
||||||
|
mLastAppliedIndexFormat = DXGI_FORMAT_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnSetPipeline(const RenderPipelineBase* pipeline) {
|
||||||
|
mD3D12BufferView.Format =
|
||||||
|
DXGIIndexFormat(pipeline->GetVertexInputDescriptor()->indexFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Apply(ID3D12GraphicsCommandList* commandList) {
|
||||||
|
if (mD3D12BufferView.Format == mLastAppliedIndexFormat) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
commandList->IASetIndexBuffer(&mD3D12BufferView);
|
||||||
|
mLastAppliedIndexFormat = mD3D12BufferView.Format;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
DXGI_FORMAT mLastAppliedIndexFormat = DXGI_FORMAT_UNKNOWN;
|
||||||
|
D3D12_INDEX_BUFFER_VIEW mD3D12BufferView = {};
|
||||||
|
};
|
||||||
|
|
||||||
void AllocateAndSetDescriptorHeaps(Device* device,
|
void AllocateAndSetDescriptorHeaps(Device* device,
|
||||||
BindGroupStateTracker* bindingTracker,
|
BindGroupStateTracker* bindingTracker,
|
||||||
RenderPassDescriptorHeapTracker* renderPassTracker,
|
RenderPassDescriptorHeapTracker* renderPassTracker,
|
||||||
|
@ -997,6 +1027,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
RenderPipeline* lastPipeline = nullptr;
|
RenderPipeline* lastPipeline = nullptr;
|
||||||
PipelineLayout* lastLayout = nullptr;
|
PipelineLayout* lastLayout = nullptr;
|
||||||
VertexBufferTracker vertexBufferTracker = {};
|
VertexBufferTracker vertexBufferTracker = {};
|
||||||
|
IndexBufferTracker indexBufferTracker = {};
|
||||||
|
|
||||||
auto EncodeRenderBundleCommand = [&](CommandIterator* iter, Command type) {
|
auto EncodeRenderBundleCommand = [&](CommandIterator* iter, Command type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -1011,6 +1042,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
case Command::DrawIndexed: {
|
case Command::DrawIndexed: {
|
||||||
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
||||||
|
|
||||||
|
indexBufferTracker.Apply(commandList.Get());
|
||||||
vertexBufferTracker.Apply(commandList.Get(), lastPipeline);
|
vertexBufferTracker.Apply(commandList.Get(), lastPipeline);
|
||||||
commandList->DrawIndexedInstanced(draw->indexCount, draw->instanceCount,
|
commandList->DrawIndexedInstanced(draw->indexCount, draw->instanceCount,
|
||||||
draw->firstIndex, draw->baseVertex,
|
draw->firstIndex, draw->baseVertex,
|
||||||
|
@ -1032,6 +1064,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
case Command::DrawIndexedIndirect: {
|
case Command::DrawIndexedIndirect: {
|
||||||
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
||||||
|
|
||||||
|
indexBufferTracker.Apply(commandList.Get());
|
||||||
vertexBufferTracker.Apply(commandList.Get(), lastPipeline);
|
vertexBufferTracker.Apply(commandList.Get(), lastPipeline);
|
||||||
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
||||||
ComPtr<ID3D12CommandSignature> signature =
|
ComPtr<ID3D12CommandSignature> signature =
|
||||||
|
@ -1086,6 +1119,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
commandList->SetPipelineState(pipeline->GetPipelineState().Get());
|
commandList->SetPipelineState(pipeline->GetPipelineState().Get());
|
||||||
commandList->IASetPrimitiveTopology(pipeline->GetD3D12PrimitiveTopology());
|
commandList->IASetPrimitiveTopology(pipeline->GetD3D12PrimitiveTopology());
|
||||||
|
|
||||||
|
indexBufferTracker.OnSetPipeline(pipeline);
|
||||||
bindingTracker->SetInheritedBindGroups(commandList, lastLayout, layout);
|
bindingTracker->SetInheritedBindGroups(commandList, lastLayout, layout);
|
||||||
|
|
||||||
lastPipeline = pipeline;
|
lastPipeline = pipeline;
|
||||||
|
@ -1108,17 +1142,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
case Command::SetIndexBuffer: {
|
case Command::SetIndexBuffer: {
|
||||||
SetIndexBufferCmd* cmd = iter->NextCommand<SetIndexBufferCmd>();
|
SetIndexBufferCmd* cmd = iter->NextCommand<SetIndexBufferCmd>();
|
||||||
|
|
||||||
Buffer* buffer = ToBackend(cmd->buffer.Get());
|
indexBufferTracker.OnSetIndexBuffer(ToBackend(cmd->buffer.Get()), cmd->offset);
|
||||||
D3D12_INDEX_BUFFER_VIEW bufferView;
|
|
||||||
bufferView.BufferLocation = buffer->GetVA() + cmd->offset;
|
|
||||||
bufferView.SizeInBytes = buffer->GetSize() - cmd->offset;
|
|
||||||
// TODO(cwallez@chromium.org): Make index buffers lazily applied, right now
|
|
||||||
// this will break if the pipeline is changed for one with a different index
|
|
||||||
// format after SetIndexBuffer
|
|
||||||
bufferView.Format =
|
|
||||||
DXGIIndexFormat(lastPipeline->GetVertexInputDescriptor()->indexFormat);
|
|
||||||
|
|
||||||
commandList->IASetIndexBuffer(&bufferView);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetVertexBuffers: {
|
case Command::SetVertexBuffers: {
|
||||||
|
|
Loading…
Reference in New Issue