summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp151
1 files changed, 85 insertions, 66 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 9cd95dadc..8037aadc5 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -2499,61 +2499,81 @@ private:
2499 const bool depth_compare = 2499 const bool depth_compare =
2500 instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC); 2500 instr.tex.UsesMiscMode(Tegra::Shader::TextureMiscMode::DC);
2501 u32 num_coordinates = TextureCoordinates(texture_type); 2501 u32 num_coordinates = TextureCoordinates(texture_type);
2502 if (depth_compare) 2502 u32 start_index = 0;
2503 num_coordinates += 1; 2503 std::string array_elem;
2504 if (is_array) {
2505 array_elem = regs.GetRegisterAsInteger(instr.gpr8);
2506 start_index = 1;
2507 }
2508 auto process_mode = instr.tex.GetTextureProcessMode();
2509 u32 start_index_b = 0;
2510 std::string lod_value;
2511 if (process_mode != Tegra::Shader::TextureProcessMode::LZ &&
2512 process_mode != Tegra::Shader::TextureProcessMode::None) {
2513 start_index_b = 1;
2514 lod_value = regs.GetRegisterAsFloat(instr.gpr20);
2515 }
2516
2517 std::string depth_value;
2518 if (depth_compare) {
2519 depth_value = regs.GetRegisterAsFloat(instr.gpr20.Value() + start_index_b);
2520 }
2521
2522 bool depth_compare_extra = false;
2504 2523
2505 switch (num_coordinates) { 2524 switch (num_coordinates) {
2506 case 1: { 2525 case 1: {
2526 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index);
2507 if (is_array) { 2527 if (is_array) {
2508 const std::string index = regs.GetRegisterAsInteger(instr.gpr8); 2528 if (depth_compare) {
2509 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2529 coord = "vec3 coords = vec3(" + x + ", " + depth_value + ", " +
2510 coord = "vec2 coords = vec2(" + x + ", " + index + ");"; 2530 array_elem + ");";
2531 } else {
2532 coord = "vec2 coords = vec2(" + x + ", " + array_elem + ");";
2533 }
2511 } else { 2534 } else {
2512 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2535 if (depth_compare) {
2513 coord = "float coords = " + x + ';'; 2536 coord = "vec2 coords = vec2(" + x + ", " + depth_value + ");";
2537 } else {
2538 coord = "float coords = " + x + ';';
2539 }
2514 } 2540 }
2515 break; 2541 break;
2516 } 2542 }
2517 case 2: { 2543 case 2: {
2544 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index);
2545 const std::string y =
2546 regs.GetRegisterAsFloat(instr.gpr8.Value() + start_index + 1);
2518 if (is_array) { 2547 if (is_array) {
2519 const std::string index = regs.GetRegisterAsInteger(instr.gpr8); 2548 if (depth_compare) {
2520 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2549 coord = "vec4 coords = vec4(" + x + ", " + y + ", " + depth_value +
2521 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2); 2550 ", " + array_elem + ");";
2522 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + index + ");"; 2551 } else {
2552 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + array_elem + ");";
2553 }
2523 } else { 2554 } else {
2524 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2555 if (depth_compare) {
2525 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2556 coord =
2526 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 2557 "vec3 coords = vec3(" + x + ", " + y + ", " + depth_value + ");";
2558 } else {
2559 coord = "vec2 coords = vec2(" + x + ", " + y + ");";
2560 }
2527 } 2561 }
2528 break; 2562 break;
2529 } 2563 }
2530 case 3: { 2564 case 3: {
2531 if (depth_compare) { 2565 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2532 if (is_array) { 2566 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2533 const std::string index = regs.GetRegisterAsInteger(instr.gpr8); 2567 const std::string z = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2);
2534 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2568 if (is_array) {
2535 const std::string y = regs.GetRegisterAsFloat(instr.gpr20); 2569 depth_compare_extra = depth_compare;
2536 const std::string z = regs.GetRegisterAsFloat(instr.gpr20.Value() + 1); 2570 coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " +
2537 coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + 2571 array_elem + ");";
2538 ");";
2539 } else {
2540 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2541 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2542 const std::string z = regs.GetRegisterAsFloat(instr.gpr20);
2543 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");";
2544 }
2545 } else { 2572 } else {
2546 if (is_array) { 2573 if (depth_compare) {
2547 const std::string index = regs.GetRegisterAsInteger(instr.gpr8); 2574 coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " +
2548 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2575 depth_value + ");";
2549 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2);
2550 const std::string z = regs.GetRegisterAsFloat(instr.gpr8.Value() + 3);
2551 coord = "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index +
2552 ");";
2553 } else { 2576 } else {
2554 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2555 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2556 const std::string z = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2);
2557 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");"; 2577 coord = "vec3 coords = vec3(" + x + ", " + y + ", " + z + ");";
2558 } 2578 }
2559 } 2579 }
@@ -2569,8 +2589,6 @@ private:
2569 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 2589 coord = "vec2 coords = vec2(" + x + ", " + y + ");";
2570 texture_type = Tegra::Shader::TextureType::Texture2D; 2590 texture_type = Tegra::Shader::TextureType::Texture2D;
2571 } 2591 }
2572 // TODO: make sure coordinates are always indexed to gpr8 and gpr20 is always bias
2573 // or lod.
2574 2592
2575 const std::string sampler = 2593 const std::string sampler =
2576 GetSampler(instr.sampler, texture_type, is_array, depth_compare); 2594 GetSampler(instr.sampler, texture_type, is_array, depth_compare);
@@ -2584,48 +2602,49 @@ private:
2584 2602
2585 switch (instr.tex.GetTextureProcessMode()) { 2603 switch (instr.tex.GetTextureProcessMode()) {
2586 case Tegra::Shader::TextureProcessMode::None: { 2604 case Tegra::Shader::TextureProcessMode::None: {
2587 texture = "texture(" + sampler + ", coords)"; 2605 if (!depth_compare_extra) {
2606 texture = "texture(" + sampler + ", coords)";
2607 } else {
2608 texture = "texture(" + sampler + ", coords, " + depth_value + ')';
2609 }
2588 break; 2610 break;
2589 } 2611 }
2590 case Tegra::Shader::TextureProcessMode::LZ: { 2612 case Tegra::Shader::TextureProcessMode::LZ: {
2591 texture = "textureLod(" + sampler + ", coords, 0.0)"; 2613 if (!depth_compare_extra) {
2614 texture = "textureLod(" + sampler + ", coords, 0.0)";
2615 } else {
2616 texture = "texture(" + sampler + ", coords, " + depth_value + ')';
2617 }
2592 break; 2618 break;
2593 } 2619 }
2594 case Tegra::Shader::TextureProcessMode::LB: 2620 case Tegra::Shader::TextureProcessMode::LB:
2595 case Tegra::Shader::TextureProcessMode::LBA: { 2621 case Tegra::Shader::TextureProcessMode::LBA: {
2596 const std::string bias = [&]() {
2597 if (depth_compare) {
2598 if (is_array)
2599 return regs.GetRegisterAsFloat(instr.gpr20.Value() + 2);
2600 else
2601 return regs.GetRegisterAsFloat(instr.gpr20.Value() + 1);
2602 } else {
2603 return regs.GetRegisterAsFloat(instr.gpr20);
2604 }
2605 }();
2606 shader.AddLine("float bias = " + bias + ';');
2607
2608 // TODO: Figure if A suffix changes the equation at all. 2622 // TODO: Figure if A suffix changes the equation at all.
2609 texture = "texture(" + sampler + ", coords, bias)"; 2623 if (!depth_compare_extra) {
2624 texture = "texture(" + sampler + ", coords, " + lod_value + ')';
2625 } else {
2626 texture = "texture(" + sampler + ", coords, " + depth_value + ')';
2627 LOG_WARNING(HW_GPU, "OpenGL Limitation: can't set bias value along depth compare");
2628 }
2610 break; 2629 break;
2611 } 2630 }
2612 case Tegra::Shader::TextureProcessMode::LL: 2631 case Tegra::Shader::TextureProcessMode::LL:
2613 case Tegra::Shader::TextureProcessMode::LLA: { 2632 case Tegra::Shader::TextureProcessMode::LLA: {
2614 const std::string lod = [&]() {
2615 if (num_coordinates <= 2) {
2616 return regs.GetRegisterAsFloat(instr.gpr20);
2617 } else {
2618 return regs.GetRegisterAsFloat(instr.gpr20.Value() + 1);
2619 }
2620 }();
2621 shader.AddLine("float lod = " + lod + ';');
2622
2623 // TODO: Figure if A suffix changes the equation at all. 2633 // TODO: Figure if A suffix changes the equation at all.
2624 texture = "textureLod(" + sampler + ", coords, lod)"; 2634 if (!depth_compare_extra) {
2635 texture = "textureLod(" + sampler + ", coords, " + lod_value + ')';
2636 } else {
2637 texture = "texture(" + sampler + ", coords, " + depth_value + ')';
2638 LOG_WARNING(HW_GPU, "OpenGL Limitation: can't set lod value along depth compare");
2639 }
2625 break; 2640 break;
2626 } 2641 }
2627 default: { 2642 default: {
2628 texture = "texture(" + sampler + ", coords)"; 2643 if (!depth_compare_extra) {
2644 texture = "texture(" + sampler + ", coords)";
2645 } else {
2646 texture = "texture(" + sampler + ", coords, " + depth_value + ')';
2647 }
2629 UNIMPLEMENTED_MSG("Unhandled texture process mode {}", 2648 UNIMPLEMENTED_MSG("Unhandled texture process mode {}",
2630 static_cast<u32>(instr.tex.GetTextureProcessMode())); 2649 static_cast<u32>(instr.tex.GetTextureProcessMode()));
2631 } 2650 }