diff --git a/examples/HelloDepthStencil.cpp b/examples/HelloDepthStencil.cpp index 97439a2beb..81c49c2216 100644 --- a/examples/HelloDepthStencil.cpp +++ b/examples/HelloDepthStencil.cpp @@ -222,6 +222,7 @@ void init() { .SetLayout(pl) .SetStage(nxt::ShaderStage::Vertex, vsModule, "main") .SetStage(nxt::ShaderStage::Fragment, fsModule, "main") + .SetIndexFormat(nxt::IndexFormat::Uint32) .SetInputState(inputState) .SetDepthStencilState(depthStencilState) .GetResult(); @@ -286,7 +287,7 @@ void frame() { .TransitionBufferUsage(cameraBuffer, nxt::BufferUsageBit::Uniform) .SetBindGroup(0, bindGroup[0]) .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets) - .SetIndexBuffer(indexBuffer, 0, nxt::IndexFormat::Uint32) + .SetIndexBuffer(indexBuffer, 0) .DrawElements(36, 1, 0, 0) .SetStencilReference(0x1) diff --git a/examples/HelloIndices.cpp b/examples/HelloIndices.cpp index 5c94277c72..691263d869 100644 --- a/examples/HelloIndices.cpp +++ b/examples/HelloIndices.cpp @@ -81,6 +81,7 @@ void init() { .SetSubpass(renderpass, 0) .SetStage(nxt::ShaderStage::Vertex, vsModule, "main") .SetStage(nxt::ShaderStage::Fragment, fsModule, "main") + .SetIndexFormat(nxt::IndexFormat::Uint32) .SetInputState(inputState) .GetResult(); } @@ -96,7 +97,7 @@ void frame() { .BeginRenderSubpass() .SetRenderPipeline(pipeline) .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets) - .SetIndexBuffer(indexBuffer, 0, nxt::IndexFormat::Uint32) + .SetIndexBuffer(indexBuffer, 0) .DrawElements(3, 1, 0, 0) .EndRenderSubpass() .EndRenderPass() diff --git a/examples/HelloTriangle.cpp b/examples/HelloTriangle.cpp index 90aec10653..f540fc3468 100644 --- a/examples/HelloTriangle.cpp +++ b/examples/HelloTriangle.cpp @@ -129,6 +129,7 @@ void init() { .SetLayout(pl) .SetStage(nxt::ShaderStage::Vertex, vsModule, "main") .SetStage(nxt::ShaderStage::Fragment, fsModule, "main") + .SetIndexFormat(nxt::IndexFormat::Uint32) .SetInputState(inputState) .GetResult(); @@ -159,7 +160,7 @@ void frame() { .SetRenderPipeline(pipeline) .SetBindGroup(0, bindGroup) .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets) - .SetIndexBuffer(indexBuffer, 0, nxt::IndexFormat::Uint32) + .SetIndexBuffer(indexBuffer, 0) .DrawElements(3, 1, 0, 0) .EndRenderSubpass() .EndRenderPass() diff --git a/examples/glTFViewer/glTFViewer.cpp b/examples/glTFViewer/glTFViewer.cpp index 66eb41aa14..37f637d6ff 100644 --- a/examples/glTFViewer/glTFViewer.cpp +++ b/examples/glTFViewer/glTFViewer.cpp @@ -295,6 +295,7 @@ namespace { .SetLayout(pipelineLayout) .SetStage(nxt::ShaderStage::Vertex, oVSModule, "main") .SetStage(nxt::ShaderStage::Fragment, oFSModule, "main") + .SetIndexFormat(nxt::IndexFormat::Uint16) .SetInputState(inputState) .SetDepthStencilState(depthStencilState) .GetResult(); @@ -544,7 +545,7 @@ namespace { continue; } const auto& oIndicesBuffer = buffers.at(iIndices.bufferView); - cmd.SetIndexBuffer(oIndicesBuffer, static_cast(iIndices.byteOffset), nxt::IndexFormat::Uint16); + cmd.SetIndexBuffer(oIndicesBuffer, static_cast(iIndices.byteOffset)); cmd.DrawElements(static_cast(iIndices.count), 1, 0, 0); } else { // DrawArrays diff --git a/next.json b/next.json index 9671852caa..905cbdf7bf 100644 --- a/next.json +++ b/next.json @@ -457,8 +457,7 @@ "name": "set index buffer", "args": [ {"name": "buffer", "type": "buffer"}, - {"name": "offset", "type": "uint32_t"}, - {"name": "format", "type": "index format"} + {"name": "offset", "type": "uint32_t"} ] }, { @@ -939,6 +938,12 @@ {"name": "depth stencil state", "type": "depth stencil state"} ] }, + { + "name": "set index format", + "args": [ + {"name": "format", "type": "index format"} + ] + }, { "name": "set input state", "args": [ diff --git a/src/backend/CommandBuffer.cpp b/src/backend/CommandBuffer.cpp index 011daf1b88..9c30bd2db2 100644 --- a/src/backend/CommandBuffer.cpp +++ b/src/backend/CommandBuffer.cpp @@ -820,14 +820,13 @@ namespace backend { cmd->group = group; } - void CommandBufferBuilder::SetIndexBuffer(BufferBase* buffer, uint32_t offset, nxt::IndexFormat format) { + void CommandBufferBuilder::SetIndexBuffer(BufferBase* buffer, uint32_t offset) { // TODO(kainino@chromium.org): validation SetIndexBufferCmd* cmd = allocator.Allocate(Command::SetIndexBuffer); new(cmd) SetIndexBufferCmd; cmd->buffer = buffer; cmd->offset = offset; - cmd->format = format; } void CommandBufferBuilder::SetVertexBuffers(uint32_t startSlot, uint32_t count, BufferBase* const* buffers, uint32_t const* offsets){ diff --git a/src/backend/CommandBuffer.h b/src/backend/CommandBuffer.h index cf3ed3db27..a2eb45ac37 100644 --- a/src/backend/CommandBuffer.h +++ b/src/backend/CommandBuffer.h @@ -83,7 +83,7 @@ namespace backend { void SetStencilReference(uint32_t reference); void SetBlendColor(float r, float g, float b, float a); void SetBindGroup(uint32_t groupIndex, BindGroupBase* group); - void SetIndexBuffer(BufferBase* buffer, uint32_t offset, nxt::IndexFormat format); + void SetIndexBuffer(BufferBase* buffer, uint32_t offset); template void SetVertexBuffers(uint32_t startSlot, uint32_t count, T* const* buffers, uint32_t const* offsets) { diff --git a/src/backend/Commands.h b/src/backend/Commands.h index e386995cbe..607ee0834c 100644 --- a/src/backend/Commands.h +++ b/src/backend/Commands.h @@ -152,7 +152,6 @@ namespace backend { struct SetIndexBufferCmd { Ref buffer; uint32_t offset; - nxt::IndexFormat format; }; struct SetVertexBuffersCmd { diff --git a/src/backend/RenderPipeline.cpp b/src/backend/RenderPipeline.cpp index a149966867..a2c4775a08 100644 --- a/src/backend/RenderPipeline.cpp +++ b/src/backend/RenderPipeline.cpp @@ -28,6 +28,7 @@ namespace backend { RenderPipelineBase::RenderPipelineBase(RenderPipelineBuilder* builder) : PipelineBase(builder), depthStencilState(std::move(builder->depthStencilState)), + indexFormat(builder->indexFormat), inputState(std::move(builder->inputState)), primitiveTopology(builder->primitiveTopology), blendStates(builder->blendStates), @@ -55,6 +56,10 @@ namespace backend { return depthStencilState.Get(); } + nxt::IndexFormat RenderPipelineBase::GetIndexFormat() const { + return indexFormat; + } + InputStateBase* RenderPipelineBase::GetInputState() { return inputState.Get(); } @@ -122,6 +127,10 @@ namespace backend { this->depthStencilState = depthStencilState; } + void RenderPipelineBuilder::SetIndexFormat(nxt::IndexFormat format) { + this->indexFormat = format; + } + void RenderPipelineBuilder::SetInputState(InputStateBase* inputState) { this->inputState = inputState; } diff --git a/src/backend/RenderPipeline.h b/src/backend/RenderPipeline.h index ab225c7a81..93194a0c53 100644 --- a/src/backend/RenderPipeline.h +++ b/src/backend/RenderPipeline.h @@ -30,6 +30,7 @@ namespace backend { BlendStateBase* GetBlendState(uint32_t attachmentSlot); DepthStencilStateBase* GetDepthStencilState(); + nxt::IndexFormat GetIndexFormat() const; InputStateBase* GetInputState(); nxt::PrimitiveTopology GetPrimitiveTopology() const; RenderPassBase* GetRenderPass(); @@ -37,6 +38,7 @@ namespace backend { private: Ref depthStencilState; + nxt::IndexFormat indexFormat; Ref inputState; nxt::PrimitiveTopology primitiveTopology; std::array, kMaxColorAttachments> blendStates; @@ -52,6 +54,7 @@ namespace backend { void SetColorAttachmentBlendState(uint32_t attachmentSlot, BlendStateBase* blendState); void SetDepthStencilState(DepthStencilStateBase* depthStencilState); void SetPrimitiveTopology(nxt::PrimitiveTopology primitiveTopology); + void SetIndexFormat(nxt::IndexFormat format); void SetInputState(InputStateBase* inputState); void SetSubpass(RenderPassBase* renderPass, uint32_t subpass); @@ -64,6 +67,7 @@ namespace backend { Ref inputState; // TODO(enga@google.com): Remove default when we validate that all required properties are set nxt::PrimitiveTopology primitiveTopology = nxt::PrimitiveTopology::TriangleList; + nxt::IndexFormat indexFormat = nxt::IndexFormat::Uint32; std::bitset blendStatesSet; std::array, kMaxColorAttachments> blendStates; Ref renderPass; diff --git a/src/backend/d3d12/CommandBufferD3D12.cpp b/src/backend/d3d12/CommandBufferD3D12.cpp index 8be64e44e8..74f1b8fe67 100644 --- a/src/backend/d3d12/CommandBufferD3D12.cpp +++ b/src/backend/d3d12/CommandBufferD3D12.cpp @@ -560,7 +560,10 @@ namespace d3d12 { D3D12_INDEX_BUFFER_VIEW bufferView; bufferView.BufferLocation = buffer->GetVA() + cmd->offset; bufferView.SizeInBytes = buffer->GetSize() - cmd->offset; - bufferView.Format = DXGIIndexFormat(cmd->format); + //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(lastRenderPipeline->GetIndexFormat()); commandList->IASetIndexBuffer(&bufferView); } diff --git a/src/backend/metal/CommandBufferMTL.mm b/src/backend/metal/CommandBufferMTL.mm index 8f65f298d7..95a2d9bcc5 100644 --- a/src/backend/metal/CommandBufferMTL.mm +++ b/src/backend/metal/CommandBufferMTL.mm @@ -29,15 +29,6 @@ namespace backend { namespace metal { namespace { - MTLIndexType IndexFormatType(nxt::IndexFormat format) { - switch (format) { - case nxt::IndexFormat::Uint16: - return MTLIndexTypeUInt16; - case nxt::IndexFormat::Uint32: - return MTLIndexTypeUInt32; - } - } - struct CurrentEncoders { Device* device; @@ -172,7 +163,6 @@ namespace metal { RenderPipeline* lastRenderPipeline = nullptr; id indexBuffer = nil; uint32_t indexBufferOffset = 0; - MTLIndexType indexType = MTLIndexTypeUInt32; CurrentEncoders encoders; encoders.device = device; @@ -333,7 +323,7 @@ namespace metal { [encoders.render drawIndexedPrimitives:lastRenderPipeline->GetMTLPrimitiveTopology() indexCount:draw->indexCount - indexType:indexType + indexType:lastRenderPipeline->GetMTLIndexType() indexBuffer:indexBuffer indexBufferOffset:indexBufferOffset instanceCount:draw->instanceCount @@ -564,7 +554,6 @@ namespace metal { auto b = ToBackend(cmd->buffer.Get()); indexBuffer = b->GetMTLBuffer(); indexBufferOffset = cmd->offset; - indexType = IndexFormatType(cmd->format); } break; diff --git a/src/backend/metal/RenderPipelineMTL.h b/src/backend/metal/RenderPipelineMTL.h index 33f4830a79..c057dad47c 100644 --- a/src/backend/metal/RenderPipelineMTL.h +++ b/src/backend/metal/RenderPipelineMTL.h @@ -27,11 +27,13 @@ namespace metal { RenderPipeline(RenderPipelineBuilder* builder); ~RenderPipeline(); + MTLIndexType GetMTLIndexType() const; MTLPrimitiveType GetMTLPrimitiveTopology() const; void Encode(id encoder); private: + MTLIndexType mtlIndexType; MTLPrimitiveType mtlPrimitiveTopology; id mtlRenderPipelineState = nil; }; diff --git a/src/backend/metal/RenderPipelineMTL.mm b/src/backend/metal/RenderPipelineMTL.mm index 56db4d73a4..a8c93518a6 100644 --- a/src/backend/metal/RenderPipelineMTL.mm +++ b/src/backend/metal/RenderPipelineMTL.mm @@ -53,10 +53,21 @@ namespace metal { return MTLPrimitiveTopologyClassTriangle; } } + + MTLIndexType MTLIndexFormat(nxt::IndexFormat format) { + switch (format) { + case nxt::IndexFormat::Uint16: + return MTLIndexTypeUInt16; + case nxt::IndexFormat::Uint32: + return MTLIndexTypeUInt32; + } + } } RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder) - : RenderPipelineBase(builder), mtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) { + : RenderPipelineBase(builder), + mtlIndexType(MTLIndexFormat(GetIndexFormat())), + mtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) { auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice(); @@ -121,6 +132,10 @@ namespace metal { [mtlRenderPipelineState release]; } + MTLIndexType RenderPipeline::GetMTLIndexType() const { + return mtlIndexType; + } + MTLPrimitiveType RenderPipeline::GetMTLPrimitiveTopology() const { return mtlPrimitiveTopology; } diff --git a/src/backend/opengl/CommandBufferGL.cpp b/src/backend/opengl/CommandBufferGL.cpp index 1917c79702..aff11a1b5a 100644 --- a/src/backend/opengl/CommandBufferGL.cpp +++ b/src/backend/opengl/CommandBufferGL.cpp @@ -129,7 +129,6 @@ namespace opengl { PipelineGL* lastGLPipeline = nullptr; RenderPipeline* lastRenderPipeline = nullptr; uint32_t indexBufferOffset = 0; - nxt::IndexFormat indexBufferFormat = nxt::IndexFormat::Uint16; PersistentPipelineState persistentPipelineState; persistentPipelineState.SetDefaultState(); @@ -380,8 +379,9 @@ namespace opengl { DrawElementsCmd* draw = commands.NextCommand(); pushConstants.Apply(lastPipeline, lastGLPipeline); - size_t formatSize = IndexFormatSize(indexBufferFormat); - GLenum formatType = IndexFormatType(indexBufferFormat); + nxt::IndexFormat indexFormat = lastRenderPipeline->GetIndexFormat(); + size_t formatSize = IndexFormatSize(indexFormat); + GLenum formatType = IndexFormatType(indexFormat); if (draw->firstInstance > 0) { glDrawElementsInstancedBaseInstance(lastRenderPipeline->GetGLPrimitiveTopology(), @@ -530,7 +530,6 @@ namespace opengl { GLuint buffer = ToBackend(cmd->buffer.Get())->GetHandle(); indexBufferOffset = cmd->offset; - indexBufferFormat = cmd->format; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); } break;