mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-13 22:40:29 +02:00
thin3d: Add partial support for 32-bit index buffers. Add DrawIndexedUP.
This commit is contained in:
1 parent
0f50225f8e
commit
8f8598c347
9 files changed
+103
-10
No files matched your search
@@ -131,6 +131,8 @@ public:
|
||||
void Draw(int vertexCount, int offset) override;
|
||||
void DrawIndexed(int indexCount, int offset) override;
|
||||
void DrawUP(const void *vdata, int vertexCount) override;
|
||||
void DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount, IndexFormat ifmt) override;
|
||||
|
||||
void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override;
|
||||
|
||||
void BeginFrame(DebugFlags debugFlags) override;
|
||||
@@ -218,6 +220,7 @@ private:
|
||||
|
||||
bool dirtyIndexBuffer_ = false;
|
||||
ID3D11Buffer *nextIndexBuffer_ = nullptr;
|
||||
DXGI_FORMAT nextIndexBufferFormat_ = DXGI_FORMAT_R16_UINT;
|
||||
UINT nextIndexBufferOffset_ = 0;
|
||||
|
||||
InvalidationCallback invalidationCallback_;
|
||||
@@ -235,6 +238,7 @@ private:
|
||||
// Temporaries
|
||||
ID3D11Texture2D *packTexture_ = nullptr;
|
||||
Buffer *upBuffer_ = nullptr;
|
||||
Buffer *upIBuffer_ = nullptr;
|
||||
|
||||
// System info
|
||||
D3D_FEATURE_LEVEL featureLevel_;
|
||||
@@ -351,6 +355,7 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de
|
||||
const size_t UP_MAX_BYTES = 65536 * 24;
|
||||
|
||||
upBuffer_ = D3D11DrawContext::CreateBuffer(UP_MAX_BYTES, BufferUsageFlag::DYNAMIC | BufferUsageFlag::VERTEXDATA);
|
||||
upIBuffer_ = D3D11DrawContext::CreateBuffer(UP_MAX_BYTES, BufferUsageFlag::DYNAMIC | BufferUsageFlag::INDEXDATA);
|
||||
|
||||
IDXGIDevice1 *dxgiDevice1 = nullptr;
|
||||
hr = device_->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void **>(&dxgiDevice1));
|
||||
@@ -364,6 +369,7 @@ D3D11DrawContext::~D3D11DrawContext() {
|
||||
DestroyPresets();
|
||||
|
||||
upBuffer_->Release();
|
||||
upIBuffer_->Release();
|
||||
packTexture_->Release();
|
||||
|
||||
// Release references.
|
||||
@@ -1255,7 +1261,7 @@ void D3D11DrawContext::ApplyCurrentState() {
|
||||
context_->IASetVertexBuffers(0, 1, &nextVertexBuffer_, &curPipeline_->input->stride, &nextVertexBufferOffset_);
|
||||
}
|
||||
if (dirtyIndexBuffer_) {
|
||||
context_->IASetIndexBuffer(nextIndexBuffer_, DXGI_FORMAT_R16_UINT, nextIndexBufferOffset_);
|
||||
context_->IASetIndexBuffer(nextIndexBuffer_, nextIndexBufferFormat_, nextIndexBufferOffset_);
|
||||
dirtyIndexBuffer_ = false;
|
||||
}
|
||||
if (curPipeline_->dynamicUniforms) {
|
||||
@@ -1334,6 +1340,7 @@ void D3D11DrawContext::BindIndexBuffer(Buffer *indexBuffer, int offset) {
|
||||
dirtyIndexBuffer_ = true;
|
||||
nextIndexBuffer_ = buf ? buf->buf : 0;
|
||||
nextIndexBufferOffset_ = buf ? offset : 0;
|
||||
nextIndexBufferFormat_ = DXGI_FORMAT_R16_UINT;
|
||||
}
|
||||
|
||||
void D3D11DrawContext::Draw(int vertexCount, int offset) {
|
||||
@@ -1347,8 +1354,6 @@ void D3D11DrawContext::DrawIndexed(int indexCount, int offset) {
|
||||
}
|
||||
|
||||
void D3D11DrawContext::DrawUP(const void *vdata, int vertexCount) {
|
||||
ApplyCurrentState();
|
||||
|
||||
int byteSize = vertexCount * curPipeline_->input->stride;
|
||||
|
||||
UpdateBuffer(upBuffer_, (const uint8_t *)vdata, 0, byteSize, Draw::UPDATE_DISCARD);
|
||||
@@ -1357,6 +1362,20 @@ void D3D11DrawContext::DrawUP(const void *vdata, int vertexCount) {
|
||||
Draw(vertexCount, offset);
|
||||
}
|
||||
|
||||
void D3D11DrawContext::DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount, IndexFormat ifmt) {
|
||||
int vbyteSize = vertexCount * curPipeline_->input->stride;
|
||||
int ibyteSize = indexCount * (ifmt == IndexFormat::U32 ? 4 : 2);
|
||||
|
||||
UpdateBuffer(upBuffer_, (const uint8_t *)vdata, 0, vbyteSize, Draw::UPDATE_DISCARD);
|
||||
BindVertexBuffer(upBuffer_, 0);
|
||||
|
||||
UpdateBuffer(upIBuffer_, (const uint8_t *)idata, 0, ibyteSize, Draw::UPDATE_DISCARD);
|
||||
BindIndexBuffer(upIBuffer_, 0);
|
||||
// Override the index buffer format.
|
||||
nextIndexBufferFormat_ = ifmt == IndexFormat::U32 ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
|
||||
DrawIndexed(indexCount, 0);
|
||||
}
|
||||
|
||||
uint32_t D3D11DrawContext::GetDataFormatSupport(DataFormat fmt) const {
|
||||
DXGI_FORMAT giFmt = dataFormatToD3D11(fmt);
|
||||
if (giFmt == DXGI_FORMAT_UNKNOWN)
|
||||
|
||||
@@ -573,6 +573,7 @@ public:
|
||||
void Draw(int vertexCount, int offset) override;
|
||||
void DrawIndexed(int vertexCount, int offset) override;
|
||||
void DrawUP(const void *vdata, int vertexCount) override;
|
||||
void DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount, IndexFormat ifmt) override;
|
||||
void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override;
|
||||
|
||||
uint64_t GetNativeObject(NativeObject obj, void *srcObject) override {
|
||||
@@ -1172,6 +1173,16 @@ void D3D9Context::DrawUP(const void *vdata, int vertexCount) {
|
||||
device_->DrawPrimitiveUP(curPipeline_->prim, D3DPrimCount(curPipeline_->prim, vertexCount), vdata, curPipeline_->inputLayout->GetStride());
|
||||
}
|
||||
|
||||
void D3D9Context::DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount, IndexFormat ifmt) {
|
||||
curPipeline_->inputLayout->Apply(device_);
|
||||
curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_);
|
||||
ApplyDynamicState();
|
||||
|
||||
device_->DrawIndexedPrimitiveUP(curPipeline_->prim, 0, vertexCount, D3DPrimCount(curPipeline_->prim, indexCount),
|
||||
idata, ifmt == IndexFormat::U32 ? D3DFMT_INDEX32 : D3DFMT_INDEX16,
|
||||
vdata, curPipeline_->inputLayout->GetStride());
|
||||
}
|
||||
|
||||
static uint32_t SwapRB(uint32_t c) {
|
||||
return (c & 0xFF00FF00) | ((c >> 16) & 0xFF) | ((c << 16) & 0xFF0000);
|
||||
}
|
||||
|
||||
@@ -443,6 +443,7 @@ public:
|
||||
void Draw(int vertexCount, int offset) override;
|
||||
void DrawIndexed(int vertexCount, int offset) override;
|
||||
void DrawUP(const void *vdata, int vertexCount) override;
|
||||
void DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount, IndexFormat ifmt) override;
|
||||
|
||||
void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override;
|
||||
|
||||
@@ -1417,6 +1418,29 @@ void OpenGLContext::DrawUP(const void *vdata, int vertexCount) {
|
||||
renderManager_.Draw(curPipeline_->inputLayout->inputLayout_, buf, offset, curPipeline_->prim, 0, vertexCount);
|
||||
}
|
||||
|
||||
void OpenGLContext::DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount, IndexFormat ifmt) {
|
||||
_assert_(curPipeline_->inputLayout != nullptr);
|
||||
int stride = curPipeline_->inputLayout->stride;
|
||||
uint32_t vdataSize = stride * vertexCount;
|
||||
uint32_t idataSize = indexCount * (ifmt == IndexFormat::U32 ? 4 : 2);
|
||||
|
||||
FrameData &frameData = frameData_[renderManager_.GetCurFrame()];
|
||||
|
||||
GLRBuffer *vbuf;
|
||||
uint32_t voffset;
|
||||
uint8_t *dest = frameData.push->Allocate(vdataSize, 4, &vbuf, &voffset);
|
||||
memcpy(dest, vdata, vdataSize);
|
||||
|
||||
GLRBuffer *ibuf;
|
||||
uint32_t ioffset;
|
||||
dest = frameData.push->Allocate(idataSize, 4, &ibuf, &ioffset);
|
||||
memcpy(dest, idata, idataSize);
|
||||
|
||||
ApplySamplers();
|
||||
_assert_(curPipeline_->inputLayout);
|
||||
renderManager_.DrawIndexed(curPipeline_->inputLayout->inputLayout_, vbuf, voffset, ibuf, ioffset, curPipeline_->prim, 0, ifmt == IndexFormat::U32 ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, vertexCount);
|
||||
}
|
||||
|
||||
void OpenGLContext::Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) {
|
||||
float col[4];
|
||||
Uint8x4ToFloat4(col, colorval);
|
||||
|
||||
@@ -1165,7 +1165,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
|
||||
VkDescriptorSet set = (*descSets)[c.drawIndexed.descSetIndex].set;
|
||||
_dbg_assert_(set != VK_NULL_HANDLE);
|
||||
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &set, c.drawIndexed.numUboOffsets, c.drawIndexed.uboOffsets);
|
||||
vkCmdBindIndexBuffer(cmd, c.drawIndexed.ibuffer, c.drawIndexed.ioffset, VK_INDEX_TYPE_UINT16);
|
||||
vkCmdBindIndexBuffer(cmd, c.drawIndexed.ibuffer, c.drawIndexed.ioffset, c.drawIndexed.itype);
|
||||
VkDeviceSize voffset = c.drawIndexed.voffset;
|
||||
vkCmdBindVertexBuffers(cmd, 0, 1, &c.drawIndexed.vbuffer, &voffset);
|
||||
vkCmdDrawIndexed(cmd, c.drawIndexed.count, c.drawIndexed.instances, 0, 0, 0);
|
||||
|
||||
@@ -80,6 +80,7 @@ struct VkRenderData {
|
||||
uint32_t voffset;
|
||||
uint32_t ioffset;
|
||||
uint32_t count;
|
||||
VkIndexType itype; // TODO: pack this into one of the others, it's really a single bit
|
||||
} drawIndexed;
|
||||
struct {
|
||||
uint32_t clearColor;
|
||||
|
||||
@@ -471,7 +471,7 @@ public:
|
||||
curRenderStep_->render.numDraws++;
|
||||
}
|
||||
|
||||
void DrawIndexed(int descSetIndex, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, VkBuffer ibuffer, int ioffset, int count, int numInstances) {
|
||||
void DrawIndexed(int descSetIndex, int numUboOffsets, const uint32_t *uboOffsets, VkBuffer vbuffer, int voffset, VkBuffer ibuffer, int ioffset, int count, int numInstances, VkIndexType itype) {
|
||||
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER && curStepHasViewport_ && curStepHasScissor_);
|
||||
VkRenderData &data = curRenderStep_->commands.push_uninitialized();
|
||||
data.cmd = VKRRenderCommand::DRAW_INDEXED;
|
||||
@@ -483,6 +483,7 @@ public:
|
||||
data.drawIndexed.ibuffer = ibuffer;
|
||||
data.drawIndexed.ioffset = ioffset;
|
||||
data.drawIndexed.numUboOffsets = numUboOffsets;
|
||||
data.drawIndexed.itype = itype;
|
||||
_dbg_assert_(numUboOffsets <= ARRAY_SIZE(data.drawIndexed.uboOffsets));
|
||||
for (int i = 0; i < numUboOffsets; i++)
|
||||
data.drawIndexed.uboOffsets[i] = uboOffsets[i];
|
||||
|
||||
@@ -491,6 +491,7 @@ public:
|
||||
void Draw(int vertexCount, int offset) override;
|
||||
void DrawIndexed(int vertexCount, int offset) override;
|
||||
void DrawUP(const void *vdata, int vertexCount) override;
|
||||
void DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount, IndexFormat ifmt) override;
|
||||
|
||||
void BindCurrentPipeline();
|
||||
void ApplyDynamicState();
|
||||
@@ -1497,7 +1498,7 @@ void VKContext::DrawIndexed(int vertexCount, int offset) {
|
||||
int descSetIndex;
|
||||
PackedDescriptor *descriptors = renderManager_.PushDescriptorSet(4, &descSetIndex);
|
||||
BindDescriptors(vulkanUBObuf, descriptors);
|
||||
renderManager_.DrawIndexed(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffset_, vulkanIbuf, (int)ibBindOffset + offset * sizeof(uint32_t), vertexCount, 1);
|
||||
renderManager_.DrawIndexed(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffset_, vulkanIbuf, (int)ibBindOffset + offset * sizeof(uint32_t), vertexCount, 1, VK_INDEX_TYPE_UINT16);
|
||||
}
|
||||
|
||||
void VKContext::DrawUP(const void *vdata, int vertexCount) {
|
||||
@@ -1520,7 +1521,37 @@ void VKContext::DrawUP(const void *vdata, int vertexCount) {
|
||||
int descSetIndex;
|
||||
PackedDescriptor *descriptors = renderManager_.PushDescriptorSet(4, &descSetIndex);
|
||||
BindDescriptors(vulkanUBObuf, descriptors);
|
||||
renderManager_.Draw(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset + curVBufferOffset_, vertexCount);
|
||||
renderManager_.Draw(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset, vertexCount);
|
||||
}
|
||||
|
||||
void VKContext::DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount, IndexFormat ifmt) {
|
||||
_dbg_assert_(vertexCount >= 0);
|
||||
_dbg_assert_(indexCount >= 0);
|
||||
if (vertexCount <= 0 || indexCount <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
VkBuffer vulkanVbuf, vulkanIbuf, vulkanUBObuf;
|
||||
size_t vdataSize = vertexCount * curPipeline_->stride;
|
||||
uint32_t vbBindOffset;
|
||||
uint8_t *vdataPtr = push_->Allocate(vdataSize, 4, &vulkanVbuf, &vbBindOffset);
|
||||
_assert_(vdataPtr != nullptr);
|
||||
memcpy(vdataPtr, vdata, vdataSize);
|
||||
|
||||
size_t idataSize = indexCount * (ifmt == IndexFormat::U32 ? 4 : 2);
|
||||
uint32_t ibBindOffset;
|
||||
uint8_t *idataPtr = push_->Allocate(idataSize, 4, &vulkanIbuf, &ibBindOffset);
|
||||
_assert_(idataPtr != nullptr);
|
||||
memcpy(idataPtr, vdata, idataSize);
|
||||
|
||||
uint32_t ubo_offset = (uint32_t)curPipeline_->PushUBO(push_, vulkan_, &vulkanUBObuf);
|
||||
|
||||
BindCurrentPipeline();
|
||||
ApplyDynamicState();
|
||||
int descSetIndex;
|
||||
PackedDescriptor *descriptors = renderManager_.PushDescriptorSet(4, &descSetIndex);
|
||||
BindDescriptors(vulkanUBObuf, descriptors);
|
||||
renderManager_.DrawIndexed(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset, vulkanIbuf, (int)ibBindOffset, indexCount, 1, ifmt == IndexFormat::U32 ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16);
|
||||
}
|
||||
|
||||
void VKContext::BindCurrentPipeline() {
|
||||
|
||||
+7
-1
@@ -180,6 +180,11 @@ enum class Facing {
|
||||
CW,
|
||||
};
|
||||
|
||||
enum class IndexFormat {
|
||||
U16,
|
||||
U32,
|
||||
};
|
||||
|
||||
enum BorderColor {
|
||||
DONT_CARE,
|
||||
TRANSPARENT_BLACK,
|
||||
@@ -827,7 +832,8 @@ public:
|
||||
virtual void Draw(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;
|
||||
|
||||
virtual void DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount, IndexFormat ifmt) = 0; // Supports 32-bit indices, for IMGUI use.
|
||||
|
||||
// Frame management (for the purposes of sync and resource management, necessary with modern APIs). Default implementations here.
|
||||
virtual void BeginFrame(DebugFlags debugFlags) = 0;
|
||||
virtual void EndFrame() = 0;
|
||||
|
||||
@@ -374,7 +374,7 @@ void DrawEngineVulkan::DoFlush() {
|
||||
if (!ibuf) {
|
||||
ibOffset = (uint32_t)pushIndex_->Push(decIndex_, sizeof(uint16_t) * vertexCount, 4, &ibuf);
|
||||
}
|
||||
renderManager->DrawIndexed(descSetIndex, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, vertexCount, 1);
|
||||
renderManager->DrawIndexed(descSetIndex, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, vertexCount, 1, VK_INDEX_TYPE_UINT16);
|
||||
} else {
|
||||
renderManager->Draw(descSetIndex, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, vertexCount);
|
||||
}
|
||||
@@ -539,7 +539,7 @@ void DrawEngineVulkan::DoFlush() {
|
||||
VkBuffer vbuf, ibuf;
|
||||
vbOffset = (uint32_t)pushVertex_->Push(result.drawBuffer, numDecodedVerts_ * sizeof(TransformedVertex), 4, &vbuf);
|
||||
ibOffset = (uint32_t)pushIndex_->Push(inds, sizeof(short) * result.drawNumTrans, 4, &ibuf);
|
||||
renderManager->DrawIndexed(descSetIndex, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, result.drawNumTrans, 1);
|
||||
renderManager->DrawIndexed(descSetIndex, ARRAY_SIZE(dynamicUBOOffsets), dynamicUBOOffsets, vbuf, vbOffset, ibuf, ibOffset, result.drawNumTrans, 1, VK_INDEX_TYPE_UINT16);
|
||||
} else if (result.action == SW_CLEAR) {
|
||||
// Note: we won't get here if the clear is alpha but not color, or color but not alpha.
|
||||
bool clearColor = gstate.isClearModeColorMask();
|
||||
|
||||
Reference in new issue
Block a user