diff options
| author | 2020-04-05 12:54:48 +0700 | |
|---|---|---|
| committer | 2020-04-05 12:54:48 +0700 | |
| commit | 24cc64c5b36e349f4b949193dd16dc053da964ce (patch) | |
| tree | d137df50744c9980e3d51248b3bc64a09593ec4b /src | |
| parent | tweaking. (diff) | |
| download | yuzu-24cc64c5b36e349f4b949193dd16dc053da964ce.tar.gz yuzu-24cc64c5b36e349f4b949193dd16dc053da964ce.tar.xz yuzu-24cc64c5b36e349f4b949193dd16dc053da964ce.zip | |
shader_decode: get sampler descriptor from registry.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/image.cpp | 170 |
1 files changed, 93 insertions, 77 deletions
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 07eb36153..731f61ee8 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp | |||
| @@ -10,8 +10,6 @@ | |||
| 10 | #include "common/bit_field.h" | 10 | #include "common/bit_field.h" |
| 11 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "common/logging/log.h" | 12 | #include "common/logging/log.h" |
| 13 | #include "core/core.h" | ||
| 14 | #include "video_core/engines/maxwell_3d.h" | ||
| 15 | #include "video_core/engines/shader_bytecode.h" | 13 | #include "video_core/engines/shader_bytecode.h" |
| 16 | #include "video_core/shader/node_helper.h" | 14 | #include "video_core/shader/node_helper.h" |
| 17 | #include "video_core/shader/shader_ir.h" | 15 | #include "video_core/shader/shader_ir.h" |
| @@ -28,8 +26,10 @@ using Tegra::Texture::TextureFormat; | |||
| 28 | using Tegra::Texture::TICEntry; | 26 | using Tegra::Texture::TICEntry; |
| 29 | 27 | ||
| 30 | namespace { | 28 | namespace { |
| 31 | ComponentType GetComponentType(TICEntry tic, std::size_t component) { | 29 | |
| 32 | const TextureFormat format{tic.format}; | 30 | |
| 31 | ComponentType GetComponentType(Tegra::Engines::SamplerDescriptor descriptor, std::size_t component) { | ||
| 32 | const TextureFormat format{descriptor.format}; | ||
| 33 | switch (format) { | 33 | switch (format) { |
| 34 | case TextureFormat::R16_G16_B16_A16: | 34 | case TextureFormat::R16_G16_B16_A16: |
| 35 | case TextureFormat::R32_G32_B32_A32: | 35 | case TextureFormat::R32_G32_B32_A32: |
| @@ -40,82 +40,82 @@ ComponentType GetComponentType(TICEntry tic, std::size_t component) { | |||
| 40 | case TextureFormat::R16: | 40 | case TextureFormat::R16: |
| 41 | case TextureFormat::R8: | 41 | case TextureFormat::R8: |
| 42 | case TextureFormat::R1: | 42 | case TextureFormat::R1: |
| 43 | if (0 == component) { | 43 | if (component == 0) { |
| 44 | return tic.r_type; | 44 | return descriptor.r_type; |
| 45 | } | 45 | } |
| 46 | if (1 == component) { | 46 | if (component == 1) { |
| 47 | return tic.g_type; | 47 | return descriptor.g_type; |
| 48 | } | 48 | } |
| 49 | if (2 == component) { | 49 | if (component == 2) { |
| 50 | return tic.b_type; | 50 | return descriptor.b_type; |
| 51 | } | 51 | } |
| 52 | if (3 == component) { | 52 | if (component == 3) { |
| 53 | return tic.a_type; | 53 | return descriptor.a_type; |
| 54 | } | 54 | } |
| 55 | break; | 55 | break; |
| 56 | case TextureFormat::A8R8G8B8: | 56 | case TextureFormat::A8R8G8B8: |
| 57 | if (0 == component) { | 57 | if (component == 0) { |
| 58 | return tic.a_type; | 58 | return descriptor.a_type; |
| 59 | } | 59 | } |
| 60 | if (1 == component) { | 60 | if (component == 1) { |
| 61 | return tic.r_type; | 61 | return descriptor.r_type; |
| 62 | } | 62 | } |
| 63 | if (2 == component) { | 63 | if (component == 2) { |
| 64 | return tic.g_type; | 64 | return descriptor.g_type; |
| 65 | } | 65 | } |
| 66 | if (3 == component) { | 66 | if (component == 3) { |
| 67 | return tic.b_type; | 67 | return descriptor.b_type; |
| 68 | } | 68 | } |
| 69 | break; | 69 | break; |
| 70 | case TextureFormat::A2B10G10R10: | 70 | case TextureFormat::A2B10G10R10: |
| 71 | case TextureFormat::A4B4G4R4: | 71 | case TextureFormat::A4B4G4R4: |
| 72 | case TextureFormat::A5B5G5R1: | 72 | case TextureFormat::A5B5G5R1: |
| 73 | case TextureFormat::A1B5G5R5: | 73 | case TextureFormat::A1B5G5R5: |
| 74 | if (0 == component) { | 74 | if (component == 0) { |
| 75 | return tic.a_type; | 75 | return descriptor.a_type; |
| 76 | } | 76 | } |
| 77 | if (1 == component) { | 77 | if (component == 1) { |
| 78 | return tic.b_type; | 78 | return descriptor.b_type; |
| 79 | } | 79 | } |
| 80 | if (2 == component) { | 80 | if (component == 2) { |
| 81 | return tic.g_type; | 81 | return descriptor.g_type; |
| 82 | } | 82 | } |
| 83 | if (3 == component) { | 83 | if (component == 3) { |
| 84 | return tic.r_type; | 84 | return descriptor.r_type; |
| 85 | } | 85 | } |
| 86 | break; | 86 | break; |
| 87 | case TextureFormat::R32_B24G8: | 87 | case TextureFormat::R32_B24G8: |
| 88 | if (0 == component) { | 88 | if (component == 0) { |
| 89 | return tic.r_type; | 89 | return descriptor.r_type; |
| 90 | } | 90 | } |
| 91 | if (1 == component) { | 91 | if (component == 1) { |
| 92 | return tic.b_type; | 92 | return descriptor.b_type; |
| 93 | } | 93 | } |
| 94 | if (2 == component) { | 94 | if (component == 2) { |
| 95 | return tic.g_type; | 95 | return descriptor.g_type; |
| 96 | } | 96 | } |
| 97 | break; | 97 | break; |
| 98 | case TextureFormat::B5G6R5: | 98 | case TextureFormat::B5G6R5: |
| 99 | case TextureFormat::B6G5R5: | 99 | case TextureFormat::B6G5R5: |
| 100 | if (0 == component) { | 100 | if (component == 0) { |
| 101 | return tic.b_type; | 101 | return descriptor.b_type; |
| 102 | } | 102 | } |
| 103 | if (1 == component) { | 103 | if (component == 1) { |
| 104 | return tic.g_type; | 104 | return descriptor.g_type; |
| 105 | } | 105 | } |
| 106 | if (2 == component) { | 106 | if (component == 2) { |
| 107 | return tic.r_type; | 107 | return descriptor.r_type; |
| 108 | } | 108 | } |
| 109 | break; | 109 | break; |
| 110 | case TextureFormat::G8R24: | 110 | case TextureFormat::G8R24: |
| 111 | case TextureFormat::G24R8: | 111 | case TextureFormat::G24R8: |
| 112 | case TextureFormat::G8R8: | 112 | case TextureFormat::G8R8: |
| 113 | case TextureFormat::G4R4: | 113 | case TextureFormat::G4R4: |
| 114 | if (0 == component) { | 114 | if (component == 0) { |
| 115 | return tic.g_type; | 115 | return descriptor.g_type; |
| 116 | } | 116 | } |
| 117 | if (1 == component) { | 117 | if (component == 1) { |
| 118 | return tic.r_type; | 118 | return descriptor.r_type; |
| 119 | } | 119 | } |
| 120 | break; | 120 | break; |
| 121 | } | 121 | } |
| @@ -141,76 +141,76 @@ u32 GetComponentSize(TextureFormat format, std::size_t component) { | |||
| 141 | case TextureFormat::R16_G16_B16_A16: | 141 | case TextureFormat::R16_G16_B16_A16: |
| 142 | return 16; | 142 | return 16; |
| 143 | case TextureFormat::R32_G32_B32: | 143 | case TextureFormat::R32_G32_B32: |
| 144 | return (0 == component || 1 == component || 2 == component) ? 32 : 0; | 144 | return (component == 0 || component == 1 || component == 2) ? 32 : 0; |
| 145 | case TextureFormat::R32_G32: | 145 | case TextureFormat::R32_G32: |
| 146 | return (0 == component || 1 == component) ? 32 : 0; | 146 | return (component == 0 || component == 1) ? 32 : 0; |
| 147 | case TextureFormat::R16_G16: | 147 | case TextureFormat::R16_G16: |
| 148 | return (0 == component || 1 == component) ? 16 : 0; | 148 | return (component == 0 || component == 1) ? 16 : 0; |
| 149 | case TextureFormat::R32: | 149 | case TextureFormat::R32: |
| 150 | return (0 == component) ? 32 : 0; | 150 | return (component == 0) ? 32 : 0; |
| 151 | case TextureFormat::R16: | 151 | case TextureFormat::R16: |
| 152 | return (0 == component) ? 16 : 0; | 152 | return (component == 0) ? 16 : 0; |
| 153 | case TextureFormat::R8: | 153 | case TextureFormat::R8: |
| 154 | return (0 == component) ? 8 : 0; | 154 | return (component == 0) ? 8 : 0; |
| 155 | case TextureFormat::R1: | 155 | case TextureFormat::R1: |
| 156 | return (0 == component) ? 1 : 0; | 156 | return (component == 0) ? 1 : 0; |
| 157 | case TextureFormat::A8R8G8B8: | 157 | case TextureFormat::A8R8G8B8: |
| 158 | return 8; | 158 | return 8; |
| 159 | case TextureFormat::A2B10G10R10: | 159 | case TextureFormat::A2B10G10R10: |
| 160 | return (3 == component || 2 == component || 1 == component) ? 10 : 2; | 160 | return (component == 3 || component == 2 || component == 1) ? 10 : 2; |
| 161 | case TextureFormat::A4B4G4R4: | 161 | case TextureFormat::A4B4G4R4: |
| 162 | return 4; | 162 | return 4; |
| 163 | case TextureFormat::A5B5G5R1: | 163 | case TextureFormat::A5B5G5R1: |
| 164 | return (0 == component || 1 == component || 2 == component) ? 5 : 1; | 164 | return (component == 0 || component == 1 || component == 2) ? 5 : 1; |
| 165 | case TextureFormat::A1B5G5R5: | 165 | case TextureFormat::A1B5G5R5: |
| 166 | return (1 == component || 2 == component || 3 == component) ? 5 : 1; | 166 | return (component == 1 || component == 2 || component == 3) ? 5 : 1; |
| 167 | case TextureFormat::R32_B24G8: | 167 | case TextureFormat::R32_B24G8: |
| 168 | if (0 == component) { | 168 | if (component == 0) { |
| 169 | return 32; | 169 | return 32; |
| 170 | } | 170 | } |
| 171 | if (1 == component) { | 171 | if (component == 1) { |
| 172 | return 24; | 172 | return 24; |
| 173 | } | 173 | } |
| 174 | if (2 == component) { | 174 | if (component == 2) { |
| 175 | return 8; | 175 | return 8; |
| 176 | } | 176 | } |
| 177 | return 0; | 177 | return 0; |
| 178 | case TextureFormat::B5G6R5: | 178 | case TextureFormat::B5G6R5: |
| 179 | if (0 == component || 2 == component) { | 179 | if (component == 0 || component == 2) { |
| 180 | return 5; | 180 | return 5; |
| 181 | } | 181 | } |
| 182 | if (1 == component) { | 182 | if (component == 1) { |
| 183 | return 6; | 183 | return 6; |
| 184 | } | 184 | } |
| 185 | return 0; | 185 | return 0; |
| 186 | case TextureFormat::B6G5R5: | 186 | case TextureFormat::B6G5R5: |
| 187 | if (1 == component || 2 == component) { | 187 | if (component == 1 || component == 2) { |
| 188 | return 5; | 188 | return 5; |
| 189 | } | 189 | } |
| 190 | if (0 == component) { | 190 | if (component == 0) { |
| 191 | return 6; | 191 | return 6; |
| 192 | } | 192 | } |
| 193 | return 0; | 193 | return 0; |
| 194 | case TextureFormat::G8R24: | 194 | case TextureFormat::G8R24: |
| 195 | if (0 == component) { | 195 | if (component == 0) { |
| 196 | return 8; | 196 | return 8; |
| 197 | } | 197 | } |
| 198 | if (1 == component) { | 198 | if (component == 1) { |
| 199 | return 24; | 199 | return 24; |
| 200 | } | 200 | } |
| 201 | return 0; | 201 | return 0; |
| 202 | case TextureFormat::G24R8: | 202 | case TextureFormat::G24R8: |
| 203 | if (0 == component) { | 203 | if (component == 0) { |
| 204 | return 8; | 204 | return 8; |
| 205 | } | 205 | } |
| 206 | if (1 == component) { | 206 | if (component == 1) { |
| 207 | return 24; | 207 | return 24; |
| 208 | } | 208 | } |
| 209 | return 0; | 209 | return 0; |
| 210 | case TextureFormat::G8R8: | 210 | case TextureFormat::G8R8: |
| 211 | return (0 == component || 1 == component) ? 8 : 0; | 211 | return (component == 0 || component == 1) ? 8 : 0; |
| 212 | case TextureFormat::G4R4: | 212 | case TextureFormat::G4R4: |
| 213 | return (0 == component || 1 == component) ? 4 : 0; | 213 | return (component == 0 || component == 1) ? 4 : 0; |
| 214 | default: | 214 | default: |
| 215 | UNIMPLEMENTED_MSG("texture format not implement={}", format); | 215 | UNIMPLEMENTED_MSG("texture format not implement={}", format); |
| 216 | return 0; | 216 | return 0; |
| @@ -311,10 +311,23 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { | |||
| 311 | } else if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::D_BA) { | 311 | } else if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::D_BA) { |
| 312 | UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32); | 312 | UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32); |
| 313 | 313 | ||
| 314 | const auto maxwell3d = &Core::System::GetInstance().GPU().Maxwell3D(); | 314 | auto descriptor = [this, instr] { |
| 315 | const auto tex_info = maxwell3d->GetStageTexture(shader_stage, image.GetOffset()); | 315 | std::optional<Tegra::Engines::SamplerDescriptor> descriptor; |
| 316 | if (instr.suldst.is_immediate) { | ||
| 317 | descriptor = registry.ObtainBoundSampler(instr.image.index.Value()); | ||
| 318 | } else { | ||
| 319 | const Node image_register = GetRegister(instr.gpr39); | ||
| 320 | const auto [base_image, buffer, offset] = TrackCbuf( | ||
| 321 | image_register, global_code, static_cast<s64>(global_code.size())); | ||
| 322 | descriptor = registry.ObtainBindlessSampler(buffer, offset); | ||
| 323 | } | ||
| 324 | if (!descriptor) { | ||
| 325 | UNREACHABLE_MSG("Failed to obtain image descriptor"); | ||
| 326 | } | ||
| 327 | return *descriptor; | ||
| 328 | }(); | ||
| 316 | 329 | ||
| 317 | const auto comp_mask = GetImageComponentMask(tex_info.tic.format); | 330 | const auto comp_mask = GetImageComponentMask(descriptor.format); |
| 318 | // TODO(namkazt): let's suppose image format is same as store type. we check on it | 331 | // TODO(namkazt): let's suppose image format is same as store type. we check on it |
| 319 | // later. | 332 | // later. |
| 320 | 333 | ||
| @@ -327,8 +340,8 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { | |||
| 327 | if (!IsComponentEnabled(comp_mask, element)) { | 340 | if (!IsComponentEnabled(comp_mask, element)) { |
| 328 | continue; | 341 | continue; |
| 329 | } | 342 | } |
| 330 | const auto component_type = GetComponentType(tex_info.tic, element); | 343 | const auto component_type = GetComponentType(descriptor, element); |
| 331 | const auto component_size = GetComponentSize(tex_info.tic.format, element); | 344 | const auto component_size = GetComponentSize(descriptor.format, element); |
| 332 | bool is_signed = true; | 345 | bool is_signed = true; |
| 333 | MetaImage meta{image, {}, element}; | 346 | MetaImage meta{image, {}, element}; |
| 334 | const Node original_value = | 347 | const Node original_value = |
| @@ -339,20 +352,23 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { | |||
| 339 | case ComponentType::SNORM: { | 352 | case ComponentType::SNORM: { |
| 340 | // range [-1.0, 1.0] | 353 | // range [-1.0, 1.0] |
| 341 | auto cnv_value = | 354 | auto cnv_value = |
| 342 | Operation(OperationCode::FMul, original_value, Immediate(128.f)); | 355 | Operation(OperationCode::FAdd, original_value, Immediate(1.f)); |
| 356 | cnv_value = Operation(OperationCode::FMul, std::move(cnv_value), | ||
| 357 | Immediate(127.f)); | ||
| 358 | is_signed = false; | ||
| 343 | return SignedOperation(OperationCode::ICastFloat, is_signed, | 359 | return SignedOperation(OperationCode::ICastFloat, is_signed, |
| 344 | std::move(cnv_value)); | 360 | std::move(cnv_value)); |
| 345 | } | 361 | } |
| 346 | case ComponentType::UNORM: { | 362 | case ComponentType::UNORM: { |
| 347 | // range [0.0, 1.0] | 363 | // range [0.0, 1.0] |
| 348 | auto cnv_value = | 364 | auto cnv_value = |
| 349 | Operation(OperationCode::FMul, original_value, Immediate(256.f)); | 365 | Operation(OperationCode::FMul, original_value, Immediate(255.f)); |
| 350 | is_signed = false; | 366 | is_signed = false; |
| 351 | return SignedOperation(OperationCode::ICastFloat, is_signed, | 367 | return SignedOperation(OperationCode::ICastFloat, is_signed, |
| 352 | std::move(cnv_value)); | 368 | std::move(cnv_value)); |
| 353 | } | 369 | } |
| 354 | case ComponentType::SINT: // range [-128,128] | 370 | case ComponentType::SINT: // range [-128,128] |
| 355 | return original_value; | 371 | return Operation(OperationCode::IAdd, original_value, Immediate(128)); |
| 356 | case ComponentType::UINT: // range [0, 255] | 372 | case ComponentType::UINT: // range [0, 255] |
| 357 | is_signed = false; | 373 | is_signed = false; |
| 358 | return original_value; | 374 | return original_value; |
| @@ -364,13 +380,13 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { | |||
| 364 | } | 380 | } |
| 365 | }(); | 381 | }(); |
| 366 | // shift element to correct position | 382 | // shift element to correct position |
| 367 | shifted_counter += component_size; | 383 | const auto shifted = shifted_counter; |
| 368 | const auto shifted = 32 - shifted_counter; | ||
| 369 | if (shifted > 0) { | 384 | if (shifted > 0) { |
| 370 | converted_value = | 385 | converted_value = |
| 371 | SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, | 386 | SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, |
| 372 | std::move(converted_value), Immediate(shifted)); | 387 | std::move(converted_value), Immediate(shifted)); |
| 373 | } | 388 | } |
| 389 | shifted_counter += component_size; | ||
| 374 | 390 | ||
| 375 | // add value into result | 391 | // add value into result |
| 376 | value = Operation(OperationCode::UBitwiseOr, value, std::move(converted_value)); | 392 | value = Operation(OperationCode::UBitwiseOr, value, std::move(converted_value)); |