From 8f2069ef71eb5829c0b0abe9b3035c66c2c64236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 10 May 2023 00:48:01 +0200 Subject: [PATCH 1/5] GLQueueRunner: Combine BindVertexBuffer with BindIndexBuffer --- Common/GPU/OpenGL/GLQueueRunner.cpp | 16 +++++++++------- Common/GPU/OpenGL/GLQueueRunner.h | 1 + Common/GPU/OpenGL/GLRenderManager.h | 11 ++--------- Common/GPU/OpenGL/thin3d_gl.cpp | 7 +++---- GPU/GLES/DrawEngineGLES.cpp | 9 ++++----- 5 files changed, 19 insertions(+), 25 deletions(-) diff --git a/Common/GPU/OpenGL/GLQueueRunner.cpp b/Common/GPU/OpenGL/GLQueueRunner.cpp index 80a3193e40db..3f0c9291ab4e 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.cpp +++ b/Common/GPU/OpenGL/GLQueueRunner.cpp @@ -1176,6 +1176,14 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last auto &entry = layout->entries[i]; glVertexAttribPointer(entry.location, entry.count, entry.type, entry.normalized, entry.stride, (const void *)(c.bindVertexBuffer.offset + entry.offset)); } + if (c.bindVertexBuffer.indexBuffer) { + GLuint buf = c.bindVertexBuffer.indexBuffer->buffer_; + _dbg_assert_(!(c.bindVertexBuffer.indexBuffer && c.bindVertexBuffer.indexBuffer->Mapped())); + if (buf != curElemArrayBuffer) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf); + curElemArrayBuffer = buf; + } + } CHECK_GL_ERROR_IF_DEBUG(); break; } @@ -1183,14 +1191,8 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last { if (c.bind_buffer.target == GL_ARRAY_BUFFER) { Crash(); - } else if (c.bind_buffer.target == GL_ELEMENT_ARRAY_BUFFER) { - GLuint buf = c.bind_buffer.buffer ? c.bind_buffer.buffer->buffer_ : 0; - _dbg_assert_(!(c.bind_buffer.buffer && c.bind_buffer.buffer->Mapped())); - if (buf != curElemArrayBuffer) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf); - curElemArrayBuffer = buf; - } } else { + // is this used? GLuint buf = c.bind_buffer.buffer ? c.bind_buffer.buffer->buffer_ : 0; _dbg_assert_(!(c.bind_buffer.buffer && c.bind_buffer.buffer->Mapped())); glBindBuffer(c.bind_buffer.target, buf); diff --git a/Common/GPU/OpenGL/GLQueueRunner.h b/Common/GPU/OpenGL/GLQueueRunner.h index e662b43dd190..0c8456e13fd4 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.h +++ b/Common/GPU/OpenGL/GLQueueRunner.h @@ -175,6 +175,7 @@ struct GLRRenderData { GLRInputLayout *inputLayout; GLRBuffer *buffer; size_t offset; + GLRBuffer *indexBuffer; } bindVertexBuffer; struct { int slot; diff --git a/Common/GPU/OpenGL/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h index f06724a6cbef..6505418c8396 100644 --- a/Common/GPU/OpenGL/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -641,21 +641,14 @@ class GLRenderManager { #endif } - void BindIndexBuffer(GLRBuffer *buffer) { // Want to support an offset but can't in ES 2.0. We supply an offset when binding the buffers instead. - _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); - GLRRenderData data{ GLRRenderCommand::BIND_BUFFER}; - data.bind_buffer.buffer = buffer; - data.bind_buffer.target = GL_ELEMENT_ARRAY_BUFFER; - curRenderStep_->commands.push_back(data); - } - - void BindVertexBuffer(GLRInputLayout *inputLayout, GLRBuffer *buffer, size_t offset) { + void BindVertexBuffer(GLRInputLayout *inputLayout, GLRBuffer *buffer, size_t offset, GLRBuffer *indexBuffer) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); _dbg_assert_(inputLayout); GLRRenderData data{ GLRRenderCommand::BIND_VERTEX_BUFFER }; data.bindVertexBuffer.inputLayout = inputLayout; data.bindVertexBuffer.offset = offset; data.bindVertexBuffer.buffer = buffer; + data.bindVertexBuffer.indexBuffer = indexBuffer; curRenderStep_->commands.push_back(data); } diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index a50346f2b29f..e57d6caba785 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -1333,7 +1333,7 @@ void OpenGLContext::Draw(int vertexCount, int offset) { _dbg_assert_msg_(curVBuffers_[0] != nullptr, "Can't call Draw without a vertex buffer"); ApplySamplers(); if (curPipeline_->inputLayout) { - renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]); + renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0], nullptr); } renderManager_.Draw(curPipeline_->prim, offset, vertexCount); } @@ -1343,9 +1343,8 @@ void OpenGLContext::DrawIndexed(int vertexCount, int offset) { _dbg_assert_msg_(curIBuffer_ != nullptr, "Can't call DrawIndexed without an index buffer"); ApplySamplers(); if (curPipeline_->inputLayout) { - renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0]); + renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0], curIBuffer_->buffer_); } - renderManager_.BindIndexBuffer(curIBuffer_->buffer_); renderManager_.DrawIndexed(curPipeline_->prim, vertexCount, GL_UNSIGNED_SHORT, (void *)((intptr_t)curIBufferOffset_ + offset * sizeof(uint32_t))); } @@ -1361,7 +1360,7 @@ void OpenGLContext::DrawUP(const void *vdata, int vertexCount) { ApplySamplers(); if (curPipeline_->inputLayout) { - renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, buf, offset); + renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, buf, offset, nullptr); } renderManager_.Draw(curPipeline_->prim, 0, vertexCount); } diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index fb9c51105b24..9088af9146a3 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -326,16 +326,16 @@ void DrawEngineGLES::DoFlush() { LinkedShader *program = shaderManager_->ApplyFragmentShader(vsid, vshader, pipelineState_, framebufferManager_->UseBufferedRendering()); GLRInputLayout *inputLayout = SetupDecFmtForDraw(program, dec_->GetDecVtxFmt()); - render_->BindVertexBuffer(inputLayout, vertexBuffer, vertexBufferOffset); if (useElements) { if (!indexBuffer) { size_t esz = sizeof(uint16_t) * indexGen.VertexCount(); void *dest = frameData.pushIndex->Push(esz, &indexBufferOffset, &indexBuffer); memcpy(dest, decIndex, esz); } - render_->BindIndexBuffer(indexBuffer); + render_->BindVertexBuffer(inputLayout, vertexBuffer, vertexBufferOffset, indexBuffer); render_->DrawIndexed(glprim[prim], vertexCount, GL_UNSIGNED_SHORT, (GLvoid*)(intptr_t)indexBufferOffset); } else { + render_->BindVertexBuffer(inputLayout, vertexBuffer, vertexBufferOffset, nullptr); render_->Draw(glprim[prim], 0, vertexCount); } } else { @@ -434,12 +434,11 @@ void DrawEngineGLES::DoFlush() { if (result.drawIndexed) { vertexBufferOffset = (uint32_t)frameData.pushVertex->Push(result.drawBuffer, maxIndex * sizeof(TransformedVertex), &vertexBuffer); indexBufferOffset = (uint32_t)frameData.pushIndex->Push(inds, sizeof(uint16_t) * result.drawNumTrans, &indexBuffer); - render_->BindVertexBuffer(softwareInputLayout_, vertexBuffer, vertexBufferOffset); - render_->BindIndexBuffer(indexBuffer); + render_->BindVertexBuffer(softwareInputLayout_, vertexBuffer, vertexBufferOffset, indexBuffer); render_->DrawIndexed(glprim[prim], result.drawNumTrans, GL_UNSIGNED_SHORT, (void *)(intptr_t)indexBufferOffset); } else { vertexBufferOffset = (uint32_t)frameData.pushVertex->Push(result.drawBuffer, result.drawNumTrans * sizeof(TransformedVertex), &vertexBuffer); - render_->BindVertexBuffer(softwareInputLayout_, vertexBuffer, vertexBufferOffset); + render_->BindVertexBuffer(softwareInputLayout_, vertexBuffer, vertexBufferOffset, nullptr); render_->Draw(glprim[prim], 0, result.drawNumTrans); } } else if (result.action == SW_CLEAR) { From c8820462511fd77fcf4bb1bfe934c142133da35d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 10 May 2023 00:59:03 +0200 Subject: [PATCH 2/5] Remove redundant render command --- Common/GPU/OpenGL/GLQueueRunner.cpp | 13 ------------- Common/GPU/OpenGL/GLQueueRunner.h | 1 - 2 files changed, 14 deletions(-) diff --git a/Common/GPU/OpenGL/GLQueueRunner.cpp b/Common/GPU/OpenGL/GLQueueRunner.cpp index 3f0c9291ab4e..64118e6a1a38 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.cpp +++ b/Common/GPU/OpenGL/GLQueueRunner.cpp @@ -1187,19 +1187,6 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last CHECK_GL_ERROR_IF_DEBUG(); break; } - case GLRRenderCommand::BIND_BUFFER: - { - if (c.bind_buffer.target == GL_ARRAY_BUFFER) { - Crash(); - } else { - // is this used? - GLuint buf = c.bind_buffer.buffer ? c.bind_buffer.buffer->buffer_ : 0; - _dbg_assert_(!(c.bind_buffer.buffer && c.bind_buffer.buffer->Mapped())); - glBindBuffer(c.bind_buffer.target, buf); - } - CHECK_GL_ERROR_IF_DEBUG(); - break; - } case GLRRenderCommand::GENMIPS: // TODO: Should we include the texture handle in the command? // Also, should this not be an init command? diff --git a/Common/GPU/OpenGL/GLQueueRunner.h b/Common/GPU/OpenGL/GLQueueRunner.h index 0c8456e13fd4..8ff5a8b0388c 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.h +++ b/Common/GPU/OpenGL/GLQueueRunner.h @@ -61,7 +61,6 @@ enum class GLRRenderCommand : uint8_t { BINDTEXTURE, BIND_FB_TEXTURE, BIND_VERTEX_BUFFER, - BIND_BUFFER, GENMIPS, DRAW, DRAW_INDEXED, From d5e0299b0bbc308c6575d730b0f3b46c995f11b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 10 May 2023 10:32:13 +0200 Subject: [PATCH 3/5] GLR: Share union struct between Draw/DrawIndex --- Common/GPU/OpenGL/GLQueueRunner.cpp | 7 +++---- Common/GPU/OpenGL/GLQueueRunner.h | 9 ++------- Common/GPU/OpenGL/GLRenderManager.h | 12 ++++++------ Common/VR/PPSSPPVR.cpp | 2 +- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/Common/GPU/OpenGL/GLQueueRunner.cpp b/Common/GPU/OpenGL/GLQueueRunner.cpp index 64118e6a1a38..2c15f5f2d9ad 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.cpp +++ b/Common/GPU/OpenGL/GLQueueRunner.cpp @@ -1196,12 +1196,11 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last glDrawArrays(c.draw.mode, c.draw.first, c.draw.count); break; case GLRRenderCommand::DRAW_INDEXED: - if (c.drawIndexed.instances == 1) { - glDrawElements(c.drawIndexed.mode, c.drawIndexed.count, c.drawIndexed.indexType, c.drawIndexed.indices); + if (c.draw.instances == 1) { + glDrawElements(c.draw.mode, c.draw.count, c.draw.indexType, c.draw.indices); } else { - glDrawElementsInstanced(c.drawIndexed.mode, c.drawIndexed.count, c.drawIndexed.indexType, c.drawIndexed.indices, c.drawIndexed.instances); + glDrawElementsInstanced(c.draw.mode, c.draw.count, c.draw.indexType, c.draw.indices, c.draw.instances); } - CHECK_GL_ERROR_IF_DEBUG(); break; case GLRRenderCommand::TEXTURESAMPLER: { diff --git a/Common/GPU/OpenGL/GLQueueRunner.h b/Common/GPU/OpenGL/GLQueueRunner.h index 8ff5a8b0388c..a7b67c48d9cd 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.h +++ b/Common/GPU/OpenGL/GLQueueRunner.h @@ -109,17 +109,12 @@ struct GLRRenderData { } stencilOp; // also write mask struct { GLenum mode; // primitive - GLint buffer; GLint first; GLint count; - } draw; - struct { - GLenum mode; // primitive - GLint count; + void *indices; GLint instances; GLint indexType; - void *indices; - } drawIndexed; + } draw; struct { const char *name; // if null, use loc const GLint *loc; // NOTE: This is a pointer so we can immediately use things that are "queried" during program creation. diff --git a/Common/GPU/OpenGL/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h index 6505418c8396..2c2aa9361477 100644 --- a/Common/GPU/OpenGL/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -923,7 +923,7 @@ class GLRenderManager { data.draw.mode = mode; data.draw.first = first; data.draw.count = count; - data.draw.buffer = 0; + data.draw.indices = nullptr; curRenderStep_->commands.push_back(data); curRenderStep_->render.numDraws++; } @@ -931,11 +931,11 @@ class GLRenderManager { void DrawIndexed(GLenum mode, int count, GLenum indexType, void *indices, int instances = 1) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::DRAW_INDEXED }; - data.drawIndexed.mode = mode; - data.drawIndexed.count = count; - data.drawIndexed.indexType = indexType; - data.drawIndexed.instances = instances; - data.drawIndexed.indices = indices; + data.draw.mode = mode; + data.draw.count = count; + data.draw.indices = indices; + data.draw.indexType = indexType; + data.draw.instances = instances; curRenderStep_->commands.push_back(data); curRenderStep_->render.numDraws++; } diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index 7daf981e2607..65acd261a7da 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -575,7 +575,7 @@ void PreprocessSkyplane(GLRStep* step) { if (command.cmd == GLRRenderCommand::DEPTH) { depthEnabled = command.depth.enabled; } else if ((command.cmd == GLRRenderCommand::DRAW_INDEXED) && !depthEnabled) { - command.drawIndexed.count = 0; + command.draw.count = 0; } } } From c7caefe6d86cbb5de535bbd99ecaf41298a8d3d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 10 May 2023 10:40:07 +0200 Subject: [PATCH 4/5] Have Draw and DrawIndexed share command and struct. Will make the next change easier. --- Common/GPU/OpenGL/GLQueueRunner.cpp | 19 ++++++++++--------- Common/GPU/OpenGL/GLQueueRunner.h | 3 +-- Common/GPU/OpenGL/GLRenderManager.h | 6 +++--- Common/VR/PPSSPPVR.cpp | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Common/GPU/OpenGL/GLQueueRunner.cpp b/Common/GPU/OpenGL/GLQueueRunner.cpp index 2c15f5f2d9ad..b4fa20438c35 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.cpp +++ b/Common/GPU/OpenGL/GLQueueRunner.cpp @@ -1187,20 +1187,21 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last CHECK_GL_ERROR_IF_DEBUG(); break; } - case GLRRenderCommand::GENMIPS: - // TODO: Should we include the texture handle in the command? - // Also, should this not be an init command? - glGenerateMipmap(GL_TEXTURE_2D); - break; case GLRRenderCommand::DRAW: - glDrawArrays(c.draw.mode, c.draw.first, c.draw.count); - break; - case GLRRenderCommand::DRAW_INDEXED: - if (c.draw.instances == 1) { + if (c.draw.indexType == 0) { + glDrawArrays(c.draw.mode, c.draw.first, c.draw.count); + } else if (c.draw.instances == 1) { glDrawElements(c.draw.mode, c.draw.count, c.draw.indexType, c.draw.indices); } else { glDrawElementsInstanced(c.draw.mode, c.draw.count, c.draw.indexType, c.draw.indices, c.draw.instances); } + CHECK_GL_ERROR_IF_DEBUG(); + break; + case GLRRenderCommand::GENMIPS: + // TODO: Should we include the texture handle in the command? + // Also, should this not be an init command? + glGenerateMipmap(GL_TEXTURE_2D); + CHECK_GL_ERROR_IF_DEBUG(); break; case GLRRenderCommand::TEXTURESAMPLER: { diff --git a/Common/GPU/OpenGL/GLQueueRunner.h b/Common/GPU/OpenGL/GLQueueRunner.h index a7b67c48d9cd..abd8b94b38d1 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.h +++ b/Common/GPU/OpenGL/GLQueueRunner.h @@ -63,7 +63,6 @@ enum class GLRRenderCommand : uint8_t { BIND_VERTEX_BUFFER, GENMIPS, DRAW, - DRAW_INDEXED, TEXTURE_SUBIMAGE, }; @@ -111,9 +110,9 @@ struct GLRRenderData { GLenum mode; // primitive GLint first; GLint count; + GLint indexType; void *indices; GLint instances; - GLint indexType; } draw; struct { const char *name; // if null, use loc diff --git a/Common/GPU/OpenGL/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h index 2c2aa9361477..538f02314984 100644 --- a/Common/GPU/OpenGL/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -923,18 +923,18 @@ class GLRenderManager { data.draw.mode = mode; data.draw.first = first; data.draw.count = count; - data.draw.indices = nullptr; + data.draw.indexType = 0; curRenderStep_->commands.push_back(data); curRenderStep_->render.numDraws++; } void DrawIndexed(GLenum mode, int count, GLenum indexType, void *indices, int instances = 1) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); - GLRRenderData data{ GLRRenderCommand::DRAW_INDEXED }; + GLRRenderData data{ GLRRenderCommand::DRAW }; data.draw.mode = mode; data.draw.count = count; - data.draw.indices = indices; data.draw.indexType = indexType; + data.draw.indices = indices; data.draw.instances = instances; curRenderStep_->commands.push_back(data); curRenderStep_->render.numDraws++; diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index 65acd261a7da..e580a6af8030 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -574,7 +574,7 @@ void PreprocessSkyplane(GLRStep* step) { for (auto& command : step->commands) { if (command.cmd == GLRRenderCommand::DEPTH) { depthEnabled = command.depth.enabled; - } else if ((command.cmd == GLRRenderCommand::DRAW_INDEXED) && !depthEnabled) { + } else if ((command.cmd == GLRRenderCommand::DRAW && command.draw.indices != nullptr) && !depthEnabled) { command.draw.count = 0; } } From b27c427547d1b432e8bfffbb1e31ddf007092f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 10 May 2023 10:49:27 +0200 Subject: [PATCH 5/5] We always bind and draw together, so let's combine them to one command. --- Common/GPU/OpenGL/GLQueueRunner.cpp | 34 +++++++++++++---------------- Common/GPU/OpenGL/GLQueueRunner.h | 10 ++++----- Common/GPU/OpenGL/GLRenderManager.h | 23 +++++++++---------- Common/GPU/OpenGL/thin3d_gl.cpp | 20 +++++++---------- GPU/GLES/DrawEngineGLES.cpp | 19 +++++++++------- 5 files changed, 48 insertions(+), 58 deletions(-) diff --git a/Common/GPU/OpenGL/GLQueueRunner.cpp b/Common/GPU/OpenGL/GLQueueRunner.cpp index b4fa20438c35..06e0e9428dd8 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.cpp +++ b/Common/GPU/OpenGL/GLQueueRunner.cpp @@ -1148,12 +1148,12 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last CHECK_GL_ERROR_IF_DEBUG(); break; } - case GLRRenderCommand::BIND_VERTEX_BUFFER: + case GLRRenderCommand::DRAW: { // TODO: Add fast path for glBindVertexBuffer - GLRInputLayout *layout = c.bindVertexBuffer.inputLayout; - GLuint buf = c.bindVertexBuffer.buffer ? c.bindVertexBuffer.buffer->buffer_ : 0; - _dbg_assert_(!c.bindVertexBuffer.buffer || !c.bindVertexBuffer.buffer->Mapped()); + GLRInputLayout *layout = c.draw.inputLayout; + GLuint buf = c.draw.buffer ? c.draw.buffer->buffer_ : 0; + _dbg_assert_(!c.draw.buffer || !c.draw.buffer->Mapped()); if (buf != curArrayBuffer) { glBindBuffer(GL_ARRAY_BUFFER, buf); curArrayBuffer = buf; @@ -1161,7 +1161,6 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last if (attrMask != layout->semanticsMask_) { int enable = layout->semanticsMask_ & ~attrMask; int disable = (~layout->semanticsMask_) & attrMask; - for (int i = 0; i < 7; i++) { // SEM_MAX if (enable & (1 << i)) { glEnableVertexAttribArray(i); @@ -1174,29 +1173,26 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last } for (size_t i = 0; i < layout->entries.size(); i++) { auto &entry = layout->entries[i]; - glVertexAttribPointer(entry.location, entry.count, entry.type, entry.normalized, entry.stride, (const void *)(c.bindVertexBuffer.offset + entry.offset)); + glVertexAttribPointer(entry.location, entry.count, entry.type, entry.normalized, entry.stride, (const void *)(c.draw.offset + entry.offset)); } - if (c.bindVertexBuffer.indexBuffer) { - GLuint buf = c.bindVertexBuffer.indexBuffer->buffer_; - _dbg_assert_(!(c.bindVertexBuffer.indexBuffer && c.bindVertexBuffer.indexBuffer->Mapped())); + if (c.draw.indexBuffer) { + GLuint buf = c.draw.indexBuffer->buffer_; + _dbg_assert_(!(c.draw.indexBuffer && c.draw.indexBuffer->Mapped())); if (buf != curElemArrayBuffer) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf); curElemArrayBuffer = buf; } - } - CHECK_GL_ERROR_IF_DEBUG(); - break; - } - case GLRRenderCommand::DRAW: - if (c.draw.indexType == 0) { - glDrawArrays(c.draw.mode, c.draw.first, c.draw.count); - } else if (c.draw.instances == 1) { - glDrawElements(c.draw.mode, c.draw.count, c.draw.indexType, c.draw.indices); + if (c.draw.instances == 1) { + glDrawElements(c.draw.mode, c.draw.count, c.draw.indexType, c.draw.indices); + } else { + glDrawElementsInstanced(c.draw.mode, c.draw.count, c.draw.indexType, c.draw.indices, c.draw.instances); + } } else { - glDrawElementsInstanced(c.draw.mode, c.draw.count, c.draw.indexType, c.draw.indices, c.draw.instances); + glDrawArrays(c.draw.mode, c.draw.first, c.draw.count); } CHECK_GL_ERROR_IF_DEBUG(); break; + } case GLRRenderCommand::GENMIPS: // TODO: Should we include the texture handle in the command? // Also, should this not be an init command? diff --git a/Common/GPU/OpenGL/GLQueueRunner.h b/Common/GPU/OpenGL/GLQueueRunner.h index abd8b94b38d1..c7b6134f1741 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.h +++ b/Common/GPU/OpenGL/GLQueueRunner.h @@ -107,6 +107,10 @@ struct GLRRenderData { uint8_t writeMask; } stencilOp; // also write mask struct { + GLRInputLayout *inputLayout; + GLRBuffer *buffer; + size_t offset; + GLRBuffer *indexBuffer; GLenum mode; // primitive GLint first; GLint count; @@ -164,12 +168,6 @@ struct GLRRenderData { struct { GLRProgram *program; } program; - struct { - GLRInputLayout *inputLayout; - GLRBuffer *buffer; - size_t offset; - GLRBuffer *indexBuffer; - } bindVertexBuffer; struct { int slot; GLenum wrapS; diff --git a/Common/GPU/OpenGL/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h index 538f02314984..64edeca3d68c 100644 --- a/Common/GPU/OpenGL/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -641,17 +641,6 @@ class GLRenderManager { #endif } - void BindVertexBuffer(GLRInputLayout *inputLayout, GLRBuffer *buffer, size_t offset, GLRBuffer *indexBuffer) { - _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); - _dbg_assert_(inputLayout); - GLRRenderData data{ GLRRenderCommand::BIND_VERTEX_BUFFER }; - data.bindVertexBuffer.inputLayout = inputLayout; - data.bindVertexBuffer.offset = offset; - data.bindVertexBuffer.buffer = buffer; - data.bindVertexBuffer.indexBuffer = indexBuffer; - curRenderStep_->commands.push_back(data); - } - void SetDepth(bool enabled, bool write, GLenum func) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::DEPTH }; @@ -917,9 +906,13 @@ class GLRenderManager { curRenderStep_->commands.push_back(data); } - void Draw(GLenum mode, int first, int count) { + void Draw(GLRInputLayout *inputLayout, GLRBuffer *buffer, size_t offset, GLenum mode, int first, int count) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::DRAW }; + data.draw.inputLayout = inputLayout; + data.draw.offset = offset; + data.draw.buffer = buffer; + data.draw.indexBuffer = nullptr; data.draw.mode = mode; data.draw.first = first; data.draw.count = count; @@ -928,9 +921,13 @@ class GLRenderManager { curRenderStep_->render.numDraws++; } - void DrawIndexed(GLenum mode, int count, GLenum indexType, void *indices, int instances = 1) { + void DrawIndexed(GLRInputLayout *inputLayout, GLRBuffer *buffer, size_t offset, GLRBuffer *indexBuffer, GLenum mode, int count, GLenum indexType, void *indices, int instances = 1) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); GLRRenderData data{ GLRRenderCommand::DRAW }; + data.draw.inputLayout = inputLayout; + data.draw.offset = offset; + data.draw.buffer = buffer; + data.draw.indexBuffer = indexBuffer; data.draw.mode = mode; data.draw.count = count; data.draw.indexType = indexType; diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index e57d6caba785..aae890ee182f 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -1332,20 +1332,18 @@ void OpenGLContext::UpdateDynamicUniformBuffer(const void *ub, size_t size) { void OpenGLContext::Draw(int vertexCount, int offset) { _dbg_assert_msg_(curVBuffers_[0] != nullptr, "Can't call Draw without a vertex buffer"); ApplySamplers(); - if (curPipeline_->inputLayout) { - renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0], nullptr); - } - renderManager_.Draw(curPipeline_->prim, offset, vertexCount); + _assert_(curPipeline_->inputLayout); + renderManager_.Draw(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0], curPipeline_->prim, offset, vertexCount); } void OpenGLContext::DrawIndexed(int vertexCount, int offset) { _dbg_assert_msg_(curVBuffers_[0] != nullptr, "Can't call DrawIndexed without a vertex buffer"); _dbg_assert_msg_(curIBuffer_ != nullptr, "Can't call DrawIndexed without an index buffer"); ApplySamplers(); - if (curPipeline_->inputLayout) { - renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0], curIBuffer_->buffer_); - } - renderManager_.DrawIndexed(curPipeline_->prim, vertexCount, GL_UNSIGNED_SHORT, (void *)((intptr_t)curIBufferOffset_ + offset * sizeof(uint32_t))); + _assert_(curPipeline_->inputLayout); + renderManager_.DrawIndexed( + curPipeline_->inputLayout->inputLayout_, curVBuffers_[0]->buffer_, curVBufferOffsets_[0], curIBuffer_->buffer_, + curPipeline_->prim, vertexCount, GL_UNSIGNED_SHORT, (void *)((intptr_t)curIBufferOffset_ + offset * sizeof(uint32_t))); } void OpenGLContext::DrawUP(const void *vdata, int vertexCount) { @@ -1359,10 +1357,8 @@ void OpenGLContext::DrawUP(const void *vdata, int vertexCount) { size_t offset = frameData.push->Push(vdata, dataSize, &buf); ApplySamplers(); - if (curPipeline_->inputLayout) { - renderManager_.BindVertexBuffer(curPipeline_->inputLayout->inputLayout_, buf, offset, nullptr); - } - renderManager_.Draw(curPipeline_->prim, 0, vertexCount); + _assert_(curPipeline_->inputLayout); + renderManager_.Draw(curPipeline_->inputLayout->inputLayout_, buf, offset, curPipeline_->prim, 0, vertexCount); } void OpenGLContext::Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) { diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 9088af9146a3..0ea95fbffe91 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -332,11 +332,13 @@ void DrawEngineGLES::DoFlush() { void *dest = frameData.pushIndex->Push(esz, &indexBufferOffset, &indexBuffer); memcpy(dest, decIndex, esz); } - render_->BindVertexBuffer(inputLayout, vertexBuffer, vertexBufferOffset, indexBuffer); - render_->DrawIndexed(glprim[prim], vertexCount, GL_UNSIGNED_SHORT, (GLvoid*)(intptr_t)indexBufferOffset); + render_->DrawIndexed( + inputLayout, vertexBuffer, vertexBufferOffset, indexBuffer, + glprim[prim], vertexCount, GL_UNSIGNED_SHORT, (GLvoid*)(intptr_t)indexBufferOffset); } else { - render_->BindVertexBuffer(inputLayout, vertexBuffer, vertexBufferOffset, nullptr); - render_->Draw(glprim[prim], 0, vertexCount); + render_->Draw( + inputLayout, vertexBuffer, vertexBufferOffset, + glprim[prim], 0, vertexCount); } } else { PROFILE_THIS_SCOPE("soft"); @@ -434,12 +436,13 @@ void DrawEngineGLES::DoFlush() { if (result.drawIndexed) { vertexBufferOffset = (uint32_t)frameData.pushVertex->Push(result.drawBuffer, maxIndex * sizeof(TransformedVertex), &vertexBuffer); indexBufferOffset = (uint32_t)frameData.pushIndex->Push(inds, sizeof(uint16_t) * result.drawNumTrans, &indexBuffer); - render_->BindVertexBuffer(softwareInputLayout_, vertexBuffer, vertexBufferOffset, indexBuffer); - render_->DrawIndexed(glprim[prim], result.drawNumTrans, GL_UNSIGNED_SHORT, (void *)(intptr_t)indexBufferOffset); + render_->DrawIndexed( + softwareInputLayout_, vertexBuffer, vertexBufferOffset, indexBuffer, + glprim[prim], result.drawNumTrans, GL_UNSIGNED_SHORT, (void *)(intptr_t)indexBufferOffset); } else { vertexBufferOffset = (uint32_t)frameData.pushVertex->Push(result.drawBuffer, result.drawNumTrans * sizeof(TransformedVertex), &vertexBuffer); - render_->BindVertexBuffer(softwareInputLayout_, vertexBuffer, vertexBufferOffset, nullptr); - render_->Draw(glprim[prim], 0, result.drawNumTrans); + render_->Draw( + softwareInputLayout_, vertexBuffer, vertexBufferOffset, glprim[prim], 0, result.drawNumTrans); } } else if (result.action == SW_CLEAR) { u32 clearColor = result.color;