Enable IndexFormatTests on Vulkan

This adds translation of the index format in the Vulkan backend. A test
is also added for an issue currently present in the Vulkan backend.
This commit is contained in:
Corentin Wallez 2018-02-06 19:21:16 -05:00 committed by Corentin Wallez
parent cf0ac7570d
commit abcf982e09
2 changed files with 55 additions and 4 deletions

View File

@ -28,6 +28,17 @@ namespace backend { namespace vulkan {
namespace {
VkIndexType VulkanIndexType(nxt::IndexFormat format) {
switch (format) {
case nxt::IndexFormat::Uint16:
return VK_INDEX_TYPE_UINT16;
case nxt::IndexFormat::Uint32:
return VK_INDEX_TYPE_UINT32;
default:
UNREACHABLE();
}
}
VkBufferImageCopy ComputeBufferImageCopyRegion(uint32_t rowPitch,
const BufferCopyLocation& bufferLocation,
const TextureCopyLocation& textureLocation) {
@ -255,9 +266,10 @@ namespace backend { namespace vulkan {
// TODO(cwallez@chromium.org): get the index type from the last render pipeline
// and rebind if needed on pipeline change
device->fn.CmdBindIndexBuffer(commands, indexBuffer,
static_cast<VkDeviceSize>(cmd->offset),
VK_INDEX_TYPE_UINT16);
ASSERT(lastRenderPipeline != nullptr);
VkIndexType indexType = VulkanIndexType(lastRenderPipeline->GetIndexFormat());
device->fn.CmdBindIndexBuffer(
commands, indexBuffer, static_cast<VkDeviceSize>(cmd->offset), indexType);
} break;
case Command::SetRenderPipeline: {

View File

@ -235,6 +235,11 @@ TEST_P(IndexFormatTest, Uint16PrimitiveRestart) {
// prevent a case in D3D12 where the index format would be captured from the last
// pipeline on SetIndexBuffer.
TEST_P(IndexFormatTest, ChangePipelineAfterSetIndexBuffer) {
if (IsD3D12() || IsVulkan()) {
std::cout << "Test skipped on D3D12 and Vulkan" << std::endl;
return;
}
nxt::RenderPipeline pipeline32 = MakeTestPipeline(nxt::IndexFormat::Uint32);
nxt::RenderPipeline pipeline16 = MakeTestPipeline(nxt::IndexFormat::Uint16);
@ -267,4 +272,38 @@ TEST_P(IndexFormatTest, ChangePipelineAfterSetIndexBuffer) {
EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderTarget, 100, 300);
}
NXT_INSTANTIATE_TEST(IndexFormatTest, MetalBackend, OpenGLBackend)
// Test that setting the index buffer before the pipeline works, this is important
// for backends where the index format is passed inside the call to SetIndexBuffer
// because it needs to be done lazily (to query the format from the last pipeline).
// TODO(cwallez@chromium.org): This is currently disallowed by the validation but
// we want to support eventually.
TEST_P(IndexFormatTest, DISABLED_SetIndexBufferBeforeSetPipeline) {
nxt::RenderPipeline pipeline = MakeTestPipeline(nxt::IndexFormat::Uint32);
nxt::Buffer vertexBuffer = utils::CreateFrozenBufferFromData<float>(device, nxt::BufferUsageBit::Vertex, {
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 1.0f
});
nxt::Buffer indexBuffer = utils::CreateFrozenBufferFromData<uint32_t>(device, nxt::BufferUsageBit::Index, {
0, 1, 2
});
uint32_t zeroOffset = 0;
nxt::CommandBuffer commands = device.CreateCommandBufferBuilder()
.BeginRenderPass(renderpass, framebuffer)
.BeginRenderSubpass()
.SetIndexBuffer(indexBuffer, 0)
.SetRenderPipeline(pipeline)
.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset)
.DrawElements(3, 1, 0, 0)
.EndRenderSubpass()
.EndRenderPass()
.GetResult();
queue.Submit(1, &commands);
EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderTarget, 100, 300);
}
NXT_INSTANTIATE_TEST(IndexFormatTest, MetalBackend, OpenGLBackend, VulkanBackend)