mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-12 09:09:47 +12:00
Immediate mode vertex submission attempt 1
This commit is contained in:
parent
6ecdf71dbc
commit
922424b8d0
4 changed files with 61 additions and 10 deletions
|
@ -22,6 +22,11 @@ class GPU {
|
||||||
std::array<u32, regNum> regs; // GPU internal registers
|
std::array<u32, regNum> regs; // GPU internal registers
|
||||||
std::array<vec4f, 16> currentAttributes; // Vertex attributes before being passed to the shader
|
std::array<vec4f, 16> currentAttributes; // Vertex attributes before being passed to the shader
|
||||||
|
|
||||||
|
std::array<vec4f, 16> immediateModeAttributes; // Vertex attributes uploaded via immediate mode submission
|
||||||
|
std::array<Vertex, 3> immediateModeVertices;
|
||||||
|
uint immediateModeVertIndex;
|
||||||
|
uint immediateModeAttrIndex; // Index of the immediate mode attribute we're uploading
|
||||||
|
|
||||||
template <bool indexed>
|
template <bool indexed>
|
||||||
void drawArrays();
|
void drawArrays();
|
||||||
|
|
||||||
|
@ -53,7 +58,7 @@ class GPU {
|
||||||
std::array<u32, 3> fixedAttrBuff; // Buffer to hold fixed attributes in until they get submitted
|
std::array<u32, 3> fixedAttrBuff; // Buffer to hold fixed attributes in until they get submitted
|
||||||
|
|
||||||
Renderer renderer;
|
Renderer renderer;
|
||||||
|
Vertex getImmediateModeVertex();
|
||||||
public:
|
public:
|
||||||
GPU(Memory& mem);
|
GPU(Memory& mem);
|
||||||
void initGraphicsContext() { renderer.initGraphicsContext(); }
|
void initGraphicsContext() { renderer.initGraphicsContext(); }
|
||||||
|
|
|
@ -18,6 +18,9 @@ void GPU::reset() {
|
||||||
fixedAttribMask = 0;
|
fixedAttribMask = 0;
|
||||||
fixedAttribIndex = 0;
|
fixedAttribIndex = 0;
|
||||||
fixedAttribCount = 0;
|
fixedAttribCount = 0;
|
||||||
|
immediateModeAttrIndex = 0;
|
||||||
|
immediateModeVertIndex = 0;
|
||||||
|
|
||||||
fixedAttrBuff.fill(0);
|
fixedAttrBuff.fill(0);
|
||||||
|
|
||||||
for (auto& e : attributeInfo) {
|
for (auto& e : attributeInfo) {
|
||||||
|
@ -193,7 +196,6 @@ void GPU::drawArrays() {
|
||||||
|
|
||||||
//printf("(x, y, z, w) = (%f, %f, %f, %f)\n", (double)vertices[i].position.x(), (double)vertices[i].position.y(), (double)vertices[i].position.z(), (double)vertices[i].position.w());
|
//printf("(x, y, z, w) = (%f, %f, %f, %f)\n", (double)vertices[i].position.x(), (double)vertices[i].position.y(), (double)vertices[i].position.z(), (double)vertices[i].position.w());
|
||||||
//printf("(r, g, b, a) = (%f, %f, %f, %f)\n", (double)vertices[i].colour.r(), (double)vertices[i].colour.g(), (double)vertices[i].colour.b(), (double)vertices[i].colour.a());
|
//printf("(r, g, b, a) = (%f, %f, %f, %f)\n", (double)vertices[i].colour.r(), (double)vertices[i].colour.g(), (double)vertices[i].colour.b(), (double)vertices[i].colour.a());
|
||||||
//printf("(u, v ) = (%f, %f)\n", vertices[i].UVs.u(), vertices[i].UVs.v());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The fourth type is meant to be "Geometry primitive". TODO: Find out what that is
|
// The fourth type is meant to be "Geometry primitive". TODO: Find out what that is
|
||||||
|
@ -204,8 +206,24 @@ void GPU::drawArrays() {
|
||||||
renderer.drawVertices(shape, vertices, vertexCount);
|
renderer.drawVertices(shape, vertices, vertexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vertex GPU::getImmediateModeVertex() {
|
||||||
|
Vertex v;
|
||||||
|
const int totalAttrCount = (regs[PICAInternalRegs::VertexShaderAttrNum] & 0xf) + 1;
|
||||||
|
|
||||||
|
// Copy immediate mode attributes to vertex shader unit
|
||||||
|
for (int i = 0; i < totalAttrCount; i++) {
|
||||||
|
shaderUnit.vs.inputs[i] = immediateModeAttributes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run VS and return vertex data. TODO: Don't hardcode offsets for each attribute
|
||||||
|
shaderUnit.vs.run();
|
||||||
|
std::memcpy(&v.position, &shaderUnit.vs.outputs[0], sizeof(vec4f));
|
||||||
|
std::memcpy(&v.colour, &shaderUnit.vs.outputs[1], sizeof(vec4f));
|
||||||
|
std::memcpy(&v.UVs, &shaderUnit.vs.outputs[2], 2 * sizeof(f24));
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
void GPU::fireDMA(u32 dest, u32 source, u32 size) {
|
void GPU::fireDMA(u32 dest, u32 source, u32 size) {
|
||||||
printf("[GPU] DMA of %08X bytes from %08X to %08X\n", size, source, dest);
|
|
||||||
constexpr u32 vramStart = VirtualAddrs::VramStart;
|
constexpr u32 vramStart = VirtualAddrs::VramStart;
|
||||||
constexpr u32 vramSize = VirtualAddrs::VramSize;
|
constexpr u32 vramSize = VirtualAddrs::VramSize;
|
||||||
|
|
||||||
|
|
|
@ -104,24 +104,52 @@ void GPU::writeInternalReg(u32 index, u32 value, u32 mask) {
|
||||||
fixedAttribCount = 0;
|
fixedAttribCount = 0;
|
||||||
fixedAttribIndex = value & 0xf;
|
fixedAttribIndex = value & 0xf;
|
||||||
|
|
||||||
if (fixedAttribIndex == 0xf) Helpers::panic("[PICA] Immediate mode vertex submission");
|
if (fixedAttribIndex == 0xf) {
|
||||||
|
log("[PICA] Immediate mode vertex submission enabled");
|
||||||
|
immediateModeAttrIndex = 0;
|
||||||
|
immediateModeVertIndex = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FixedAttribData0: case FixedAttribData1: case FixedAttribData2:
|
case FixedAttribData0: case FixedAttribData1: case FixedAttribData2:
|
||||||
if (fixedAttribIndex >= 12) Helpers::panic("[PICA] Tried to write to fixed attribute %d", fixedAttribIndex);
|
|
||||||
|
|
||||||
fixedAttrBuff[fixedAttribCount++] = value;
|
fixedAttrBuff[fixedAttribCount++] = value;
|
||||||
|
|
||||||
if (fixedAttribCount == 3) {
|
if (fixedAttribCount == 3) {
|
||||||
fixedAttribCount = 0;
|
fixedAttribCount = 0;
|
||||||
|
|
||||||
vec4f& attr = shaderUnit.vs.fixedAttributes[fixedAttribIndex];
|
vec4f attr;
|
||||||
// These are stored in the reverse order anyone would expect them to be in
|
// These are stored in the reverse order anyone would expect them to be in
|
||||||
attr.x() = f24::fromRaw(fixedAttrBuff[2] & 0xffffff);
|
attr.x() = f24::fromRaw(fixedAttrBuff[2] & 0xffffff);
|
||||||
attr.y() = f24::fromRaw(((fixedAttrBuff[1] & 0xffff) << 8) | (fixedAttrBuff[2] >> 24));
|
attr.y() = f24::fromRaw(((fixedAttrBuff[1] & 0xffff) << 8) | (fixedAttrBuff[2] >> 24));
|
||||||
attr.z() = f24::fromRaw(((fixedAttrBuff[0] & 0xff) << 16) | (fixedAttrBuff[1] >> 16));
|
attr.z() = f24::fromRaw(((fixedAttrBuff[0] & 0xff) << 16) | (fixedAttrBuff[1] >> 16));
|
||||||
attr.w() = f24::fromRaw(fixedAttrBuff[0] >> 8);
|
attr.w() = f24::fromRaw(fixedAttrBuff[0] >> 8);
|
||||||
|
|
||||||
fixedAttribIndex++;
|
// If the fixed attribute index is < 12, we're just writing to one of the fixed attributes
|
||||||
|
if (fixedAttribIndex < 12) [[likely]] {
|
||||||
|
shaderUnit.vs.fixedAttributes[fixedAttribIndex++] = attr;
|
||||||
|
} else if (fixedAttribIndex == 15) { // Otherwise if it's 15, we're submitting an immediate mode vertex
|
||||||
|
const uint totalAttrCount = (regs[PICAInternalRegs::VertexShaderAttrNum] & 0xf) + 1;
|
||||||
|
if (totalAttrCount <= immediateModeAttrIndex) {
|
||||||
|
printf("Broken state in the immediate mode vertex submission pipeline. Failing silently\n");
|
||||||
|
immediateModeAttrIndex = 0;
|
||||||
|
immediateModeVertIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
immediateModeAttributes[immediateModeAttrIndex++] = attr;
|
||||||
|
if (immediateModeAttrIndex == totalAttrCount) {
|
||||||
|
Vertex v = getImmediateModeVertex();
|
||||||
|
immediateModeAttrIndex = 0;
|
||||||
|
immediateModeVertices[immediateModeVertIndex++] = v;
|
||||||
|
|
||||||
|
// If we've reached 3 verts, issue a draw call
|
||||||
|
if (immediateModeVertIndex == 3) {
|
||||||
|
renderer.drawVertices(OpenGL::Triangle, &immediateModeVertices[0], 3);
|
||||||
|
immediateModeVertIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // Writing to fixed attributes 13 and 14 probably does nothing, but we'll see
|
||||||
|
log("Wrote to invalid fixed vertex attribute %d\n", fixedAttribIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -51,9 +51,9 @@ const char* fragmentShader = R"(
|
||||||
fragColour = colour;
|
fragColour = colour;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get original depth value pre-perspective by converting from [near, far] = [0, 1] to [-1, 1]
|
// Get original depth value by converting from [near, far] = [0, 1] to [-1, 1]
|
||||||
// We do this by converting to [0, 2] first and subtracting 1 to go to [-1, 1]
|
// We do this by converting to [0, 2] first and subtracting 1 to go to [-1, 1]
|
||||||
float z_over_w = gl_FragCoord.z * 2.0f - 1.0;
|
float z_over_w = gl_FragCoord.z * 2.0f - 1.0f;
|
||||||
float depth = z_over_w * u_depthScale + u_depthOffset;
|
float depth = z_over_w * u_depthScale + u_depthOffset;
|
||||||
|
|
||||||
if (!u_depthmapEnable) // Divide z by w if depthmap enable == 0 (ie using W-buffering)
|
if (!u_depthmapEnable) // Divide z by w if depthmap enable == 0 (ie using W-buffering)
|
||||||
|
|
Loading…
Add table
Reference in a new issue