mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-18 03:31:31 +12:00
GL: Actually upload data to stream buffers
This commit is contained in:
parent
e34bdb6841
commit
f96b609123
5 changed files with 46 additions and 27 deletions
|
@ -11,15 +11,16 @@ namespace PICA {
|
||||||
struct AttributeInfo {
|
struct AttributeInfo {
|
||||||
u8* data;
|
u8* data;
|
||||||
u32 offset;
|
u32 offset;
|
||||||
|
u32 size;
|
||||||
|
|
||||||
u8 type;
|
u8 type;
|
||||||
u8 componentCount;
|
u8 componentCount;
|
||||||
bool fixed;
|
bool fixed;
|
||||||
|
bool isPadding;
|
||||||
|
|
||||||
std::array<float, 4> fixedValue; // For fixed attributes
|
std::array<float, 4> fixedValue; // For fixed attributes
|
||||||
};
|
};
|
||||||
|
|
||||||
u8* vertexBuffer;
|
|
||||||
u8* indexBuffer;
|
u8* indexBuffer;
|
||||||
|
|
||||||
// Minimum and maximum index in the index buffer for a draw call
|
// Minimum and maximum index in the index buffer for a draw call
|
||||||
|
@ -31,5 +32,6 @@ namespace PICA {
|
||||||
|
|
||||||
bool canBeAccelerated;
|
bool canBeAccelerated;
|
||||||
bool indexed;
|
bool indexed;
|
||||||
|
bool useShortIndices;
|
||||||
};
|
};
|
||||||
} // namespace PICA
|
} // namespace PICA
|
|
@ -38,7 +38,6 @@ struct GLStateManager {
|
||||||
|
|
||||||
GLuint stencilMask;
|
GLuint stencilMask;
|
||||||
GLuint boundVAO;
|
GLuint boundVAO;
|
||||||
GLuint boundVBO;
|
|
||||||
GLuint currentProgram;
|
GLuint currentProgram;
|
||||||
GLuint boundUBO;
|
GLuint boundUBO;
|
||||||
|
|
||||||
|
@ -173,13 +172,6 @@ struct GLStateManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bindVBO(GLuint handle) {
|
|
||||||
if (boundVBO != handle) {
|
|
||||||
boundVBO = handle;
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void useProgram(GLuint handle) {
|
void useProgram(GLuint handle) {
|
||||||
if (currentProgram != handle) {
|
if (currentProgram != handle) {
|
||||||
currentProgram = handle;
|
currentProgram = handle;
|
||||||
|
@ -195,7 +187,6 @@ struct GLStateManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
void bindVAO(const OpenGL::VertexArray& vao) { bindVAO(vao.handle()); }
|
void bindVAO(const OpenGL::VertexArray& vao) { bindVAO(vao.handle()); }
|
||||||
void bindVBO(const OpenGL::VertexBuffer& vbo) { bindVBO(vbo.handle()); }
|
|
||||||
void useProgram(const OpenGL::Program& program) { useProgram(program.handle()); }
|
void useProgram(const OpenGL::Program& program) { useProgram(program.handle()); }
|
||||||
|
|
||||||
void setColourMask(bool r, bool g, bool b, bool a) {
|
void setColourMask(bool r, bool g, bool b, bool a) {
|
||||||
|
|
|
@ -12,7 +12,6 @@ void GPU::getAcceleratedDrawInfo(PICA::DrawAcceleration& accel, bool indexed) {
|
||||||
const u32 vertexBase = ((regs[PICA::InternalRegs::VertexAttribLoc] >> 1) & 0xfffffff) * 16;
|
const u32 vertexBase = ((regs[PICA::InternalRegs::VertexAttribLoc] >> 1) & 0xfffffff) * 16;
|
||||||
const u32 vertexCount = regs[PICA::InternalRegs::VertexCountReg]; // Total # of vertices to transfer
|
const u32 vertexCount = regs[PICA::InternalRegs::VertexCountReg]; // Total # of vertices to transfer
|
||||||
|
|
||||||
accel.vertexBuffer = getPointerPhys<u8>(vertexBase);
|
|
||||||
if (indexed) {
|
if (indexed) {
|
||||||
u32 indexBufferConfig = regs[PICA::InternalRegs::IndexBufferConfig];
|
u32 indexBufferConfig = regs[PICA::InternalRegs::IndexBufferConfig];
|
||||||
u32 indexBufferPointer = vertexBase + (indexBufferConfig & 0xfffffff);
|
u32 indexBufferPointer = vertexBase + (indexBufferConfig & 0xfffffff);
|
||||||
|
@ -22,11 +21,12 @@ void GPU::getAcceleratedDrawInfo(PICA::DrawAcceleration& accel, bool indexed) {
|
||||||
u16 maximumIndex = 0;
|
u16 maximumIndex = 0;
|
||||||
|
|
||||||
// Check whether the index buffer uses u16 indices or u8
|
// Check whether the index buffer uses u16 indices or u8
|
||||||
bool shortIndex = Helpers::getBit<31>(indexBufferConfig); // Indicates whether vert indices are 16-bit or 8-bit
|
accel.useShortIndices = Helpers::getBit<31>(indexBufferConfig); // Indicates whether vert indices are 16-bit or 8-bit
|
||||||
|
|
||||||
// Calculate the minimum and maximum indices used in the index buffer, so we'll only upload them
|
// Calculate the minimum and maximum indices used in the index buffer, so we'll only upload them
|
||||||
if (shortIndex) {
|
if (accel.useShortIndices) {
|
||||||
u16* indexBuffer16 = reinterpret_cast<u16*>(indexBuffer);
|
u16* indexBuffer16 = reinterpret_cast<u16*>(indexBuffer);
|
||||||
|
|
||||||
for (int i = 0; i < vertexCount; i++) {
|
for (int i = 0; i < vertexCount; i++) {
|
||||||
u16 index = indexBuffer16[i];
|
u16 index = indexBuffer16[i];
|
||||||
minimumIndex = std::min(minimumIndex, index);
|
minimumIndex = std::min(minimumIndex, index);
|
||||||
|
@ -84,6 +84,7 @@ void GPU::getAcceleratedDrawInfo(PICA::DrawAcceleration& accel, bool indexed) {
|
||||||
attributeOffset += (index - 11) << 2;
|
attributeOffset += (index - 11) << 2;
|
||||||
|
|
||||||
attr.data = nullptr;
|
attr.data = nullptr;
|
||||||
|
attr.isPadding = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,18 +92,19 @@ void GPU::getAcceleratedDrawInfo(PICA::DrawAcceleration& accel, bool indexed) {
|
||||||
const u32 attribType = attribInfo & 0x3; // Type of attribute (sbyte/ubyte/short/float)
|
const u32 attribType = attribInfo & 0x3; // Type of attribute (sbyte/ubyte/short/float)
|
||||||
const u32 size = (attribInfo >> 2) + 1; // Total number of components
|
const u32 size = (attribInfo >> 2) + 1; // Total number of components
|
||||||
|
|
||||||
|
// Size of each component based on the attribute type
|
||||||
|
static constexpr u32 sizePerComponent[4] = {1, 1, 2, 4};
|
||||||
|
|
||||||
attr.componentCount = size;
|
attr.componentCount = size;
|
||||||
attr.offset = attributeOffset;
|
attr.offset = attributeOffset;
|
||||||
|
attr.size = size * sizePerComponent[attribType];
|
||||||
attr.type = attribType;
|
attr.type = attribType;
|
||||||
|
attr.isPadding = false;
|
||||||
|
attributeOffset += attr.size;
|
||||||
|
|
||||||
// Get a pointer to the data where this attribute is stored
|
// Get a pointer to the data where this attribute is stored
|
||||||
const u32 attrAddress = vertexBase + attr.offset + (accel.minimumIndex * attrData.size);
|
const u32 attrAddress = vertexBase + attr.offset + (accel.minimumIndex * attrData.size);
|
||||||
attr.data = getPointerPhys<u8>(attrAddress);
|
attr.data = getPointerPhys<u8>(attrAddress);
|
||||||
|
|
||||||
// Size of each component based on the attribute type
|
|
||||||
static constexpr u32 sizePerComponent[4] = {1, 1, 2, 4};
|
|
||||||
attributeOffset += size * sizePerComponent[attribType];
|
|
||||||
|
|
||||||
attrCount += 1;
|
attrCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +116,7 @@ void GPU::getAcceleratedDrawInfo(PICA::DrawAcceleration& accel, bool indexed) {
|
||||||
attr.fixed = true;
|
attr.fixed = true;
|
||||||
// Set the data pointer to nullptr in order to catch any potential bugs
|
// Set the data pointer to nullptr in order to catch any potential bugs
|
||||||
attr.data = nullptr;
|
attr.data = nullptr;
|
||||||
|
attr.isPadding = false;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
attr.fixedValue[i] = fixedAttr[i].toFloat32();
|
attr.fixedValue[i] = fixedAttr[i].toFloat32();
|
||||||
|
|
|
@ -73,10 +73,7 @@ void GLStateManager::resetVAO() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLStateManager::resetBuffers() {
|
void GLStateManager::resetBuffers() {
|
||||||
boundVBO = 0;
|
|
||||||
boundUBO = 0;
|
boundUBO = 0;
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ void RendererGL::initGraphicsContextInternal() {
|
||||||
glBufferData(GL_UNIFORM_BUFFER, PICAShader::totalUniformSize(), nullptr, GL_DYNAMIC_DRAW);
|
glBufferData(GL_UNIFORM_BUFFER, PICAShader::totalUniformSize(), nullptr, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
vbo.createFixedSize(sizeof(Vertex) * vertexBufferSize * 2, GL_STREAM_DRAW);
|
vbo.createFixedSize(sizeof(Vertex) * vertexBufferSize * 2, GL_STREAM_DRAW);
|
||||||
gl.bindVBO(vbo);
|
vbo.bind();
|
||||||
// Initialize the VAO used when not using hw shaders
|
// Initialize the VAO used when not using hw shaders
|
||||||
defaultVAO.create();
|
defaultVAO.create();
|
||||||
gl.bindVAO(defaultVAO);
|
gl.bindVAO(defaultVAO);
|
||||||
|
@ -439,7 +439,7 @@ void RendererGL::drawVertices(PICA::PrimType primType, std::span<const Vertex> v
|
||||||
|
|
||||||
const auto primitiveTopology = primTypes[static_cast<usize>(primType)];
|
const auto primitiveTopology = primTypes[static_cast<usize>(primType)];
|
||||||
gl.disableScissor();
|
gl.disableScissor();
|
||||||
gl.bindVBO(vbo);
|
vbo.bind();
|
||||||
gl.bindVAO(usingAcceleratedShader ? hwShaderVAO : defaultVAO);
|
gl.bindVAO(usingAcceleratedShader ? hwShaderVAO : defaultVAO);
|
||||||
|
|
||||||
gl.enableClipPlane(0); // Clipping plane 0 is always enabled
|
gl.enableClipPlane(0); // Clipping plane 0 is always enabled
|
||||||
|
@ -1135,11 +1135,37 @@ void RendererGL::accelerateVertexUpload(ShaderUnit& shaderUnit, PICA::DrawAccele
|
||||||
GL_FLOAT, // 3: Float
|
GL_FLOAT, // 3: Float
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const u32 vertexCount = accel->maximumIndex - accel->minimumIndex + 1;
|
||||||
|
|
||||||
|
// Update index buffer if necessary
|
||||||
|
if (accel->indexed) {
|
||||||
|
const bool shortIndex = accel->useShortIndices;
|
||||||
|
const usize indexBufferSize = usize(vertexCount) * (shortIndex ? sizeof(u16) : sizeof(u8));
|
||||||
|
|
||||||
|
auto indexBufferRes = hwIndexBuffer->Map(4, indexBufferSize);
|
||||||
|
std::memcpy(indexBufferRes.pointer, accel->indexBuffer, indexBufferSize);
|
||||||
|
hwIndexBuffer->Unmap(indexBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto vertexBufferRes = hwVertexBuffer->Map(4, accel->vertexDataSize);
|
||||||
|
u8* vertexData = static_cast<u8*>(vertexBufferRes.pointer);
|
||||||
|
|
||||||
for (int i = 0; i < totalAttribCount; i++) {
|
for (int i = 0; i < totalAttribCount; i++) {
|
||||||
const auto& attrib = accel->attributeInfo[i];
|
const auto& attrib = accel->attributeInfo[i];
|
||||||
printf(
|
|
||||||
"%s attribute starting from offset %d with a size of %d components\n", attrib.fixed ? "Fixed" : "Variable", (!attrib.fixed) ? attrib.offset : 0,
|
if (attrib.fixed) {
|
||||||
!attrib.fixed ? attrib.componentCount : 4
|
Helpers::panic("Fixed attribute!");
|
||||||
);
|
} else {
|
||||||
|
if (attrib.isPadding) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 attributeSize = attrib.size * vertexCount;
|
||||||
|
|
||||||
|
std::memcpy(vertexData, attrib.data, attributeSize);
|
||||||
|
vertexData += attributeSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hwVertexBuffer->Unmap(accel->vertexDataSize);
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue