Make the index format part of the pipeline state.

This commit is contained in:
Corentin Wallez 2017-09-19 13:38:05 -04:00 committed by Corentin Wallez
parent 715ac712c6
commit 405dcd636a
15 changed files with 56 additions and 28 deletions

View File

@ -222,6 +222,7 @@ void init() {
.SetLayout(pl) .SetLayout(pl)
.SetStage(nxt::ShaderStage::Vertex, vsModule, "main") .SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
.SetStage(nxt::ShaderStage::Fragment, fsModule, "main") .SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
.SetIndexFormat(nxt::IndexFormat::Uint32)
.SetInputState(inputState) .SetInputState(inputState)
.SetDepthStencilState(depthStencilState) .SetDepthStencilState(depthStencilState)
.GetResult(); .GetResult();
@ -286,7 +287,7 @@ void frame() {
.TransitionBufferUsage(cameraBuffer, nxt::BufferUsageBit::Uniform) .TransitionBufferUsage(cameraBuffer, nxt::BufferUsageBit::Uniform)
.SetBindGroup(0, bindGroup[0]) .SetBindGroup(0, bindGroup[0])
.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets) .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets)
.SetIndexBuffer(indexBuffer, 0, nxt::IndexFormat::Uint32) .SetIndexBuffer(indexBuffer, 0)
.DrawElements(36, 1, 0, 0) .DrawElements(36, 1, 0, 0)
.SetStencilReference(0x1) .SetStencilReference(0x1)

View File

@ -81,6 +81,7 @@ void init() {
.SetSubpass(renderpass, 0) .SetSubpass(renderpass, 0)
.SetStage(nxt::ShaderStage::Vertex, vsModule, "main") .SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
.SetStage(nxt::ShaderStage::Fragment, fsModule, "main") .SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
.SetIndexFormat(nxt::IndexFormat::Uint32)
.SetInputState(inputState) .SetInputState(inputState)
.GetResult(); .GetResult();
} }
@ -96,7 +97,7 @@ void frame() {
.BeginRenderSubpass() .BeginRenderSubpass()
.SetRenderPipeline(pipeline) .SetRenderPipeline(pipeline)
.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets) .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets)
.SetIndexBuffer(indexBuffer, 0, nxt::IndexFormat::Uint32) .SetIndexBuffer(indexBuffer, 0)
.DrawElements(3, 1, 0, 0) .DrawElements(3, 1, 0, 0)
.EndRenderSubpass() .EndRenderSubpass()
.EndRenderPass() .EndRenderPass()

View File

@ -129,6 +129,7 @@ void init() {
.SetLayout(pl) .SetLayout(pl)
.SetStage(nxt::ShaderStage::Vertex, vsModule, "main") .SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
.SetStage(nxt::ShaderStage::Fragment, fsModule, "main") .SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
.SetIndexFormat(nxt::IndexFormat::Uint32)
.SetInputState(inputState) .SetInputState(inputState)
.GetResult(); .GetResult();
@ -159,7 +160,7 @@ void frame() {
.SetRenderPipeline(pipeline) .SetRenderPipeline(pipeline)
.SetBindGroup(0, bindGroup) .SetBindGroup(0, bindGroup)
.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets) .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets)
.SetIndexBuffer(indexBuffer, 0, nxt::IndexFormat::Uint32) .SetIndexBuffer(indexBuffer, 0)
.DrawElements(3, 1, 0, 0) .DrawElements(3, 1, 0, 0)
.EndRenderSubpass() .EndRenderSubpass()
.EndRenderPass() .EndRenderPass()

View File

@ -295,6 +295,7 @@ namespace {
.SetLayout(pipelineLayout) .SetLayout(pipelineLayout)
.SetStage(nxt::ShaderStage::Vertex, oVSModule, "main") .SetStage(nxt::ShaderStage::Vertex, oVSModule, "main")
.SetStage(nxt::ShaderStage::Fragment, oFSModule, "main") .SetStage(nxt::ShaderStage::Fragment, oFSModule, "main")
.SetIndexFormat(nxt::IndexFormat::Uint16)
.SetInputState(inputState) .SetInputState(inputState)
.SetDepthStencilState(depthStencilState) .SetDepthStencilState(depthStencilState)
.GetResult(); .GetResult();
@ -544,7 +545,7 @@ namespace {
continue; continue;
} }
const auto& oIndicesBuffer = buffers.at(iIndices.bufferView); const auto& oIndicesBuffer = buffers.at(iIndices.bufferView);
cmd.SetIndexBuffer(oIndicesBuffer, static_cast<uint32_t>(iIndices.byteOffset), nxt::IndexFormat::Uint16); cmd.SetIndexBuffer(oIndicesBuffer, static_cast<uint32_t>(iIndices.byteOffset));
cmd.DrawElements(static_cast<uint32_t>(iIndices.count), 1, 0, 0); cmd.DrawElements(static_cast<uint32_t>(iIndices.count), 1, 0, 0);
} else { } else {
// DrawArrays // DrawArrays

View File

@ -457,8 +457,7 @@
"name": "set index buffer", "name": "set index buffer",
"args": [ "args": [
{"name": "buffer", "type": "buffer"}, {"name": "buffer", "type": "buffer"},
{"name": "offset", "type": "uint32_t"}, {"name": "offset", "type": "uint32_t"}
{"name": "format", "type": "index format"}
] ]
}, },
{ {
@ -939,6 +938,12 @@
{"name": "depth stencil state", "type": "depth stencil state"} {"name": "depth stencil state", "type": "depth stencil state"}
] ]
}, },
{
"name": "set index format",
"args": [
{"name": "format", "type": "index format"}
]
},
{ {
"name": "set input state", "name": "set input state",
"args": [ "args": [

View File

@ -820,14 +820,13 @@ namespace backend {
cmd->group = group; 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 // TODO(kainino@chromium.org): validation
SetIndexBufferCmd* cmd = allocator.Allocate<SetIndexBufferCmd>(Command::SetIndexBuffer); SetIndexBufferCmd* cmd = allocator.Allocate<SetIndexBufferCmd>(Command::SetIndexBuffer);
new(cmd) SetIndexBufferCmd; new(cmd) SetIndexBufferCmd;
cmd->buffer = buffer; cmd->buffer = buffer;
cmd->offset = offset; cmd->offset = offset;
cmd->format = format;
} }
void CommandBufferBuilder::SetVertexBuffers(uint32_t startSlot, uint32_t count, BufferBase* const* buffers, uint32_t const* offsets){ void CommandBufferBuilder::SetVertexBuffers(uint32_t startSlot, uint32_t count, BufferBase* const* buffers, uint32_t const* offsets){

View File

@ -83,7 +83,7 @@ namespace backend {
void SetStencilReference(uint32_t reference); void SetStencilReference(uint32_t reference);
void SetBlendColor(float r, float g, float b, float a); void SetBlendColor(float r, float g, float b, float a);
void SetBindGroup(uint32_t groupIndex, BindGroupBase* group); 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<typename T> template<typename T>
void SetVertexBuffers(uint32_t startSlot, uint32_t count, T* const* buffers, uint32_t const* offsets) { void SetVertexBuffers(uint32_t startSlot, uint32_t count, T* const* buffers, uint32_t const* offsets) {

View File

@ -152,7 +152,6 @@ namespace backend {
struct SetIndexBufferCmd { struct SetIndexBufferCmd {
Ref<BufferBase> buffer; Ref<BufferBase> buffer;
uint32_t offset; uint32_t offset;
nxt::IndexFormat format;
}; };
struct SetVertexBuffersCmd { struct SetVertexBuffersCmd {

View File

@ -28,6 +28,7 @@ namespace backend {
RenderPipelineBase::RenderPipelineBase(RenderPipelineBuilder* builder) RenderPipelineBase::RenderPipelineBase(RenderPipelineBuilder* builder)
: PipelineBase(builder), : PipelineBase(builder),
depthStencilState(std::move(builder->depthStencilState)), depthStencilState(std::move(builder->depthStencilState)),
indexFormat(builder->indexFormat),
inputState(std::move(builder->inputState)), inputState(std::move(builder->inputState)),
primitiveTopology(builder->primitiveTopology), primitiveTopology(builder->primitiveTopology),
blendStates(builder->blendStates), blendStates(builder->blendStates),
@ -55,6 +56,10 @@ namespace backend {
return depthStencilState.Get(); return depthStencilState.Get();
} }
nxt::IndexFormat RenderPipelineBase::GetIndexFormat() const {
return indexFormat;
}
InputStateBase* RenderPipelineBase::GetInputState() { InputStateBase* RenderPipelineBase::GetInputState() {
return inputState.Get(); return inputState.Get();
} }
@ -122,6 +127,10 @@ namespace backend {
this->depthStencilState = depthStencilState; this->depthStencilState = depthStencilState;
} }
void RenderPipelineBuilder::SetIndexFormat(nxt::IndexFormat format) {
this->indexFormat = format;
}
void RenderPipelineBuilder::SetInputState(InputStateBase* inputState) { void RenderPipelineBuilder::SetInputState(InputStateBase* inputState) {
this->inputState = inputState; this->inputState = inputState;
} }

View File

@ -30,6 +30,7 @@ namespace backend {
BlendStateBase* GetBlendState(uint32_t attachmentSlot); BlendStateBase* GetBlendState(uint32_t attachmentSlot);
DepthStencilStateBase* GetDepthStencilState(); DepthStencilStateBase* GetDepthStencilState();
nxt::IndexFormat GetIndexFormat() const;
InputStateBase* GetInputState(); InputStateBase* GetInputState();
nxt::PrimitiveTopology GetPrimitiveTopology() const; nxt::PrimitiveTopology GetPrimitiveTopology() const;
RenderPassBase* GetRenderPass(); RenderPassBase* GetRenderPass();
@ -37,6 +38,7 @@ namespace backend {
private: private:
Ref<DepthStencilStateBase> depthStencilState; Ref<DepthStencilStateBase> depthStencilState;
nxt::IndexFormat indexFormat;
Ref<InputStateBase> inputState; Ref<InputStateBase> inputState;
nxt::PrimitiveTopology primitiveTopology; nxt::PrimitiveTopology primitiveTopology;
std::array<Ref<BlendStateBase>, kMaxColorAttachments> blendStates; std::array<Ref<BlendStateBase>, kMaxColorAttachments> blendStates;
@ -52,6 +54,7 @@ namespace backend {
void SetColorAttachmentBlendState(uint32_t attachmentSlot, BlendStateBase* blendState); void SetColorAttachmentBlendState(uint32_t attachmentSlot, BlendStateBase* blendState);
void SetDepthStencilState(DepthStencilStateBase* depthStencilState); void SetDepthStencilState(DepthStencilStateBase* depthStencilState);
void SetPrimitiveTopology(nxt::PrimitiveTopology primitiveTopology); void SetPrimitiveTopology(nxt::PrimitiveTopology primitiveTopology);
void SetIndexFormat(nxt::IndexFormat format);
void SetInputState(InputStateBase* inputState); void SetInputState(InputStateBase* inputState);
void SetSubpass(RenderPassBase* renderPass, uint32_t subpass); void SetSubpass(RenderPassBase* renderPass, uint32_t subpass);
@ -64,6 +67,7 @@ namespace backend {
Ref<InputStateBase> inputState; Ref<InputStateBase> inputState;
// TODO(enga@google.com): Remove default when we validate that all required properties are set // TODO(enga@google.com): Remove default when we validate that all required properties are set
nxt::PrimitiveTopology primitiveTopology = nxt::PrimitiveTopology::TriangleList; nxt::PrimitiveTopology primitiveTopology = nxt::PrimitiveTopology::TriangleList;
nxt::IndexFormat indexFormat = nxt::IndexFormat::Uint32;
std::bitset<kMaxColorAttachments> blendStatesSet; std::bitset<kMaxColorAttachments> blendStatesSet;
std::array<Ref<BlendStateBase>, kMaxColorAttachments> blendStates; std::array<Ref<BlendStateBase>, kMaxColorAttachments> blendStates;
Ref<RenderPassBase> renderPass; Ref<RenderPassBase> renderPass;

View File

@ -560,7 +560,10 @@ namespace d3d12 {
D3D12_INDEX_BUFFER_VIEW bufferView; D3D12_INDEX_BUFFER_VIEW bufferView;
bufferView.BufferLocation = buffer->GetVA() + cmd->offset; bufferView.BufferLocation = buffer->GetVA() + cmd->offset;
bufferView.SizeInBytes = buffer->GetSize() - 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); commandList->IASetIndexBuffer(&bufferView);
} }

View File

@ -29,15 +29,6 @@ namespace backend {
namespace metal { namespace metal {
namespace { namespace {
MTLIndexType IndexFormatType(nxt::IndexFormat format) {
switch (format) {
case nxt::IndexFormat::Uint16:
return MTLIndexTypeUInt16;
case nxt::IndexFormat::Uint32:
return MTLIndexTypeUInt32;
}
}
struct CurrentEncoders { struct CurrentEncoders {
Device* device; Device* device;
@ -172,7 +163,6 @@ namespace metal {
RenderPipeline* lastRenderPipeline = nullptr; RenderPipeline* lastRenderPipeline = nullptr;
id<MTLBuffer> indexBuffer = nil; id<MTLBuffer> indexBuffer = nil;
uint32_t indexBufferOffset = 0; uint32_t indexBufferOffset = 0;
MTLIndexType indexType = MTLIndexTypeUInt32;
CurrentEncoders encoders; CurrentEncoders encoders;
encoders.device = device; encoders.device = device;
@ -333,7 +323,7 @@ namespace metal {
[encoders.render [encoders.render
drawIndexedPrimitives:lastRenderPipeline->GetMTLPrimitiveTopology() drawIndexedPrimitives:lastRenderPipeline->GetMTLPrimitiveTopology()
indexCount:draw->indexCount indexCount:draw->indexCount
indexType:indexType indexType:lastRenderPipeline->GetMTLIndexType()
indexBuffer:indexBuffer indexBuffer:indexBuffer
indexBufferOffset:indexBufferOffset indexBufferOffset:indexBufferOffset
instanceCount:draw->instanceCount instanceCount:draw->instanceCount
@ -564,7 +554,6 @@ namespace metal {
auto b = ToBackend(cmd->buffer.Get()); auto b = ToBackend(cmd->buffer.Get());
indexBuffer = b->GetMTLBuffer(); indexBuffer = b->GetMTLBuffer();
indexBufferOffset = cmd->offset; indexBufferOffset = cmd->offset;
indexType = IndexFormatType(cmd->format);
} }
break; break;

View File

@ -27,11 +27,13 @@ namespace metal {
RenderPipeline(RenderPipelineBuilder* builder); RenderPipeline(RenderPipelineBuilder* builder);
~RenderPipeline(); ~RenderPipeline();
MTLIndexType GetMTLIndexType() const;
MTLPrimitiveType GetMTLPrimitiveTopology() const; MTLPrimitiveType GetMTLPrimitiveTopology() const;
void Encode(id<MTLRenderCommandEncoder> encoder); void Encode(id<MTLRenderCommandEncoder> encoder);
private: private:
MTLIndexType mtlIndexType;
MTLPrimitiveType mtlPrimitiveTopology; MTLPrimitiveType mtlPrimitiveTopology;
id<MTLRenderPipelineState> mtlRenderPipelineState = nil; id<MTLRenderPipelineState> mtlRenderPipelineState = nil;
}; };

View File

@ -53,10 +53,21 @@ namespace metal {
return MTLPrimitiveTopologyClassTriangle; 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) RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
: RenderPipelineBase(builder), mtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) { : RenderPipelineBase(builder),
mtlIndexType(MTLIndexFormat(GetIndexFormat())),
mtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) {
auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice(); auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice();
@ -121,6 +132,10 @@ namespace metal {
[mtlRenderPipelineState release]; [mtlRenderPipelineState release];
} }
MTLIndexType RenderPipeline::GetMTLIndexType() const {
return mtlIndexType;
}
MTLPrimitiveType RenderPipeline::GetMTLPrimitiveTopology() const { MTLPrimitiveType RenderPipeline::GetMTLPrimitiveTopology() const {
return mtlPrimitiveTopology; return mtlPrimitiveTopology;
} }

View File

@ -129,7 +129,6 @@ namespace opengl {
PipelineGL* lastGLPipeline = nullptr; PipelineGL* lastGLPipeline = nullptr;
RenderPipeline* lastRenderPipeline = nullptr; RenderPipeline* lastRenderPipeline = nullptr;
uint32_t indexBufferOffset = 0; uint32_t indexBufferOffset = 0;
nxt::IndexFormat indexBufferFormat = nxt::IndexFormat::Uint16;
PersistentPipelineState persistentPipelineState; PersistentPipelineState persistentPipelineState;
persistentPipelineState.SetDefaultState(); persistentPipelineState.SetDefaultState();
@ -380,8 +379,9 @@ namespace opengl {
DrawElementsCmd* draw = commands.NextCommand<DrawElementsCmd>(); DrawElementsCmd* draw = commands.NextCommand<DrawElementsCmd>();
pushConstants.Apply(lastPipeline, lastGLPipeline); pushConstants.Apply(lastPipeline, lastGLPipeline);
size_t formatSize = IndexFormatSize(indexBufferFormat); nxt::IndexFormat indexFormat = lastRenderPipeline->GetIndexFormat();
GLenum formatType = IndexFormatType(indexBufferFormat); size_t formatSize = IndexFormatSize(indexFormat);
GLenum formatType = IndexFormatType(indexFormat);
if (draw->firstInstance > 0) { if (draw->firstInstance > 0) {
glDrawElementsInstancedBaseInstance(lastRenderPipeline->GetGLPrimitiveTopology(), glDrawElementsInstancedBaseInstance(lastRenderPipeline->GetGLPrimitiveTopology(),
@ -530,7 +530,6 @@ namespace opengl {
GLuint buffer = ToBackend(cmd->buffer.Get())->GetHandle(); GLuint buffer = ToBackend(cmd->buffer.Get())->GetHandle();
indexBufferOffset = cmd->offset; indexBufferOffset = cmd->offset;
indexBufferFormat = cmd->format;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
} }
break; break;