From 4bf92a66c5cafa8c6d5dc1477322e27a8f016b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 15 May 2020 18:07:07 +0200 Subject: [PATCH] Thin3D: use 16-bit indices. Fixes #12898. --- GPU/Common/PresentationCommon.cpp | 6 ++++-- ext/native/thin3d/thin3d.h | 3 +-- ext/native/thin3d/thin3d_d3d11.cpp | 4 ++-- ext/native/thin3d/thin3d_d3d9.cpp | 2 +- ext/native/thin3d/thin3d_gl.cpp | 2 +- ext/native/thin3d/thin3d_vulkan.cpp | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index c107c5681566..1bd7ec843721 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "base/display.h" #include "base/timeutil.h" #include "file/vfs.h" @@ -318,7 +319,7 @@ void PresentationCommon::CreateDeviceObjects() { vdata_ = draw_->CreateBuffer(sizeof(Vertex) * 8, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA); // TODO: Use 4 and a strip? shorts? - idata_ = draw_->CreateBuffer(sizeof(int) * 6, BufferUsageFlag::DYNAMIC | BufferUsageFlag::INDEXDATA); + idata_ = draw_->CreateBuffer(sizeof(uint16_t) * 6, BufferUsageFlag::DYNAMIC | BufferUsageFlag::INDEXDATA); samplerNearest_ = draw_->CreateSamplerState({ TextureFilter::NEAREST, TextureFilter::NEAREST, TextureFilter::NEAREST, 0.0f, TextureAddressMode::CLAMP_TO_EDGE, TextureAddressMode::CLAMP_TO_EDGE, TextureAddressMode::CLAMP_TO_EDGE }); samplerLinear_ = draw_->CreateSamplerState({ TextureFilter::LINEAR, TextureFilter::LINEAR, TextureFilter::LINEAR, 0.0f, TextureAddressMode::CLAMP_TO_EDGE, TextureAddressMode::CLAMP_TO_EDGE, TextureAddressMode::CLAMP_TO_EDGE }); @@ -437,7 +438,8 @@ void PresentationCommon::CopyToOutput(OutputFlags flags, int uvRotation, float u // Make sure Direct3D 11 clears state, since we set shaders outside Draw. draw_->BindPipeline(nullptr); - int indexes[] = { 0, 1, 2, 0, 2, 3 }; + // Wouldn't it be enough to do this only when creating the index buffer? + uint16_t indexes[] = { 0, 1, 2, 0, 2, 3 }; draw_->UpdateBuffer(idata_, (const uint8_t *)indexes, 0, sizeof(indexes), Draw::UPDATE_DISCARD); // TODO: If shader objects have been created by now, we might have received errors. diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 4aa42c63370a..b64b33e886e6 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -644,9 +644,8 @@ class DrawContext { // Call this with 0 to signal that you have been drawing on your own, and need the state reset on the next pipeline bind. virtual void BindPipeline(Pipeline *pipeline) = 0; - // TODO: Add more sophisticated draws with buffer offsets, and multidraws. virtual void Draw(int vertexCount, int offset) = 0; - virtual void DrawIndexed(int vertexCount, int offset) = 0; + virtual void DrawIndexed(int vertexCount, int offset) = 0; // Always 16-bit indices. virtual void DrawUP(const void *vdata, int vertexCount) = 0; // Frame management (for the purposes of sync and resource management, necessary with modern APIs). Default implementations here. diff --git a/ext/native/thin3d/thin3d_d3d11.cpp b/ext/native/thin3d/thin3d_d3d11.cpp index e7447bec049f..31a3ad7b888c 100644 --- a/ext/native/thin3d/thin3d_d3d11.cpp +++ b/ext/native/thin3d/thin3d_d3d11.cpp @@ -1066,7 +1066,7 @@ void D3D11DrawContext::ApplyCurrentState() { int numVBs = (int)curPipeline_->input->strides.size(); context_->IASetVertexBuffers(0, 1, nextVertexBuffers_, (UINT *)curPipeline_->input->strides.data(), (UINT *)nextVertexBufferOffsets_); if (dirtyIndexBuffer_) { - context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R32_UINT, nextIndexBufferOffset_); + context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R16_UINT, nextIndexBufferOffset_); dirtyIndexBuffer_ = false; } if (curPipeline_->dynamicUniforms) { @@ -1340,7 +1340,7 @@ void D3D11DrawContext::BeginFrame() { } if (curPipeline_) { context_->IASetVertexBuffers(0, 1, nextVertexBuffers_, (UINT *)curPipeline_->input->strides.data(), (UINT *)nextVertexBufferOffsets_); - context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R32_UINT, nextIndexBufferOffset_); + context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R16_UINT, nextIndexBufferOffset_); if (curPipeline_->dynamicUniforms) { context_->VSSetConstantBuffers(0, 1, &curPipeline_->dynamicUniforms); context_->PSSetConstantBuffers(0, 1, &curPipeline_->dynamicUniforms); diff --git a/ext/native/thin3d/thin3d_d3d9.cpp b/ext/native/thin3d/thin3d_d3d9.cpp index 22d719dd3817..b4d446ed9d8f 100644 --- a/ext/native/thin3d/thin3d_d3d9.cpp +++ b/ext/native/thin3d/thin3d_d3d9.cpp @@ -856,7 +856,7 @@ class D3D9Buffer : public Buffer { D3D9Buffer(LPDIRECT3DDEVICE9 device, size_t size, uint32_t flags) : vbuffer_(nullptr), ibuffer_(nullptr), maxSize_(size) { if (flags & BufferUsageFlag::INDEXDATA) { DWORD usage = D3DUSAGE_DYNAMIC; - device->CreateIndexBuffer((UINT)size, usage, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &ibuffer_, NULL); + device->CreateIndexBuffer((UINT)size, usage, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ibuffer_, NULL); } else { DWORD usage = D3DUSAGE_DYNAMIC; device->CreateVertexBuffer((UINT)size, usage, 0, D3DPOOL_DEFAULT, &vbuffer_, NULL); diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index a9186127356b..8eadd95644cf 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -1095,7 +1095,7 @@ void OpenGLContext::DrawIndexed(int vertexCount, int offset) { ApplySamplers(); renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]); renderManager_.BindIndexBuffer(curIBuffer_->buffer_); - renderManager_.DrawIndexed(curPipeline_->prim, vertexCount, GL_UNSIGNED_INT, (void *)((intptr_t)curIBufferOffset_ + offset * sizeof(uint32_t))); + renderManager_.DrawIndexed(curPipeline_->prim, vertexCount, GL_UNSIGNED_SHORT, (void *)((intptr_t)curIBufferOffset_ + offset * sizeof(uint32_t))); } void OpenGLContext::DrawUP(const void *vdata, int vertexCount) { diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 6eec1514dad8..c89b079c682d 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -1267,7 +1267,7 @@ void VKContext::DrawIndexed(int vertexCount, int offset) { renderManager_.BindPipeline(curPipeline_->vkpipeline); ApplyDynamicState(); - renderManager_.DrawIndexed(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vulkanIbuf, (int)ibBindOffset + offset * sizeof(uint32_t), vertexCount, 1, VK_INDEX_TYPE_UINT32); + renderManager_.DrawIndexed(pipelineLayout_, descSet, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffsets_[0], vulkanIbuf, (int)ibBindOffset + offset * sizeof(uint32_t), vertexCount, 1, VK_INDEX_TYPE_UINT16); } void VKContext::DrawUP(const void *vdata, int vertexCount) {