Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 14 additions & 29 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,26 +1173,22 @@ 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));
}
CHECK_GL_ERROR_IF_DEBUG();
break;
}
case GLRRenderCommand::BIND_BUFFER:
{
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 (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;
}
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 {
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);
glDrawArrays(c.draw.mode, c.draw.first, c.draw.count);
}
CHECK_GL_ERROR_IF_DEBUG();
break;
Expand All @@ -1202,16 +1197,6 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last
// 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.drawIndexed.instances == 1) {
glDrawElements(c.drawIndexed.mode, c.drawIndexed.count, c.drawIndexed.indexType, c.drawIndexed.indices);
} else {
glDrawElementsInstanced(c.drawIndexed.mode, c.drawIndexed.count, c.drawIndexed.indexType, c.drawIndexed.indices, c.drawIndexed.instances);
}
CHECK_GL_ERROR_IF_DEBUG();
break;
case GLRRenderCommand::TEXTURESAMPLER:
Expand Down
20 changes: 6 additions & 14 deletions Common/GPU/OpenGL/GLQueueRunner.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,8 @@ enum class GLRRenderCommand : uint8_t {
BINDTEXTURE,
BIND_FB_TEXTURE,
BIND_VERTEX_BUFFER,
BIND_BUFFER,
GENMIPS,
DRAW,
DRAW_INDEXED,
TEXTURE_SUBIMAGE,
};

Expand Down Expand Up @@ -109,18 +107,17 @@ struct GLRRenderData {
uint8_t writeMask;
} stencilOp; // also write mask
struct {
GLRInputLayout *inputLayout;
GLRBuffer *buffer;
size_t offset;
GLRBuffer *indexBuffer;
GLenum mode; // primitive
GLint buffer;
GLint first;
GLint count;
} draw;
struct {
GLenum mode; // primitive
GLint count;
GLint instances;
GLint indexType;
void *indices;
} drawIndexed;
GLint instances;
} 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.
Expand Down Expand Up @@ -171,11 +168,6 @@ struct GLRRenderData {
struct {
GLRProgram *program;
} program;
struct {
GLRInputLayout *inputLayout;
GLRBuffer *buffer;
size_t offset;
} bindVertexBuffer;
struct {
int slot;
GLenum wrapS;
Expand Down
44 changes: 17 additions & 27 deletions Common/GPU/OpenGL/GLRenderManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -641,24 +641,6 @@ 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) {
_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;
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 @@ -924,25 +906,33 @@ 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;
data.draw.buffer = 0;
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) {
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_INDEXED };
data.drawIndexed.mode = mode;
data.drawIndexed.count = count;
data.drawIndexed.indexType = indexType;
data.drawIndexed.instances = instances;
data.drawIndexed.indices = indices;
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;
data.draw.indices = indices;
data.draw.instances = instances;
curRenderStep_->commands.push_back(data);
curRenderStep_->render.numDraws++;
}
Expand Down
21 changes: 8 additions & 13 deletions Common/GPU/OpenGL/thin3d_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1332,21 +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]);
}
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]);
}
renderManager_.BindIndexBuffer(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 @@ -1360,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);
}
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
4 changes: 2 additions & 2 deletions Common/VR/PPSSPPVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,8 +574,8 @@ 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) {
command.drawIndexed.count = 0;
} else if ((command.cmd == GLRRenderCommand::DRAW && command.draw.indices != nullptr) && !depthEnabled) {
command.draw.count = 0;
}
}
}
Expand Down
20 changes: 11 additions & 9 deletions GPU/GLES/DrawEngineGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,17 +326,19 @@ 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_->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_->Draw(glprim[prim], 0, vertexCount);
render_->Draw(
inputLayout, vertexBuffer, vertexBufferOffset,
glprim[prim], 0, vertexCount);
}
} else {
PROFILE_THIS_SCOPE("soft");
Expand Down Expand Up @@ -434,13 +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);
render_->BindIndexBuffer(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);
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