mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-06 22:25:41 +12:00
GL renderer: Add fallback for when driver doesn't provide glDrawRangeElementsBaseVertex (#617)
* GL: Add fallback for when driver doesn't provide glDrawRangeElementsBaseVertex * GL: Fix fallback when glDrawRangeElementsBaseVertex is absent
This commit is contained in:
parent
54d0618f02
commit
cdc61ea95a
2 changed files with 45 additions and 6 deletions
|
@ -250,4 +250,25 @@ namespace PICA::IndexBuffer {
|
||||||
return analyzePortable<useShortIndices>(indexBuffer, vertexCount);
|
return analyzePortable<useShortIndices>(indexBuffer, vertexCount);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In some really unfortunate scenarios (eg Android Studio emulator), we don't have access to glDrawRangeElementsBaseVertex
|
||||||
|
// So we need to subtract the base vertex index from every index in the index buffer ourselves
|
||||||
|
// This is not really common, so we do it without SIMD for the moment, just to be able to run on Android Studio
|
||||||
|
template <bool useShortIndices>
|
||||||
|
void subtractBaseIndex(u8* indexBuffer, u32 indexCount, u16 baseIndex) {
|
||||||
|
// Calculate the minimum and maximum indices used in the index buffer, so we'll only upload them
|
||||||
|
if constexpr (useShortIndices) {
|
||||||
|
u16* indexBuffer16 = reinterpret_cast<u16*>(indexBuffer);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < indexCount; i++) {
|
||||||
|
indexBuffer16[i] -= baseIndex;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
u8 baseIndex8 = u8(baseIndex);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < indexCount; i++) {
|
||||||
|
indexBuffer[i] -= baseIndex8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace PICA::IndexBuffer
|
} // namespace PICA::IndexBuffer
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "PICA/float_types.hpp"
|
#include "PICA/float_types.hpp"
|
||||||
#include "PICA/gpu.hpp"
|
#include "PICA/gpu.hpp"
|
||||||
#include "PICA/pica_frag_uniforms.hpp"
|
#include "PICA/pica_frag_uniforms.hpp"
|
||||||
|
#include "PICA/pica_simd.hpp"
|
||||||
#include "PICA/regs.hpp"
|
#include "PICA/regs.hpp"
|
||||||
#include "PICA/shader_decompiler.hpp"
|
#include "PICA/shader_decompiler.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
|
@ -192,8 +193,8 @@ void RendererGL::initGraphicsContextInternal() {
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
// Populate our driver info structure
|
// Populate our driver info structure
|
||||||
driverInfo.supportsExtFbFetch = GLAD_GL_EXT_shader_framebuffer_fetch != 0;
|
driverInfo.supportsExtFbFetch = (GLAD_GL_EXT_shader_framebuffer_fetch != 0);
|
||||||
driverInfo.supportsArmFbFetch = GLAD_GL_ARM_shader_framebuffer_fetch != 0;
|
driverInfo.supportsArmFbFetch = (GLAD_GL_ARM_shader_framebuffer_fetch != 0);
|
||||||
|
|
||||||
// Initialize the default vertex shader used with shadergen
|
// Initialize the default vertex shader used with shadergen
|
||||||
std::string defaultShadergenVSSource = fragShaderGen.getDefaultVertexShader();
|
std::string defaultShadergenVSSource = fragShaderGen.getDefaultVertexShader();
|
||||||
|
@ -519,10 +520,20 @@ void RendererGL::drawVertices(PICA::PrimType primType, std::span<const Vertex> v
|
||||||
if (performIndexedRender) {
|
if (performIndexedRender) {
|
||||||
// When doing indexed rendering, use glDrawRangeElementsBaseVertex to issue the indexed draw
|
// When doing indexed rendering, use glDrawRangeElementsBaseVertex to issue the indexed draw
|
||||||
hwIndexBuffer->Bind();
|
hwIndexBuffer->Bind();
|
||||||
glDrawRangeElementsBaseVertex(
|
|
||||||
primitiveTopology, minimumIndex, maximumIndex, GLsizei(vertices.size()), usingShortIndices ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE,
|
if (glDrawRangeElementsBaseVertex != nullptr) [[likely]] {
|
||||||
hwIndexBufferOffset, -GLint(minimumIndex)
|
glDrawRangeElementsBaseVertex(
|
||||||
);
|
primitiveTopology, minimumIndex, maximumIndex, GLsizei(vertices.size()), usingShortIndices ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE,
|
||||||
|
hwIndexBufferOffset, -GLint(minimumIndex)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// If glDrawRangeElementsBaseVertex is not available then prepareForDraw will have subtracted the base vertex from the index buffer
|
||||||
|
// for us, so just use glDrawRangeElements
|
||||||
|
glDrawRangeElements(
|
||||||
|
primitiveTopology, 0, GLint(maximumIndex - minimumIndex), GLsizei(vertices.size()),
|
||||||
|
usingShortIndices ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE, hwIndexBufferOffset
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// When doing non-indexed rendering, just use glDrawArrays
|
// When doing non-indexed rendering, just use glDrawArrays
|
||||||
OpenGL::draw(primitiveTopology, GLsizei(vertices.size()));
|
OpenGL::draw(primitiveTopology, GLsizei(vertices.size()));
|
||||||
|
@ -1170,6 +1181,13 @@ void RendererGL::accelerateVertexUpload(ShaderUnit& shaderUnit, PICA::DrawAccele
|
||||||
hwIndexBufferOffset = reinterpret_cast<void*>(usize(indexBufferRes.buffer_offset));
|
hwIndexBufferOffset = reinterpret_cast<void*>(usize(indexBufferRes.buffer_offset));
|
||||||
|
|
||||||
std::memcpy(indexBufferRes.pointer, accel->indexBuffer, indexBufferSize);
|
std::memcpy(indexBufferRes.pointer, accel->indexBuffer, indexBufferSize);
|
||||||
|
// If we don't have glDrawRangeElementsBaseVertex, we must subtract the base index value from our index buffer manually
|
||||||
|
if (glDrawRangeElementsBaseVertex == nullptr) [[unlikely]] {
|
||||||
|
const u32 indexCount = regs[PICA::InternalRegs::VertexCountReg];
|
||||||
|
usingShortIndices ? PICA::IndexBuffer::subtractBaseIndex<true>((u8*)indexBufferRes.pointer, indexCount, accel->minimumIndex)
|
||||||
|
: PICA::IndexBuffer::subtractBaseIndex<false>((u8*)indexBufferRes.pointer, indexCount, accel->minimumIndex);
|
||||||
|
}
|
||||||
|
|
||||||
hwIndexBuffer->Unmap(indexBufferSize);
|
hwIndexBuffer->Unmap(indexBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue