Skip to content

Commit

Permalink
We always bind and draw together, so let's combine them to one command.
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed May 10, 2023
1 parent c7caefe commit b27c427
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 58 deletions.
34 changes: 15 additions & 19 deletions Common/GPU/OpenGL/GLQueueRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1148,20 +1148,19 @@ 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;
}
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);
Expand All @@ -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?
Expand Down
10 changes: 4 additions & 6 deletions Common/GPU/OpenGL/GLQueueRunner.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
23 changes: 10 additions & 13 deletions Common/GPU/OpenGL/GLRenderManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
20 changes: 8 additions & 12 deletions Common/GPU/OpenGL/thin3d_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
19 changes: 11 additions & 8 deletions GPU/GLES/DrawEngineGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit b27c427

Please sign in to comment.