diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 151 |
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 | } |