diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/maxwell_dma.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 4 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 1 | ||||
| -rw-r--r-- | src/video_core/memory_manager.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 52 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 21 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 44 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.cpp | 4 |
9 files changed, 90 insertions, 52 deletions
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 442138988..c298f0bfb 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp | |||
| @@ -49,7 +49,11 @@ void MaxwellDMA::HandleCopy() { | |||
| 49 | ASSERT(regs.src_params.pos_y == 0); | 49 | ASSERT(regs.src_params.pos_y == 0); |
| 50 | ASSERT(regs.dst_params.pos_x == 0); | 50 | ASSERT(regs.dst_params.pos_x == 0); |
| 51 | ASSERT(regs.dst_params.pos_y == 0); | 51 | ASSERT(regs.dst_params.pos_y == 0); |
| 52 | ASSERT(regs.exec.is_dst_linear != regs.exec.is_src_linear); | 52 | |
| 53 | if (regs.exec.is_dst_linear == regs.exec.is_src_linear) { | ||
| 54 | Memory::CopyBlock(dest_cpu, source_cpu, regs.x_count * regs.y_count); | ||
| 55 | return; | ||
| 56 | } | ||
| 53 | 57 | ||
| 54 | u8* src_buffer = Memory::GetPointer(source_cpu); | 58 | u8* src_buffer = Memory::GetPointer(source_cpu); |
| 55 | u8* dst_buffer = Memory::GetPointer(dest_cpu); | 59 | u8* dst_buffer = Memory::GetPointer(dest_cpu); |
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index cb4db0679..86fd64979 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -142,6 +142,7 @@ enum class PredCondition : u64 { | |||
| 142 | GreaterThan = 4, | 142 | GreaterThan = 4, |
| 143 | NotEqual = 5, | 143 | NotEqual = 5, |
| 144 | GreaterEqual = 6, | 144 | GreaterEqual = 6, |
| 145 | NotEqualWithNan = 13, | ||
| 145 | // TODO(Subv): Other condition types | 146 | // TODO(Subv): Other condition types |
| 146 | }; | 147 | }; |
| 147 | 148 | ||
| @@ -165,7 +166,6 @@ enum class SubOp : u64 { | |||
| 165 | Lg2 = 0x3, | 166 | Lg2 = 0x3, |
| 166 | Rcp = 0x4, | 167 | Rcp = 0x4, |
| 167 | Rsq = 0x5, | 168 | Rsq = 0x5, |
| 168 | Min = 0x8, | ||
| 169 | }; | 169 | }; |
| 170 | 170 | ||
| 171 | enum class F2iRoundingOp : u64 { | 171 | enum class F2iRoundingOp : u64 { |
| @@ -209,7 +209,7 @@ union Instruction { | |||
| 209 | } pred; | 209 | } pred; |
| 210 | BitField<19, 1, u64> negate_pred; | 210 | BitField<19, 1, u64> negate_pred; |
| 211 | BitField<20, 8, Register> gpr20; | 211 | BitField<20, 8, Register> gpr20; |
| 212 | BitField<20, 7, SubOp> sub_op; | 212 | BitField<20, 4, SubOp> sub_op; |
| 213 | BitField<28, 8, Register> gpr28; | 213 | BitField<28, 8, Register> gpr28; |
| 214 | BitField<39, 8, Register> gpr39; | 214 | BitField<39, 8, Register> gpr39; |
| 215 | BitField<48, 16, u64> opcode; | 215 | BitField<48, 16, u64> opcode; |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 7b4e9b842..d0a4ac267 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -16,6 +16,7 @@ namespace Tegra { | |||
| 16 | enum class RenderTargetFormat : u32 { | 16 | enum class RenderTargetFormat : u32 { |
| 17 | NONE = 0x0, | 17 | NONE = 0x0, |
| 18 | RGBA32_FLOAT = 0xC0, | 18 | RGBA32_FLOAT = 0xC0, |
| 19 | RGBA32_UINT = 0xC2, | ||
| 19 | RGBA16_FLOAT = 0xCA, | 20 | RGBA16_FLOAT = 0xCA, |
| 20 | RGB10_A2_UNORM = 0xD1, | 21 | RGB10_A2_UNORM = 0xD1, |
| 21 | RGBA8_UNORM = 0xD5, | 22 | RGBA8_UNORM = 0xD5, |
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 5cefce9fc..2f814a184 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -100,9 +100,9 @@ boost::optional<GPUVAddr> MemoryManager::FindFreeBlock(u64 size, u64 align) { | |||
| 100 | 100 | ||
| 101 | boost::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { | 101 | boost::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { |
| 102 | VAddr base_addr = PageSlot(gpu_addr); | 102 | VAddr base_addr = PageSlot(gpu_addr); |
| 103 | ASSERT(base_addr != static_cast<u64>(PageStatus::Unmapped)); | ||
| 104 | 103 | ||
| 105 | if (base_addr == static_cast<u64>(PageStatus::Allocated)) { | 104 | if (base_addr == static_cast<u64>(PageStatus::Allocated) || |
| 105 | base_addr == static_cast<u64>(PageStatus::Unmapped)) { | ||
| 106 | return {}; | 106 | return {}; |
| 107 | } | 107 | } |
| 108 | 108 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 62ee45a36..45560fbee 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -636,7 +636,11 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, GLuint program, | |||
| 636 | glProgramUniform1i(program, uniform, current_bindpoint); | 636 | glProgramUniform1i(program, uniform, current_bindpoint); |
| 637 | 637 | ||
| 638 | const auto texture = maxwell3d.GetStageTexture(entry.GetStage(), entry.GetOffset()); | 638 | const auto texture = maxwell3d.GetStageTexture(entry.GetStage(), entry.GetOffset()); |
| 639 | ASSERT(texture.enabled); | 639 | |
| 640 | if (!texture.enabled) { | ||
| 641 | state.texture_units[current_bindpoint].texture_2d = 0; | ||
| 642 | continue; | ||
| 643 | } | ||
| 640 | 644 | ||
| 641 | texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc); | 645 | texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc); |
| 642 | Surface surface = res_cache.GetTextureSurface(texture); | 646 | Surface surface = res_cache.GetTextureSurface(texture); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 63f5999ea..9410ddb4e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -27,6 +27,7 @@ struct FormatTuple { | |||
| 27 | GLint internal_format; | 27 | GLint internal_format; |
| 28 | GLenum format; | 28 | GLenum format; |
| 29 | GLenum type; | 29 | GLenum type; |
| 30 | ComponentType component_type; | ||
| 30 | bool compressed; | 31 | bool compressed; |
| 31 | }; | 32 | }; |
| 32 | 33 | ||
| @@ -65,29 +66,33 @@ struct FormatTuple { | |||
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ | 68 | static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ |
| 68 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // ABGR8 | 69 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8 |
| 69 | {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false}, // B5G6R5 | 70 | {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, ComponentType::UNorm, false}, // B5G6R5 |
| 70 | {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false}, // A2B10G10R10 | 71 | {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, ComponentType::UNorm, |
| 71 | {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, false}, // A1B5G5R5 | 72 | false}, // A2B10G10R10 |
| 72 | {GL_R8, GL_RED, GL_UNSIGNED_BYTE, false}, // R8 | 73 | {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ComponentType::UNorm, false}, // A1B5G5R5 |
| 73 | {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, false}, // RGBA16F | 74 | {GL_R8, GL_RED, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // R8 |
| 74 | {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, false}, // R11FG11FB10F | 75 | {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, ComponentType::Float, false}, // RGBA16F |
| 75 | {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT1 | 76 | {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, ComponentType::Float, |
| 76 | {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT23 | 77 | false}, // R11FG11FB10F |
| 77 | {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT45 | 78 | {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RGBA32UI |
| 78 | {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, true}, // DXN1 | 79 | {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, |
| 79 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_4X4 | 80 | true}, // DXT1 |
| 81 | {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, | ||
| 82 | true}, // DXT23 | ||
| 83 | {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, | ||
| 84 | true}, // DXT45 | ||
| 85 | {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, true}, // DXN1 | ||
| 86 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4 | ||
| 80 | }}; | 87 | }}; |
| 81 | 88 | ||
| 82 | static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { | 89 | static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { |
| 83 | const SurfaceType type = SurfaceParams::GetFormatType(pixel_format); | 90 | const SurfaceType type = SurfaceParams::GetFormatType(pixel_format); |
| 84 | if (type == SurfaceType::ColorTexture) { | 91 | if (type == SurfaceType::ColorTexture) { |
| 85 | ASSERT(static_cast<size_t>(pixel_format) < tex_format_tuples.size()); | 92 | ASSERT(static_cast<size_t>(pixel_format) < tex_format_tuples.size()); |
| 86 | // For now only UNORM components are supported, or either R11FG11FB10F or RGBA16F which | 93 | auto& format = tex_format_tuples[static_cast<unsigned int>(pixel_format)]; |
| 87 | // are type FLOAT | 94 | ASSERT(component_type == format.component_type); |
| 88 | ASSERT(component_type == ComponentType::UNorm || pixel_format == PixelFormat::RGBA16F || | 95 | return format; |
| 89 | pixel_format == PixelFormat::R11FG11FB10F); | ||
| 90 | return tex_format_tuples[static_cast<unsigned int>(pixel_format)]; | ||
| 91 | } else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) { | 96 | } else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) { |
| 92 | // TODO(Subv): Implement depth formats | 97 | // TODO(Subv): Implement depth formats |
| 93 | ASSERT_MSG(false, "Unimplemented"); | 98 | ASSERT_MSG(false, "Unimplemented"); |
| @@ -166,9 +171,10 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), | |||
| 166 | MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>, | 171 | MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>, |
| 167 | MortonCopy<true, PixelFormat::A2B10G10R10>, MortonCopy<true, PixelFormat::A1B5G5R5>, | 172 | MortonCopy<true, PixelFormat::A2B10G10R10>, MortonCopy<true, PixelFormat::A1B5G5R5>, |
| 168 | MortonCopy<true, PixelFormat::R8>, MortonCopy<true, PixelFormat::RGBA16F>, | 173 | MortonCopy<true, PixelFormat::R8>, MortonCopy<true, PixelFormat::RGBA16F>, |
| 169 | MortonCopy<true, PixelFormat::R11FG11FB10F>, MortonCopy<true, PixelFormat::DXT1>, | 174 | MortonCopy<true, PixelFormat::R11FG11FB10F>, MortonCopy<true, PixelFormat::RGBA32UI>, |
| 170 | MortonCopy<true, PixelFormat::DXT23>, MortonCopy<true, PixelFormat::DXT45>, | 175 | MortonCopy<true, PixelFormat::DXT1>, MortonCopy<true, PixelFormat::DXT23>, |
| 171 | MortonCopy<true, PixelFormat::DXN1>, MortonCopy<true, PixelFormat::ASTC_2D_4X4>, | 176 | MortonCopy<true, PixelFormat::DXT45>, MortonCopy<true, PixelFormat::DXN1>, |
| 177 | MortonCopy<true, PixelFormat::ASTC_2D_4X4>, | ||
| 172 | }; | 178 | }; |
| 173 | 179 | ||
| 174 | static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), | 180 | static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), |
| @@ -181,6 +187,7 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), | |||
| 181 | MortonCopy<false, PixelFormat::R8>, | 187 | MortonCopy<false, PixelFormat::R8>, |
| 182 | MortonCopy<false, PixelFormat::RGBA16F>, | 188 | MortonCopy<false, PixelFormat::RGBA16F>, |
| 183 | MortonCopy<false, PixelFormat::R11FG11FB10F>, | 189 | MortonCopy<false, PixelFormat::R11FG11FB10F>, |
| 190 | MortonCopy<false, PixelFormat::RGBA32UI>, | ||
| 184 | // TODO(Subv): Swizzling the DXT1/DXT23/DXT45/DXN1 formats is not yet supported | 191 | // TODO(Subv): Swizzling the DXT1/DXT23/DXT45/DXN1 formats is not yet supported |
| 185 | nullptr, | 192 | nullptr, |
| 186 | nullptr, | 193 | nullptr, |
| @@ -454,6 +461,11 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) { | |||
| 454 | return {}; | 461 | return {}; |
| 455 | } | 462 | } |
| 456 | 463 | ||
| 464 | const auto& gpu = Core::System::GetInstance().GPU(); | ||
| 465 | // Don't try to create any entries in the cache if the address of the texture is invalid. | ||
| 466 | if (gpu.memory_manager->GpuToCpuAddress(params.addr) == boost::none) | ||
| 467 | return {}; | ||
| 468 | |||
| 457 | // Check for an exact match in existing surfaces | 469 | // Check for an exact match in existing surfaces |
| 458 | const auto& surface_key{SurfaceKey::Create(params)}; | 470 | const auto& surface_key{SurfaceKey::Create(params)}; |
| 459 | const auto& search{surface_cache.find(surface_key)}; | 471 | const auto& search{surface_cache.find(surface_key)}; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 85e7c8888..99be250b4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -30,11 +30,12 @@ struct SurfaceParams { | |||
| 30 | R8 = 4, | 30 | R8 = 4, |
| 31 | RGBA16F = 5, | 31 | RGBA16F = 5, |
| 32 | R11FG11FB10F = 6, | 32 | R11FG11FB10F = 6, |
| 33 | DXT1 = 7, | 33 | RGBA32UI = 7, |
| 34 | DXT23 = 8, | 34 | DXT1 = 8, |
| 35 | DXT45 = 9, | 35 | DXT23 = 9, |
| 36 | DXN1 = 10, // This is also known as BC4 | 36 | DXT45 = 10, |
| 37 | ASTC_2D_4X4 = 11, | 37 | DXN1 = 11, // This is also known as BC4 |
| 38 | ASTC_2D_4X4 = 12, | ||
| 38 | 39 | ||
| 39 | Max, | 40 | Max, |
| 40 | Invalid = 255, | 41 | Invalid = 255, |
| @@ -77,6 +78,7 @@ struct SurfaceParams { | |||
| 77 | 1, // R8 | 78 | 1, // R8 |
| 78 | 1, // RGBA16F | 79 | 1, // RGBA16F |
| 79 | 1, // R11FG11FB10F | 80 | 1, // R11FG11FB10F |
| 81 | 1, // RGBA32UI | ||
| 80 | 4, // DXT1 | 82 | 4, // DXT1 |
| 81 | 4, // DXT23 | 83 | 4, // DXT23 |
| 82 | 4, // DXT45 | 84 | 4, // DXT45 |
| @@ -100,6 +102,7 @@ struct SurfaceParams { | |||
| 100 | 8, // R8 | 102 | 8, // R8 |
| 101 | 64, // RGBA16F | 103 | 64, // RGBA16F |
| 102 | 32, // R11FG11FB10F | 104 | 32, // R11FG11FB10F |
| 105 | 128, // RGBA32UI | ||
| 103 | 64, // DXT1 | 106 | 64, // DXT1 |
| 104 | 128, // DXT23 | 107 | 128, // DXT23 |
| 105 | 128, // DXT45 | 108 | 128, // DXT45 |
| @@ -125,6 +128,8 @@ struct SurfaceParams { | |||
| 125 | return PixelFormat::RGBA16F; | 128 | return PixelFormat::RGBA16F; |
| 126 | case Tegra::RenderTargetFormat::R11G11B10_FLOAT: | 129 | case Tegra::RenderTargetFormat::R11G11B10_FLOAT: |
| 127 | return PixelFormat::R11FG11FB10F; | 130 | return PixelFormat::R11FG11FB10F; |
| 131 | case Tegra::RenderTargetFormat::RGBA32_UINT: | ||
| 132 | return PixelFormat::RGBA32UI; | ||
| 128 | default: | 133 | default: |
| 129 | NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | 134 | NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); |
| 130 | UNREACHABLE(); | 135 | UNREACHABLE(); |
| @@ -148,6 +153,8 @@ struct SurfaceParams { | |||
| 148 | return PixelFormat::RGBA16F; | 153 | return PixelFormat::RGBA16F; |
| 149 | case Tegra::Texture::TextureFormat::BF10GF11RF11: | 154 | case Tegra::Texture::TextureFormat::BF10GF11RF11: |
| 150 | return PixelFormat::R11FG11FB10F; | 155 | return PixelFormat::R11FG11FB10F; |
| 156 | case Tegra::Texture::TextureFormat::R32_G32_B32_A32: | ||
| 157 | return PixelFormat::RGBA32UI; | ||
| 151 | case Tegra::Texture::TextureFormat::DXT1: | 158 | case Tegra::Texture::TextureFormat::DXT1: |
| 152 | return PixelFormat::DXT1; | 159 | return PixelFormat::DXT1; |
| 153 | case Tegra::Texture::TextureFormat::DXT23: | 160 | case Tegra::Texture::TextureFormat::DXT23: |
| @@ -181,6 +188,8 @@ struct SurfaceParams { | |||
| 181 | return Tegra::Texture::TextureFormat::R16_G16_B16_A16; | 188 | return Tegra::Texture::TextureFormat::R16_G16_B16_A16; |
| 182 | case PixelFormat::R11FG11FB10F: | 189 | case PixelFormat::R11FG11FB10F: |
| 183 | return Tegra::Texture::TextureFormat::BF10GF11RF11; | 190 | return Tegra::Texture::TextureFormat::BF10GF11RF11; |
| 191 | case PixelFormat::RGBA32UI: | ||
| 192 | return Tegra::Texture::TextureFormat::R32_G32_B32_A32; | ||
| 184 | case PixelFormat::DXT1: | 193 | case PixelFormat::DXT1: |
| 185 | return Tegra::Texture::TextureFormat::DXT1; | 194 | return Tegra::Texture::TextureFormat::DXT1; |
| 186 | case PixelFormat::DXT23: | 195 | case PixelFormat::DXT23: |
| @@ -217,6 +226,8 @@ struct SurfaceParams { | |||
| 217 | case Tegra::RenderTargetFormat::RGBA16_FLOAT: | 226 | case Tegra::RenderTargetFormat::RGBA16_FLOAT: |
| 218 | case Tegra::RenderTargetFormat::R11G11B10_FLOAT: | 227 | case Tegra::RenderTargetFormat::R11G11B10_FLOAT: |
| 219 | return ComponentType::Float; | 228 | return ComponentType::Float; |
| 229 | case Tegra::RenderTargetFormat::RGBA32_UINT: | ||
| 230 | return ComponentType::UInt; | ||
| 220 | default: | 231 | default: |
| 221 | NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | 232 | NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); |
| 222 | UNREACHABLE(); | 233 | UNREACHABLE(); |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 46eaad021..bbccf0bfd 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -719,21 +719,31 @@ private: | |||
| 719 | /** | 719 | /** |
| 720 | * Returns the comparison string to use to compare two values in the 'set' family of | 720 | * Returns the comparison string to use to compare two values in the 'set' family of |
| 721 | * instructions. | 721 | * instructions. |
| 722 | * @params condition The condition used in the 'set'-family instruction. | 722 | * @param condition The condition used in the 'set'-family instruction. |
| 723 | * @param op_a First operand to use for the comparison. | ||
| 724 | * @param op_b Second operand to use for the comparison. | ||
| 723 | * @returns String corresponding to the GLSL operator that matches the desired comparison. | 725 | * @returns String corresponding to the GLSL operator that matches the desired comparison. |
| 724 | */ | 726 | */ |
| 725 | std::string GetPredicateComparison(Tegra::Shader::PredCondition condition) const { | 727 | std::string GetPredicateComparison(Tegra::Shader::PredCondition condition, |
| 728 | const std::string& op_a, const std::string& op_b) const { | ||
| 726 | using Tegra::Shader::PredCondition; | 729 | using Tegra::Shader::PredCondition; |
| 727 | static const std::unordered_map<PredCondition, const char*> PredicateComparisonStrings = { | 730 | static const std::unordered_map<PredCondition, const char*> PredicateComparisonStrings = { |
| 728 | {PredCondition::LessThan, "<"}, {PredCondition::Equal, "=="}, | 731 | {PredCondition::LessThan, "<"}, {PredCondition::Equal, "=="}, |
| 729 | {PredCondition::LessEqual, "<="}, {PredCondition::GreaterThan, ">"}, | 732 | {PredCondition::LessEqual, "<="}, {PredCondition::GreaterThan, ">"}, |
| 730 | {PredCondition::NotEqual, "!="}, {PredCondition::GreaterEqual, ">="}, | 733 | {PredCondition::NotEqual, "!="}, {PredCondition::GreaterEqual, ">="}, |
| 734 | {PredCondition::NotEqualWithNan, "!="}, | ||
| 731 | }; | 735 | }; |
| 732 | 736 | ||
| 733 | auto comparison = PredicateComparisonStrings.find(condition); | 737 | const auto& comparison{PredicateComparisonStrings.find(condition)}; |
| 734 | ASSERT_MSG(comparison != PredicateComparisonStrings.end(), | 738 | ASSERT_MSG(comparison != PredicateComparisonStrings.end(), |
| 735 | "Unknown predicate comparison operation"); | 739 | "Unknown predicate comparison operation"); |
| 736 | return comparison->second; | 740 | |
| 741 | std::string predicate{'(' + op_a + ") " + comparison->second + " (" + op_b + ')'}; | ||
| 742 | if (condition == PredCondition::NotEqualWithNan) { | ||
| 743 | predicate += " || isnan(" + op_a + ") || isnan(" + op_b + ')'; | ||
| 744 | } | ||
| 745 | |||
| 746 | return predicate; | ||
| 737 | } | 747 | } |
| 738 | 748 | ||
| 739 | /** | 749 | /** |
| @@ -907,10 +917,6 @@ private: | |||
| 907 | regs.SetRegisterToFloat(instr.gpr0, 0, "inversesqrt(" + op_a + ')', 1, 1, | 917 | regs.SetRegisterToFloat(instr.gpr0, 0, "inversesqrt(" + op_a + ')', 1, 1, |
| 908 | instr.alu.saturate_d); | 918 | instr.alu.saturate_d); |
| 909 | break; | 919 | break; |
| 910 | case SubOp::Min: | ||
| 911 | regs.SetRegisterToFloat(instr.gpr0, 0, "min(" + op_a + "," + op_b + ')', 1, 1, | ||
| 912 | instr.alu.saturate_d); | ||
| 913 | break; | ||
| 914 | default: | 920 | default: |
| 915 | NGLOG_CRITICAL(HW_GPU, "Unhandled MUFU sub op: {0:x}", | 921 | NGLOG_CRITICAL(HW_GPU, "Unhandled MUFU sub op: {0:x}", |
| 916 | static_cast<unsigned>(instr.sub_op.Value())); | 922 | static_cast<unsigned>(instr.sub_op.Value())); |
| @@ -1415,10 +1421,9 @@ private: | |||
| 1415 | std::string second_pred = | 1421 | std::string second_pred = |
| 1416 | GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0); | 1422 | GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0); |
| 1417 | 1423 | ||
| 1418 | std::string comparator = GetPredicateComparison(instr.fsetp.cond); | ||
| 1419 | std::string combiner = GetPredicateCombiner(instr.fsetp.op); | 1424 | std::string combiner = GetPredicateCombiner(instr.fsetp.op); |
| 1420 | 1425 | ||
| 1421 | std::string predicate = '(' + op_a + ") " + comparator + " (" + op_b + ')'; | 1426 | std::string predicate = GetPredicateComparison(instr.fsetp.cond, op_a, op_b); |
| 1422 | // Set the primary predicate to the result of Predicate OP SecondPredicate | 1427 | // Set the primary predicate to the result of Predicate OP SecondPredicate |
| 1423 | SetPredicate(instr.fsetp.pred3, | 1428 | SetPredicate(instr.fsetp.pred3, |
| 1424 | '(' + predicate + ") " + combiner + " (" + second_pred + ')'); | 1429 | '(' + predicate + ") " + combiner + " (" + second_pred + ')'); |
| @@ -1453,10 +1458,9 @@ private: | |||
| 1453 | std::string second_pred = | 1458 | std::string second_pred = |
| 1454 | GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0); | 1459 | GetPredicateCondition(instr.isetp.pred39, instr.isetp.neg_pred != 0); |
| 1455 | 1460 | ||
| 1456 | std::string comparator = GetPredicateComparison(instr.isetp.cond); | ||
| 1457 | std::string combiner = GetPredicateCombiner(instr.isetp.op); | 1461 | std::string combiner = GetPredicateCombiner(instr.isetp.op); |
| 1458 | 1462 | ||
| 1459 | std::string predicate = '(' + op_a + ") " + comparator + " (" + op_b + ')'; | 1463 | std::string predicate = GetPredicateComparison(instr.isetp.cond, op_a, op_b); |
| 1460 | // Set the primary predicate to the result of Predicate OP SecondPredicate | 1464 | // Set the primary predicate to the result of Predicate OP SecondPredicate |
| 1461 | SetPredicate(instr.isetp.pred3, | 1465 | SetPredicate(instr.isetp.pred3, |
| 1462 | '(' + predicate + ") " + combiner + " (" + second_pred + ')'); | 1466 | '(' + predicate + ") " + combiner + " (" + second_pred + ')'); |
| @@ -1503,11 +1507,10 @@ private: | |||
| 1503 | std::string second_pred = | 1507 | std::string second_pred = |
| 1504 | GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); | 1508 | GetPredicateCondition(instr.fset.pred39, instr.fset.neg_pred != 0); |
| 1505 | 1509 | ||
| 1506 | std::string comparator = GetPredicateComparison(instr.fset.cond); | ||
| 1507 | std::string combiner = GetPredicateCombiner(instr.fset.op); | 1510 | std::string combiner = GetPredicateCombiner(instr.fset.op); |
| 1508 | 1511 | ||
| 1509 | std::string predicate = "(((" + op_a + ") " + comparator + " (" + op_b + ")) " + | 1512 | std::string predicate = "((" + GetPredicateComparison(instr.fset.cond, op_a, op_b) + |
| 1510 | combiner + " (" + second_pred + "))"; | 1513 | ") " + combiner + " (" + second_pred + "))"; |
| 1511 | 1514 | ||
| 1512 | if (instr.fset.bf) { | 1515 | if (instr.fset.bf) { |
| 1513 | regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); | 1516 | regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); |
| @@ -1538,11 +1541,10 @@ private: | |||
| 1538 | std::string second_pred = | 1541 | std::string second_pred = |
| 1539 | GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0); | 1542 | GetPredicateCondition(instr.iset.pred39, instr.iset.neg_pred != 0); |
| 1540 | 1543 | ||
| 1541 | std::string comparator = GetPredicateComparison(instr.iset.cond); | ||
| 1542 | std::string combiner = GetPredicateCombiner(instr.iset.op); | 1544 | std::string combiner = GetPredicateCombiner(instr.iset.op); |
| 1543 | 1545 | ||
| 1544 | std::string predicate = "(((" + op_a + ") " + comparator + " (" + op_b + ")) " + | 1546 | std::string predicate = "((" + GetPredicateComparison(instr.iset.cond, op_a, op_b) + |
| 1545 | combiner + " (" + second_pred + "))"; | 1547 | ") " + combiner + " (" + second_pred + "))"; |
| 1546 | 1548 | ||
| 1547 | if (instr.iset.bf) { | 1549 | if (instr.iset.bf) { |
| 1548 | regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); | 1550 | regs.SetRegisterToFloat(instr.gpr0, 0, predicate + " ? 1.0 : 0.0", 1, 1); |
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 0db4367f1..eaf15da32 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp | |||
| @@ -65,6 +65,8 @@ u32 BytesPerPixel(TextureFormat format) { | |||
| 65 | return 1; | 65 | return 1; |
| 66 | case TextureFormat::R16_G16_B16_A16: | 66 | case TextureFormat::R16_G16_B16_A16: |
| 67 | return 8; | 67 | return 8; |
| 68 | case TextureFormat::R32_G32_B32_A32: | ||
| 69 | return 16; | ||
| 68 | default: | 70 | default: |
| 69 | UNIMPLEMENTED_MSG("Format not implemented"); | 71 | UNIMPLEMENTED_MSG("Format not implemented"); |
| 70 | break; | 72 | break; |
| @@ -94,6 +96,7 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, | |||
| 94 | case TextureFormat::B5G6R5: | 96 | case TextureFormat::B5G6R5: |
| 95 | case TextureFormat::R8: | 97 | case TextureFormat::R8: |
| 96 | case TextureFormat::R16_G16_B16_A16: | 98 | case TextureFormat::R16_G16_B16_A16: |
| 99 | case TextureFormat::R32_G32_B32_A32: | ||
| 97 | case TextureFormat::BF10GF11RF11: | 100 | case TextureFormat::BF10GF11RF11: |
| 98 | case TextureFormat::ASTC_2D_4X4: | 101 | case TextureFormat::ASTC_2D_4X4: |
| 99 | CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, | 102 | CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, |
| @@ -124,6 +127,7 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat | |||
| 124 | case TextureFormat::B5G6R5: | 127 | case TextureFormat::B5G6R5: |
| 125 | case TextureFormat::R8: | 128 | case TextureFormat::R8: |
| 126 | case TextureFormat::BF10GF11RF11: | 129 | case TextureFormat::BF10GF11RF11: |
| 130 | case TextureFormat::R32_G32_B32_A32: | ||
| 127 | // TODO(Subv): For the time being just forward the same data without any decoding. | 131 | // TODO(Subv): For the time being just forward the same data without any decoding. |
| 128 | rgba_data = texture_data; | 132 | rgba_data = texture_data; |
| 129 | break; | 133 | break; |