|
@@ -8,6 +8,8 @@
|
|
|
#include <glad/glad.h>
|
|
#include <glad/glad.h>
|
|
|
|
|
|
|
|
#include "common/color.h"
|
|
#include "common/color.h"
|
|
|
|
|
+#include "common/file_util.h"
|
|
|
|
|
+#include "common/make_unique.h"
|
|
|
#include "common/math_util.h"
|
|
#include "common/math_util.h"
|
|
|
#include "common/microprofile.h"
|
|
#include "common/microprofile.h"
|
|
|
#include "common/profiler.h"
|
|
#include "common/profiler.h"
|
|
@@ -19,7 +21,7 @@
|
|
|
#include "video_core/pica.h"
|
|
#include "video_core/pica.h"
|
|
|
#include "video_core/utils.h"
|
|
#include "video_core/utils.h"
|
|
|
#include "video_core/renderer_opengl/gl_rasterizer.h"
|
|
#include "video_core/renderer_opengl/gl_rasterizer.h"
|
|
|
-#include "video_core/renderer_opengl/gl_shaders.h"
|
|
|
|
|
|
|
+#include "video_core/renderer_opengl/gl_shader_gen.h"
|
|
|
#include "video_core/renderer_opengl/gl_shader_util.h"
|
|
#include "video_core/renderer_opengl/gl_shader_util.h"
|
|
|
#include "video_core/renderer_opengl/pica_to_gl.h"
|
|
#include "video_core/renderer_opengl/pica_to_gl.h"
|
|
|
|
|
|
|
@@ -38,36 +40,6 @@ RasterizerOpenGL::RasterizerOpenGL() : last_fb_color_addr(0), last_fb_depth_addr
|
|
|
RasterizerOpenGL::~RasterizerOpenGL() { }
|
|
RasterizerOpenGL::~RasterizerOpenGL() { }
|
|
|
|
|
|
|
|
void RasterizerOpenGL::InitObjects() {
|
|
void RasterizerOpenGL::InitObjects() {
|
|
|
- // Create the hardware shader program and get attrib/uniform locations
|
|
|
|
|
- shader.Create(GLShaders::g_vertex_shader_hw, GLShaders::g_fragment_shader_hw);
|
|
|
|
|
- attrib_position = glGetAttribLocation(shader.handle, "vert_position");
|
|
|
|
|
- attrib_color = glGetAttribLocation(shader.handle, "vert_color");
|
|
|
|
|
- attrib_texcoords = glGetAttribLocation(shader.handle, "vert_texcoords");
|
|
|
|
|
-
|
|
|
|
|
- uniform_alphatest_enabled = glGetUniformLocation(shader.handle, "alphatest_enabled");
|
|
|
|
|
- uniform_alphatest_func = glGetUniformLocation(shader.handle, "alphatest_func");
|
|
|
|
|
- uniform_alphatest_ref = glGetUniformLocation(shader.handle, "alphatest_ref");
|
|
|
|
|
-
|
|
|
|
|
- uniform_tex = glGetUniformLocation(shader.handle, "tex");
|
|
|
|
|
-
|
|
|
|
|
- uniform_tev_combiner_buffer_color = glGetUniformLocation(shader.handle, "tev_combiner_buffer_color");
|
|
|
|
|
-
|
|
|
|
|
- const auto tev_stages = Pica::g_state.regs.GetTevStages();
|
|
|
|
|
- for (unsigned tev_stage_index = 0; tev_stage_index < tev_stages.size(); ++tev_stage_index) {
|
|
|
|
|
- auto& uniform_tev_cfg = uniform_tev_cfgs[tev_stage_index];
|
|
|
|
|
-
|
|
|
|
|
- std::string tev_ref_str = "tev_cfgs[" + std::to_string(tev_stage_index) + "]";
|
|
|
|
|
- uniform_tev_cfg.enabled = glGetUniformLocation(shader.handle, (tev_ref_str + ".enabled").c_str());
|
|
|
|
|
- uniform_tev_cfg.color_sources = glGetUniformLocation(shader.handle, (tev_ref_str + ".color_sources").c_str());
|
|
|
|
|
- uniform_tev_cfg.alpha_sources = glGetUniformLocation(shader.handle, (tev_ref_str + ".alpha_sources").c_str());
|
|
|
|
|
- uniform_tev_cfg.color_modifiers = glGetUniformLocation(shader.handle, (tev_ref_str + ".color_modifiers").c_str());
|
|
|
|
|
- uniform_tev_cfg.alpha_modifiers = glGetUniformLocation(shader.handle, (tev_ref_str + ".alpha_modifiers").c_str());
|
|
|
|
|
- uniform_tev_cfg.color_alpha_op = glGetUniformLocation(shader.handle, (tev_ref_str + ".color_alpha_op").c_str());
|
|
|
|
|
- uniform_tev_cfg.color_alpha_multiplier = glGetUniformLocation(shader.handle, (tev_ref_str + ".color_alpha_multiplier").c_str());
|
|
|
|
|
- uniform_tev_cfg.const_color = glGetUniformLocation(shader.handle, (tev_ref_str + ".const_color").c_str());
|
|
|
|
|
- uniform_tev_cfg.updates_combiner_buffer_color_alpha = glGetUniformLocation(shader.handle, (tev_ref_str + ".updates_combiner_buffer_color_alpha").c_str());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
// Create sampler objects
|
|
// Create sampler objects
|
|
|
for (size_t i = 0; i < texture_samplers.size(); ++i) {
|
|
for (size_t i = 0; i < texture_samplers.size(); ++i) {
|
|
|
texture_samplers[i].Create();
|
|
texture_samplers[i].Create();
|
|
@@ -78,29 +50,25 @@ void RasterizerOpenGL::InitObjects() {
|
|
|
vertex_buffer.Create();
|
|
vertex_buffer.Create();
|
|
|
vertex_array.Create();
|
|
vertex_array.Create();
|
|
|
|
|
|
|
|
- // Update OpenGL state
|
|
|
|
|
state.draw.vertex_array = vertex_array.handle;
|
|
state.draw.vertex_array = vertex_array.handle;
|
|
|
state.draw.vertex_buffer = vertex_buffer.handle;
|
|
state.draw.vertex_buffer = vertex_buffer.handle;
|
|
|
- state.draw.shader_program = shader.handle;
|
|
|
|
|
-
|
|
|
|
|
state.Apply();
|
|
state.Apply();
|
|
|
|
|
|
|
|
- // Set the texture samplers to correspond to different texture units
|
|
|
|
|
- glUniform1i(uniform_tex, 0);
|
|
|
|
|
- glUniform1i(uniform_tex + 1, 1);
|
|
|
|
|
- glUniform1i(uniform_tex + 2, 2);
|
|
|
|
|
-
|
|
|
|
|
// Set vertex attributes
|
|
// Set vertex attributes
|
|
|
- glVertexAttribPointer(attrib_position, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position));
|
|
|
|
|
- glVertexAttribPointer(attrib_color, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, color));
|
|
|
|
|
- glVertexAttribPointer(attrib_texcoords, 2, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord0));
|
|
|
|
|
- glVertexAttribPointer(attrib_texcoords + 1, 2, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord1));
|
|
|
|
|
- glVertexAttribPointer(attrib_texcoords + 2, 2, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord2));
|
|
|
|
|
- glEnableVertexAttribArray(attrib_position);
|
|
|
|
|
- glEnableVertexAttribArray(attrib_color);
|
|
|
|
|
- glEnableVertexAttribArray(attrib_texcoords);
|
|
|
|
|
- glEnableVertexAttribArray(attrib_texcoords + 1);
|
|
|
|
|
- glEnableVertexAttribArray(attrib_texcoords + 2);
|
|
|
|
|
|
|
+ glVertexAttribPointer(GLShader::ATTRIBUTE_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position));
|
|
|
|
|
+ glEnableVertexAttribArray(GLShader::ATTRIBUTE_POSITION);
|
|
|
|
|
+
|
|
|
|
|
+ glVertexAttribPointer(GLShader::ATTRIBUTE_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, color));
|
|
|
|
|
+ glEnableVertexAttribArray(GLShader::ATTRIBUTE_COLOR);
|
|
|
|
|
+
|
|
|
|
|
+ glVertexAttribPointer(GLShader::ATTRIBUTE_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord0));
|
|
|
|
|
+ glVertexAttribPointer(GLShader::ATTRIBUTE_TEXCOORD1, 2, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord1));
|
|
|
|
|
+ glVertexAttribPointer(GLShader::ATTRIBUTE_TEXCOORD2, 2, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord2));
|
|
|
|
|
+ glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD0);
|
|
|
|
|
+ glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD1);
|
|
|
|
|
+ glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD2);
|
|
|
|
|
+
|
|
|
|
|
+ SetShader();
|
|
|
|
|
|
|
|
// Create textures for OGL framebuffer that will be rendered to, initially 1x1 to succeed in framebuffer creation
|
|
// Create textures for OGL framebuffer that will be rendered to, initially 1x1 to succeed in framebuffer creation
|
|
|
fb_color_texture.texture.Create();
|
|
fb_color_texture.texture.Create();
|
|
@@ -150,61 +118,15 @@ void RasterizerOpenGL::InitObjects() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void RasterizerOpenGL::Reset() {
|
|
void RasterizerOpenGL::Reset() {
|
|
|
- const auto& regs = Pica::g_state.regs;
|
|
|
|
|
-
|
|
|
|
|
SyncCullMode();
|
|
SyncCullMode();
|
|
|
SyncBlendEnabled();
|
|
SyncBlendEnabled();
|
|
|
SyncBlendFuncs();
|
|
SyncBlendFuncs();
|
|
|
SyncBlendColor();
|
|
SyncBlendColor();
|
|
|
- SyncAlphaTest();
|
|
|
|
|
SyncLogicOp();
|
|
SyncLogicOp();
|
|
|
SyncStencilTest();
|
|
SyncStencilTest();
|
|
|
SyncDepthTest();
|
|
SyncDepthTest();
|
|
|
|
|
|
|
|
- // TEV stage 0
|
|
|
|
|
- SyncTevSources(0, regs.tev_stage0);
|
|
|
|
|
- SyncTevModifiers(0, regs.tev_stage0);
|
|
|
|
|
- SyncTevOps(0, regs.tev_stage0);
|
|
|
|
|
- SyncTevColor(0, regs.tev_stage0);
|
|
|
|
|
- SyncTevMultipliers(0, regs.tev_stage0);
|
|
|
|
|
-
|
|
|
|
|
- // TEV stage 1
|
|
|
|
|
- SyncTevSources(1, regs.tev_stage1);
|
|
|
|
|
- SyncTevModifiers(1, regs.tev_stage1);
|
|
|
|
|
- SyncTevOps(1, regs.tev_stage1);
|
|
|
|
|
- SyncTevColor(1, regs.tev_stage1);
|
|
|
|
|
- SyncTevMultipliers(1, regs.tev_stage1);
|
|
|
|
|
-
|
|
|
|
|
- // TEV stage 2
|
|
|
|
|
- SyncTevSources(2, regs.tev_stage2);
|
|
|
|
|
- SyncTevModifiers(2, regs.tev_stage2);
|
|
|
|
|
- SyncTevOps(2, regs.tev_stage2);
|
|
|
|
|
- SyncTevColor(2, regs.tev_stage2);
|
|
|
|
|
- SyncTevMultipliers(2, regs.tev_stage2);
|
|
|
|
|
-
|
|
|
|
|
- // TEV stage 3
|
|
|
|
|
- SyncTevSources(3, regs.tev_stage3);
|
|
|
|
|
- SyncTevModifiers(3, regs.tev_stage3);
|
|
|
|
|
- SyncTevOps(3, regs.tev_stage3);
|
|
|
|
|
- SyncTevColor(3, regs.tev_stage3);
|
|
|
|
|
- SyncTevMultipliers(3, regs.tev_stage3);
|
|
|
|
|
-
|
|
|
|
|
- // TEV stage 4
|
|
|
|
|
- SyncTevSources(4, regs.tev_stage4);
|
|
|
|
|
- SyncTevModifiers(4, regs.tev_stage4);
|
|
|
|
|
- SyncTevOps(4, regs.tev_stage4);
|
|
|
|
|
- SyncTevColor(4, regs.tev_stage4);
|
|
|
|
|
- SyncTevMultipliers(4, regs.tev_stage4);
|
|
|
|
|
-
|
|
|
|
|
- // TEV stage 5
|
|
|
|
|
- SyncTevSources(5, regs.tev_stage5);
|
|
|
|
|
- SyncTevModifiers(5, regs.tev_stage5);
|
|
|
|
|
- SyncTevOps(5, regs.tev_stage5);
|
|
|
|
|
- SyncTevColor(5, regs.tev_stage5);
|
|
|
|
|
- SyncTevMultipliers(5, regs.tev_stage5);
|
|
|
|
|
-
|
|
|
|
|
- SyncCombinerColor();
|
|
|
|
|
- SyncCombinerWriteFlags();
|
|
|
|
|
|
|
+ SetShader();
|
|
|
|
|
|
|
|
res_cache.FullFlush();
|
|
res_cache.FullFlush();
|
|
|
}
|
|
}
|
|
@@ -221,6 +143,11 @@ void RasterizerOpenGL::DrawTriangles() {
|
|
|
SyncFramebuffer();
|
|
SyncFramebuffer();
|
|
|
SyncDrawState();
|
|
SyncDrawState();
|
|
|
|
|
|
|
|
|
|
+ if (state.draw.shader_dirty) {
|
|
|
|
|
+ SetShader();
|
|
|
|
|
+ state.draw.shader_dirty = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
glBufferData(GL_ARRAY_BUFFER, vertex_batch.size() * sizeof(HardwareVertex), vertex_batch.data(), GL_STREAM_DRAW);
|
|
glBufferData(GL_ARRAY_BUFFER, vertex_batch.size() * sizeof(HardwareVertex), vertex_batch.data(), GL_STREAM_DRAW);
|
|
|
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertex_batch.size());
|
|
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertex_batch.size());
|
|
|
|
|
|
|
@@ -272,6 +199,7 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
|
|
|
// Alpha test
|
|
// Alpha test
|
|
|
case PICA_REG_INDEX(output_merger.alpha_test):
|
|
case PICA_REG_INDEX(output_merger.alpha_test):
|
|
|
SyncAlphaTest();
|
|
SyncAlphaTest();
|
|
|
|
|
+ state.draw.shader_dirty = true;
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
// Stencil test
|
|
// Stencil test
|
|
@@ -290,117 +218,57 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
|
|
|
SyncLogicOp();
|
|
SyncLogicOp();
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
- // TEV stage 0
|
|
|
|
|
|
|
+ // TEV stages
|
|
|
case PICA_REG_INDEX(tev_stage0.color_source1):
|
|
case PICA_REG_INDEX(tev_stage0.color_source1):
|
|
|
- SyncTevSources(0, regs.tev_stage0);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage0.color_modifier1):
|
|
case PICA_REG_INDEX(tev_stage0.color_modifier1):
|
|
|
- SyncTevModifiers(0, regs.tev_stage0);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage0.color_op):
|
|
case PICA_REG_INDEX(tev_stage0.color_op):
|
|
|
- SyncTevOps(0, regs.tev_stage0);
|
|
|
|
|
- break;
|
|
|
|
|
- case PICA_REG_INDEX(tev_stage0.const_r):
|
|
|
|
|
- SyncTevColor(0, regs.tev_stage0);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage0.color_scale):
|
|
case PICA_REG_INDEX(tev_stage0.color_scale):
|
|
|
- SyncTevMultipliers(0, regs.tev_stage0);
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- // TEV stage 1
|
|
|
|
|
case PICA_REG_INDEX(tev_stage1.color_source1):
|
|
case PICA_REG_INDEX(tev_stage1.color_source1):
|
|
|
- SyncTevSources(1, regs.tev_stage1);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage1.color_modifier1):
|
|
case PICA_REG_INDEX(tev_stage1.color_modifier1):
|
|
|
- SyncTevModifiers(1, regs.tev_stage1);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage1.color_op):
|
|
case PICA_REG_INDEX(tev_stage1.color_op):
|
|
|
- SyncTevOps(1, regs.tev_stage1);
|
|
|
|
|
- break;
|
|
|
|
|
- case PICA_REG_INDEX(tev_stage1.const_r):
|
|
|
|
|
- SyncTevColor(1, regs.tev_stage1);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage1.color_scale):
|
|
case PICA_REG_INDEX(tev_stage1.color_scale):
|
|
|
- SyncTevMultipliers(1, regs.tev_stage1);
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- // TEV stage 2
|
|
|
|
|
case PICA_REG_INDEX(tev_stage2.color_source1):
|
|
case PICA_REG_INDEX(tev_stage2.color_source1):
|
|
|
- SyncTevSources(2, regs.tev_stage2);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage2.color_modifier1):
|
|
case PICA_REG_INDEX(tev_stage2.color_modifier1):
|
|
|
- SyncTevModifiers(2, regs.tev_stage2);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage2.color_op):
|
|
case PICA_REG_INDEX(tev_stage2.color_op):
|
|
|
- SyncTevOps(2, regs.tev_stage2);
|
|
|
|
|
- break;
|
|
|
|
|
- case PICA_REG_INDEX(tev_stage2.const_r):
|
|
|
|
|
- SyncTevColor(2, regs.tev_stage2);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage2.color_scale):
|
|
case PICA_REG_INDEX(tev_stage2.color_scale):
|
|
|
- SyncTevMultipliers(2, regs.tev_stage2);
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- // TEV stage 3
|
|
|
|
|
case PICA_REG_INDEX(tev_stage3.color_source1):
|
|
case PICA_REG_INDEX(tev_stage3.color_source1):
|
|
|
- SyncTevSources(3, regs.tev_stage3);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage3.color_modifier1):
|
|
case PICA_REG_INDEX(tev_stage3.color_modifier1):
|
|
|
- SyncTevModifiers(3, regs.tev_stage3);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage3.color_op):
|
|
case PICA_REG_INDEX(tev_stage3.color_op):
|
|
|
- SyncTevOps(3, regs.tev_stage3);
|
|
|
|
|
- break;
|
|
|
|
|
- case PICA_REG_INDEX(tev_stage3.const_r):
|
|
|
|
|
- SyncTevColor(3, regs.tev_stage3);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage3.color_scale):
|
|
case PICA_REG_INDEX(tev_stage3.color_scale):
|
|
|
- SyncTevMultipliers(3, regs.tev_stage3);
|
|
|
|
|
- break;
|
|
|
|
|
-
|
|
|
|
|
- // TEV stage 4
|
|
|
|
|
case PICA_REG_INDEX(tev_stage4.color_source1):
|
|
case PICA_REG_INDEX(tev_stage4.color_source1):
|
|
|
- SyncTevSources(4, regs.tev_stage4);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage4.color_modifier1):
|
|
case PICA_REG_INDEX(tev_stage4.color_modifier1):
|
|
|
- SyncTevModifiers(4, regs.tev_stage4);
|
|
|
|
|
- break;
|
|
|
|
|
case PICA_REG_INDEX(tev_stage4.color_op):
|
|
case PICA_REG_INDEX(tev_stage4.color_op):
|
|
|
- SyncTevOps(4, regs.tev_stage4);
|
|
|
|
|
|
|
+ case PICA_REG_INDEX(tev_stage4.color_scale):
|
|
|
|
|
+ case PICA_REG_INDEX(tev_stage5.color_source1):
|
|
|
|
|
+ case PICA_REG_INDEX(tev_stage5.color_modifier1):
|
|
|
|
|
+ case PICA_REG_INDEX(tev_stage5.color_op):
|
|
|
|
|
+ case PICA_REG_INDEX(tev_stage5.color_scale):
|
|
|
|
|
+ case PICA_REG_INDEX(tev_combiner_buffer_input):
|
|
|
|
|
+ state.draw.shader_dirty = true;
|
|
|
break;
|
|
break;
|
|
|
- case PICA_REG_INDEX(tev_stage4.const_r):
|
|
|
|
|
- SyncTevColor(4, regs.tev_stage4);
|
|
|
|
|
|
|
+ case PICA_REG_INDEX(tev_stage0.const_r):
|
|
|
|
|
+ SyncTevConstColor(0, regs.tev_stage0);
|
|
|
break;
|
|
break;
|
|
|
- case PICA_REG_INDEX(tev_stage4.color_scale):
|
|
|
|
|
- SyncTevMultipliers(4, regs.tev_stage4);
|
|
|
|
|
|
|
+ case PICA_REG_INDEX(tev_stage1.const_r):
|
|
|
|
|
+ SyncTevConstColor(1, regs.tev_stage1);
|
|
|
break;
|
|
break;
|
|
|
-
|
|
|
|
|
- // TEV stage 5
|
|
|
|
|
- case PICA_REG_INDEX(tev_stage5.color_source1):
|
|
|
|
|
- SyncTevSources(5, regs.tev_stage5);
|
|
|
|
|
|
|
+ case PICA_REG_INDEX(tev_stage2.const_r):
|
|
|
|
|
+ SyncTevConstColor(2, regs.tev_stage2);
|
|
|
break;
|
|
break;
|
|
|
- case PICA_REG_INDEX(tev_stage5.color_modifier1):
|
|
|
|
|
- SyncTevModifiers(5, regs.tev_stage5);
|
|
|
|
|
|
|
+ case PICA_REG_INDEX(tev_stage3.const_r):
|
|
|
|
|
+ SyncTevConstColor(3, regs.tev_stage3);
|
|
|
break;
|
|
break;
|
|
|
- case PICA_REG_INDEX(tev_stage5.color_op):
|
|
|
|
|
- SyncTevOps(5, regs.tev_stage5);
|
|
|
|
|
|
|
+ case PICA_REG_INDEX(tev_stage4.const_r):
|
|
|
|
|
+ SyncTevConstColor(4, regs.tev_stage4);
|
|
|
break;
|
|
break;
|
|
|
case PICA_REG_INDEX(tev_stage5.const_r):
|
|
case PICA_REG_INDEX(tev_stage5.const_r):
|
|
|
- SyncTevColor(5, regs.tev_stage5);
|
|
|
|
|
- break;
|
|
|
|
|
- case PICA_REG_INDEX(tev_stage5.color_scale):
|
|
|
|
|
- SyncTevMultipliers(5, regs.tev_stage5);
|
|
|
|
|
|
|
+ SyncTevConstColor(5, regs.tev_stage5);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
// TEV combiner buffer color
|
|
// TEV combiner buffer color
|
|
|
case PICA_REG_INDEX(tev_combiner_buffer_color):
|
|
case PICA_REG_INDEX(tev_combiner_buffer_color):
|
|
|
SyncCombinerColor();
|
|
SyncCombinerColor();
|
|
|
break;
|
|
break;
|
|
|
-
|
|
|
|
|
- // TEV combiner buffer write flags
|
|
|
|
|
- case PICA_REG_INDEX(tev_combiner_buffer_input):
|
|
|
|
|
- SyncCombinerWriteFlags();
|
|
|
|
|
- break;
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -592,6 +460,41 @@ void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::
|
|
|
state.Apply();
|
|
state.Apply();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void RasterizerOpenGL::SetShader() {
|
|
|
|
|
+ PicaShaderConfig config = PicaShaderConfig::CurrentConfig();
|
|
|
|
|
+ std::unique_ptr<PicaShader> shader = Common::make_unique<PicaShader>();
|
|
|
|
|
+
|
|
|
|
|
+ // Find (or generate) the GLSL shader for the current TEV state
|
|
|
|
|
+ auto cached_shader = shader_cache.find(config);
|
|
|
|
|
+ if (cached_shader != shader_cache.end()) {
|
|
|
|
|
+ current_shader = cached_shader->second.get();
|
|
|
|
|
+
|
|
|
|
|
+ state.draw.shader_program = current_shader->shader.handle;
|
|
|
|
|
+ state.Apply();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ LOG_DEBUG(Render_OpenGL, "Creating new shader");
|
|
|
|
|
+
|
|
|
|
|
+ shader->shader.Create(GLShader::GenerateVertexShader().c_str(), GLShader::GenerateFragmentShader(config).c_str());
|
|
|
|
|
+
|
|
|
|
|
+ state.draw.shader_program = shader->shader.handle;
|
|
|
|
|
+ state.Apply();
|
|
|
|
|
+
|
|
|
|
|
+ // Set the texture samplers to correspond to different texture units
|
|
|
|
|
+ glUniform1i(PicaShader::Uniform::Texture0, 0);
|
|
|
|
|
+ glUniform1i(PicaShader::Uniform::Texture1, 1);
|
|
|
|
|
+ glUniform1i(PicaShader::Uniform::Texture2, 2);
|
|
|
|
|
+
|
|
|
|
|
+ current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Update uniforms
|
|
|
|
|
+ SyncAlphaTest();
|
|
|
|
|
+ SyncCombinerColor();
|
|
|
|
|
+ auto& tev_stages = Pica::g_state.regs.GetTevStages();
|
|
|
|
|
+ for (int index = 0; index < tev_stages.size(); ++index)
|
|
|
|
|
+ SyncTevConstColor(index, tev_stages[index]);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void RasterizerOpenGL::SyncFramebuffer() {
|
|
void RasterizerOpenGL::SyncFramebuffer() {
|
|
|
const auto& regs = Pica::g_state.regs;
|
|
const auto& regs = Pica::g_state.regs;
|
|
|
|
|
|
|
@@ -712,9 +615,7 @@ void RasterizerOpenGL::SyncBlendColor() {
|
|
|
|
|
|
|
|
void RasterizerOpenGL::SyncAlphaTest() {
|
|
void RasterizerOpenGL::SyncAlphaTest() {
|
|
|
const auto& regs = Pica::g_state.regs;
|
|
const auto& regs = Pica::g_state.regs;
|
|
|
- glUniform1i(uniform_alphatest_enabled, regs.output_merger.alpha_test.enable);
|
|
|
|
|
- glUniform1i(uniform_alphatest_func, (GLint)regs.output_merger.alpha_test.func.Value());
|
|
|
|
|
- glUniform1f(uniform_alphatest_ref, regs.output_merger.alpha_test.ref / 255.0f);
|
|
|
|
|
|
|
+ glUniform1i(PicaShader::Uniform::AlphaTestRef, regs.output_merger.alpha_test.ref);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void RasterizerOpenGL::SyncLogicOp() {
|
|
void RasterizerOpenGL::SyncLogicOp() {
|
|
@@ -744,56 +645,14 @@ void RasterizerOpenGL::SyncDepthTest() {
|
|
|
state.depth.write_mask = regs.output_merger.depth_write_enable ? GL_TRUE : GL_FALSE;
|
|
state.depth.write_mask = regs.output_merger.depth_write_enable ? GL_TRUE : GL_FALSE;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void RasterizerOpenGL::SyncTevSources(unsigned stage_index, const Pica::Regs::TevStageConfig& config) {
|
|
|
|
|
- GLint color_srcs[3] = { (GLint)config.color_source1.Value(),
|
|
|
|
|
- (GLint)config.color_source2.Value(),
|
|
|
|
|
- (GLint)config.color_source3.Value() };
|
|
|
|
|
- GLint alpha_srcs[3] = { (GLint)config.alpha_source1.Value(),
|
|
|
|
|
- (GLint)config.alpha_source2.Value(),
|
|
|
|
|
- (GLint)config.alpha_source3.Value() };
|
|
|
|
|
-
|
|
|
|
|
- glUniform3iv(uniform_tev_cfgs[stage_index].color_sources, 1, color_srcs);
|
|
|
|
|
- glUniform3iv(uniform_tev_cfgs[stage_index].alpha_sources, 1, alpha_srcs);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void RasterizerOpenGL::SyncTevModifiers(unsigned stage_index, const Pica::Regs::TevStageConfig& config) {
|
|
|
|
|
- GLint color_mods[3] = { (GLint)config.color_modifier1.Value(),
|
|
|
|
|
- (GLint)config.color_modifier2.Value(),
|
|
|
|
|
- (GLint)config.color_modifier3.Value() };
|
|
|
|
|
- GLint alpha_mods[3] = { (GLint)config.alpha_modifier1.Value(),
|
|
|
|
|
- (GLint)config.alpha_modifier2.Value(),
|
|
|
|
|
- (GLint)config.alpha_modifier3.Value() };
|
|
|
|
|
-
|
|
|
|
|
- glUniform3iv(uniform_tev_cfgs[stage_index].color_modifiers, 1, color_mods);
|
|
|
|
|
- glUniform3iv(uniform_tev_cfgs[stage_index].alpha_modifiers, 1, alpha_mods);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void RasterizerOpenGL::SyncTevOps(unsigned stage_index, const Pica::Regs::TevStageConfig& config) {
|
|
|
|
|
- glUniform2i(uniform_tev_cfgs[stage_index].color_alpha_op, (GLint)config.color_op.Value(), (GLint)config.alpha_op.Value());
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void RasterizerOpenGL::SyncTevColor(unsigned stage_index, const Pica::Regs::TevStageConfig& config) {
|
|
|
|
|
- auto const_color = PicaToGL::ColorRGBA8(config.const_color);
|
|
|
|
|
- glUniform4fv(uniform_tev_cfgs[stage_index].const_color, 1, const_color.data());
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void RasterizerOpenGL::SyncTevMultipliers(unsigned stage_index, const Pica::Regs::TevStageConfig& config) {
|
|
|
|
|
- glUniform2i(uniform_tev_cfgs[stage_index].color_alpha_multiplier, config.GetColorMultiplier(), config.GetAlphaMultiplier());
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
void RasterizerOpenGL::SyncCombinerColor() {
|
|
void RasterizerOpenGL::SyncCombinerColor() {
|
|
|
auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw);
|
|
auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw);
|
|
|
- glUniform4fv(uniform_tev_combiner_buffer_color, 1, combiner_color.data());
|
|
|
|
|
|
|
+ glUniform4fv(PicaShader::Uniform::TevCombinerBufferColor, 1, combiner_color.data());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void RasterizerOpenGL::SyncCombinerWriteFlags() {
|
|
|
|
|
- const auto& regs = Pica::g_state.regs;
|
|
|
|
|
- const auto tev_stages = regs.GetTevStages();
|
|
|
|
|
- for (unsigned tev_stage_index = 0; tev_stage_index < tev_stages.size(); ++tev_stage_index) {
|
|
|
|
|
- glUniform2i(uniform_tev_cfgs[tev_stage_index].updates_combiner_buffer_color_alpha,
|
|
|
|
|
- regs.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferColor(tev_stage_index),
|
|
|
|
|
- regs.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferAlpha(tev_stage_index));
|
|
|
|
|
- }
|
|
|
|
|
|
|
+void RasterizerOpenGL::SyncTevConstColor(int stage_index, const Pica::Regs::TevStageConfig& tev_stage) {
|
|
|
|
|
+ auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color);
|
|
|
|
|
+ glUniform4fv(PicaShader::Uniform::TevConstColors + stage_index, 1, const_color.data());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void RasterizerOpenGL::SyncDrawState() {
|
|
void RasterizerOpenGL::SyncDrawState() {
|
|
@@ -824,12 +683,6 @@ void RasterizerOpenGL::SyncDrawState() {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Skip processing TEV stages that simply pass the previous stage results through
|
|
|
|
|
- const auto tev_stages = regs.GetTevStages();
|
|
|
|
|
- for (unsigned tev_stage_index = 0; tev_stage_index < tev_stages.size(); ++tev_stage_index) {
|
|
|
|
|
- glUniform1i(uniform_tev_cfgs[tev_stage_index].enabled, !IsPassThroughTevStage(tev_stages[tev_stage_index]));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
state.Apply();
|
|
state.Apply();
|
|
|
}
|
|
}
|
|
|
|
|
|