Implement 'baseVertex' in drawIndexed() on D3D12, Metal and Vulkan
This patch adds the support of the parameter 'baseVertex' of drawIndexed on D3D12, Metal and Vulkan back-ends. BUG=dawn:51 TEST=dawn_end2end_tests Change-Id: Ibd25884ad2abceaaed744d74c4ee6b0ae6b3fa1b Reviewed-on: https://dawn-review.googlesource.com/c/3221 Commit-Queue: Jiawei Shao <jiawei.shao@intel.com> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
8d08d23a66
commit
ff9562f792
2
BUILD.gn
2
BUILD.gn
|
@ -884,7 +884,7 @@ test("dawn_end2end_tests") {
|
||||||
"src/tests/end2end/ComputeCopyStorageBufferTests.cpp",
|
"src/tests/end2end/ComputeCopyStorageBufferTests.cpp",
|
||||||
"src/tests/end2end/CopyTests.cpp",
|
"src/tests/end2end/CopyTests.cpp",
|
||||||
"src/tests/end2end/DepthStencilStateTests.cpp",
|
"src/tests/end2end/DepthStencilStateTests.cpp",
|
||||||
"src/tests/end2end/DrawElementsTests.cpp",
|
"src/tests/end2end/DrawIndexedTests.cpp",
|
||||||
"src/tests/end2end/FenceTests.cpp",
|
"src/tests/end2end/FenceTests.cpp",
|
||||||
"src/tests/end2end/IndexFormatTests.cpp",
|
"src/tests/end2end/IndexFormatTests.cpp",
|
||||||
"src/tests/end2end/InputStateTests.cpp",
|
"src/tests/end2end/InputStateTests.cpp",
|
||||||
|
|
|
@ -839,6 +839,7 @@
|
||||||
{"name": "index count", "type": "uint32_t"},
|
{"name": "index count", "type": "uint32_t"},
|
||||||
{"name": "instance count", "type": "uint32_t"},
|
{"name": "instance count", "type": "uint32_t"},
|
||||||
{"name": "first index", "type": "uint32_t"},
|
{"name": "first index", "type": "uint32_t"},
|
||||||
|
{"name": "base vertex", "type": "uint32_t"},
|
||||||
{"name": "first instance", "type": "uint32_t"}
|
{"name": "first instance", "type": "uint32_t"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -164,7 +164,7 @@ void frame() {
|
||||||
pass.SetBindGroup(0, bindGroup);
|
pass.SetBindGroup(0, bindGroup);
|
||||||
pass.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets);
|
pass.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets);
|
||||||
pass.SetIndexBuffer(indexBuffer, 0);
|
pass.SetIndexBuffer(indexBuffer, 0);
|
||||||
pass.DrawIndexed(3, 1, 0, 0);
|
pass.DrawIndexed(3, 1, 0, 0, 0);
|
||||||
pass.EndPass();
|
pass.EndPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -278,18 +278,18 @@ void frame() {
|
||||||
pass.SetBindGroup(0, bindGroup[0]);
|
pass.SetBindGroup(0, bindGroup[0]);
|
||||||
pass.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets);
|
pass.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets);
|
||||||
pass.SetIndexBuffer(indexBuffer, 0);
|
pass.SetIndexBuffer(indexBuffer, 0);
|
||||||
pass.DrawIndexed(36, 1, 0, 0);
|
pass.DrawIndexed(36, 1, 0, 0, 0);
|
||||||
|
|
||||||
pass.SetStencilReference(0x1);
|
pass.SetStencilReference(0x1);
|
||||||
pass.SetRenderPipeline(planePipeline);
|
pass.SetRenderPipeline(planePipeline);
|
||||||
pass.SetBindGroup(0, bindGroup[0]);
|
pass.SetBindGroup(0, bindGroup[0]);
|
||||||
pass.SetVertexBuffers(0, 1, &planeBuffer, vertexBufferOffsets);
|
pass.SetVertexBuffers(0, 1, &planeBuffer, vertexBufferOffsets);
|
||||||
pass.DrawIndexed(6, 1, 0, 0);
|
pass.DrawIndexed(6, 1, 0, 0, 0);
|
||||||
|
|
||||||
pass.SetRenderPipeline(reflectionPipeline);
|
pass.SetRenderPipeline(reflectionPipeline);
|
||||||
pass.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets);
|
pass.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets);
|
||||||
pass.SetBindGroup(0, bindGroup[1]);
|
pass.SetBindGroup(0, bindGroup[1]);
|
||||||
pass.DrawIndexed(36, 1, 0, 0);
|
pass.DrawIndexed(36, 1, 0, 0, 0);
|
||||||
|
|
||||||
pass.EndPass();
|
pass.EndPass();
|
||||||
}
|
}
|
||||||
|
|
|
@ -537,7 +537,7 @@ namespace {
|
||||||
}
|
}
|
||||||
const auto& oIndicesBuffer = buffers.at(iIndices.bufferView);
|
const auto& oIndicesBuffer = buffers.at(iIndices.bufferView);
|
||||||
pass.SetIndexBuffer(oIndicesBuffer, static_cast<uint32_t>(iIndices.byteOffset));
|
pass.SetIndexBuffer(oIndicesBuffer, static_cast<uint32_t>(iIndices.byteOffset));
|
||||||
pass.DrawIndexed(static_cast<uint32_t>(iIndices.count), 1, 0, 0);
|
pass.DrawIndexed(static_cast<uint32_t>(iIndices.count), 1, 0, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
// DrawArrays
|
// DrawArrays
|
||||||
pass.Draw(vertexCount, 1, 0, 0);
|
pass.Draw(vertexCount, 1, 0, 0);
|
||||||
|
|
|
@ -103,6 +103,7 @@ namespace dawn_native {
|
||||||
uint32_t indexCount;
|
uint32_t indexCount;
|
||||||
uint32_t instanceCount;
|
uint32_t instanceCount;
|
||||||
uint32_t firstIndex;
|
uint32_t firstIndex;
|
||||||
|
uint32_t baseVertex;
|
||||||
uint32_t firstInstance;
|
uint32_t firstInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace dawn_native {
|
||||||
void RenderPassEncoderBase::DrawIndexed(uint32_t indexCount,
|
void RenderPassEncoderBase::DrawIndexed(uint32_t indexCount,
|
||||||
uint32_t instanceCount,
|
uint32_t instanceCount,
|
||||||
uint32_t firstIndex,
|
uint32_t firstIndex,
|
||||||
|
uint32_t baseVertex,
|
||||||
uint32_t firstInstance) {
|
uint32_t firstInstance) {
|
||||||
if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) {
|
if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) {
|
||||||
return;
|
return;
|
||||||
|
@ -58,6 +59,7 @@ namespace dawn_native {
|
||||||
draw->indexCount = indexCount;
|
draw->indexCount = indexCount;
|
||||||
draw->instanceCount = instanceCount;
|
draw->instanceCount = instanceCount;
|
||||||
draw->firstIndex = firstIndex;
|
draw->firstIndex = firstIndex;
|
||||||
|
draw->baseVertex = baseVertex;
|
||||||
draw->firstInstance = firstInstance;
|
draw->firstInstance = firstInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ namespace dawn_native {
|
||||||
void DrawIndexed(uint32_t vertexCount,
|
void DrawIndexed(uint32_t vertexCount,
|
||||||
uint32_t instanceCount,
|
uint32_t instanceCount,
|
||||||
uint32_t firstIndex,
|
uint32_t firstIndex,
|
||||||
|
uint32_t baseVertex,
|
||||||
uint32_t firstInstance);
|
uint32_t firstInstance);
|
||||||
|
|
||||||
void SetRenderPipeline(RenderPipelineBase* pipeline);
|
void SetRenderPipeline(RenderPipelineBase* pipeline);
|
||||||
|
|
|
@ -550,7 +550,8 @@ namespace dawn_native { namespace d3d12 {
|
||||||
case Command::DrawIndexed: {
|
case Command::DrawIndexed: {
|
||||||
DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
|
DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
|
||||||
commandList->DrawIndexedInstanced(draw->indexCount, draw->instanceCount,
|
commandList->DrawIndexedInstanced(draw->indexCount, draw->instanceCount,
|
||||||
draw->firstIndex, 0, draw->firstInstance);
|
draw->firstIndex, draw->baseVertex,
|
||||||
|
draw->firstInstance);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetRenderPipeline: {
|
case Command::SetRenderPipeline: {
|
||||||
|
|
|
@ -424,7 +424,7 @@ namespace dawn_native { namespace metal {
|
||||||
indexBuffer:indexBuffer
|
indexBuffer:indexBuffer
|
||||||
indexBufferOffset:indexBufferBaseOffset + draw->firstIndex * formatSize
|
indexBufferOffset:indexBufferBaseOffset + draw->firstIndex * formatSize
|
||||||
instanceCount:draw->instanceCount
|
instanceCount:draw->instanceCount
|
||||||
baseVertex:0
|
baseVertex:draw->baseVertex
|
||||||
baseInstance:draw->firstInstance];
|
baseInstance:draw->firstInstance];
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
|
@ -332,9 +332,9 @@ namespace dawn_native { namespace vulkan {
|
||||||
DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
|
DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
|
||||||
|
|
||||||
descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||||
uint32_t vertexOffset = 0;
|
|
||||||
device->fn.CmdDrawIndexed(commands, draw->indexCount, draw->instanceCount,
|
device->fn.CmdDrawIndexed(commands, draw->indexCount, draw->instanceCount,
|
||||||
draw->firstIndex, vertexOffset, draw->firstInstance);
|
draw->firstIndex, draw->baseVertex,
|
||||||
|
draw->firstInstance);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetBindGroup: {
|
case Command::SetBindGroup: {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
constexpr uint32_t kRTSize = 4;
|
constexpr uint32_t kRTSize = 4;
|
||||||
|
|
||||||
class DrawElementsTest : public DawnTest {
|
class DrawIndexedTest : public DawnTest {
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
DawnTest::SetUp();
|
DawnTest::SetUp();
|
||||||
|
@ -59,10 +59,17 @@ class DrawElementsTest : public DawnTest {
|
||||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
||||||
vertexBuffer = utils::CreateBufferFromData<float>(device, dawn::BufferUsageBit::Vertex, {
|
vertexBuffer = utils::CreateBufferFromData<float>(device, dawn::BufferUsageBit::Vertex, {
|
||||||
|
// First quad: the first 3 vertices represent the bottom left triangle
|
||||||
-1.0f, -1.0f, 0.0f, 1.0f,
|
-1.0f, -1.0f, 0.0f, 1.0f,
|
||||||
1.0f, 1.0f, 0.0f, 1.0f,
|
1.0f, 1.0f, 0.0f, 1.0f,
|
||||||
-1.0f, 1.0f, 0.0f, 1.0f,
|
-1.0f, 1.0f, 0.0f, 1.0f,
|
||||||
1.0f, -1.0f, 0.0f, 1.0f
|
1.0f, -1.0f, 0.0f, 1.0f,
|
||||||
|
|
||||||
|
// Second quad: the first 3 vertices represent the top right triangle
|
||||||
|
-1.0f, -1.0f, 0.0f, 1.0f,
|
||||||
|
1.0f, 1.0f, 0.0f, 1.0f,
|
||||||
|
1.0f, -1.0f, 0.0f, 1.0f,
|
||||||
|
-1.0f, 1.0f, 0.0f, 1.0f
|
||||||
});
|
});
|
||||||
indexBuffer = utils::CreateBufferFromData<uint32_t>(device, dawn::BufferUsageBit::Index, {
|
indexBuffer = utils::CreateBufferFromData<uint32_t>(device, dawn::BufferUsageBit::Index, {
|
||||||
0, 1, 2, 0, 3, 1
|
0, 1, 2, 0, 3, 1
|
||||||
|
@ -75,7 +82,8 @@ class DrawElementsTest : public DawnTest {
|
||||||
dawn::Buffer indexBuffer;
|
dawn::Buffer indexBuffer;
|
||||||
|
|
||||||
void Test(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex,
|
void Test(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex,
|
||||||
uint32_t firstInstance, RGBA8 bottomLeftExpected, RGBA8 topRightExpected) {
|
uint32_t baseVertex, uint32_t firstInstance, RGBA8 bottomLeftExpected,
|
||||||
|
RGBA8 topRightExpected) {
|
||||||
uint32_t zeroOffset = 0;
|
uint32_t zeroOffset = 0;
|
||||||
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||||
{
|
{
|
||||||
|
@ -83,7 +91,7 @@ class DrawElementsTest : public DawnTest {
|
||||||
pass.SetRenderPipeline(pipeline);
|
pass.SetRenderPipeline(pipeline);
|
||||||
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
||||||
pass.SetIndexBuffer(indexBuffer, 0);
|
pass.SetIndexBuffer(indexBuffer, 0);
|
||||||
pass.DrawIndexed(indexCount, instanceCount, firstIndex, firstInstance);
|
pass.DrawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance);
|
||||||
pass.EndPass();
|
pass.EndPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,20 +103,34 @@ class DrawElementsTest : public DawnTest {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// The most basic DrawElements triangle draw.
|
// The most basic DrawIndexed triangle draw.
|
||||||
TEST_P(DrawElementsTest, Uint32) {
|
TEST_P(DrawIndexedTest, Uint32) {
|
||||||
|
|
||||||
RGBA8 filled(0, 255, 0, 255);
|
RGBA8 filled(0, 255, 0, 255);
|
||||||
RGBA8 notFilled(0, 0, 0, 0);
|
RGBA8 notFilled(0, 0, 0, 0);
|
||||||
|
|
||||||
// Test a draw with no indices.
|
// Test a draw with no indices.
|
||||||
Test(0, 0, 0, 0, notFilled, notFilled);
|
Test(0, 0, 0, 0, 0, notFilled, notFilled);
|
||||||
// Test a draw with only the first 3 indices (bottom left triangle)
|
// Test a draw with only the first 3 indices of the first quad (bottom left triangle)
|
||||||
Test(3, 1, 0, 0, filled, notFilled);
|
Test(3, 1, 0, 0, 0, filled, notFilled);
|
||||||
// Test a draw with only the last 3 indices (top right triangle)
|
// Test a draw with only the last 3 indices of the first quad (top right triangle)
|
||||||
Test(3, 1, 3, 0, notFilled, filled);
|
Test(3, 1, 3, 0, 0, notFilled, filled);
|
||||||
// Test a draw with all 6 indices (both triangles).
|
// Test a draw with all 6 indices (both triangles).
|
||||||
Test(6, 1, 0, 0, filled, filled);
|
Test(6, 1, 0, 0, 0, filled, filled);
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(DrawElementsTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend)
|
// Test the parameter 'baseVertex' of DrawIndexed() works.
|
||||||
|
TEST_P(DrawIndexedTest, BaseVertex) {
|
||||||
|
// TODO(jiawei.shao@intel.com): enable 'baseVertex' on OpenGL back-ends
|
||||||
|
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||||
|
|
||||||
|
RGBA8 filled(0, 255, 0, 255);
|
||||||
|
RGBA8 notFilled(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// Test a draw with only the first 3 indices of the second quad (top right triangle)
|
||||||
|
Test(3, 1, 0, 4, 0, notFilled, filled);
|
||||||
|
// Test a draw with only the last 3 indices of the second quad (bottom left triangle)
|
||||||
|
Test(3, 1, 3, 4, 0, filled, notFilled);
|
||||||
|
}
|
||||||
|
|
||||||
|
DAWN_INSTANTIATE_TEST(DrawIndexedTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend)
|
|
@ -87,7 +87,7 @@ TEST_P(IndexFormatTest, Uint32) {
|
||||||
pass.SetRenderPipeline(pipeline);
|
pass.SetRenderPipeline(pipeline);
|
||||||
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
||||||
pass.SetIndexBuffer(indexBuffer, 0);
|
pass.SetIndexBuffer(indexBuffer, 0);
|
||||||
pass.DrawIndexed(3, 1, 0, 0);
|
pass.DrawIndexed(3, 1, 0, 0, 0);
|
||||||
pass.EndPass();
|
pass.EndPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ TEST_P(IndexFormatTest, Uint16) {
|
||||||
pass.SetRenderPipeline(pipeline);
|
pass.SetRenderPipeline(pipeline);
|
||||||
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
||||||
pass.SetIndexBuffer(indexBuffer, 0);
|
pass.SetIndexBuffer(indexBuffer, 0);
|
||||||
pass.DrawIndexed(3, 1, 0, 0);
|
pass.DrawIndexed(3, 1, 0, 0, 0);
|
||||||
pass.EndPass();
|
pass.EndPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ TEST_P(IndexFormatTest, Uint32PrimitiveRestart) {
|
||||||
pass.SetRenderPipeline(pipeline);
|
pass.SetRenderPipeline(pipeline);
|
||||||
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
||||||
pass.SetIndexBuffer(indexBuffer, 0);
|
pass.SetIndexBuffer(indexBuffer, 0);
|
||||||
pass.DrawIndexed(7, 1, 0, 0);
|
pass.DrawIndexed(7, 1, 0, 0, 0);
|
||||||
pass.EndPass();
|
pass.EndPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ TEST_P(IndexFormatTest, Uint16PrimitiveRestart) {
|
||||||
pass.SetRenderPipeline(pipeline);
|
pass.SetRenderPipeline(pipeline);
|
||||||
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
||||||
pass.SetIndexBuffer(indexBuffer, 0);
|
pass.SetIndexBuffer(indexBuffer, 0);
|
||||||
pass.DrawIndexed(7, 1, 0, 0);
|
pass.DrawIndexed(7, 1, 0, 0, 0);
|
||||||
pass.EndPass();
|
pass.EndPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ TEST_P(IndexFormatTest, ChangePipelineAfterSetIndexBuffer) {
|
||||||
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
||||||
pass.SetIndexBuffer(indexBuffer, 0);
|
pass.SetIndexBuffer(indexBuffer, 0);
|
||||||
pass.SetRenderPipeline(pipeline32);
|
pass.SetRenderPipeline(pipeline32);
|
||||||
pass.DrawIndexed(3, 1, 0, 0);
|
pass.DrawIndexed(3, 1, 0, 0, 0);
|
||||||
pass.EndPass();
|
pass.EndPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ TEST_P(IndexFormatTest, DISABLED_SetIndexBufferBeforeSetPipeline) {
|
||||||
pass.SetIndexBuffer(indexBuffer, 0);
|
pass.SetIndexBuffer(indexBuffer, 0);
|
||||||
pass.SetRenderPipeline(pipeline);
|
pass.SetRenderPipeline(pipeline);
|
||||||
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
|
||||||
pass.DrawIndexed(3, 1, 0, 0);
|
pass.DrawIndexed(3, 1, 0, 0, 0);
|
||||||
pass.EndPass();
|
pass.EndPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue