Skip to content

Commit

Permalink
HW shaders: Accelerate index draws
Browse files Browse the repository at this point in the history
  • Loading branch information
wheremyfoodat committed Aug 25, 2024
1 parent e925a91 commit 24aec39
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 10 deletions.
8 changes: 7 additions & 1 deletion include/renderer_gl/renderer_gl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,15 @@ class RendererGL final : public Renderer {
float oldDepthScale = -1.0;
float oldDepthOffset = 0.0;
bool oldDepthmapEnable = false;
// Set by prepareDraw, tells us whether the current draw is using hw-accelerated shader
// Set by prepareForDraw, tells us whether the current draw is using hw-accelerated shader
bool usingAcceleratedShader = false;
bool performIndexedRender = false;
bool usingShortIndices = false;

// Set by prepareForDraw, metadata for indexed renders
GLuint minimumIndex = 0;
GLuint maximumIndex = 0;
void* hwIndexBufferOffset = nullptr;

// Cached pointer to the current vertex shader when using HW accelerated shaders
OpenGL::Shader* generatedVertexShader = nullptr;
Expand Down
26 changes: 17 additions & 9 deletions src/core/renderer_gl/renderer_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,10 +435,8 @@ void RendererGL::drawVertices(PICA::PrimType primType, std::span<const Vertex> v
const auto primitiveTopology = primTypes[static_cast<usize>(primType)];
gl.disableScissor();

if (usingAcceleratedShader) {
hwVertexBuffer->Bind();
gl.bindVAO(hwShaderVAO);
} else {
// If we're using accelerated shaders, the hw VAO, VBO and EBO objects will have already been bound in prepareForDraw
if (!usingAcceleratedShader) {
vbo.bind();
gl.bindVAO(defaultVAO);
}
Expand Down Expand Up @@ -509,9 +507,12 @@ void RendererGL::drawVertices(PICA::PrimType primType, std::span<const Vertex> v
OpenGL::draw(primitiveTopology, GLsizei(vertices.size()));
} else {
if (performIndexedRender) {
// When doing indexed rendering, bind the IBO and use glDrawRangeElementsBaseVertex to issue the indexed draw
// When doing indexed rendering, bind the EBO and use glDrawRangeElementsBaseVertex to issue the indexed draw
hwIndexBuffer->Bind();
//glDrawRangeElementsBaseVertex();
glDrawRangeElementsBaseVertex(
primitiveTopology, minimumIndex, maximumIndex, GLsizei(vertices.size()), usingShortIndices ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE,
hwIndexBufferOffset, -minimumIndex
);
} else {
// When doing non-indexed rendering, just use glDrawArrays
OpenGL::draw(primitiveTopology, GLsizei(vertices.size()));
Expand Down Expand Up @@ -1008,7 +1009,10 @@ bool RendererGL::prepareForDraw(ShaderUnit& shaderUnit, PICA::DrawAcceleration*

// Upload vertex data and index buffer data to our GPU
accelerateVertexUpload(shaderUnit, accel);

performIndexedRender = accel->indexed;
minimumIndex = GLsizei(accel->minimumIndex);
maximumIndex = GLsizei(accel->maximumIndex);
}
}

Expand Down Expand Up @@ -1146,17 +1150,21 @@ void RendererGL::accelerateVertexUpload(ShaderUnit& shaderUnit, PICA::DrawAccele

// Update index buffer if necessary
if (accel->indexed) {
const bool shortIndex = accel->useShortIndices;
const usize indexBufferSize = usize(vertexCount) * (shortIndex ? sizeof(u16) : sizeof(u8));
usingShortIndices = accel->useShortIndices;
const usize indexBufferSize = usize(vertexCount) * (usingShortIndices ? sizeof(u16) : sizeof(u8));

hwIndexBuffer->Bind();
auto indexBufferRes = hwIndexBuffer->Map(4, indexBufferSize);
hwIndexBufferOffset = reinterpret_cast<void*>(usize(indexBufferRes.buffer_offset));

std::memcpy(indexBufferRes.pointer, accel->indexBuffer, indexBufferSize);
hwIndexBuffer->Unmap(indexBufferSize);
}

hwVertexBuffer->Bind();
auto vertexBufferRes = hwVertexBuffer->Map(4, accel->vertexDataSize);

u8* vertexData = static_cast<u8*>(vertexBufferRes.pointer);

gl.bindVAO(hwShaderVAO);

for (int i = 0; i < totalAttribCount; i++) {
Expand Down

0 comments on commit 24aec39

Please sign in to comment.