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 = {};
|
||||
};
|
||||
|
||||
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,
|
||||
BindGroupStateTracker* bindingTracker,
|
||||
RenderPassDescriptorHeapTracker* renderPassTracker,
|
||||
|
@ -997,6 +1027,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
RenderPipeline* lastPipeline = nullptr;
|
||||
PipelineLayout* lastLayout = nullptr;
|
||||
VertexBufferTracker vertexBufferTracker = {};
|
||||
IndexBufferTracker indexBufferTracker = {};
|
||||
|
||||
auto EncodeRenderBundleCommand = [&](CommandIterator* iter, Command type) {
|
||||
switch (type) {
|
||||
|
@ -1011,6 +1042,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
case Command::DrawIndexed: {
|
||||
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
||||
|
||||
indexBufferTracker.Apply(commandList.Get());
|
||||
vertexBufferTracker.Apply(commandList.Get(), lastPipeline);
|
||||
commandList->DrawIndexedInstanced(draw->indexCount, draw->instanceCount,
|
||||
draw->firstIndex, draw->baseVertex,
|
||||
|
@ -1032,6 +1064,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
case Command::DrawIndexedIndirect: {
|
||||
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
||||
|
||||
indexBufferTracker.Apply(commandList.Get());
|
||||
vertexBufferTracker.Apply(commandList.Get(), lastPipeline);
|
||||
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
||||
ComPtr<ID3D12CommandSignature> signature =
|
||||
|
@ -1086,6 +1119,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
commandList->SetPipelineState(pipeline->GetPipelineState().Get());
|
||||
commandList->IASetPrimitiveTopology(pipeline->GetD3D12PrimitiveTopology());
|
||||
|
||||
indexBufferTracker.OnSetPipeline(pipeline);
|
||||
bindingTracker->SetInheritedBindGroups(commandList, lastLayout, layout);
|
||||
|
||||
lastPipeline = pipeline;
|
||||
|
@ -1108,17 +1142,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
case Command::SetIndexBuffer: {
|
||||
SetIndexBufferCmd* cmd = iter->NextCommand<SetIndexBufferCmd>();
|
||||
|
||||
Buffer* buffer = ToBackend(cmd->buffer.Get());
|
||||
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);
|
||||
indexBufferTracker.OnSetIndexBuffer(ToBackend(cmd->buffer.Get()), cmd->offset);
|
||||
} break;
|
||||
|
||||
case Command::SetVertexBuffers: {
|
||||
|
|
Loading…
Reference in New Issue