#pragma once #include #include #include #include "helpers.hpp" #include "opengl.hpp" #include "PICA/float_types.hpp" enum class ShaderType { Vertex, Geometry }; class PICAShader { using f24 = Floats::f24; using vec4f = OpenGL::Vector; int bufferIndex; // Index of the next instruction to overwrite for shader uploads ShaderType type; public: std::array loadedShader; // Currently loaded & active shader std::array bufferedShader; // Shader to be transferred when the SH_CODETRANSFER_END reg gets written to u32 boolUniform; std::array intUniforms; std::array floatUniforms; std::array fixedAttributes; // Fixed vertex attributes std::array attributes; // Attributes past to the shader std::array outputs; PICAShader(ShaderType type) : type(type) {} void reset() { loadedShader.fill(0); bufferedShader.fill(0); intUniforms.fill(0); boolUniform = 0; bufferIndex = 0; const vec4f zero = vec4f({ f24::fromFloat32(0.0), f24::fromFloat32(0.0), f24::fromFloat32(0.0), f24::fromFloat32(0.0) }); attributes.fill(zero); floatUniforms.fill(zero); outputs.fill(zero); } void finalize() { std::memcpy(&loadedShader[0], &bufferedShader[0], 512 * sizeof(u32)); } void setBufferIndex(u32 offset) { if (offset != 0) Helpers::panic("Is this register 9 or 11 bit?"); bufferIndex = (offset >> 2) & 511; } void uploadWord(u32 word) { bufferedShader[bufferIndex++] = word; bufferIndex &= 511; } void run(); };