[GPU] Upgrade TEV functions and variables to Pesca style

This commit is contained in:
fleroviux 2023-06-20 22:28:58 +02:00
parent 7ad8a5041e
commit 2f19310c42

View file

@ -88,73 +88,73 @@ const char* fragmentShader = R"(
uniform sampler2D u_tex1;
uniform sampler2D u_tex2;
vec4 tev_sources[16];
vec4 tev_next_previous_buffer;
bool tev_unimplemented_source = false;
vec4 tevSources[16];
vec4 tevNextPreviousBuffer;
bool tevUnimplementedSourceFlag = false;
// OpenGL ES 1.1 reference pages for TEVs (this is what the PICA200 implements):
// https://registry.khronos.org/OpenGL-Refpages/es1.1/xhtml/glTexEnv.xml
vec4 tev_fetch_source(uint src_id) {
vec4 tevFetchSource(uint src_id) {
if (src_id >= 6u && src_id < 13u) {
tev_unimplemented_source = true;
tevUnimplementedSourceFlag = true;
}
return tev_sources[src_id];
return tevSources[src_id];
}
vec4 tev_get_color_and_alpha_source(int tev_id, int src_id) {
vec4 tevGetColorAndAlphaSource(int tev_id, int src_id) {
vec4 result;
vec4 color_source = tev_fetch_source((u_textureEnvSource[tev_id] >> (src_id * 4)) & 15u);
vec4 alpha_source = tev_fetch_source((u_textureEnvSource[tev_id] >> (src_id * 4 + 16)) & 15u);
vec4 colorSource = tevFetchSource((u_textureEnvSource[tev_id] >> (src_id * 4)) & 15u);
vec4 alphaSource = tevFetchSource((u_textureEnvSource[tev_id] >> (src_id * 4 + 16)) & 15u);
uint color_operand = (u_textureEnvOperand[tev_id] >> (src_id * 4)) & 15u;
uint alpha_operand = (u_textureEnvOperand[tev_id] >> (12 + src_id * 4)) & 7u;
uint colorOperand = (u_textureEnvOperand[tev_id] >> (src_id * 4)) & 15u;
uint alphaOperand = (u_textureEnvOperand[tev_id] >> (12 + src_id * 4)) & 7u;
// TODO: figure out what the undocumented values do
switch (color_operand) {
case 0u: result.rgb = color_source.rgb; break; // Source color
case 1u: result.rgb = 1.0 - color_source.rgb; break; // One minus source color
case 2u: result.rgb = vec3(color_source.a); break; // Source alpha
case 3u: result.rgb = vec3(1.0 - color_source.a); break; // One minus source alpha
case 4u: result.rgb = vec3(color_source.r); break; // Source red
case 5u: result.rgb = vec3(1.0 - color_source.r); break; // One minus source red
case 8u: result.rgb = vec3(color_source.g); break; // Source green
case 9u: result.rgb = vec3(1.0 - color_source.g); break; // One minus source green
case 12u: result.rgb = vec3(color_source.b); break; // Source blue
case 13u: result.rgb = vec3(1.0 - color_source.b); break; // One minus source blue
switch (colorOperand) {
case 0u: result.rgb = colorSource.rgb; break; // Source color
case 1u: result.rgb = 1.0 - colorSource.rgb; break; // One minus source color
case 2u: result.rgb = vec3(colorSource.a); break; // Source alpha
case 3u: result.rgb = vec3(1.0 - colorSource.a); break; // One minus source alpha
case 4u: result.rgb = vec3(colorSource.r); break; // Source red
case 5u: result.rgb = vec3(1.0 - colorSource.r); break; // One minus source red
case 8u: result.rgb = vec3(colorSource.g); break; // Source green
case 9u: result.rgb = vec3(1.0 - colorSource.g); break; // One minus source green
case 12u: result.rgb = vec3(colorSource.b); break; // Source blue
case 13u: result.rgb = vec3(1.0 - colorSource.b); break; // One minus source blue
default: break;
}
// TODO: figure out what the undocumented values do
switch (alpha_operand) {
case 0u: result.a = alpha_source.a; break; // Source alpha
case 1u: result.a = 1.0 - alpha_source.a; break; // One minus source alpha
case 2u: result.a = alpha_source.r; break; // Source red
case 3u: result.a = 1.0 - alpha_source.r; break; // One minus source red
case 4u: result.a = alpha_source.g; break; // Source green
case 5u: result.a = 1.0 - alpha_source.g; break; // One minus source green
case 6u: result.a = alpha_source.b; break; // Source blue
case 7u: result.a = 1.0 - alpha_source.b; break; // One minus source blue
switch (alphaOperand) {
case 0u: result.a = alphaSource.a; break; // Source alpha
case 1u: result.a = 1.0 - alphaSource.a; break; // One minus source alpha
case 2u: result.a = alphaSource.r; break; // Source red
case 3u: result.a = 1.0 - alphaSource.r; break; // One minus source red
case 4u: result.a = alphaSource.g; break; // Source green
case 5u: result.a = 1.0 - alphaSource.g; break; // One minus source green
case 6u: result.a = alphaSource.b; break; // Source blue
case 7u: result.a = 1.0 - alphaSource.b; break; // One minus source blue
default: break;
}
return result;
}
vec4 tev_combine(int tev_id) {
vec4 source0 = tev_get_color_and_alpha_source(tev_id, 0);
vec4 source1 = tev_get_color_and_alpha_source(tev_id, 1);
vec4 source2 = tev_get_color_and_alpha_source(tev_id, 2);
vec4 tevCalculateCombiner(int tev_id) {
vec4 source0 = tevGetColorAndAlphaSource(tev_id, 0);
vec4 source1 = tevGetColorAndAlphaSource(tev_id, 1);
vec4 source2 = tevGetColorAndAlphaSource(tev_id, 2);
uint color_combine = u_textureEnvCombiner[tev_id] & 15u;
uint alpha_combine = (u_textureEnvCombiner[tev_id] >> 16) & 15u;
uint colorCombine = u_textureEnvCombiner[tev_id] & 15u;
uint alphaCombine = (u_textureEnvCombiner[tev_id] >> 16) & 15u;
vec4 result = vec4(1.0);
// TODO: figure out what the undocumented values do
switch (color_combine) {
switch (colorCombine) {
case 0u: result.rgb = source0.rgb; break; // Replace
case 1u: result.rgb = source0.rgb * source1.rgb; break; // Modulate
case 2u: result.rgb = min(vec3(1.0), source0.rgb + source1.rgb); break; // Add
@ -168,10 +168,10 @@ const char* fragmentShader = R"(
default: break;
}
if (color_combine != 7u) { // The color combiner also writes the alpha channel in the "Dot3 RGBA" mode.
if (colorCombine != 7u) { // The color combiner also writes the alpha channel in the "Dot3 RGBA" mode.
// TODO: figure out what the undocumented values do
// TODO: test if the alpha combiner supports all the same modes as the color combiner.
switch (alpha_combine) {
switch (alphaCombine) {
case 0u: result.a = source0.a; break; // Replace
case 1u: result.a = source0.a * source1.a; break; // Modulate
case 2u: result.a = min(1.0, source0.a + source1.a); break; // Add
@ -191,40 +191,40 @@ const char* fragmentShader = R"(
}
void main() {
vec2 tex2_uv = (u_textureConfig & (1 << 13)) != 0u ? v_texcoord1 : v_texcoord2;
vec2 tex2UV = (u_textureConfig & (1 << 13)) != 0u ? v_texcoord1 : v_texcoord2;
// TODO: what do invalid sources and disabled textures read as?
// And what does the "previous combiner" source read initially?
tev_sources[0] = v_colour; // Primary/vertex color
tev_sources[1] = vec4(vec3(0.5), 1.0); // Fragment primary color
tev_sources[2] = vec4(vec3(0.5), 1.0); // Fragment secondary color
if ((u_textureConfig & 1u) != 0u) tev_sources[3] = texture(u_tex0, v_texcoord0.xy);
if ((u_textureConfig & 2u) != 0u) tev_sources[4] = texture(u_tex1, v_texcoord1);
if ((u_textureConfig & 4u) != 0u) tev_sources[5] = texture(u_tex2, tex2_uv);
tev_sources[13] = vec4(0.0); // Previous buffer
tev_sources[15] = vec4(0.0); // Previous combiner
tevSources[0] = v_colour; // Primary/vertex color
tevSources[1] = vec4(vec3(0.5), 1.0); // Fragment primary color
tevSources[2] = vec4(vec3(0.5), 1.0); // Fragment secondary color
if ((u_textureConfig & 1u) != 0u) tevSources[3] = texture(u_tex0, v_texcoord0.xy);
if ((u_textureConfig & 2u) != 0u) tevSources[4] = texture(u_tex1, v_texcoord1);
if ((u_textureConfig & 4u) != 0u) tevSources[5] = texture(u_tex2, tex2UV);
tevSources[13] = vec4(0.0); // Previous buffer
tevSources[15] = vec4(0.0); // Previous combiner
tev_next_previous_buffer = v_textureEnvBufferColor;
tevNextPreviousBuffer = v_textureEnvBufferColor;
for (int i = 0; i < 6; i++) {
tev_sources[14] = v_textureEnvColor[i]; // Constant color
tev_sources[15] = tev_combine(i);
tev_sources[13] = tev_next_previous_buffer;
tevSources[14] = v_textureEnvColor[i]; // Constant color
tevSources[15] = tevCalculateCombiner(i);
tevSources[13] = tevNextPreviousBuffer;
if (i < 4) {
if ((u_textureEnvUpdateBuffer & (0x100u << i)) != 0u) {
tev_next_previous_buffer.rgb = tev_sources[15].rgb;
tevNextPreviousBuffer.rgb = tevSources[15].rgb;
}
if ((u_textureEnvUpdateBuffer & (0x1000u << i)) != 0u) {
tev_next_previous_buffer.a = tev_sources[15].a;
tevNextPreviousBuffer.a = tevSources[15].a;
}
}
}
fragColour = tev_sources[15];
fragColour = tevSources[15];
if (tev_unimplemented_source) {
if (tevUnimplementedSourceFlag) {
// fragColour = vec4(1.0, 0.0, 1.0, 1.0);
}