diff options
| author | 2020-04-06 13:09:19 +0700 | |
|---|---|---|
| committer | 2020-04-06 13:09:19 +0700 | |
| commit | 2906372ba18b1c6238062c7ac91ccf9536fc649b (patch) | |
| tree | 97dabf3cdb1f74a02ad6e725e6eceadccd8e943a /src | |
| parent | silent warning (conversion error) (diff) | |
| download | yuzu-2906372ba18b1c6238062c7ac91ccf9536fc649b.tar.gz yuzu-2906372ba18b1c6238062c7ac91ccf9536fc649b.tar.xz yuzu-2906372ba18b1c6238062c7ac91ccf9536fc649b.zip | |
shader_decode: SULD.D implement bits64 and reverse shader ir init method to removed shader stage.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/shader/decode/image.cpp | 127 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 9 |
5 files changed, 105 insertions, 46 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index dc6825a00..046ee55a5 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -234,7 +234,7 @@ Shader CachedShader::CreateStageFromMemory(const ShaderParameters& params, | |||
| 234 | const std::size_t size_in_bytes = code.size() * sizeof(u64); | 234 | const std::size_t size_in_bytes = code.size() * sizeof(u64); |
| 235 | 235 | ||
| 236 | auto registry = std::make_shared<Registry>(shader_type, params.system.GPU().Maxwell3D()); | 236 | auto registry = std::make_shared<Registry>(shader_type, params.system.GPU().Maxwell3D()); |
| 237 | const ShaderIR ir(code, shader_type, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry); | 237 | const ShaderIR ir(code, STAGE_MAIN_OFFSET, COMPILER_SETTINGS, *registry); |
| 238 | // TODO(Rodrigo): Handle VertexA shaders | 238 | // TODO(Rodrigo): Handle VertexA shaders |
| 239 | // std::optional<ShaderIR> ir_b; | 239 | // std::optional<ShaderIR> ir_b; |
| 240 | // if (!code_b.empty()) { | 240 | // if (!code_b.empty()) { |
| @@ -264,7 +264,7 @@ Shader CachedShader::CreateKernelFromMemory(const ShaderParameters& params, Prog | |||
| 264 | 264 | ||
| 265 | auto& engine = params.system.GPU().KeplerCompute(); | 265 | auto& engine = params.system.GPU().KeplerCompute(); |
| 266 | auto registry = std::make_shared<Registry>(ShaderType::Compute, engine); | 266 | auto registry = std::make_shared<Registry>(ShaderType::Compute, engine); |
| 267 | const ShaderIR ir(code, ShaderType::Compute, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry); | 267 | const ShaderIR ir(code, KERNEL_MAIN_OFFSET, COMPILER_SETTINGS, *registry); |
| 268 | const u64 uid = params.unique_identifier; | 268 | const u64 uid = params.unique_identifier; |
| 269 | auto program = BuildShader(params.device, ShaderType::Compute, uid, ir, *registry); | 269 | auto program = BuildShader(params.device, ShaderType::Compute, uid, ir, *registry); |
| 270 | 270 | ||
| @@ -341,7 +341,7 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, | |||
| 341 | const bool is_compute = entry.type == ShaderType::Compute; | 341 | const bool is_compute = entry.type == ShaderType::Compute; |
| 342 | const u32 main_offset = is_compute ? KERNEL_MAIN_OFFSET : STAGE_MAIN_OFFSET; | 342 | const u32 main_offset = is_compute ? KERNEL_MAIN_OFFSET : STAGE_MAIN_OFFSET; |
| 343 | auto registry = MakeRegistry(entry); | 343 | auto registry = MakeRegistry(entry); |
| 344 | const ShaderIR ir(entry.code, entry.type, main_offset, COMPILER_SETTINGS, *registry); | 344 | const ShaderIR ir(entry.code, main_offset, COMPILER_SETTINGS, *registry); |
| 345 | 345 | ||
| 346 | std::shared_ptr<OGLProgram> program; | 346 | std::shared_ptr<OGLProgram> program; |
| 347 | if (precompiled_entry) { | 347 | if (precompiled_entry) { |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 7a8824ebc..557b9d662 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -162,7 +162,7 @@ CachedShader::CachedShader(Core::System& system, Tegra::Engines::ShaderType stag | |||
| 162 | ProgramCode program_code, u32 main_offset) | 162 | ProgramCode program_code, u32 main_offset) |
| 163 | : RasterizerCacheObject{host_ptr}, gpu_addr{gpu_addr}, cpu_addr{cpu_addr}, | 163 | : RasterizerCacheObject{host_ptr}, gpu_addr{gpu_addr}, cpu_addr{cpu_addr}, |
| 164 | program_code{std::move(program_code)}, registry{stage, GetEngine(system, stage)}, | 164 | program_code{std::move(program_code)}, registry{stage, GetEngine(system, stage)}, |
| 165 | shader_ir{this->program_code, stage, main_offset, compiler_settings, registry}, | 165 | shader_ir{this->program_code, main_offset, compiler_settings, registry}, |
| 166 | entries{GenerateShaderEntries(shader_ir)} {} | 166 | entries{GenerateShaderEntries(shader_ir)} {} |
| 167 | 167 | ||
| 168 | CachedShader::~CachedShader() = default; | 168 | CachedShader::~CachedShader() = default; |
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp index 8d4530386..68913085f 100644 --- a/src/video_core/shader/decode/image.cpp +++ b/src/video_core/shader/decode/image.cpp | |||
| @@ -271,6 +271,40 @@ std::size_t GetImageTypeNumCoordinates(Tegra::Shader::ImageType image_type) { | |||
| 271 | } | 271 | } |
| 272 | } // Anonymous namespace | 272 | } // Anonymous namespace |
| 273 | 273 | ||
| 274 | Node ShaderIR::GetComponentValue(ComponentType component_type, u32 component_size, | ||
| 275 | const Node original_value, bool* is_signed) { | ||
| 276 | switch (component_type) { | ||
| 277 | case ComponentType::SNORM: { | ||
| 278 | *is_signed = true; | ||
| 279 | // range [-1.0, 1.0] | ||
| 280 | auto cnv_value = Operation(OperationCode::FMul, original_value, | ||
| 281 | Immediate((1 << component_size) / 2.f - 1.f)); | ||
| 282 | cnv_value = SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); | ||
| 283 | return BitfieldExtract(std::move(cnv_value), 0, component_size); | ||
| 284 | } | ||
| 285 | case ComponentType::SINT: | ||
| 286 | case ComponentType::UNORM: { | ||
| 287 | *is_signed = component_type == ComponentType::SINT; | ||
| 288 | // range [0.0, 1.0] | ||
| 289 | auto cnv_value = | ||
| 290 | Operation(OperationCode::FMul, original_value, Immediate((1 << component_size) - 1.f)); | ||
| 291 | return SignedOperation(OperationCode::ICastFloat, is_signed, std::move(cnv_value)); | ||
| 292 | } | ||
| 293 | case ComponentType::UINT: // range [0, (1 << component_size) - 1] | ||
| 294 | *is_signed = false; | ||
| 295 | return original_value; | ||
| 296 | case ComponentType::FLOAT: | ||
| 297 | if (component_size == 16) { | ||
| 298 | return Operation(OperationCode::HCastFloat, original_value); | ||
| 299 | } else { | ||
| 300 | return original_value; | ||
| 301 | } | ||
| 302 | default: | ||
| 303 | UNIMPLEMENTED_MSG("Unimplement component type={}", component_type); | ||
| 304 | return original_value; | ||
| 305 | } | ||
| 306 | } | ||
| 307 | |||
| 274 | u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { | 308 | u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { |
| 275 | const Instruction instr = {program_code[pc]}; | 309 | const Instruction instr = {program_code[pc]}; |
| 276 | const auto opcode = OpCode::Decode(instr); | 310 | const auto opcode = OpCode::Decode(instr); |
| @@ -309,7 +343,8 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { | |||
| 309 | SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); | 343 | SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); |
| 310 | } | 344 | } |
| 311 | } else if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::D_BA) { | 345 | } else if (instr.suldst.mode == Tegra::Shader::SurfaceDataMode::D_BA) { |
| 312 | UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32); | 346 | UNIMPLEMENTED_IF(instr.suldst.GetStoreDataLayout() != StoreType::Bits32 && |
| 347 | instr.suldst.GetStoreDataLayout() != StoreType::Bits64); | ||
| 313 | 348 | ||
| 314 | auto descriptor = [this, instr] { | 349 | auto descriptor = [this, instr] { |
| 315 | std::optional<Tegra::Engines::SamplerDescriptor> descriptor; | 350 | std::optional<Tegra::Engines::SamplerDescriptor> descriptor; |
| @@ -333,7 +368,6 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { | |||
| 333 | switch (instr.suldst.GetStoreDataLayout()) { | 368 | switch (instr.suldst.GetStoreDataLayout()) { |
| 334 | case StoreType::Bits32: { | 369 | case StoreType::Bits32: { |
| 335 | u32 shifted_counter = 0; | 370 | u32 shifted_counter = 0; |
| 336 | // value should be RGBA format | ||
| 337 | Node value = Immediate(0); | 371 | Node value = Immediate(0); |
| 338 | for (u32 element = 0; element < 4; ++element) { | 372 | for (u32 element = 0; element < 4; ++element) { |
| 339 | if (!IsComponentEnabled(comp_mask, element)) { | 373 | if (!IsComponentEnabled(comp_mask, element)) { |
| @@ -343,39 +377,12 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { | |||
| 343 | const auto component_size = GetComponentSize(descriptor.format, element); | 377 | const auto component_size = GetComponentSize(descriptor.format, element); |
| 344 | bool is_signed = true; | 378 | bool is_signed = true; |
| 345 | MetaImage meta{image, {}, element}; | 379 | MetaImage meta{image, {}, element}; |
| 346 | const Node original_value = | 380 | |
| 347 | Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)); | 381 | Node converted_value = GetComponentValue( |
| 348 | 382 | component_type, component_size, | |
| 349 | Node converted_value = [&] { | 383 | Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)), |
| 350 | switch (component_type) { | 384 | &is_signed); |
| 351 | case ComponentType::SNORM: { | 385 | |
| 352 | is_signed = true; | ||
| 353 | // range [-1.0, 1.0] | ||
| 354 | auto cnv_value = | ||
| 355 | Operation(OperationCode::FMul, original_value, Immediate(127.f)); | ||
| 356 | cnv_value = SignedOperation(OperationCode::ICastFloat, is_signed, | ||
| 357 | std::move(cnv_value)); | ||
| 358 | return BitfieldExtract(std::move(cnv_value), 0, 8); | ||
| 359 | } | ||
| 360 | case ComponentType::SINT: | ||
| 361 | case ComponentType::UNORM: { | ||
| 362 | is_signed = false; | ||
| 363 | // range [0.0, 1.0] | ||
| 364 | auto cnv_value = | ||
| 365 | Operation(OperationCode::FMul, original_value, Immediate(255.f)); | ||
| 366 | return SignedOperation(OperationCode::ICastFloat, is_signed, | ||
| 367 | std::move(cnv_value)); | ||
| 368 | } | ||
| 369 | case ComponentType::UINT: // range [0, 255] | ||
| 370 | is_signed = false; | ||
| 371 | return original_value; | ||
| 372 | case ComponentType::FLOAT: | ||
| 373 | return original_value; | ||
| 374 | default: | ||
| 375 | UNIMPLEMENTED_MSG("Unimplement component type={}", component_type); | ||
| 376 | return original_value; | ||
| 377 | } | ||
| 378 | }(); | ||
| 379 | // shift element to correct position | 386 | // shift element to correct position |
| 380 | const auto shifted = shifted_counter; | 387 | const auto shifted = shifted_counter; |
| 381 | if (shifted > 0) { | 388 | if (shifted > 0) { |
| @@ -391,6 +398,56 @@ u32 ShaderIR::DecodeImage(NodeBlock& bb, u32 pc) { | |||
| 391 | SetRegister(bb, instr.gpr0.Value(), std::move(value)); | 398 | SetRegister(bb, instr.gpr0.Value(), std::move(value)); |
| 392 | break; | 399 | break; |
| 393 | } | 400 | } |
| 401 | case StoreType::Bits64: { | ||
| 402 | u32 indexer = 0; | ||
| 403 | u32 shifted_counter = 0; | ||
| 404 | Node value = Immediate(0); | ||
| 405 | for (u32 element = 0; element < 4; ++element) { | ||
| 406 | if (!IsComponentEnabled(comp_mask, element)) { | ||
| 407 | continue; | ||
| 408 | } | ||
| 409 | const auto component_type = GetComponentType(descriptor, element); | ||
| 410 | const auto component_size = GetComponentSize(descriptor.format, element); | ||
| 411 | |||
| 412 | bool is_signed = true; | ||
| 413 | MetaImage meta{image, {}, element}; | ||
| 414 | |||
| 415 | Node converted_value = GetComponentValue( | ||
| 416 | component_type, component_size, | ||
| 417 | Operation(OperationCode::ImageLoad, meta, GetCoordinates(type)), | ||
| 418 | &is_signed); | ||
| 419 | |||
| 420 | // shift element to correct position | ||
| 421 | const auto shifted = shifted_counter; | ||
| 422 | if (shifted > 0) { | ||
| 423 | converted_value = | ||
| 424 | SignedOperation(OperationCode::ILogicalShiftLeft, is_signed, | ||
| 425 | std::move(converted_value), Immediate(shifted)); | ||
| 426 | } | ||
| 427 | shifted_counter += component_size; | ||
| 428 | |||
| 429 | // add value into result | ||
| 430 | value = Operation(OperationCode::UBitwiseOr, value, std::move(converted_value)); | ||
| 431 | |||
| 432 | // if we shifted enough for 1 byte -> we save it into temp | ||
| 433 | if (shifted_counter >= 32) { | ||
| 434 | SetTemporary(bb, indexer++, std::move(value)); | ||
| 435 | |||
| 436 | // we only use 2 bytes for bits64 | ||
| 437 | if (indexer >= 2) { | ||
| 438 | break; | ||
| 439 | } | ||
| 440 | |||
| 441 | // reset counter and value to prepare pack next byte | ||
| 442 | value = Immediate(0); | ||
| 443 | shifted_counter = 0; | ||
| 444 | } | ||
| 445 | } | ||
| 446 | for (u32 i = 0; i < indexer; ++i) { | ||
| 447 | SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); | ||
| 448 | } | ||
| 449 | break; | ||
| 450 | } | ||
| 394 | default: | 451 | default: |
| 395 | UNREACHABLE(); | 452 | UNREACHABLE(); |
| 396 | break; | 453 | break; |
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index bbd86a2c5..baf7188d2 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp | |||
| @@ -24,10 +24,9 @@ using Tegra::Shader::PredCondition; | |||
| 24 | using Tegra::Shader::PredOperation; | 24 | using Tegra::Shader::PredOperation; |
| 25 | using Tegra::Shader::Register; | 25 | using Tegra::Shader::Register; |
| 26 | 26 | ||
| 27 | ShaderIR::ShaderIR(const ProgramCode& program_code, Tegra::Engines::ShaderType shader_stage, | 27 | ShaderIR::ShaderIR(const ProgramCode& program_code, u32 main_offset, CompilerSettings settings, |
| 28 | u32 main_offset, CompilerSettings settings, Registry& registry) | 28 | Registry& registry) |
| 29 | : program_code{program_code}, shader_stage{shader_stage}, | 29 | : program_code{program_code}, main_offset{main_offset}, settings{settings}, registry{registry} { |
| 30 | main_offset{main_offset}, settings{settings}, registry{registry} { | ||
| 31 | Decode(); | 30 | Decode(); |
| 32 | PostDecode(); | 31 | PostDecode(); |
| 33 | } | 32 | } |
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index e531181cd..408cce71e 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -68,8 +68,8 @@ struct GlobalMemoryUsage { | |||
| 68 | 68 | ||
| 69 | class ShaderIR final { | 69 | class ShaderIR final { |
| 70 | public: | 70 | public: |
| 71 | explicit ShaderIR(const ProgramCode& program_code, Tegra::Engines::ShaderType shader_stage, | 71 | explicit ShaderIR(const ProgramCode& program_code, u32 main_offset, CompilerSettings settings, |
| 72 | u32 main_offset, CompilerSettings settings, Registry& registry); | 72 | Registry& registry); |
| 73 | ~ShaderIR(); | 73 | ~ShaderIR(); |
| 74 | 74 | ||
| 75 | const std::map<u32, NodeBlock>& GetBasicBlocks() const { | 75 | const std::map<u32, NodeBlock>& GetBasicBlocks() const { |
| @@ -312,6 +312,10 @@ private: | |||
| 312 | /// Conditionally saturates a half float pair | 312 | /// Conditionally saturates a half float pair |
| 313 | Node GetSaturatedHalfFloat(Node value, bool saturate = true); | 313 | Node GetSaturatedHalfFloat(Node value, bool saturate = true); |
| 314 | 314 | ||
| 315 | /// Get image component value by type and size | ||
| 316 | Node GetComponentValue(Tegra::Texture::ComponentType component_type, u32 component_size, | ||
| 317 | const Node original_value, bool* is_signed); | ||
| 318 | |||
| 315 | /// Returns a predicate comparing two floats | 319 | /// Returns a predicate comparing two floats |
| 316 | Node GetPredicateComparisonFloat(Tegra::Shader::PredCondition condition, Node op_a, Node op_b); | 320 | Node GetPredicateComparisonFloat(Tegra::Shader::PredCondition condition, Node op_a, Node op_b); |
| 317 | /// Returns a predicate comparing two integers | 321 | /// Returns a predicate comparing two integers |
| @@ -419,7 +423,6 @@ private: | |||
| 419 | u32 NewCustomVariable(); | 423 | u32 NewCustomVariable(); |
| 420 | 424 | ||
| 421 | const ProgramCode& program_code; | 425 | const ProgramCode& program_code; |
| 422 | const Tegra::Engines::ShaderType shader_stage; | ||
| 423 | const u32 main_offset; | 426 | const u32 main_offset; |
| 424 | const CompilerSettings settings; | 427 | const CompilerSettings settings; |
| 425 | Registry& registry; | 428 | Registry& registry; |