More hw VAO work

This commit is contained in:
wheremyfoodat 2024-08-24 02:58:05 +03:00
parent cf31f7b7e0
commit 5d6f59112a
3 changed files with 70 additions and 6 deletions

View file

@ -6,13 +6,28 @@
namespace PICA {
struct DrawAcceleration {
static constexpr u32 maxAttribCount = 12;
struct AttributeInfo {
u32 offset;
u8 type;
u8 componentCount;
bool fixed;
std::array<float, 4> fixedValue; // For fixed attributes
};
u8* vertexBuffer;
u8* indexBuffer;
// Minimum and maximum index in the index buffer for a draw call
u16 minimumIndex, maximumIndex;
u32 totalAttribCount;
u32 vertexDataSize;
std::array<AttributeInfo, maxAttribCount> attributeInfo;
bool canBeAccelerated;
bool indexed;
};

View file

@ -7,6 +7,8 @@
void GPU::getAcceleratedDrawInfo(PICA::DrawAcceleration& accel, bool indexed) {
accel.indexed = indexed;
accel.totalAttribCount = totalAttribCount;
const u32 vertexBase = ((regs[PICA::InternalRegs::VertexAttribLoc] >> 1) & 0xfffffff) * 16;
const u32 vertexCount = regs[PICA::InternalRegs::VertexCountReg]; // Total # of vertices to transfer
@ -47,23 +49,60 @@ void GPU::getAcceleratedDrawInfo(PICA::DrawAcceleration& accel, bool indexed) {
accel.maximumIndex = accel.minimumIndex + vertexCount - 1;
}
const u64 vertexCfg = u64(regs[PICA::InternalRegs::AttribFormatLow]) | (u64(regs[PICA::InternalRegs::AttribFormatHigh]) << 32);
int buffer = 0;
accel.vertexDataSize = 0;
for (int attrCount = 0; attrCount < totalAttribCount; attrCount++) {
bool fixedAttribute = (fixedAttribMask & (1 << attrCount)) != 0;
auto& attr = accel.attributeInfo[attrCount];
attr.fixed = (fixedAttribMask & (1 << attrCount)) != 0;
if (!fixedAttribute) {
auto& attr = attributeInfo[buffer]; // Get information for this attribute
if (attr.componentCount != 0) {
// Variable attribute attribute
if (!attr.fixed) {
auto& attrData = attributeInfo[buffer]; // Get information for this attribute
u64 attrCfg = attrData.getConfigFull(); // Get config1 | (config2 << 32)
u32 attributeOffset = attrData.offset;
if (attrData.componentCount != 0) {
// Size of the attribute in bytes multiplied by the total number of vertices
const u32 bytes = attr.size * vertexCount;
const u32 bytes = attrData.size * vertexCount;
// Add it to the total vertex data size, aligned to 4 bytes.
accel.vertexDataSize += (bytes + 3) & ~3;
}
for (int i = 0; i < attrData.componentCount; i++) {
uint index = (attrCfg >> (i * 4)) & 0xf; // Get index of attribute in vertexCfg
// Vertex attributes used as padding
// 12, 13, 14 and 15 are equivalent to 4, 8, 12 and 16 bytes of padding respectively
if (index >= 12) [[unlikely]] {
Helpers::panic("Padding attribute");
// Align attribute address up to a 4 byte boundary
attributeOffset = (attributeOffset + 3) & -4;
attributeOffset += (index - 11) << 2;
continue;
}
u32 attribInfo = (vertexCfg >> (index * 4)) & 0xf;
u32 attribType = attribInfo & 0x3; // Type of attribute(sbyte/ubyte/short/float)
u32 size = (attribInfo >> 2) + 1; // Total number of components
attr.componentCount = size;
attr.offset = attributeOffset;
attr.type = attribType;
// Size of each component based on the attribute type
static constexpr u32 sizePerComponent[4] = {1, 1, 2, 4};
attributeOffset += size * sizePerComponent[attribType];
}
buffer++;
} else {
vec4f& fixedAttr = shaderUnit.vs.fixedAttributes[attrCount];
for (int i = 0; i < 4; i++) {
attr.fixedValue[i] = fixedAttr[i].toFloat32();
}
}
}

View file

@ -1115,5 +1115,15 @@ void RendererGL::initUbershader(OpenGL::Program& program) {
}
void RendererGL::accelerateVertexUpload(ShaderUnit& shaderUnit, PICA::DrawAcceleration* accel) {
u32 buffer = 0; // Vertex buffer index for non-fixed attributes
u32 attrCount = 0;
const u32 totalAttribCount = accel->totalAttribCount;
static constexpr GLenum attributeFormats[4] = {
GL_BYTE, // 0: Signed byte
GL_UNSIGNED_BYTE, // 1: Unsigned byte
GL_SHORT, // 2: Short
GL_FLOAT, // 3: Float
};
}