Implement primitive topology in OpenGL, Metal, and D3D12 backends

This commit is contained in:
Austin Eng 2017-07-24 14:40:06 -04:00 committed by Austin Eng
parent 3e9e315636
commit d81fd82bde
9 changed files with 88 additions and 11 deletions

View File

@ -399,7 +399,6 @@ namespace d3d12 {
{
DrawArraysCmd* draw = commands.NextCommand<DrawArraysCmd>();
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
commandList->DrawInstanced(
draw->vertexCount,
draw->instanceCount,
@ -413,7 +412,6 @@ namespace d3d12 {
{
DrawElementsCmd* draw = commands.NextCommand<DrawElementsCmd>();
commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
commandList->DrawIndexedInstanced(
draw->indexCount,
draw->instanceCount,
@ -464,6 +462,7 @@ namespace d3d12 {
commandList->SetGraphicsRootSignature(layout->GetRootSignature().Get());
commandList->SetPipelineState(pipeline->GetPipelineState().Get());
commandList->IASetPrimitiveTopology(pipeline->GetD3D12PrimitiveTopology());
bindingTracker.SetInheritedBindGroups(commandList, lastLayout, layout);

View File

@ -25,8 +25,27 @@
namespace backend {
namespace d3d12 {
namespace {
D3D12_PRIMITIVE_TOPOLOGY D3D12PrimitiveTopology(nxt::PrimitiveTopology primitiveTopology) {
switch (primitiveTopology) {
case nxt::PrimitiveTopology::Point:
return D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
case nxt::PrimitiveTopology::Line:
return D3D_PRIMITIVE_TOPOLOGY_LINELIST;
case nxt::PrimitiveTopology::LineStrip:
return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
case nxt::PrimitiveTopology::Triangle:
return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
case nxt::PrimitiveTopology::TriangleStrip:
return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
default:
UNREACHABLE();
}
}
}
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
: RenderPipelineBase(builder) {
: RenderPipelineBase(builder), d3d12PrimitiveTopology(D3D12PrimitiveTopology(GetPrimitiveTopology())) {
uint32_t compileFlags = 0;
#if defined(_DEBUG)
// Enable better shader debugging with the graphics debugging tools.
@ -132,6 +151,10 @@ namespace d3d12 {
ASSERT_SUCCESS(device->GetD3D12Device()->CreateGraphicsPipelineState(&descriptor, IID_PPV_ARGS(&pipelineState)));
}
D3D12_PRIMITIVE_TOPOLOGY RenderPipeline::GetD3D12PrimitiveTopology() const {
return d3d12PrimitiveTopology;
}
ComPtr<ID3D12PipelineState> RenderPipeline::GetPipelineState() {
return pipelineState;
}

View File

@ -26,9 +26,11 @@ namespace d3d12 {
public:
RenderPipeline(RenderPipelineBuilder* builder);
D3D12_PRIMITIVE_TOPOLOGY GetD3D12PrimitiveTopology() const;
ComPtr<ID3D12PipelineState> GetPipelineState();
private:
D3D12_PRIMITIVE_TOPOLOGY d3d12PrimitiveTopology;
ComPtr<ID3D12PipelineState> pipelineState;
};

View File

@ -279,7 +279,7 @@ namespace metal {
ASSERT(encoders.render);
[encoders.render
drawPrimitives:MTLPrimitiveTypeTriangle
drawPrimitives:lastRenderPipeline->GetMTLPrimitiveTopology()
vertexStart:draw->firstVertex
vertexCount:draw->vertexCount
instanceCount:draw->instanceCount
@ -293,7 +293,7 @@ namespace metal {
ASSERT(encoders.render);
[encoders.render
drawIndexedPrimitives:MTLPrimitiveTypeTriangle
drawIndexedPrimitives:lastRenderPipeline->GetMTLPrimitiveTopology()
indexCount:draw->indexCount
indexType:indexType
indexBuffer:indexBuffer

View File

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

View File

@ -23,8 +23,25 @@
namespace backend {
namespace metal {
namespace {
MTLPrimitiveType MTLPrimitiveTopology(nxt::PrimitiveTopology primitiveTopology) {
switch (primitiveTopology) {
case nxt::PrimitiveTopology::Point:
return MTLPrimitiveTypePoint;
case nxt::PrimitiveTopology::Line:
return MTLPrimitiveTypeLine;
case nxt::PrimitiveTopology::LineStrip:
return MTLPrimitiveTypeLineStrip;
case nxt::PrimitiveTopology::Triangle:
return MTLPrimitiveTypeTriangle;
case nxt::PrimitiveTopology::TriangleStrip:
return MTLPrimitiveTypeTriangleStrip;
}
}
}
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
: RenderPipelineBase(builder) {
: RenderPipelineBase(builder), mtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) {
auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice();
@ -73,6 +90,10 @@ namespace metal {
[mtlRenderPipelineState release];
}
MTLPrimitiveType RenderPipeline::GetMTLPrimitiveTopology() const {
return mtlPrimitiveTopology;
}
void RenderPipeline::Encode(id<MTLRenderCommandEncoder> encoder) {
[encoder setRenderPipelineState:mtlRenderPipelineState];
}

View File

@ -236,11 +236,11 @@ namespace opengl {
{
DrawArraysCmd* draw = commands.NextCommand<DrawArraysCmd>();
if (draw->firstInstance > 0) {
glDrawArraysInstancedBaseInstance(GL_TRIANGLES,
glDrawArraysInstancedBaseInstance(lastRenderPipeline->GetGLPrimitiveTopology(),
draw->firstVertex, draw->vertexCount, draw->instanceCount, draw->firstInstance);
} else {
// This branch is only needed on OpenGL < 4.2
glDrawArraysInstanced(GL_TRIANGLES,
glDrawArraysInstanced(lastRenderPipeline->GetGLPrimitiveTopology(),
draw->firstVertex, draw->vertexCount, draw->instanceCount);
}
}
@ -253,13 +253,13 @@ namespace opengl {
GLenum formatType = IndexFormatType(indexBufferFormat);
if (draw->firstInstance > 0) {
glDrawElementsInstancedBaseInstance(GL_TRIANGLES,
glDrawElementsInstancedBaseInstance(lastRenderPipeline->GetGLPrimitiveTopology(),
draw->indexCount, formatType,
reinterpret_cast<void*>(draw->firstIndex * formatSize + indexBufferOffset),
draw->instanceCount, draw->firstInstance);
} else {
// This branch is only needed on OpenGL < 4.2
glDrawElementsInstanced(GL_TRIANGLES,
glDrawElementsInstanced(lastRenderPipeline->GetGLPrimitiveTopology(),
draw->indexCount, formatType,
reinterpret_cast<void*>(draw->firstIndex * formatSize + indexBufferOffset),
draw->instanceCount);

View File

@ -21,8 +21,32 @@
namespace backend {
namespace opengl {
namespace {
GLenum GLPrimitiveTopology(nxt::PrimitiveTopology primitiveTopology) {
switch (primitiveTopology) {
case nxt::PrimitiveTopology::Point:
return GL_POINTS;
case nxt::PrimitiveTopology::Line:
return GL_LINES;
case nxt::PrimitiveTopology::LineStrip:
return GL_LINE_STRIP;
case nxt::PrimitiveTopology::Triangle:
return GL_TRIANGLES;
case nxt::PrimitiveTopology::TriangleStrip:
return GL_TRIANGLE_STRIP;
default:
UNREACHABLE();
}
}
}
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
: RenderPipelineBase(builder), PipelineGL(this, builder) {
: RenderPipelineBase(builder), PipelineGL(this, builder),
glPrimitiveTopology(GLPrimitiveTopology(GetPrimitiveTopology())) {
}
GLenum RenderPipeline::GetGLPrimitiveTopology() const {
return glPrimitiveTopology;
}
void RenderPipeline::ApplyNow(PersistentPipelineState &persistentPipelineState) {

View File

@ -32,7 +32,12 @@ namespace opengl {
public:
RenderPipeline(RenderPipelineBuilder* builder);
GLenum GetGLPrimitiveTopology() const;
void ApplyNow(PersistentPipelineState &persistentPipelineState);
private:
GLenum glPrimitiveTopology;
};
}