diff options
| author | 2017-01-27 20:51:59 -0800 | |
|---|---|---|
| committer | 2017-02-04 13:59:09 -0800 | |
| commit | 9017093f58fb08b85cfb842f305efa667d62cecb (patch) | |
| tree | 98a1e77b197a562a8f13565e62f2e8bb9220ff94 /src | |
| parent | VideoCore: Split rasterizer regs from Regs struct (diff) | |
| download | yuzu-9017093f58fb08b85cfb842f305efa667d62cecb.tar.gz yuzu-9017093f58fb08b85cfb842f305efa667d62cecb.tar.xz yuzu-9017093f58fb08b85cfb842f305efa667d62cecb.zip | |
VideoCore: Split texturing regs from Regs struct
Diffstat (limited to 'src')
| -rw-r--r-- | src/citra_qt/debugger/graphics/graphics_cmdlists.cpp | 22 | ||||
| -rw-r--r-- | src/citra_qt/debugger/graphics/graphics_surface.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/video_core/command_processor.cpp | 24 | ||||
| -rw-r--r-- | src/video_core/debug_utils/debug_utils.cpp | 35 | ||||
| -rw-r--r-- | src/video_core/debug_utils/debug_utils.h | 8 | ||||
| -rw-r--r-- | src/video_core/pica.h | 352 | ||||
| -rw-r--r-- | src/video_core/rasterizer.cpp | 52 | ||||
| -rw-r--r-- | src/video_core/regs_texturing.h | 328 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 129 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 25 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/pica_to_gl.h | 4 | ||||
| -rw-r--r-- | src/video_core/texture/texture_decode.cpp | 38 | ||||
| -rw-r--r-- | src/video_core/texture/texture_decode.h | 12 |
17 files changed, 548 insertions, 507 deletions
diff --git a/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp index ee79f0edf..adaa18cfc 100644 --- a/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp +++ b/src/citra_qt/debugger/graphics/graphics_cmdlists.cpp | |||
| @@ -123,15 +123,16 @@ void GPUCommandListModel::OnPicaTraceFinished(const Pica::DebugUtils::PicaTrace& | |||
| 123 | void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) { | 123 | void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) { |
| 124 | const unsigned int command_id = | 124 | const unsigned int command_id = |
| 125 | list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt(); | 125 | list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt(); |
| 126 | if (COMMAND_IN_RANGE(command_id, texture0) || COMMAND_IN_RANGE(command_id, texture1) || | 126 | if (COMMAND_IN_RANGE(command_id, texturing.texture0) || |
| 127 | COMMAND_IN_RANGE(command_id, texture2)) { | 127 | COMMAND_IN_RANGE(command_id, texturing.texture1) || |
| 128 | COMMAND_IN_RANGE(command_id, texturing.texture2)) { | ||
| 128 | 129 | ||
| 129 | unsigned texture_index; | 130 | unsigned texture_index; |
| 130 | if (COMMAND_IN_RANGE(command_id, texture0)) { | 131 | if (COMMAND_IN_RANGE(command_id, texturing.texture0)) { |
| 131 | texture_index = 0; | 132 | texture_index = 0; |
| 132 | } else if (COMMAND_IN_RANGE(command_id, texture1)) { | 133 | } else if (COMMAND_IN_RANGE(command_id, texturing.texture1)) { |
| 133 | texture_index = 1; | 134 | texture_index = 1; |
| 134 | } else if (COMMAND_IN_RANGE(command_id, texture2)) { | 135 | } else if (COMMAND_IN_RANGE(command_id, texturing.texture2)) { |
| 135 | texture_index = 2; | 136 | texture_index = 2; |
| 136 | } else { | 137 | } else { |
| 137 | UNREACHABLE_MSG("Unknown texture command"); | 138 | UNREACHABLE_MSG("Unknown texture command"); |
| @@ -146,19 +147,20 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) { | |||
| 146 | 147 | ||
| 147 | const unsigned int command_id = | 148 | const unsigned int command_id = |
| 148 | list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt(); | 149 | list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt(); |
| 149 | if (COMMAND_IN_RANGE(command_id, texture0) || COMMAND_IN_RANGE(command_id, texture1) || | 150 | if (COMMAND_IN_RANGE(command_id, texturing.texture0) || |
| 150 | COMMAND_IN_RANGE(command_id, texture2)) { | 151 | COMMAND_IN_RANGE(command_id, texturing.texture1) || |
| 152 | COMMAND_IN_RANGE(command_id, texturing.texture2)) { | ||
| 151 | 153 | ||
| 152 | unsigned texture_index; | 154 | unsigned texture_index; |
| 153 | if (COMMAND_IN_RANGE(command_id, texture0)) { | 155 | if (COMMAND_IN_RANGE(command_id, texturing.texture0)) { |
| 154 | texture_index = 0; | 156 | texture_index = 0; |
| 155 | } else if (COMMAND_IN_RANGE(command_id, texture1)) { | 157 | } else if (COMMAND_IN_RANGE(command_id, texturing.texture1)) { |
| 156 | texture_index = 1; | 158 | texture_index = 1; |
| 157 | } else { | 159 | } else { |
| 158 | texture_index = 2; | 160 | texture_index = 2; |
| 159 | } | 161 | } |
| 160 | 162 | ||
| 161 | const auto texture = Pica::g_state.regs.GetTextures()[texture_index]; | 163 | const auto texture = Pica::g_state.regs.texturing.GetTextures()[texture_index]; |
| 162 | const auto config = texture.config; | 164 | const auto config = texture.config; |
| 163 | const auto format = texture.format; | 165 | const auto format = texture.format; |
| 164 | 166 | ||
diff --git a/src/citra_qt/debugger/graphics/graphics_surface.cpp b/src/citra_qt/debugger/graphics/graphics_surface.cpp index bd82b00d4..406a49f42 100644 --- a/src/citra_qt/debugger/graphics/graphics_surface.cpp +++ b/src/citra_qt/debugger/graphics/graphics_surface.cpp | |||
| @@ -512,7 +512,7 @@ void GraphicsSurfaceWidget::OnUpdate() { | |||
| 512 | break; | 512 | break; |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | const auto texture = Pica::g_state.regs.GetTextures()[texture_index]; | 515 | const auto texture = Pica::g_state.regs.texturing.GetTextures()[texture_index]; |
| 516 | auto info = Pica::Texture::TextureInfo::FromPicaRegister(texture.config, texture.format); | 516 | auto info = Pica::Texture::TextureInfo::FromPicaRegister(texture.config, texture.format); |
| 517 | 517 | ||
| 518 | surface_address = info.physical_address; | 518 | surface_address = info.physical_address; |
| @@ -574,7 +574,7 @@ void GraphicsSurfaceWidget::OnUpdate() { | |||
| 574 | info.physical_address = surface_address; | 574 | info.physical_address = surface_address; |
| 575 | info.width = surface_width; | 575 | info.width = surface_width; |
| 576 | info.height = surface_height; | 576 | info.height = surface_height; |
| 577 | info.format = static_cast<Pica::Regs::TextureFormat>(surface_format); | 577 | info.format = static_cast<Pica::TexturingRegs::TextureFormat>(surface_format); |
| 578 | info.SetDefaultStride(); | 578 | info.SetDefaultStride(); |
| 579 | 579 | ||
| 580 | for (unsigned int y = 0; y < surface_height; ++y) { | 580 | for (unsigned int y = 0; y < surface_height; ++y) { |
| @@ -689,7 +689,8 @@ void GraphicsSurfaceWidget::SaveSurface() { | |||
| 689 | 689 | ||
| 690 | unsigned int GraphicsSurfaceWidget::NibblesPerPixel(GraphicsSurfaceWidget::Format format) { | 690 | unsigned int GraphicsSurfaceWidget::NibblesPerPixel(GraphicsSurfaceWidget::Format format) { |
| 691 | if (format <= Format::MaxTextureFormat) { | 691 | if (format <= Format::MaxTextureFormat) { |
| 692 | return Pica::Regs::NibblesPerPixel(static_cast<Pica::Regs::TextureFormat>(format)); | 692 | return Pica::TexturingRegs::NibblesPerPixel( |
| 693 | static_cast<Pica::TexturingRegs::TextureFormat>(format)); | ||
| 693 | } | 694 | } |
| 694 | 695 | ||
| 695 | switch (format) { | 696 | switch (format) { |
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 522d7cc13..c0358fc20 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -33,6 +33,7 @@ set(HEADERS | |||
| 33 | rasterizer.h | 33 | rasterizer.h |
| 34 | rasterizer_interface.h | 34 | rasterizer_interface.h |
| 35 | regs_rasterizer.h | 35 | regs_rasterizer.h |
| 36 | regs_texturing.h | ||
| 36 | renderer_base.h | 37 | renderer_base.h |
| 37 | renderer_opengl/gl_rasterizer.h | 38 | renderer_opengl/gl_rasterizer.h |
| 38 | renderer_opengl/gl_rasterizer_cache.h | 39 | renderer_opengl/gl_rasterizer_cache.h |
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index b4a9f23cf..fa3432f60 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp | |||
| @@ -225,13 +225,13 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 225 | 225 | ||
| 226 | if (g_debug_context && g_debug_context->recorder) { | 226 | if (g_debug_context && g_debug_context->recorder) { |
| 227 | for (int i = 0; i < 3; ++i) { | 227 | for (int i = 0; i < 3; ++i) { |
| 228 | const auto texture = regs.GetTextures()[i]; | 228 | const auto texture = regs.texturing.GetTextures()[i]; |
| 229 | if (!texture.enabled) | 229 | if (!texture.enabled) |
| 230 | continue; | 230 | continue; |
| 231 | 231 | ||
| 232 | u8* texture_data = Memory::GetPhysicalPointer(texture.config.GetPhysicalAddress()); | 232 | u8* texture_data = Memory::GetPhysicalPointer(texture.config.GetPhysicalAddress()); |
| 233 | g_debug_context->recorder->MemoryAccessed( | 233 | g_debug_context->recorder->MemoryAccessed( |
| 234 | texture_data, Pica::Regs::NibblesPerPixel(texture.format) * | 234 | texture_data, Pica::TexturingRegs::NibblesPerPixel(texture.format) * |
| 235 | texture.config.width / 2 * texture.config.height, | 235 | texture.config.width / 2 * texture.config.height, |
| 236 | texture.config.GetPhysicalAddress()); | 236 | texture.config.GetPhysicalAddress()); |
| 237 | } | 237 | } |
| @@ -438,16 +438,16 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | |||
| 438 | break; | 438 | break; |
| 439 | } | 439 | } |
| 440 | 440 | ||
| 441 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[0], 0xe8): | 441 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[0], 0xe8): |
| 442 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[1], 0xe9): | 442 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[1], 0xe9): |
| 443 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[2], 0xea): | 443 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[2], 0xea): |
| 444 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[3], 0xeb): | 444 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[3], 0xeb): |
| 445 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[4], 0xec): | 445 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[4], 0xec): |
| 446 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[5], 0xed): | 446 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[5], 0xed): |
| 447 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[6], 0xee): | 447 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[6], 0xee): |
| 448 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[7], 0xef): { | 448 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[7], 0xef): { |
| 449 | g_state.fog.lut[regs.fog_lut_offset % 128].raw = value; | 449 | g_state.fog.lut[regs.texturing.fog_lut_offset % 128].raw = value; |
| 450 | regs.fog_lut_offset.Assign(regs.fog_lut_offset + 1); | 450 | regs.texturing.fog_lut_offset.Assign(regs.texturing.fog_lut_offset + 1); |
| 451 | break; | 451 | break; |
| 452 | } | 452 | } |
| 453 | 453 | ||
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index 618268654..81cd35cd9 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp | |||
| @@ -331,7 +331,7 @@ static void FlushIOFile(png_structp png_ptr) { | |||
| 331 | } | 331 | } |
| 332 | #endif | 332 | #endif |
| 333 | 333 | ||
| 334 | void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) { | 334 | void DumpTexture(const TexturingRegs::TextureConfig& texture_config, u8* data) { |
| 335 | #ifndef HAVE_PNG | 335 | #ifndef HAVE_PNG |
| 336 | return; | 336 | return; |
| 337 | #else | 337 | #else |
| @@ -396,7 +396,7 @@ void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) { | |||
| 396 | info.width = texture_config.width; | 396 | info.width = texture_config.width; |
| 397 | info.height = texture_config.height; | 397 | info.height = texture_config.height; |
| 398 | info.stride = row_stride; | 398 | info.stride = row_stride; |
| 399 | info.format = g_state.regs.texture0_format; | 399 | info.format = g_state.regs.texturing.texture0_format; |
| 400 | Math::Vec4<u8> texture_color = Pica::Texture::LookupTexture(data, x, y, info); | 400 | Math::Vec4<u8> texture_color = Pica::Texture::LookupTexture(data, x, y, info); |
| 401 | buf[3 * x + y * row_stride] = texture_color.r(); | 401 | buf[3 * x + y * row_stride] = texture_color.r(); |
| 402 | buf[3 * x + y * row_stride + 1] = texture_color.g(); | 402 | buf[3 * x + y * row_stride + 1] = texture_color.g(); |
| @@ -434,8 +434,10 @@ static std::string ReplacePattern(const std::string& input, const std::string& p | |||
| 434 | return ret; | 434 | return ret; |
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | static std::string GetTevStageConfigSourceString(const Pica::Regs::TevStageConfig::Source& source) { | 437 | static std::string GetTevStageConfigSourceString( |
| 438 | using Source = Pica::Regs::TevStageConfig::Source; | 438 | const TexturingRegs::TevStageConfig::Source& source) { |
| 439 | |||
| 440 | using Source = TexturingRegs::TevStageConfig::Source; | ||
| 439 | static const std::map<Source, std::string> source_map = { | 441 | static const std::map<Source, std::string> source_map = { |
| 440 | {Source::PrimaryColor, "PrimaryColor"}, | 442 | {Source::PrimaryColor, "PrimaryColor"}, |
| 441 | {Source::PrimaryFragmentColor, "PrimaryFragmentColor"}, | 443 | {Source::PrimaryFragmentColor, "PrimaryFragmentColor"}, |
| @@ -457,9 +459,10 @@ static std::string GetTevStageConfigSourceString(const Pica::Regs::TevStageConfi | |||
| 457 | } | 459 | } |
| 458 | 460 | ||
| 459 | static std::string GetTevStageConfigColorSourceString( | 461 | static std::string GetTevStageConfigColorSourceString( |
| 460 | const Pica::Regs::TevStageConfig::Source& source, | 462 | const TexturingRegs::TevStageConfig::Source& source, |
| 461 | const Pica::Regs::TevStageConfig::ColorModifier modifier) { | 463 | const TexturingRegs::TevStageConfig::ColorModifier modifier) { |
| 462 | using ColorModifier = Pica::Regs::TevStageConfig::ColorModifier; | 464 | |
| 465 | using ColorModifier = TexturingRegs::TevStageConfig::ColorModifier; | ||
| 463 | static const std::map<ColorModifier, std::string> color_modifier_map = { | 466 | static const std::map<ColorModifier, std::string> color_modifier_map = { |
| 464 | {ColorModifier::SourceColor, "%source.rgb"}, | 467 | {ColorModifier::SourceColor, "%source.rgb"}, |
| 465 | {ColorModifier::OneMinusSourceColor, "(1.0 - %source.rgb)"}, | 468 | {ColorModifier::OneMinusSourceColor, "(1.0 - %source.rgb)"}, |
| @@ -483,9 +486,10 @@ static std::string GetTevStageConfigColorSourceString( | |||
| 483 | } | 486 | } |
| 484 | 487 | ||
| 485 | static std::string GetTevStageConfigAlphaSourceString( | 488 | static std::string GetTevStageConfigAlphaSourceString( |
| 486 | const Pica::Regs::TevStageConfig::Source& source, | 489 | const TexturingRegs::TevStageConfig::Source& source, |
| 487 | const Pica::Regs::TevStageConfig::AlphaModifier modifier) { | 490 | const TexturingRegs::TevStageConfig::AlphaModifier modifier) { |
| 488 | using AlphaModifier = Pica::Regs::TevStageConfig::AlphaModifier; | 491 | |
| 492 | using AlphaModifier = TexturingRegs::TevStageConfig::AlphaModifier; | ||
| 489 | static const std::map<AlphaModifier, std::string> alpha_modifier_map = { | 493 | static const std::map<AlphaModifier, std::string> alpha_modifier_map = { |
| 490 | {AlphaModifier::SourceAlpha, "%source.a"}, | 494 | {AlphaModifier::SourceAlpha, "%source.a"}, |
| 491 | {AlphaModifier::OneMinusSourceAlpha, "(1.0 - %source.a)"}, | 495 | {AlphaModifier::OneMinusSourceAlpha, "(1.0 - %source.a)"}, |
| @@ -507,8 +511,9 @@ static std::string GetTevStageConfigAlphaSourceString( | |||
| 507 | } | 511 | } |
| 508 | 512 | ||
| 509 | static std::string GetTevStageConfigOperationString( | 513 | static std::string GetTevStageConfigOperationString( |
| 510 | const Pica::Regs::TevStageConfig::Operation& operation) { | 514 | const TexturingRegs::TevStageConfig::Operation& operation) { |
| 511 | using Operation = Pica::Regs::TevStageConfig::Operation; | 515 | |
| 516 | using Operation = TexturingRegs::TevStageConfig::Operation; | ||
| 512 | static const std::map<Operation, std::string> combiner_map = { | 517 | static const std::map<Operation, std::string> combiner_map = { |
| 513 | {Operation::Replace, "%source1"}, | 518 | {Operation::Replace, "%source1"}, |
| 514 | {Operation::Modulate, "(%source1 * %source2)"}, | 519 | {Operation::Modulate, "(%source1 * %source2)"}, |
| @@ -528,7 +533,7 @@ static std::string GetTevStageConfigOperationString( | |||
| 528 | return op_it->second; | 533 | return op_it->second; |
| 529 | } | 534 | } |
| 530 | 535 | ||
| 531 | std::string GetTevStageConfigColorCombinerString(const Pica::Regs::TevStageConfig& tev_stage) { | 536 | std::string GetTevStageConfigColorCombinerString(const TexturingRegs::TevStageConfig& tev_stage) { |
| 532 | auto op_str = GetTevStageConfigOperationString(tev_stage.color_op); | 537 | auto op_str = GetTevStageConfigOperationString(tev_stage.color_op); |
| 533 | op_str = ReplacePattern( | 538 | op_str = ReplacePattern( |
| 534 | op_str, "%source1", | 539 | op_str, "%source1", |
| @@ -541,7 +546,7 @@ std::string GetTevStageConfigColorCombinerString(const Pica::Regs::TevStageConfi | |||
| 541 | GetTevStageConfigColorSourceString(tev_stage.color_source3, tev_stage.color_modifier3)); | 546 | GetTevStageConfigColorSourceString(tev_stage.color_source3, tev_stage.color_modifier3)); |
| 542 | } | 547 | } |
| 543 | 548 | ||
| 544 | std::string GetTevStageConfigAlphaCombinerString(const Pica::Regs::TevStageConfig& tev_stage) { | 549 | std::string GetTevStageConfigAlphaCombinerString(const TexturingRegs::TevStageConfig& tev_stage) { |
| 545 | auto op_str = GetTevStageConfigOperationString(tev_stage.alpha_op); | 550 | auto op_str = GetTevStageConfigOperationString(tev_stage.alpha_op); |
| 546 | op_str = ReplacePattern( | 551 | op_str = ReplacePattern( |
| 547 | op_str, "%source1", | 552 | op_str, "%source1", |
| @@ -554,7 +559,7 @@ std::string GetTevStageConfigAlphaCombinerString(const Pica::Regs::TevStageConfi | |||
| 554 | GetTevStageConfigAlphaSourceString(tev_stage.alpha_source3, tev_stage.alpha_modifier3)); | 559 | GetTevStageConfigAlphaSourceString(tev_stage.alpha_source3, tev_stage.alpha_modifier3)); |
| 555 | } | 560 | } |
| 556 | 561 | ||
| 557 | void DumpTevStageConfig(const std::array<Pica::Regs::TevStageConfig, 6>& stages) { | 562 | void DumpTevStageConfig(const std::array<TexturingRegs::TevStageConfig, 6>& stages) { |
| 558 | std::string stage_info = "Tev setup:\n"; | 563 | std::string stage_info = "Tev setup:\n"; |
| 559 | for (size_t index = 0; index < stages.size(); ++index) { | 564 | for (size_t index = 0; index < stages.size(); ++index) { |
| 560 | const auto& tev_stage = stages[index]; | 565 | const auto& tev_stage = stages[index]; |
diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h index 51270bc9c..e58b76d41 100644 --- a/src/video_core/debug_utils/debug_utils.h +++ b/src/video_core/debug_utils/debug_utils.h | |||
| @@ -205,13 +205,13 @@ inline bool IsPicaTracing() { | |||
| 205 | void OnPicaRegWrite(PicaTrace::Write write); | 205 | void OnPicaRegWrite(PicaTrace::Write write); |
| 206 | std::unique_ptr<PicaTrace> FinishPicaTracing(); | 206 | std::unique_ptr<PicaTrace> FinishPicaTracing(); |
| 207 | 207 | ||
| 208 | void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data); | 208 | void DumpTexture(const TexturingRegs::TextureConfig& texture_config, u8* data); |
| 209 | 209 | ||
| 210 | std::string GetTevStageConfigColorCombinerString(const Pica::Regs::TevStageConfig& tev_stage); | 210 | std::string GetTevStageConfigColorCombinerString(const TexturingRegs::TevStageConfig& tev_stage); |
| 211 | std::string GetTevStageConfigAlphaCombinerString(const Pica::Regs::TevStageConfig& tev_stage); | 211 | std::string GetTevStageConfigAlphaCombinerString(const TexturingRegs::TevStageConfig& tev_stage); |
| 212 | 212 | ||
| 213 | /// Dumps the Tev stage config to log at trace level | 213 | /// Dumps the Tev stage config to log at trace level |
| 214 | void DumpTevStageConfig(const std::array<Pica::Regs::TevStageConfig, 6>& stages); | 214 | void DumpTevStageConfig(const std::array<TexturingRegs::TevStageConfig, 6>& stages); |
| 215 | 215 | ||
| 216 | /** | 216 | /** |
| 217 | * Used in the vertex loader to merge access records. TODO: Investigate if actually useful. | 217 | * Used in the vertex loader to merge access records. TODO: Investigate if actually useful. |
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 9d7262b43..71194198a 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include "common/logging/log.h" | 19 | #include "common/logging/log.h" |
| 20 | #include "common/vector_math.h" | 20 | #include "common/vector_math.h" |
| 21 | #include "video_core/regs_rasterizer.h" | 21 | #include "video_core/regs_rasterizer.h" |
| 22 | #include "video_core/regs_texturing.h" | ||
| 22 | 23 | ||
| 23 | namespace Pica { | 24 | namespace Pica { |
| 24 | 25 | ||
| @@ -49,81 +50,7 @@ struct Regs { | |||
| 49 | u32 trigger_irq; | 50 | u32 trigger_irq; |
| 50 | INSERT_PADDING_WORDS(0x2f); | 51 | INSERT_PADDING_WORDS(0x2f); |
| 51 | RasterizerRegs rasterizer; | 52 | RasterizerRegs rasterizer; |
| 52 | 53 | TexturingRegs texturing; | |
| 53 | struct TextureConfig { | ||
| 54 | enum TextureType : u32 { | ||
| 55 | Texture2D = 0, | ||
| 56 | TextureCube = 1, | ||
| 57 | Shadow2D = 2, | ||
| 58 | Projection2D = 3, | ||
| 59 | ShadowCube = 4, | ||
| 60 | Disabled = 5, | ||
| 61 | }; | ||
| 62 | |||
| 63 | enum WrapMode : u32 { | ||
| 64 | ClampToEdge = 0, | ||
| 65 | ClampToBorder = 1, | ||
| 66 | Repeat = 2, | ||
| 67 | MirroredRepeat = 3, | ||
| 68 | }; | ||
| 69 | |||
| 70 | enum TextureFilter : u32 { | ||
| 71 | Nearest = 0, | ||
| 72 | Linear = 1, | ||
| 73 | }; | ||
| 74 | |||
| 75 | union { | ||
| 76 | u32 raw; | ||
| 77 | BitField<0, 8, u32> r; | ||
| 78 | BitField<8, 8, u32> g; | ||
| 79 | BitField<16, 8, u32> b; | ||
| 80 | BitField<24, 8, u32> a; | ||
| 81 | } border_color; | ||
| 82 | |||
| 83 | union { | ||
| 84 | BitField<0, 16, u32> height; | ||
| 85 | BitField<16, 16, u32> width; | ||
| 86 | }; | ||
| 87 | |||
| 88 | union { | ||
| 89 | BitField<1, 1, TextureFilter> mag_filter; | ||
| 90 | BitField<2, 1, TextureFilter> min_filter; | ||
| 91 | BitField<8, 2, WrapMode> wrap_t; | ||
| 92 | BitField<12, 2, WrapMode> wrap_s; | ||
| 93 | BitField<28, 2, TextureType> | ||
| 94 | type; ///< @note Only valid for texture 0 according to 3DBrew. | ||
| 95 | }; | ||
| 96 | |||
| 97 | INSERT_PADDING_WORDS(0x1); | ||
| 98 | |||
| 99 | u32 address; | ||
| 100 | |||
| 101 | u32 GetPhysicalAddress() const { | ||
| 102 | return DecodeAddressRegister(address); | ||
| 103 | } | ||
| 104 | |||
| 105 | // texture1 and texture2 store the texture format directly after the address | ||
| 106 | // whereas texture0 inserts some additional flags inbetween. | ||
| 107 | // Hence, we store the format separately so that all other parameters can be described | ||
| 108 | // in a single structure. | ||
| 109 | }; | ||
| 110 | |||
| 111 | enum class TextureFormat : u32 { | ||
| 112 | RGBA8 = 0, | ||
| 113 | RGB8 = 1, | ||
| 114 | RGB5A1 = 2, | ||
| 115 | RGB565 = 3, | ||
| 116 | RGBA4 = 4, | ||
| 117 | IA8 = 5, | ||
| 118 | RG8 = 6, ///< @note Also called HILO8 in 3DBrew. | ||
| 119 | I8 = 7, | ||
| 120 | A8 = 8, | ||
| 121 | IA4 = 9, | ||
| 122 | I4 = 10, | ||
| 123 | A4 = 11, | ||
| 124 | ETC1 = 12, // compressed | ||
| 125 | ETC1A4 = 13, // compressed | ||
| 126 | }; | ||
| 127 | 54 | ||
| 128 | enum class LogicOp : u32 { | 55 | enum class LogicOp : u32 { |
| 129 | Clear = 0, | 56 | Clear = 0, |
| @@ -144,239 +71,6 @@ struct Regs { | |||
| 144 | OrInverted = 15, | 71 | OrInverted = 15, |
| 145 | }; | 72 | }; |
| 146 | 73 | ||
| 147 | static unsigned NibblesPerPixel(TextureFormat format) { | ||
| 148 | switch (format) { | ||
| 149 | case TextureFormat::RGBA8: | ||
| 150 | return 8; | ||
| 151 | |||
| 152 | case TextureFormat::RGB8: | ||
| 153 | return 6; | ||
| 154 | |||
| 155 | case TextureFormat::RGB5A1: | ||
| 156 | case TextureFormat::RGB565: | ||
| 157 | case TextureFormat::RGBA4: | ||
| 158 | case TextureFormat::IA8: | ||
| 159 | case TextureFormat::RG8: | ||
| 160 | return 4; | ||
| 161 | |||
| 162 | case TextureFormat::I4: | ||
| 163 | case TextureFormat::A4: | ||
| 164 | return 1; | ||
| 165 | |||
| 166 | case TextureFormat::I8: | ||
| 167 | case TextureFormat::A8: | ||
| 168 | case TextureFormat::IA4: | ||
| 169 | return 2; | ||
| 170 | |||
| 171 | default: // placeholder for yet unknown formats | ||
| 172 | UNIMPLEMENTED(); | ||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | } | ||
| 176 | |||
| 177 | union { | ||
| 178 | BitField<0, 1, u32> texture0_enable; | ||
| 179 | BitField<1, 1, u32> texture1_enable; | ||
| 180 | BitField<2, 1, u32> texture2_enable; | ||
| 181 | }; | ||
| 182 | TextureConfig texture0; | ||
| 183 | INSERT_PADDING_WORDS(0x8); | ||
| 184 | BitField<0, 4, TextureFormat> texture0_format; | ||
| 185 | BitField<0, 1, u32> fragment_lighting_enable; | ||
| 186 | INSERT_PADDING_WORDS(0x1); | ||
| 187 | TextureConfig texture1; | ||
| 188 | BitField<0, 4, TextureFormat> texture1_format; | ||
| 189 | INSERT_PADDING_WORDS(0x2); | ||
| 190 | TextureConfig texture2; | ||
| 191 | BitField<0, 4, TextureFormat> texture2_format; | ||
| 192 | INSERT_PADDING_WORDS(0x21); | ||
| 193 | |||
| 194 | struct FullTextureConfig { | ||
| 195 | const bool enabled; | ||
| 196 | const TextureConfig config; | ||
| 197 | const TextureFormat format; | ||
| 198 | }; | ||
| 199 | const std::array<FullTextureConfig, 3> GetTextures() const { | ||
| 200 | return {{ | ||
| 201 | {texture0_enable.ToBool(), texture0, texture0_format}, | ||
| 202 | {texture1_enable.ToBool(), texture1, texture1_format}, | ||
| 203 | {texture2_enable.ToBool(), texture2, texture2_format}, | ||
| 204 | }}; | ||
| 205 | } | ||
| 206 | |||
| 207 | // 0xc0-0xff: Texture Combiner (akin to glTexEnv) | ||
| 208 | struct TevStageConfig { | ||
| 209 | enum class Source : u32 { | ||
| 210 | PrimaryColor = 0x0, | ||
| 211 | PrimaryFragmentColor = 0x1, | ||
| 212 | SecondaryFragmentColor = 0x2, | ||
| 213 | |||
| 214 | Texture0 = 0x3, | ||
| 215 | Texture1 = 0x4, | ||
| 216 | Texture2 = 0x5, | ||
| 217 | Texture3 = 0x6, | ||
| 218 | |||
| 219 | PreviousBuffer = 0xd, | ||
| 220 | Constant = 0xe, | ||
| 221 | Previous = 0xf, | ||
| 222 | }; | ||
| 223 | |||
| 224 | enum class ColorModifier : u32 { | ||
| 225 | SourceColor = 0x0, | ||
| 226 | OneMinusSourceColor = 0x1, | ||
| 227 | SourceAlpha = 0x2, | ||
| 228 | OneMinusSourceAlpha = 0x3, | ||
| 229 | SourceRed = 0x4, | ||
| 230 | OneMinusSourceRed = 0x5, | ||
| 231 | |||
| 232 | SourceGreen = 0x8, | ||
| 233 | OneMinusSourceGreen = 0x9, | ||
| 234 | |||
| 235 | SourceBlue = 0xc, | ||
| 236 | OneMinusSourceBlue = 0xd, | ||
| 237 | }; | ||
| 238 | |||
| 239 | enum class AlphaModifier : u32 { | ||
| 240 | SourceAlpha = 0x0, | ||
| 241 | OneMinusSourceAlpha = 0x1, | ||
| 242 | SourceRed = 0x2, | ||
| 243 | OneMinusSourceRed = 0x3, | ||
| 244 | SourceGreen = 0x4, | ||
| 245 | OneMinusSourceGreen = 0x5, | ||
| 246 | SourceBlue = 0x6, | ||
| 247 | OneMinusSourceBlue = 0x7, | ||
| 248 | }; | ||
| 249 | |||
| 250 | enum class Operation : u32 { | ||
| 251 | Replace = 0, | ||
| 252 | Modulate = 1, | ||
| 253 | Add = 2, | ||
| 254 | AddSigned = 3, | ||
| 255 | Lerp = 4, | ||
| 256 | Subtract = 5, | ||
| 257 | Dot3_RGB = 6, | ||
| 258 | |||
| 259 | MultiplyThenAdd = 8, | ||
| 260 | AddThenMultiply = 9, | ||
| 261 | }; | ||
| 262 | |||
| 263 | union { | ||
| 264 | u32 sources_raw; | ||
| 265 | BitField<0, 4, Source> color_source1; | ||
| 266 | BitField<4, 4, Source> color_source2; | ||
| 267 | BitField<8, 4, Source> color_source3; | ||
| 268 | BitField<16, 4, Source> alpha_source1; | ||
| 269 | BitField<20, 4, Source> alpha_source2; | ||
| 270 | BitField<24, 4, Source> alpha_source3; | ||
| 271 | }; | ||
| 272 | |||
| 273 | union { | ||
| 274 | u32 modifiers_raw; | ||
| 275 | BitField<0, 4, ColorModifier> color_modifier1; | ||
| 276 | BitField<4, 4, ColorModifier> color_modifier2; | ||
| 277 | BitField<8, 4, ColorModifier> color_modifier3; | ||
| 278 | BitField<12, 3, AlphaModifier> alpha_modifier1; | ||
| 279 | BitField<16, 3, AlphaModifier> alpha_modifier2; | ||
| 280 | BitField<20, 3, AlphaModifier> alpha_modifier3; | ||
| 281 | }; | ||
| 282 | |||
| 283 | union { | ||
| 284 | u32 ops_raw; | ||
| 285 | BitField<0, 4, Operation> color_op; | ||
| 286 | BitField<16, 4, Operation> alpha_op; | ||
| 287 | }; | ||
| 288 | |||
| 289 | union { | ||
| 290 | u32 const_color; | ||
| 291 | BitField<0, 8, u32> const_r; | ||
| 292 | BitField<8, 8, u32> const_g; | ||
| 293 | BitField<16, 8, u32> const_b; | ||
| 294 | BitField<24, 8, u32> const_a; | ||
| 295 | }; | ||
| 296 | |||
| 297 | union { | ||
| 298 | u32 scales_raw; | ||
| 299 | BitField<0, 2, u32> color_scale; | ||
| 300 | BitField<16, 2, u32> alpha_scale; | ||
| 301 | }; | ||
| 302 | |||
| 303 | inline unsigned GetColorMultiplier() const { | ||
| 304 | return (color_scale < 3) ? (1 << color_scale) : 1; | ||
| 305 | } | ||
| 306 | |||
| 307 | inline unsigned GetAlphaMultiplier() const { | ||
| 308 | return (alpha_scale < 3) ? (1 << alpha_scale) : 1; | ||
| 309 | } | ||
| 310 | }; | ||
| 311 | |||
| 312 | TevStageConfig tev_stage0; | ||
| 313 | INSERT_PADDING_WORDS(0x3); | ||
| 314 | TevStageConfig tev_stage1; | ||
| 315 | INSERT_PADDING_WORDS(0x3); | ||
| 316 | TevStageConfig tev_stage2; | ||
| 317 | INSERT_PADDING_WORDS(0x3); | ||
| 318 | TevStageConfig tev_stage3; | ||
| 319 | INSERT_PADDING_WORDS(0x3); | ||
| 320 | |||
| 321 | enum class FogMode : u32 { | ||
| 322 | None = 0, | ||
| 323 | Fog = 5, | ||
| 324 | Gas = 7, | ||
| 325 | }; | ||
| 326 | |||
| 327 | union { | ||
| 328 | BitField<0, 3, FogMode> fog_mode; | ||
| 329 | BitField<16, 1, u32> fog_flip; | ||
| 330 | |||
| 331 | union { | ||
| 332 | // Tev stages 0-3 write their output to the combiner buffer if the corresponding bit in | ||
| 333 | // these masks are set | ||
| 334 | BitField<8, 4, u32> update_mask_rgb; | ||
| 335 | BitField<12, 4, u32> update_mask_a; | ||
| 336 | |||
| 337 | bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const { | ||
| 338 | return (stage_index < 4) && (update_mask_rgb & (1 << stage_index)); | ||
| 339 | } | ||
| 340 | |||
| 341 | bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const { | ||
| 342 | return (stage_index < 4) && (update_mask_a & (1 << stage_index)); | ||
| 343 | } | ||
| 344 | } tev_combiner_buffer_input; | ||
| 345 | }; | ||
| 346 | |||
| 347 | union { | ||
| 348 | u32 raw; | ||
| 349 | BitField<0, 8, u32> r; | ||
| 350 | BitField<8, 8, u32> g; | ||
| 351 | BitField<16, 8, u32> b; | ||
| 352 | } fog_color; | ||
| 353 | |||
| 354 | INSERT_PADDING_WORDS(0x4); | ||
| 355 | |||
| 356 | BitField<0, 16, u32> fog_lut_offset; | ||
| 357 | |||
| 358 | INSERT_PADDING_WORDS(0x1); | ||
| 359 | |||
| 360 | u32 fog_lut_data[8]; | ||
| 361 | |||
| 362 | TevStageConfig tev_stage4; | ||
| 363 | INSERT_PADDING_WORDS(0x3); | ||
| 364 | TevStageConfig tev_stage5; | ||
| 365 | |||
| 366 | union { | ||
| 367 | u32 raw; | ||
| 368 | BitField<0, 8, u32> r; | ||
| 369 | BitField<8, 8, u32> g; | ||
| 370 | BitField<16, 8, u32> b; | ||
| 371 | BitField<24, 8, u32> a; | ||
| 372 | } tev_combiner_buffer_color; | ||
| 373 | |||
| 374 | INSERT_PADDING_WORDS(0x2); | ||
| 375 | |||
| 376 | const std::array<Regs::TevStageConfig, 6> GetTevStages() const { | ||
| 377 | return {{tev_stage0, tev_stage1, tev_stage2, tev_stage3, tev_stage4, tev_stage5}}; | ||
| 378 | }; | ||
| 379 | |||
| 380 | enum class BlendEquation : u32 { | 74 | enum class BlendEquation : u32 { |
| 381 | Add = 0, | 75 | Add = 0, |
| 382 | Subtract = 1, | 76 | Subtract = 1, |
| @@ -1241,26 +935,28 @@ ASSERT_REG_POSITION(rasterizer.scissor_test, 0x65); | |||
| 1241 | ASSERT_REG_POSITION(rasterizer.viewport_corner, 0x68); | 935 | ASSERT_REG_POSITION(rasterizer.viewport_corner, 0x68); |
| 1242 | ASSERT_REG_POSITION(rasterizer.depthmap_enable, 0x6D); | 936 | ASSERT_REG_POSITION(rasterizer.depthmap_enable, 0x6D); |
| 1243 | 937 | ||
| 1244 | ASSERT_REG_POSITION(texture0_enable, 0x80); | 938 | ASSERT_REG_POSITION(texturing, 0x80); |
| 1245 | ASSERT_REG_POSITION(texture0, 0x81); | 939 | ASSERT_REG_POSITION(texturing.texture0_enable, 0x80); |
| 1246 | ASSERT_REG_POSITION(texture0_format, 0x8e); | 940 | ASSERT_REG_POSITION(texturing.texture0, 0x81); |
| 1247 | ASSERT_REG_POSITION(fragment_lighting_enable, 0x8f); | 941 | ASSERT_REG_POSITION(texturing.texture0_format, 0x8e); |
| 1248 | ASSERT_REG_POSITION(texture1, 0x91); | 942 | ASSERT_REG_POSITION(texturing.fragment_lighting_enable, 0x8f); |
| 1249 | ASSERT_REG_POSITION(texture1_format, 0x96); | 943 | ASSERT_REG_POSITION(texturing.texture1, 0x91); |
| 1250 | ASSERT_REG_POSITION(texture2, 0x99); | 944 | ASSERT_REG_POSITION(texturing.texture1_format, 0x96); |
| 1251 | ASSERT_REG_POSITION(texture2_format, 0x9e); | 945 | ASSERT_REG_POSITION(texturing.texture2, 0x99); |
| 1252 | ASSERT_REG_POSITION(tev_stage0, 0xc0); | 946 | ASSERT_REG_POSITION(texturing.texture2_format, 0x9e); |
| 1253 | ASSERT_REG_POSITION(tev_stage1, 0xc8); | 947 | ASSERT_REG_POSITION(texturing.tev_stage0, 0xc0); |
| 1254 | ASSERT_REG_POSITION(tev_stage2, 0xd0); | 948 | ASSERT_REG_POSITION(texturing.tev_stage1, 0xc8); |
| 1255 | ASSERT_REG_POSITION(tev_stage3, 0xd8); | 949 | ASSERT_REG_POSITION(texturing.tev_stage2, 0xd0); |
| 1256 | ASSERT_REG_POSITION(tev_combiner_buffer_input, 0xe0); | 950 | ASSERT_REG_POSITION(texturing.tev_stage3, 0xd8); |
| 1257 | ASSERT_REG_POSITION(fog_mode, 0xe0); | 951 | ASSERT_REG_POSITION(texturing.tev_combiner_buffer_input, 0xe0); |
| 1258 | ASSERT_REG_POSITION(fog_color, 0xe1); | 952 | ASSERT_REG_POSITION(texturing.fog_mode, 0xe0); |
| 1259 | ASSERT_REG_POSITION(fog_lut_offset, 0xe6); | 953 | ASSERT_REG_POSITION(texturing.fog_color, 0xe1); |
| 1260 | ASSERT_REG_POSITION(fog_lut_data, 0xe8); | 954 | ASSERT_REG_POSITION(texturing.fog_lut_offset, 0xe6); |
| 1261 | ASSERT_REG_POSITION(tev_stage4, 0xf0); | 955 | ASSERT_REG_POSITION(texturing.fog_lut_data, 0xe8); |
| 1262 | ASSERT_REG_POSITION(tev_stage5, 0xf8); | 956 | ASSERT_REG_POSITION(texturing.tev_stage4, 0xf0); |
| 1263 | ASSERT_REG_POSITION(tev_combiner_buffer_color, 0xfd); | 957 | ASSERT_REG_POSITION(texturing.tev_stage5, 0xf8); |
| 958 | ASSERT_REG_POSITION(texturing.tev_combiner_buffer_color, 0xfd); | ||
| 959 | |||
| 1264 | ASSERT_REG_POSITION(output_merger, 0x100); | 960 | ASSERT_REG_POSITION(output_merger, 0x100); |
| 1265 | ASSERT_REG_POSITION(framebuffer, 0x110); | 961 | ASSERT_REG_POSITION(framebuffer, 0x110); |
| 1266 | ASSERT_REG_POSITION(lighting, 0x140); | 962 | ASSERT_REG_POSITION(lighting, 0x140); |
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index f82873480..48bc26571 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -397,8 +397,8 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 397 | 397 | ||
| 398 | auto w_inverse = Math::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w); | 398 | auto w_inverse = Math::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w); |
| 399 | 399 | ||
| 400 | auto textures = regs.GetTextures(); | 400 | auto textures = regs.texturing.GetTextures(); |
| 401 | auto tev_stages = regs.GetTevStages(); | 401 | auto tev_stages = regs.texturing.GetTevStages(); |
| 402 | 402 | ||
| 403 | bool stencil_action_enable = g_state.regs.output_merger.stencil_test.enable && | 403 | bool stencil_action_enable = g_state.regs.output_merger.stencil_test.enable && |
| 404 | g_state.regs.framebuffer.depth_format == Regs::DepthFormat::D24S8; | 404 | g_state.regs.framebuffer.depth_format == Regs::DepthFormat::D24S8; |
| @@ -515,9 +515,9 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 515 | // TODO: Refactor so cubemaps and shadowmaps can be handled | 515 | // TODO: Refactor so cubemaps and shadowmaps can be handled |
| 516 | if (i == 0) { | 516 | if (i == 0) { |
| 517 | switch (texture.config.type) { | 517 | switch (texture.config.type) { |
| 518 | case Regs::TextureConfig::Texture2D: | 518 | case TexturingRegs::TextureConfig::Texture2D: |
| 519 | break; | 519 | break; |
| 520 | case Regs::TextureConfig::Projection2D: { | 520 | case TexturingRegs::TextureConfig::Projection2D: { |
| 521 | auto tc0_w = GetInterpolatedAttribute(v0.tc0_w, v1.tc0_w, v2.tc0_w); | 521 | auto tc0_w = GetInterpolatedAttribute(v0.tc0_w, v1.tc0_w, v2.tc0_w); |
| 522 | u /= tc0_w; | 522 | u /= tc0_w; |
| 523 | v /= tc0_w; | 523 | v /= tc0_w; |
| @@ -536,21 +536,21 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 536 | int t = (int)(v * float24::FromFloat32(static_cast<float>(texture.config.height))) | 536 | int t = (int)(v * float24::FromFloat32(static_cast<float>(texture.config.height))) |
| 537 | .ToFloat32(); | 537 | .ToFloat32(); |
| 538 | 538 | ||
| 539 | static auto GetWrappedTexCoord = [](Regs::TextureConfig::WrapMode mode, int val, | 539 | static auto GetWrappedTexCoord = [](TexturingRegs::TextureConfig::WrapMode mode, |
| 540 | unsigned size) { | 540 | int val, unsigned size) { |
| 541 | switch (mode) { | 541 | switch (mode) { |
| 542 | case Regs::TextureConfig::ClampToEdge: | 542 | case TexturingRegs::TextureConfig::ClampToEdge: |
| 543 | val = std::max(val, 0); | 543 | val = std::max(val, 0); |
| 544 | val = std::min(val, (int)size - 1); | 544 | val = std::min(val, (int)size - 1); |
| 545 | return val; | 545 | return val; |
| 546 | 546 | ||
| 547 | case Regs::TextureConfig::ClampToBorder: | 547 | case TexturingRegs::TextureConfig::ClampToBorder: |
| 548 | return val; | 548 | return val; |
| 549 | 549 | ||
| 550 | case Regs::TextureConfig::Repeat: | 550 | case TexturingRegs::TextureConfig::Repeat: |
| 551 | return (int)((unsigned)val % size); | 551 | return (int)((unsigned)val % size); |
| 552 | 552 | ||
| 553 | case Regs::TextureConfig::MirroredRepeat: { | 553 | case TexturingRegs::TextureConfig::MirroredRepeat: { |
| 554 | unsigned int coord = ((unsigned)val % (2 * size)); | 554 | unsigned int coord = ((unsigned)val % (2 * size)); |
| 555 | if (coord >= size) | 555 | if (coord >= size) |
| 556 | coord = 2 * size - 1 - coord; | 556 | coord = 2 * size - 1 - coord; |
| @@ -564,9 +564,9 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 564 | } | 564 | } |
| 565 | }; | 565 | }; |
| 566 | 566 | ||
| 567 | if ((texture.config.wrap_s == Regs::TextureConfig::ClampToBorder && | 567 | if ((texture.config.wrap_s == TexturingRegs::TextureConfig::ClampToBorder && |
| 568 | (s < 0 || static_cast<u32>(s) >= texture.config.width)) || | 568 | (s < 0 || static_cast<u32>(s) >= texture.config.width)) || |
| 569 | (texture.config.wrap_t == Regs::TextureConfig::ClampToBorder && | 569 | (texture.config.wrap_t == TexturingRegs::TextureConfig::ClampToBorder && |
| 570 | (t < 0 || static_cast<u32>(t) >= texture.config.height))) { | 570 | (t < 0 || static_cast<u32>(t) >= texture.config.height))) { |
| 571 | auto border_color = texture.config.border_color; | 571 | auto border_color = texture.config.border_color; |
| 572 | texture_color[i] = {border_color.r, border_color.g, border_color.b, | 572 | texture_color[i] = {border_color.r, border_color.g, border_color.b, |
| @@ -602,17 +602,19 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 602 | Math::Vec4<u8> combiner_output; | 602 | Math::Vec4<u8> combiner_output; |
| 603 | Math::Vec4<u8> combiner_buffer = {0, 0, 0, 0}; | 603 | Math::Vec4<u8> combiner_buffer = {0, 0, 0, 0}; |
| 604 | Math::Vec4<u8> next_combiner_buffer = { | 604 | Math::Vec4<u8> next_combiner_buffer = { |
| 605 | regs.tev_combiner_buffer_color.r, regs.tev_combiner_buffer_color.g, | 605 | regs.texturing.tev_combiner_buffer_color.r, |
| 606 | regs.tev_combiner_buffer_color.b, regs.tev_combiner_buffer_color.a, | 606 | regs.texturing.tev_combiner_buffer_color.g, |
| 607 | regs.texturing.tev_combiner_buffer_color.b, | ||
| 608 | regs.texturing.tev_combiner_buffer_color.a, | ||
| 607 | }; | 609 | }; |
| 608 | 610 | ||
| 609 | for (unsigned tev_stage_index = 0; tev_stage_index < tev_stages.size(); | 611 | for (unsigned tev_stage_index = 0; tev_stage_index < tev_stages.size(); |
| 610 | ++tev_stage_index) { | 612 | ++tev_stage_index) { |
| 611 | const auto& tev_stage = tev_stages[tev_stage_index]; | 613 | const auto& tev_stage = tev_stages[tev_stage_index]; |
| 612 | using Source = Regs::TevStageConfig::Source; | 614 | using Source = TexturingRegs::TevStageConfig::Source; |
| 613 | using ColorModifier = Regs::TevStageConfig::ColorModifier; | 615 | using ColorModifier = TexturingRegs::TevStageConfig::ColorModifier; |
| 614 | using AlphaModifier = Regs::TevStageConfig::AlphaModifier; | 616 | using AlphaModifier = TexturingRegs::TevStageConfig::AlphaModifier; |
| 615 | using Operation = Regs::TevStageConfig::Operation; | 617 | using Operation = TexturingRegs::TevStageConfig::Operation; |
| 616 | 618 | ||
| 617 | auto GetSource = [&](Source source) -> Math::Vec4<u8> { | 619 | auto GetSource = [&](Source source) -> Math::Vec4<u8> { |
| 618 | switch (source) { | 620 | switch (source) { |
| @@ -864,14 +866,14 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 864 | 866 | ||
| 865 | combiner_buffer = next_combiner_buffer; | 867 | combiner_buffer = next_combiner_buffer; |
| 866 | 868 | ||
| 867 | if (regs.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferColor( | 869 | if (regs.texturing.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferColor( |
| 868 | tev_stage_index)) { | 870 | tev_stage_index)) { |
| 869 | next_combiner_buffer.r() = combiner_output.r(); | 871 | next_combiner_buffer.r() = combiner_output.r(); |
| 870 | next_combiner_buffer.g() = combiner_output.g(); | 872 | next_combiner_buffer.g() = combiner_output.g(); |
| 871 | next_combiner_buffer.b() = combiner_output.b(); | 873 | next_combiner_buffer.b() = combiner_output.b(); |
| 872 | } | 874 | } |
| 873 | 875 | ||
| 874 | if (regs.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferAlpha( | 876 | if (regs.texturing.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferAlpha( |
| 875 | tev_stage_index)) { | 877 | tev_stage_index)) { |
| 876 | next_combiner_buffer.a() = combiner_output.a(); | 878 | next_combiner_buffer.a() = combiner_output.a(); |
| 877 | } | 879 | } |
| @@ -924,16 +926,16 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 924 | // Not fully accurate. We'd have to know what data type is used to | 926 | // Not fully accurate. We'd have to know what data type is used to |
| 925 | // store the depth etc. Using float for now until we know more | 927 | // store the depth etc. Using float for now until we know more |
| 926 | // about Pica datatypes | 928 | // about Pica datatypes |
| 927 | if (regs.fog_mode == Regs::FogMode::Fog) { | 929 | if (regs.texturing.fog_mode == TexturingRegs::FogMode::Fog) { |
| 928 | const Math::Vec3<u8> fog_color = { | 930 | const Math::Vec3<u8> fog_color = { |
| 929 | static_cast<u8>(regs.fog_color.r.Value()), | 931 | static_cast<u8>(regs.texturing.fog_color.r.Value()), |
| 930 | static_cast<u8>(regs.fog_color.g.Value()), | 932 | static_cast<u8>(regs.texturing.fog_color.g.Value()), |
| 931 | static_cast<u8>(regs.fog_color.b.Value()), | 933 | static_cast<u8>(regs.texturing.fog_color.b.Value()), |
| 932 | }; | 934 | }; |
| 933 | 935 | ||
| 934 | // Get index into fog LUT | 936 | // Get index into fog LUT |
| 935 | float fog_index; | 937 | float fog_index; |
| 936 | if (g_state.regs.fog_flip) { | 938 | if (g_state.regs.texturing.fog_flip) { |
| 937 | fog_index = (1.0f - depth) * 128.0f; | 939 | fog_index = (1.0f - depth) * 128.0f; |
| 938 | } else { | 940 | } else { |
| 939 | fog_index = depth * 128.0f; | 941 | fog_index = depth * 128.0f; |
diff --git a/src/video_core/regs_texturing.h b/src/video_core/regs_texturing.h new file mode 100644 index 000000000..be8bc6826 --- /dev/null +++ b/src/video_core/regs_texturing.h | |||
| @@ -0,0 +1,328 @@ | |||
| 1 | // Copyright 2017 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | |||
| 9 | #include "common/assert.h" | ||
| 10 | #include "common/bit_field.h" | ||
| 11 | #include "common/common_funcs.h" | ||
| 12 | #include "common/common_types.h" | ||
| 13 | |||
| 14 | namespace Pica { | ||
| 15 | |||
| 16 | struct TexturingRegs { | ||
| 17 | struct TextureConfig { | ||
| 18 | enum TextureType : u32 { | ||
| 19 | Texture2D = 0, | ||
| 20 | TextureCube = 1, | ||
| 21 | Shadow2D = 2, | ||
| 22 | Projection2D = 3, | ||
| 23 | ShadowCube = 4, | ||
| 24 | Disabled = 5, | ||
| 25 | }; | ||
| 26 | |||
| 27 | enum WrapMode : u32 { | ||
| 28 | ClampToEdge = 0, | ||
| 29 | ClampToBorder = 1, | ||
| 30 | Repeat = 2, | ||
| 31 | MirroredRepeat = 3, | ||
| 32 | }; | ||
| 33 | |||
| 34 | enum TextureFilter : u32 { | ||
| 35 | Nearest = 0, | ||
| 36 | Linear = 1, | ||
| 37 | }; | ||
| 38 | |||
| 39 | union { | ||
| 40 | u32 raw; | ||
| 41 | BitField<0, 8, u32> r; | ||
| 42 | BitField<8, 8, u32> g; | ||
| 43 | BitField<16, 8, u32> b; | ||
| 44 | BitField<24, 8, u32> a; | ||
| 45 | } border_color; | ||
| 46 | |||
| 47 | union { | ||
| 48 | BitField<0, 16, u32> height; | ||
| 49 | BitField<16, 16, u32> width; | ||
| 50 | }; | ||
| 51 | |||
| 52 | union { | ||
| 53 | BitField<1, 1, TextureFilter> mag_filter; | ||
| 54 | BitField<2, 1, TextureFilter> min_filter; | ||
| 55 | BitField<8, 2, WrapMode> wrap_t; | ||
| 56 | BitField<12, 2, WrapMode> wrap_s; | ||
| 57 | BitField<28, 2, TextureType> | ||
| 58 | type; ///< @note Only valid for texture 0 according to 3DBrew. | ||
| 59 | }; | ||
| 60 | |||
| 61 | INSERT_PADDING_WORDS(0x1); | ||
| 62 | |||
| 63 | u32 address; | ||
| 64 | |||
| 65 | PAddr GetPhysicalAddress() const { | ||
| 66 | return address * 8; | ||
| 67 | } | ||
| 68 | |||
| 69 | // texture1 and texture2 store the texture format directly after the address | ||
| 70 | // whereas texture0 inserts some additional flags inbetween. | ||
| 71 | // Hence, we store the format separately so that all other parameters can be described | ||
| 72 | // in a single structure. | ||
| 73 | }; | ||
| 74 | |||
| 75 | enum class TextureFormat : u32 { | ||
| 76 | RGBA8 = 0, | ||
| 77 | RGB8 = 1, | ||
| 78 | RGB5A1 = 2, | ||
| 79 | RGB565 = 3, | ||
| 80 | RGBA4 = 4, | ||
| 81 | IA8 = 5, | ||
| 82 | RG8 = 6, ///< @note Also called HILO8 in 3DBrew. | ||
| 83 | I8 = 7, | ||
| 84 | A8 = 8, | ||
| 85 | IA4 = 9, | ||
| 86 | I4 = 10, | ||
| 87 | A4 = 11, | ||
| 88 | ETC1 = 12, // compressed | ||
| 89 | ETC1A4 = 13, // compressed | ||
| 90 | }; | ||
| 91 | |||
| 92 | static unsigned NibblesPerPixel(TextureFormat format) { | ||
| 93 | switch (format) { | ||
| 94 | case TextureFormat::RGBA8: | ||
| 95 | return 8; | ||
| 96 | |||
| 97 | case TextureFormat::RGB8: | ||
| 98 | return 6; | ||
| 99 | |||
| 100 | case TextureFormat::RGB5A1: | ||
| 101 | case TextureFormat::RGB565: | ||
| 102 | case TextureFormat::RGBA4: | ||
| 103 | case TextureFormat::IA8: | ||
| 104 | case TextureFormat::RG8: | ||
| 105 | return 4; | ||
| 106 | |||
| 107 | case TextureFormat::I4: | ||
| 108 | case TextureFormat::A4: | ||
| 109 | return 1; | ||
| 110 | |||
| 111 | case TextureFormat::I8: | ||
| 112 | case TextureFormat::A8: | ||
| 113 | case TextureFormat::IA4: | ||
| 114 | |||
| 115 | default: // placeholder for yet unknown formats | ||
| 116 | UNIMPLEMENTED(); | ||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | union { | ||
| 122 | BitField<0, 1, u32> texture0_enable; | ||
| 123 | BitField<1, 1, u32> texture1_enable; | ||
| 124 | BitField<2, 1, u32> texture2_enable; | ||
| 125 | }; | ||
| 126 | TextureConfig texture0; | ||
| 127 | INSERT_PADDING_WORDS(0x8); | ||
| 128 | BitField<0, 4, TextureFormat> texture0_format; | ||
| 129 | BitField<0, 1, u32> fragment_lighting_enable; | ||
| 130 | INSERT_PADDING_WORDS(0x1); | ||
| 131 | TextureConfig texture1; | ||
| 132 | BitField<0, 4, TextureFormat> texture1_format; | ||
| 133 | INSERT_PADDING_WORDS(0x2); | ||
| 134 | TextureConfig texture2; | ||
| 135 | BitField<0, 4, TextureFormat> texture2_format; | ||
| 136 | INSERT_PADDING_WORDS(0x21); | ||
| 137 | |||
| 138 | struct FullTextureConfig { | ||
| 139 | const bool enabled; | ||
| 140 | const TextureConfig config; | ||
| 141 | const TextureFormat format; | ||
| 142 | }; | ||
| 143 | const std::array<FullTextureConfig, 3> GetTextures() const { | ||
| 144 | return {{ | ||
| 145 | {texture0_enable.ToBool(), texture0, texture0_format}, | ||
| 146 | {texture1_enable.ToBool(), texture1, texture1_format}, | ||
| 147 | {texture2_enable.ToBool(), texture2, texture2_format}, | ||
| 148 | }}; | ||
| 149 | } | ||
| 150 | |||
| 151 | // 0xc0-0xff: Texture Combiner (akin to glTexEnv) | ||
| 152 | struct TevStageConfig { | ||
| 153 | enum class Source : u32 { | ||
| 154 | PrimaryColor = 0x0, | ||
| 155 | PrimaryFragmentColor = 0x1, | ||
| 156 | SecondaryFragmentColor = 0x2, | ||
| 157 | |||
| 158 | Texture0 = 0x3, | ||
| 159 | Texture1 = 0x4, | ||
| 160 | Texture2 = 0x5, | ||
| 161 | Texture3 = 0x6, | ||
| 162 | |||
| 163 | PreviousBuffer = 0xd, | ||
| 164 | Constant = 0xe, | ||
| 165 | Previous = 0xf, | ||
| 166 | }; | ||
| 167 | |||
| 168 | enum class ColorModifier : u32 { | ||
| 169 | SourceColor = 0x0, | ||
| 170 | OneMinusSourceColor = 0x1, | ||
| 171 | SourceAlpha = 0x2, | ||
| 172 | OneMinusSourceAlpha = 0x3, | ||
| 173 | SourceRed = 0x4, | ||
| 174 | OneMinusSourceRed = 0x5, | ||
| 175 | |||
| 176 | SourceGreen = 0x8, | ||
| 177 | OneMinusSourceGreen = 0x9, | ||
| 178 | |||
| 179 | SourceBlue = 0xc, | ||
| 180 | OneMinusSourceBlue = 0xd, | ||
| 181 | }; | ||
| 182 | |||
| 183 | enum class AlphaModifier : u32 { | ||
| 184 | SourceAlpha = 0x0, | ||
| 185 | OneMinusSourceAlpha = 0x1, | ||
| 186 | SourceRed = 0x2, | ||
| 187 | OneMinusSourceRed = 0x3, | ||
| 188 | SourceGreen = 0x4, | ||
| 189 | OneMinusSourceGreen = 0x5, | ||
| 190 | SourceBlue = 0x6, | ||
| 191 | OneMinusSourceBlue = 0x7, | ||
| 192 | }; | ||
| 193 | |||
| 194 | enum class Operation : u32 { | ||
| 195 | Replace = 0, | ||
| 196 | Modulate = 1, | ||
| 197 | Add = 2, | ||
| 198 | AddSigned = 3, | ||
| 199 | Lerp = 4, | ||
| 200 | Subtract = 5, | ||
| 201 | Dot3_RGB = 6, | ||
| 202 | |||
| 203 | MultiplyThenAdd = 8, | ||
| 204 | AddThenMultiply = 9, | ||
| 205 | }; | ||
| 206 | |||
| 207 | union { | ||
| 208 | u32 sources_raw; | ||
| 209 | BitField<0, 4, Source> color_source1; | ||
| 210 | BitField<4, 4, Source> color_source2; | ||
| 211 | BitField<8, 4, Source> color_source3; | ||
| 212 | BitField<16, 4, Source> alpha_source1; | ||
| 213 | BitField<20, 4, Source> alpha_source2; | ||
| 214 | BitField<24, 4, Source> alpha_source3; | ||
| 215 | }; | ||
| 216 | |||
| 217 | union { | ||
| 218 | u32 modifiers_raw; | ||
| 219 | BitField<0, 4, ColorModifier> color_modifier1; | ||
| 220 | BitField<4, 4, ColorModifier> color_modifier2; | ||
| 221 | BitField<8, 4, ColorModifier> color_modifier3; | ||
| 222 | BitField<12, 3, AlphaModifier> alpha_modifier1; | ||
| 223 | BitField<16, 3, AlphaModifier> alpha_modifier2; | ||
| 224 | BitField<20, 3, AlphaModifier> alpha_modifier3; | ||
| 225 | }; | ||
| 226 | |||
| 227 | union { | ||
| 228 | u32 ops_raw; | ||
| 229 | BitField<0, 4, Operation> color_op; | ||
| 230 | BitField<16, 4, Operation> alpha_op; | ||
| 231 | }; | ||
| 232 | |||
| 233 | union { | ||
| 234 | u32 const_color; | ||
| 235 | BitField<0, 8, u32> const_r; | ||
| 236 | BitField<8, 8, u32> const_g; | ||
| 237 | BitField<16, 8, u32> const_b; | ||
| 238 | BitField<24, 8, u32> const_a; | ||
| 239 | }; | ||
| 240 | |||
| 241 | union { | ||
| 242 | u32 scales_raw; | ||
| 243 | BitField<0, 2, u32> color_scale; | ||
| 244 | BitField<16, 2, u32> alpha_scale; | ||
| 245 | }; | ||
| 246 | |||
| 247 | inline unsigned GetColorMultiplier() const { | ||
| 248 | return (color_scale < 3) ? (1 << color_scale) : 1; | ||
| 249 | } | ||
| 250 | |||
| 251 | inline unsigned GetAlphaMultiplier() const { | ||
| 252 | return (alpha_scale < 3) ? (1 << alpha_scale) : 1; | ||
| 253 | } | ||
| 254 | }; | ||
| 255 | |||
| 256 | TevStageConfig tev_stage0; | ||
| 257 | INSERT_PADDING_WORDS(0x3); | ||
| 258 | TevStageConfig tev_stage1; | ||
| 259 | INSERT_PADDING_WORDS(0x3); | ||
| 260 | TevStageConfig tev_stage2; | ||
| 261 | INSERT_PADDING_WORDS(0x3); | ||
| 262 | TevStageConfig tev_stage3; | ||
| 263 | INSERT_PADDING_WORDS(0x3); | ||
| 264 | |||
| 265 | enum class FogMode : u32 { | ||
| 266 | None = 0, | ||
| 267 | Fog = 5, | ||
| 268 | Gas = 7, | ||
| 269 | }; | ||
| 270 | |||
| 271 | union { | ||
| 272 | BitField<0, 3, FogMode> fog_mode; | ||
| 273 | BitField<16, 1, u32> fog_flip; | ||
| 274 | |||
| 275 | union { | ||
| 276 | // Tev stages 0-3 write their output to the combiner buffer if the corresponding bit in | ||
| 277 | // these masks are set | ||
| 278 | BitField<8, 4, u32> update_mask_rgb; | ||
| 279 | BitField<12, 4, u32> update_mask_a; | ||
| 280 | |||
| 281 | bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const { | ||
| 282 | return (stage_index < 4) && (update_mask_rgb & (1 << stage_index)); | ||
| 283 | } | ||
| 284 | |||
| 285 | bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const { | ||
| 286 | return (stage_index < 4) && (update_mask_a & (1 << stage_index)); | ||
| 287 | } | ||
| 288 | } tev_combiner_buffer_input; | ||
| 289 | }; | ||
| 290 | |||
| 291 | union { | ||
| 292 | u32 raw; | ||
| 293 | BitField<0, 8, u32> r; | ||
| 294 | BitField<8, 8, u32> g; | ||
| 295 | BitField<16, 8, u32> b; | ||
| 296 | } fog_color; | ||
| 297 | |||
| 298 | INSERT_PADDING_WORDS(0x4); | ||
| 299 | |||
| 300 | BitField<0, 16, u32> fog_lut_offset; | ||
| 301 | |||
| 302 | INSERT_PADDING_WORDS(0x1); | ||
| 303 | |||
| 304 | u32 fog_lut_data[8]; | ||
| 305 | |||
| 306 | TevStageConfig tev_stage4; | ||
| 307 | INSERT_PADDING_WORDS(0x3); | ||
| 308 | TevStageConfig tev_stage5; | ||
| 309 | |||
| 310 | union { | ||
| 311 | u32 raw; | ||
| 312 | BitField<0, 8, u32> r; | ||
| 313 | BitField<8, 8, u32> g; | ||
| 314 | BitField<16, 8, u32> b; | ||
| 315 | BitField<24, 8, u32> a; | ||
| 316 | } tev_combiner_buffer_color; | ||
| 317 | |||
| 318 | INSERT_PADDING_WORDS(0x2); | ||
| 319 | |||
| 320 | const std::array<TevStageConfig, 6> GetTevStages() const { | ||
| 321 | return {{tev_stage0, tev_stage1, tev_stage2, tev_stage3, tev_stage4, tev_stage5}}; | ||
| 322 | }; | ||
| 323 | }; | ||
| 324 | |||
| 325 | static_assert(sizeof(TexturingRegs) == 0x80 * sizeof(u32), | ||
| 326 | "TexturingRegs struct has incorrect size"); | ||
| 327 | |||
| 328 | } // namespace Pica | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index c4061c005..f7eaa17e2 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -26,13 +26,15 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192)); | |||
| 26 | MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); | 26 | MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); |
| 27 | MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); | 27 | MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); |
| 28 | 28 | ||
| 29 | static bool IsPassThroughTevStage(const Pica::Regs::TevStageConfig& stage) { | 29 | static bool IsPassThroughTevStage(const Pica::TexturingRegs::TevStageConfig& stage) { |
| 30 | return (stage.color_op == Pica::Regs::TevStageConfig::Operation::Replace && | 30 | using TevStageConfig = Pica::TexturingRegs::TevStageConfig; |
| 31 | stage.alpha_op == Pica::Regs::TevStageConfig::Operation::Replace && | 31 | |
| 32 | stage.color_source1 == Pica::Regs::TevStageConfig::Source::Previous && | 32 | return (stage.color_op == TevStageConfig::Operation::Replace && |
| 33 | stage.alpha_source1 == Pica::Regs::TevStageConfig::Source::Previous && | 33 | stage.alpha_op == TevStageConfig::Operation::Replace && |
| 34 | stage.color_modifier1 == Pica::Regs::TevStageConfig::ColorModifier::SourceColor && | 34 | stage.color_source1 == TevStageConfig::Source::Previous && |
| 35 | stage.alpha_modifier1 == Pica::Regs::TevStageConfig::AlphaModifier::SourceAlpha && | 35 | stage.alpha_source1 == TevStageConfig::Source::Previous && |
| 36 | stage.color_modifier1 == TevStageConfig::ColorModifier::SourceColor && | ||
| 37 | stage.alpha_modifier1 == TevStageConfig::AlphaModifier::SourceAlpha && | ||
| 36 | stage.GetColorMultiplier() == 1 && stage.GetAlphaMultiplier() == 1); | 38 | stage.GetColorMultiplier() == 1 && stage.GetAlphaMultiplier() == 1); |
| 37 | } | 39 | } |
| 38 | 40 | ||
| @@ -242,7 +244,7 @@ void RasterizerOpenGL::DrawTriangles() { | |||
| 242 | } | 244 | } |
| 243 | 245 | ||
| 244 | // Sync and bind the texture surfaces | 246 | // Sync and bind the texture surfaces |
| 245 | const auto pica_textures = regs.GetTextures(); | 247 | const auto pica_textures = regs.texturing.GetTextures(); |
| 246 | for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) { | 248 | for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) { |
| 247 | const auto& texture = pica_textures[texture_index]; | 249 | const auto& texture = pica_textures[texture_index]; |
| 248 | 250 | ||
| @@ -348,17 +350,17 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { | |||
| 348 | break; | 350 | break; |
| 349 | 351 | ||
| 350 | // Fog state | 352 | // Fog state |
| 351 | case PICA_REG_INDEX(fog_color): | 353 | case PICA_REG_INDEX(texturing.fog_color): |
| 352 | SyncFogColor(); | 354 | SyncFogColor(); |
| 353 | break; | 355 | break; |
| 354 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[0], 0xe8): | 356 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[0], 0xe8): |
| 355 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[1], 0xe9): | 357 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[1], 0xe9): |
| 356 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[2], 0xea): | 358 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[2], 0xea): |
| 357 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[3], 0xeb): | 359 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[3], 0xeb): |
| 358 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[4], 0xec): | 360 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[4], 0xec): |
| 359 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[5], 0xed): | 361 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[5], 0xed): |
| 360 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[6], 0xee): | 362 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[6], 0xee): |
| 361 | case PICA_REG_INDEX_WORKAROUND(fog_lut_data[7], 0xef): | 363 | case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[7], 0xef): |
| 362 | uniform_block_data.fog_lut_dirty = true; | 364 | uniform_block_data.fog_lut_dirty = true; |
| 363 | break; | 365 | break; |
| 364 | 366 | ||
| @@ -411,60 +413,60 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { | |||
| 411 | break; | 413 | break; |
| 412 | 414 | ||
| 413 | // Texture 0 type | 415 | // Texture 0 type |
| 414 | case PICA_REG_INDEX(texture0.type): | 416 | case PICA_REG_INDEX(texturing.texture0.type): |
| 415 | shader_dirty = true; | 417 | shader_dirty = true; |
| 416 | break; | 418 | break; |
| 417 | 419 | ||
| 418 | // TEV stages | 420 | // TEV stages |
| 419 | // (This also syncs fog_mode and fog_flip which are part of tev_combiner_buffer_input) | 421 | // (This also syncs fog_mode and fog_flip which are part of tev_combiner_buffer_input) |
| 420 | case PICA_REG_INDEX(tev_stage0.color_source1): | 422 | case PICA_REG_INDEX(texturing.tev_stage0.color_source1): |
| 421 | case PICA_REG_INDEX(tev_stage0.color_modifier1): | 423 | case PICA_REG_INDEX(texturing.tev_stage0.color_modifier1): |
| 422 | case PICA_REG_INDEX(tev_stage0.color_op): | 424 | case PICA_REG_INDEX(texturing.tev_stage0.color_op): |
| 423 | case PICA_REG_INDEX(tev_stage0.color_scale): | 425 | case PICA_REG_INDEX(texturing.tev_stage0.color_scale): |
| 424 | case PICA_REG_INDEX(tev_stage1.color_source1): | 426 | case PICA_REG_INDEX(texturing.tev_stage1.color_source1): |
| 425 | case PICA_REG_INDEX(tev_stage1.color_modifier1): | 427 | case PICA_REG_INDEX(texturing.tev_stage1.color_modifier1): |
| 426 | case PICA_REG_INDEX(tev_stage1.color_op): | 428 | case PICA_REG_INDEX(texturing.tev_stage1.color_op): |
| 427 | case PICA_REG_INDEX(tev_stage1.color_scale): | 429 | case PICA_REG_INDEX(texturing.tev_stage1.color_scale): |
| 428 | case PICA_REG_INDEX(tev_stage2.color_source1): | 430 | case PICA_REG_INDEX(texturing.tev_stage2.color_source1): |
| 429 | case PICA_REG_INDEX(tev_stage2.color_modifier1): | 431 | case PICA_REG_INDEX(texturing.tev_stage2.color_modifier1): |
| 430 | case PICA_REG_INDEX(tev_stage2.color_op): | 432 | case PICA_REG_INDEX(texturing.tev_stage2.color_op): |
| 431 | case PICA_REG_INDEX(tev_stage2.color_scale): | 433 | case PICA_REG_INDEX(texturing.tev_stage2.color_scale): |
| 432 | case PICA_REG_INDEX(tev_stage3.color_source1): | 434 | case PICA_REG_INDEX(texturing.tev_stage3.color_source1): |
| 433 | case PICA_REG_INDEX(tev_stage3.color_modifier1): | 435 | case PICA_REG_INDEX(texturing.tev_stage3.color_modifier1): |
| 434 | case PICA_REG_INDEX(tev_stage3.color_op): | 436 | case PICA_REG_INDEX(texturing.tev_stage3.color_op): |
| 435 | case PICA_REG_INDEX(tev_stage3.color_scale): | 437 | case PICA_REG_INDEX(texturing.tev_stage3.color_scale): |
| 436 | case PICA_REG_INDEX(tev_stage4.color_source1): | 438 | case PICA_REG_INDEX(texturing.tev_stage4.color_source1): |
| 437 | case PICA_REG_INDEX(tev_stage4.color_modifier1): | 439 | case PICA_REG_INDEX(texturing.tev_stage4.color_modifier1): |
| 438 | case PICA_REG_INDEX(tev_stage4.color_op): | 440 | case PICA_REG_INDEX(texturing.tev_stage4.color_op): |
| 439 | case PICA_REG_INDEX(tev_stage4.color_scale): | 441 | case PICA_REG_INDEX(texturing.tev_stage4.color_scale): |
| 440 | case PICA_REG_INDEX(tev_stage5.color_source1): | 442 | case PICA_REG_INDEX(texturing.tev_stage5.color_source1): |
| 441 | case PICA_REG_INDEX(tev_stage5.color_modifier1): | 443 | case PICA_REG_INDEX(texturing.tev_stage5.color_modifier1): |
| 442 | case PICA_REG_INDEX(tev_stage5.color_op): | 444 | case PICA_REG_INDEX(texturing.tev_stage5.color_op): |
| 443 | case PICA_REG_INDEX(tev_stage5.color_scale): | 445 | case PICA_REG_INDEX(texturing.tev_stage5.color_scale): |
| 444 | case PICA_REG_INDEX(tev_combiner_buffer_input): | 446 | case PICA_REG_INDEX(texturing.tev_combiner_buffer_input): |
| 445 | shader_dirty = true; | 447 | shader_dirty = true; |
| 446 | break; | 448 | break; |
| 447 | case PICA_REG_INDEX(tev_stage0.const_r): | 449 | case PICA_REG_INDEX(texturing.tev_stage0.const_r): |
| 448 | SyncTevConstColor(0, regs.tev_stage0); | 450 | SyncTevConstColor(0, regs.texturing.tev_stage0); |
| 449 | break; | 451 | break; |
| 450 | case PICA_REG_INDEX(tev_stage1.const_r): | 452 | case PICA_REG_INDEX(texturing.tev_stage1.const_r): |
| 451 | SyncTevConstColor(1, regs.tev_stage1); | 453 | SyncTevConstColor(1, regs.texturing.tev_stage1); |
| 452 | break; | 454 | break; |
| 453 | case PICA_REG_INDEX(tev_stage2.const_r): | 455 | case PICA_REG_INDEX(texturing.tev_stage2.const_r): |
| 454 | SyncTevConstColor(2, regs.tev_stage2); | 456 | SyncTevConstColor(2, regs.texturing.tev_stage2); |
| 455 | break; | 457 | break; |
| 456 | case PICA_REG_INDEX(tev_stage3.const_r): | 458 | case PICA_REG_INDEX(texturing.tev_stage3.const_r): |
| 457 | SyncTevConstColor(3, regs.tev_stage3); | 459 | SyncTevConstColor(3, regs.texturing.tev_stage3); |
| 458 | break; | 460 | break; |
| 459 | case PICA_REG_INDEX(tev_stage4.const_r): | 461 | case PICA_REG_INDEX(texturing.tev_stage4.const_r): |
| 460 | SyncTevConstColor(4, regs.tev_stage4); | 462 | SyncTevConstColor(4, regs.texturing.tev_stage4); |
| 461 | break; | 463 | break; |
| 462 | case PICA_REG_INDEX(tev_stage5.const_r): | 464 | case PICA_REG_INDEX(texturing.tev_stage5.const_r): |
| 463 | SyncTevConstColor(5, regs.tev_stage5); | 465 | SyncTevConstColor(5, regs.texturing.tev_stage5); |
| 464 | break; | 466 | break; |
| 465 | 467 | ||
| 466 | // TEV combiner buffer color | 468 | // TEV combiner buffer color |
| 467 | case PICA_REG_INDEX(tev_combiner_buffer_color): | 469 | case PICA_REG_INDEX(texturing.tev_combiner_buffer_color): |
| 468 | SyncCombinerColor(); | 470 | SyncCombinerColor(); |
| 469 | break; | 471 | break; |
| 470 | 472 | ||
| @@ -979,7 +981,9 @@ void RasterizerOpenGL::SamplerInfo::Create() { | |||
| 979 | // Other attributes have correct defaults | 981 | // Other attributes have correct defaults |
| 980 | } | 982 | } |
| 981 | 983 | ||
| 982 | void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Pica::Regs::TextureConfig& config) { | 984 | void RasterizerOpenGL::SamplerInfo::SyncWithConfig( |
| 985 | const Pica::TexturingRegs::TextureConfig& config) { | ||
| 986 | |||
| 983 | GLuint s = sampler.handle; | 987 | GLuint s = sampler.handle; |
| 984 | 988 | ||
| 985 | if (mag_filter != config.mag_filter) { | 989 | if (mag_filter != config.mag_filter) { |
| @@ -1091,7 +1095,7 @@ void RasterizerOpenGL::SetShader() { | |||
| 1091 | SyncDepthOffset(); | 1095 | SyncDepthOffset(); |
| 1092 | SyncAlphaTest(); | 1096 | SyncAlphaTest(); |
| 1093 | SyncCombinerColor(); | 1097 | SyncCombinerColor(); |
| 1094 | auto& tev_stages = Pica::g_state.regs.GetTevStages(); | 1098 | auto& tev_stages = Pica::g_state.regs.texturing.GetTevStages(); |
| 1095 | for (int index = 0; index < tev_stages.size(); ++index) | 1099 | for (int index = 0; index < tev_stages.size(); ++index) |
| 1096 | SyncTevConstColor(index, tev_stages[index]); | 1100 | SyncTevConstColor(index, tev_stages[index]); |
| 1097 | 1101 | ||
| @@ -1182,8 +1186,8 @@ void RasterizerOpenGL::SyncBlendColor() { | |||
| 1182 | void RasterizerOpenGL::SyncFogColor() { | 1186 | void RasterizerOpenGL::SyncFogColor() { |
| 1183 | const auto& regs = Pica::g_state.regs; | 1187 | const auto& regs = Pica::g_state.regs; |
| 1184 | uniform_block_data.data.fog_color = { | 1188 | uniform_block_data.data.fog_color = { |
| 1185 | regs.fog_color.r.Value() / 255.0f, regs.fog_color.g.Value() / 255.0f, | 1189 | regs.texturing.fog_color.r.Value() / 255.0f, regs.texturing.fog_color.g.Value() / 255.0f, |
| 1186 | regs.fog_color.b.Value() / 255.0f, | 1190 | regs.texturing.fog_color.b.Value() / 255.0f, |
| 1187 | }; | 1191 | }; |
| 1188 | uniform_block_data.dirty = true; | 1192 | uniform_block_data.dirty = true; |
| 1189 | } | 1193 | } |
| @@ -1267,7 +1271,8 @@ void RasterizerOpenGL::SyncDepthTest() { | |||
| 1267 | } | 1271 | } |
| 1268 | 1272 | ||
| 1269 | void RasterizerOpenGL::SyncCombinerColor() { | 1273 | void RasterizerOpenGL::SyncCombinerColor() { |
| 1270 | auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw); | 1274 | auto combiner_color = |
| 1275 | PicaToGL::ColorRGBA8(Pica::g_state.regs.texturing.tev_combiner_buffer_color.raw); | ||
| 1271 | if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) { | 1276 | if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) { |
| 1272 | uniform_block_data.data.tev_combiner_buffer_color = combiner_color; | 1277 | uniform_block_data.data.tev_combiner_buffer_color = combiner_color; |
| 1273 | uniform_block_data.dirty = true; | 1278 | uniform_block_data.dirty = true; |
| @@ -1275,7 +1280,7 @@ void RasterizerOpenGL::SyncCombinerColor() { | |||
| 1275 | } | 1280 | } |
| 1276 | 1281 | ||
| 1277 | void RasterizerOpenGL::SyncTevConstColor(int stage_index, | 1282 | void RasterizerOpenGL::SyncTevConstColor(int stage_index, |
| 1278 | const Pica::Regs::TevStageConfig& tev_stage) { | 1283 | const Pica::TexturingRegs::TevStageConfig& tev_stage) { |
| 1279 | auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color); | 1284 | auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color); |
| 1280 | if (const_color != uniform_block_data.data.const_color[stage_index]) { | 1285 | if (const_color != uniform_block_data.data.const_color[stage_index]) { |
| 1281 | uniform_block_data.data.const_color[stage_index] = const_color; | 1286 | uniform_block_data.data.const_color[stage_index] = const_color; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index bd7b6874a..519df6478 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -60,12 +60,12 @@ union PicaShaderConfig { | |||
| 60 | ? regs.output_merger.alpha_test.func.Value() | 60 | ? regs.output_merger.alpha_test.func.Value() |
| 61 | : Pica::Regs::CompareFunc::Always; | 61 | : Pica::Regs::CompareFunc::Always; |
| 62 | 62 | ||
| 63 | state.texture0_type = regs.texture0.type; | 63 | state.texture0_type = regs.texturing.texture0.type; |
| 64 | 64 | ||
| 65 | // Copy relevant tev stages fields. | 65 | // Copy relevant tev stages fields. |
| 66 | // We don't sync const_color here because of the high variance, it is a | 66 | // We don't sync const_color here because of the high variance, it is a |
| 67 | // shader uniform instead. | 67 | // shader uniform instead. |
| 68 | const auto& tev_stages = regs.GetTevStages(); | 68 | const auto& tev_stages = regs.texturing.GetTevStages(); |
| 69 | DEBUG_ASSERT(state.tev_stages.size() == tev_stages.size()); | 69 | DEBUG_ASSERT(state.tev_stages.size() == tev_stages.size()); |
| 70 | for (size_t i = 0; i < tev_stages.size(); i++) { | 70 | for (size_t i = 0; i < tev_stages.size(); i++) { |
| 71 | const auto& tev_stage = tev_stages[i]; | 71 | const auto& tev_stage = tev_stages[i]; |
| @@ -75,11 +75,12 @@ union PicaShaderConfig { | |||
| 75 | state.tev_stages[i].scales_raw = tev_stage.scales_raw; | 75 | state.tev_stages[i].scales_raw = tev_stage.scales_raw; |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | state.fog_mode = regs.fog_mode; | 78 | state.fog_mode = regs.texturing.fog_mode; |
| 79 | state.fog_flip = regs.fog_flip != 0; | 79 | state.fog_flip = regs.texturing.fog_flip != 0; |
| 80 | 80 | ||
| 81 | state.combiner_buffer_input = regs.tev_combiner_buffer_input.update_mask_rgb.Value() | | 81 | state.combiner_buffer_input = |
| 82 | regs.tev_combiner_buffer_input.update_mask_a.Value() << 4; | 82 | regs.texturing.tev_combiner_buffer_input.update_mask_rgb.Value() | |
| 83 | regs.texturing.tev_combiner_buffer_input.update_mask_a.Value() << 4; | ||
| 83 | 84 | ||
| 84 | // Fragment lighting | 85 | // Fragment lighting |
| 85 | 86 | ||
| @@ -159,8 +160,8 @@ union PicaShaderConfig { | |||
| 159 | u32 modifiers_raw; | 160 | u32 modifiers_raw; |
| 160 | u32 ops_raw; | 161 | u32 ops_raw; |
| 161 | u32 scales_raw; | 162 | u32 scales_raw; |
| 162 | explicit operator Pica::Regs::TevStageConfig() const noexcept { | 163 | explicit operator Pica::TexturingRegs::TevStageConfig() const noexcept { |
| 163 | Pica::Regs::TevStageConfig stage; | 164 | Pica::TexturingRegs::TevStageConfig stage; |
| 164 | stage.sources_raw = sources_raw; | 165 | stage.sources_raw = sources_raw; |
| 165 | stage.modifiers_raw = modifiers_raw; | 166 | stage.modifiers_raw = modifiers_raw; |
| 166 | stage.ops_raw = ops_raw; | 167 | stage.ops_raw = ops_raw; |
| @@ -173,12 +174,12 @@ union PicaShaderConfig { | |||
| 173 | struct State { | 174 | struct State { |
| 174 | Pica::Regs::CompareFunc alpha_test_func; | 175 | Pica::Regs::CompareFunc alpha_test_func; |
| 175 | Pica::RasterizerRegs::ScissorMode scissor_test_mode; | 176 | Pica::RasterizerRegs::ScissorMode scissor_test_mode; |
| 176 | Pica::Regs::TextureConfig::TextureType texture0_type; | 177 | Pica::TexturingRegs::TextureConfig::TextureType texture0_type; |
| 177 | std::array<TevStageConfigRaw, 6> tev_stages; | 178 | std::array<TevStageConfigRaw, 6> tev_stages; |
| 178 | u8 combiner_buffer_input; | 179 | u8 combiner_buffer_input; |
| 179 | 180 | ||
| 180 | Pica::RasterizerRegs::DepthBuffering depthmap_enable; | 181 | Pica::RasterizerRegs::DepthBuffering depthmap_enable; |
| 181 | Pica::Regs::FogMode fog_mode; | 182 | Pica::TexturingRegs::FogMode fog_mode; |
| 182 | bool fog_flip; | 183 | bool fog_flip; |
| 183 | 184 | ||
| 184 | struct { | 185 | struct { |
| @@ -251,7 +252,7 @@ public: | |||
| 251 | 252 | ||
| 252 | private: | 253 | private: |
| 253 | struct SamplerInfo { | 254 | struct SamplerInfo { |
| 254 | using TextureConfig = Pica::Regs::TextureConfig; | 255 | using TextureConfig = Pica::TexturingRegs::TextureConfig; |
| 255 | 256 | ||
| 256 | OGLSampler sampler; | 257 | OGLSampler sampler; |
| 257 | 258 | ||
| @@ -398,7 +399,7 @@ private: | |||
| 398 | void SyncCombinerColor(); | 399 | void SyncCombinerColor(); |
| 399 | 400 | ||
| 400 | /// Syncs the TEV constant color to match the PICA register | 401 | /// Syncs the TEV constant color to match the PICA register |
| 401 | void SyncTevConstColor(int tev_index, const Pica::Regs::TevStageConfig& tev_stage); | 402 | void SyncTevConstColor(int tev_index, const Pica::TexturingRegs::TevStageConfig& tev_stage); |
| 402 | 403 | ||
| 403 | /// Syncs the lighting global ambient color to match the PICA register | 404 | /// Syncs the lighting global ambient color to match the PICA register |
| 404 | void SyncGlobalAmbient(); | 405 | void SyncGlobalAmbient(); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 60380257a..6d08d1a67 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -342,7 +342,7 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo | |||
| 342 | Pica::Texture::TextureInfo tex_info; | 342 | Pica::Texture::TextureInfo tex_info; |
| 343 | tex_info.width = params.width; | 343 | tex_info.width = params.width; |
| 344 | tex_info.height = params.height; | 344 | tex_info.height = params.height; |
| 345 | tex_info.format = (Pica::Regs::TextureFormat)params.pixel_format; | 345 | tex_info.format = (Pica::TexturingRegs::TextureFormat)params.pixel_format; |
| 346 | tex_info.SetDefaultStride(); | 346 | tex_info.SetDefaultStride(); |
| 347 | tex_info.physical_address = params.addr; | 347 | tex_info.physical_address = params.addr; |
| 348 | 348 | ||
| @@ -510,7 +510,7 @@ CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params | |||
| 510 | } | 510 | } |
| 511 | 511 | ||
| 512 | CachedSurface* RasterizerCacheOpenGL::GetTextureSurface( | 512 | CachedSurface* RasterizerCacheOpenGL::GetTextureSurface( |
| 513 | const Pica::Regs::FullTextureConfig& config) { | 513 | const Pica::TexturingRegs::FullTextureConfig& config) { |
| 514 | 514 | ||
| 515 | Pica::Texture::TextureInfo info = | 515 | Pica::Texture::TextureInfo info = |
| 516 | Pica::Texture::TextureInfo::FromPicaRegister(config.config, config.format); | 516 | Pica::Texture::TextureInfo::FromPicaRegister(config.config, config.format); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index f57fdb3cc..c354dfa33 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -96,7 +96,7 @@ struct CachedSurface { | |||
| 96 | return bpp_table[(unsigned int)format]; | 96 | return bpp_table[(unsigned int)format]; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static PixelFormat PixelFormatFromTextureFormat(Pica::Regs::TextureFormat format) { | 99 | static PixelFormat PixelFormatFromTextureFormat(Pica::TexturingRegs::TextureFormat format) { |
| 100 | return ((unsigned int)format < 14) ? (PixelFormat)format : PixelFormat::Invalid; | 100 | return ((unsigned int)format < 14) ? (PixelFormat)format : PixelFormat::Invalid; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| @@ -212,7 +212,7 @@ public: | |||
| 212 | bool load_if_create, MathUtil::Rectangle<int>& out_rect); | 212 | bool load_if_create, MathUtil::Rectangle<int>& out_rect); |
| 213 | 213 | ||
| 214 | /// Gets a surface based on the texture configuration | 214 | /// Gets a surface based on the texture configuration |
| 215 | CachedSurface* GetTextureSurface(const Pica::Regs::FullTextureConfig& config); | 215 | CachedSurface* GetTextureSurface(const Pica::TexturingRegs::FullTextureConfig& config); |
| 216 | 216 | ||
| 217 | /// Gets the color and depth surfaces and rect (resolution scaled) based on the framebuffer | 217 | /// Gets the color and depth surfaces and rect (resolution scaled) based on the framebuffer |
| 218 | /// configuration | 218 | /// configuration |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index c34c3463f..c3b0fdcee 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | using Pica::Regs; | 15 | using Pica::Regs; |
| 16 | using Pica::RasterizerRegs; | 16 | using Pica::RasterizerRegs; |
| 17 | using TevStageConfig = Regs::TevStageConfig; | 17 | using TevStageConfig = Pica::TexturingRegs::TevStageConfig; |
| 18 | 18 | ||
| 19 | namespace GLShader { | 19 | namespace GLShader { |
| 20 | 20 | ||
| @@ -47,10 +47,10 @@ static void AppendSource(std::string& out, const PicaShaderConfig& config, | |||
| 47 | case Source::Texture0: | 47 | case Source::Texture0: |
| 48 | // Only unit 0 respects the texturing type (according to 3DBrew) | 48 | // Only unit 0 respects the texturing type (according to 3DBrew) |
| 49 | switch (state.texture0_type) { | 49 | switch (state.texture0_type) { |
| 50 | case Pica::Regs::TextureConfig::Texture2D: | 50 | case Pica::TexturingRegs::TextureConfig::Texture2D: |
| 51 | out += "texture(tex[0], texcoord[0])"; | 51 | out += "texture(tex[0], texcoord[0])"; |
| 52 | break; | 52 | break; |
| 53 | case Pica::Regs::TextureConfig::Projection2D: | 53 | case Pica::TexturingRegs::TextureConfig::Projection2D: |
| 54 | out += "textureProj(tex[0], vec3(texcoord[0], texcoord0_w))"; | 54 | out += "textureProj(tex[0], vec3(texcoord[0], texcoord0_w))"; |
| 55 | break; | 55 | break; |
| 56 | default: | 56 | default: |
| @@ -308,7 +308,7 @@ static void AppendAlphaTestCondition(std::string& out, Regs::CompareFunc func) { | |||
| 308 | /// Writes the code to emulate the specified TEV stage | 308 | /// Writes the code to emulate the specified TEV stage |
| 309 | static void WriteTevStage(std::string& out, const PicaShaderConfig& config, unsigned index) { | 309 | static void WriteTevStage(std::string& out, const PicaShaderConfig& config, unsigned index) { |
| 310 | const auto stage = | 310 | const auto stage = |
| 311 | static_cast<const Pica::Regs::TevStageConfig>(config.state.tev_stages[index]); | 311 | static_cast<const Pica::TexturingRegs::TevStageConfig>(config.state.tev_stages[index]); |
| 312 | if (!IsPassThroughTevStage(stage)) { | 312 | if (!IsPassThroughTevStage(stage)) { |
| 313 | std::string index_name = std::to_string(index); | 313 | std::string index_name = std::to_string(index); |
| 314 | 314 | ||
| @@ -674,7 +674,7 @@ vec4 secondary_fragment_color = vec4(0.0); | |||
| 674 | } | 674 | } |
| 675 | 675 | ||
| 676 | // Append fog combiner | 676 | // Append fog combiner |
| 677 | if (state.fog_mode == Regs::FogMode::Fog) { | 677 | if (state.fog_mode == Pica::TexturingRegs::FogMode::Fog) { |
| 678 | // Get index into fog LUT | 678 | // Get index into fog LUT |
| 679 | if (state.fog_flip) { | 679 | if (state.fog_flip) { |
| 680 | out += "float fog_index = (1.0 - depth) * 128.0;\n"; | 680 | out += "float fog_index = (1.0 - depth) * 128.0;\n"; |
diff --git a/src/video_core/renderer_opengl/pica_to_gl.h b/src/video_core/renderer_opengl/pica_to_gl.h index cc49867c8..37cfbd45a 100644 --- a/src/video_core/renderer_opengl/pica_to_gl.h +++ b/src/video_core/renderer_opengl/pica_to_gl.h | |||
| @@ -20,7 +20,7 @@ using GLvec4 = std::array<GLfloat, 4>; | |||
| 20 | 20 | ||
| 21 | namespace PicaToGL { | 21 | namespace PicaToGL { |
| 22 | 22 | ||
| 23 | inline GLenum TextureFilterMode(Pica::Regs::TextureConfig::TextureFilter mode) { | 23 | inline GLenum TextureFilterMode(Pica::TexturingRegs::TextureConfig::TextureFilter mode) { |
| 24 | static const GLenum filter_mode_table[] = { | 24 | static const GLenum filter_mode_table[] = { |
| 25 | GL_NEAREST, // TextureFilter::Nearest | 25 | GL_NEAREST, // TextureFilter::Nearest |
| 26 | GL_LINEAR, // TextureFilter::Linear | 26 | GL_LINEAR, // TextureFilter::Linear |
| @@ -47,7 +47,7 @@ inline GLenum TextureFilterMode(Pica::Regs::TextureConfig::TextureFilter mode) { | |||
| 47 | return gl_mode; | 47 | return gl_mode; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | inline GLenum WrapMode(Pica::Regs::TextureConfig::WrapMode mode) { | 50 | inline GLenum WrapMode(Pica::TexturingRegs::TextureConfig::WrapMode mode) { |
| 51 | static const GLenum wrap_mode_table[] = { | 51 | static const GLenum wrap_mode_table[] = { |
| 52 | GL_CLAMP_TO_EDGE, // WrapMode::ClampToEdge | 52 | GL_CLAMP_TO_EDGE, // WrapMode::ClampToEdge |
| 53 | GL_CLAMP_TO_BORDER, // WrapMode::ClampToBorder | 53 | GL_CLAMP_TO_BORDER, // WrapMode::ClampToBorder |
diff --git a/src/video_core/texture/texture_decode.cpp b/src/video_core/texture/texture_decode.cpp index f611a1aa9..40d363184 100644 --- a/src/video_core/texture/texture_decode.cpp +++ b/src/video_core/texture/texture_decode.cpp | |||
| @@ -10,12 +10,12 @@ | |||
| 10 | #include "common/math_util.h" | 10 | #include "common/math_util.h" |
| 11 | #include "common/swap.h" | 11 | #include "common/swap.h" |
| 12 | #include "common/vector_math.h" | 12 | #include "common/vector_math.h" |
| 13 | #include "video_core/pica.h" | 13 | #include "video_core/regs_texturing.h" |
| 14 | #include "video_core/texture/etc1.h" | 14 | #include "video_core/texture/etc1.h" |
| 15 | #include "video_core/texture/texture_decode.h" | 15 | #include "video_core/texture/texture_decode.h" |
| 16 | #include "video_core/utils.h" | 16 | #include "video_core/utils.h" |
| 17 | 17 | ||
| 18 | using TextureFormat = Pica::Regs::TextureFormat; | 18 | using TextureFormat = Pica::TexturingRegs::TextureFormat; |
| 19 | 19 | ||
| 20 | namespace Pica { | 20 | namespace Pica { |
| 21 | namespace Texture { | 21 | namespace Texture { |
| @@ -82,32 +82,32 @@ Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int | |||
| 82 | using VideoCore::MortonInterleave; | 82 | using VideoCore::MortonInterleave; |
| 83 | 83 | ||
| 84 | switch (info.format) { | 84 | switch (info.format) { |
| 85 | case Regs::TextureFormat::RGBA8: { | 85 | case TextureFormat::RGBA8: { |
| 86 | auto res = Color::DecodeRGBA8(source + MortonInterleave(x, y) * 4); | 86 | auto res = Color::DecodeRGBA8(source + MortonInterleave(x, y) * 4); |
| 87 | return {res.r(), res.g(), res.b(), static_cast<u8>(disable_alpha ? 255 : res.a())}; | 87 | return {res.r(), res.g(), res.b(), static_cast<u8>(disable_alpha ? 255 : res.a())}; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | case Regs::TextureFormat::RGB8: { | 90 | case TextureFormat::RGB8: { |
| 91 | auto res = Color::DecodeRGB8(source + MortonInterleave(x, y) * 3); | 91 | auto res = Color::DecodeRGB8(source + MortonInterleave(x, y) * 3); |
| 92 | return {res.r(), res.g(), res.b(), 255}; | 92 | return {res.r(), res.g(), res.b(), 255}; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | case Regs::TextureFormat::RGB5A1: { | 95 | case TextureFormat::RGB5A1: { |
| 96 | auto res = Color::DecodeRGB5A1(source + MortonInterleave(x, y) * 2); | 96 | auto res = Color::DecodeRGB5A1(source + MortonInterleave(x, y) * 2); |
| 97 | return {res.r(), res.g(), res.b(), static_cast<u8>(disable_alpha ? 255 : res.a())}; | 97 | return {res.r(), res.g(), res.b(), static_cast<u8>(disable_alpha ? 255 : res.a())}; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | case Regs::TextureFormat::RGB565: { | 100 | case TextureFormat::RGB565: { |
| 101 | auto res = Color::DecodeRGB565(source + MortonInterleave(x, y) * 2); | 101 | auto res = Color::DecodeRGB565(source + MortonInterleave(x, y) * 2); |
| 102 | return {res.r(), res.g(), res.b(), 255}; | 102 | return {res.r(), res.g(), res.b(), 255}; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | case Regs::TextureFormat::RGBA4: { | 105 | case TextureFormat::RGBA4: { |
| 106 | auto res = Color::DecodeRGBA4(source + MortonInterleave(x, y) * 2); | 106 | auto res = Color::DecodeRGBA4(source + MortonInterleave(x, y) * 2); |
| 107 | return {res.r(), res.g(), res.b(), static_cast<u8>(disable_alpha ? 255 : res.a())}; | 107 | return {res.r(), res.g(), res.b(), static_cast<u8>(disable_alpha ? 255 : res.a())}; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | case Regs::TextureFormat::IA8: { | 110 | case TextureFormat::IA8: { |
| 111 | const u8* source_ptr = source + MortonInterleave(x, y) * 2; | 111 | const u8* source_ptr = source + MortonInterleave(x, y) * 2; |
| 112 | 112 | ||
| 113 | if (disable_alpha) { | 113 | if (disable_alpha) { |
| @@ -118,17 +118,17 @@ Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int | |||
| 118 | } | 118 | } |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | case Regs::TextureFormat::RG8: { | 121 | case TextureFormat::RG8: { |
| 122 | auto res = Color::DecodeRG8(source + MortonInterleave(x, y) * 2); | 122 | auto res = Color::DecodeRG8(source + MortonInterleave(x, y) * 2); |
| 123 | return {res.r(), res.g(), 0, 255}; | 123 | return {res.r(), res.g(), 0, 255}; |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | case Regs::TextureFormat::I8: { | 126 | case TextureFormat::I8: { |
| 127 | const u8* source_ptr = source + MortonInterleave(x, y); | 127 | const u8* source_ptr = source + MortonInterleave(x, y); |
| 128 | return {*source_ptr, *source_ptr, *source_ptr, 255}; | 128 | return {*source_ptr, *source_ptr, *source_ptr, 255}; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | case Regs::TextureFormat::A8: { | 131 | case TextureFormat::A8: { |
| 132 | const u8* source_ptr = source + MortonInterleave(x, y); | 132 | const u8* source_ptr = source + MortonInterleave(x, y); |
| 133 | 133 | ||
| 134 | if (disable_alpha) { | 134 | if (disable_alpha) { |
| @@ -138,7 +138,7 @@ Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int | |||
| 138 | } | 138 | } |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | case Regs::TextureFormat::IA4: { | 141 | case TextureFormat::IA4: { |
| 142 | const u8* source_ptr = source + MortonInterleave(x, y); | 142 | const u8* source_ptr = source + MortonInterleave(x, y); |
| 143 | 143 | ||
| 144 | u8 i = Color::Convert4To8(((*source_ptr) & 0xF0) >> 4); | 144 | u8 i = Color::Convert4To8(((*source_ptr) & 0xF0) >> 4); |
| @@ -152,7 +152,7 @@ Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int | |||
| 152 | } | 152 | } |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | case Regs::TextureFormat::I4: { | 155 | case TextureFormat::I4: { |
| 156 | u32 morton_offset = MortonInterleave(x, y); | 156 | u32 morton_offset = MortonInterleave(x, y); |
| 157 | const u8* source_ptr = source + morton_offset / 2; | 157 | const u8* source_ptr = source + morton_offset / 2; |
| 158 | 158 | ||
| @@ -162,7 +162,7 @@ Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int | |||
| 162 | return {i, i, i, 255}; | 162 | return {i, i, i, 255}; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | case Regs::TextureFormat::A4: { | 165 | case TextureFormat::A4: { |
| 166 | u32 morton_offset = MortonInterleave(x, y); | 166 | u32 morton_offset = MortonInterleave(x, y); |
| 167 | const u8* source_ptr = source + morton_offset / 2; | 167 | const u8* source_ptr = source + morton_offset / 2; |
| 168 | 168 | ||
| @@ -176,9 +176,9 @@ Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int | |||
| 176 | } | 176 | } |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | case Regs::TextureFormat::ETC1: | 179 | case TextureFormat::ETC1: |
| 180 | case Regs::TextureFormat::ETC1A4: { | 180 | case TextureFormat::ETC1A4: { |
| 181 | bool has_alpha = (info.format == Regs::TextureFormat::ETC1A4); | 181 | bool has_alpha = (info.format == TextureFormat::ETC1A4); |
| 182 | size_t subtile_size = has_alpha ? 16 : 8; | 182 | size_t subtile_size = has_alpha ? 16 : 8; |
| 183 | 183 | ||
| 184 | // ETC1 further subdivides each 8x8 tile into four 4x4 subtiles | 184 | // ETC1 further subdivides each 8x8 tile into four 4x4 subtiles |
| @@ -214,8 +214,8 @@ Math::Vec4<u8> LookupTexelInTile(const u8* source, unsigned int x, unsigned int | |||
| 214 | } | 214 | } |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | TextureInfo TextureInfo::FromPicaRegister(const Regs::TextureConfig& config, | 217 | TextureInfo TextureInfo::FromPicaRegister(const TexturingRegs::TextureConfig& config, |
| 218 | const Regs::TextureFormat& format) { | 218 | const TexturingRegs::TextureFormat& format) { |
| 219 | TextureInfo info; | 219 | TextureInfo info; |
| 220 | info.physical_address = config.GetPhysicalAddress(); | 220 | info.physical_address = config.GetPhysicalAddress(); |
| 221 | info.width = config.width; | 221 | info.width = config.width; |
diff --git a/src/video_core/texture/texture_decode.h b/src/video_core/texture/texture_decode.h index 5c636939a..8507cfeb8 100644 --- a/src/video_core/texture/texture_decode.h +++ b/src/video_core/texture/texture_decode.h | |||
| @@ -6,27 +6,27 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "common/vector_math.h" | 8 | #include "common/vector_math.h" |
| 9 | #include "video_core/pica.h" | 9 | #include "video_core/regs_texturing.h" |
| 10 | 10 | ||
| 11 | namespace Pica { | 11 | namespace Pica { |
| 12 | namespace Texture { | 12 | namespace Texture { |
| 13 | 13 | ||
| 14 | /// Returns the byte size of a 8*8 tile of the specified texture format. | 14 | /// Returns the byte size of a 8*8 tile of the specified texture format. |
| 15 | size_t CalculateTileSize(Pica::Regs::TextureFormat format); | 15 | size_t CalculateTileSize(TexturingRegs::TextureFormat format); |
| 16 | 16 | ||
| 17 | struct TextureInfo { | 17 | struct TextureInfo { |
| 18 | PAddr physical_address; | 18 | PAddr physical_address; |
| 19 | unsigned int width; | 19 | unsigned int width; |
| 20 | unsigned int height; | 20 | unsigned int height; |
| 21 | ptrdiff_t stride; | 21 | ptrdiff_t stride; |
| 22 | Pica::Regs::TextureFormat format; | 22 | TexturingRegs::TextureFormat format; |
| 23 | 23 | ||
| 24 | static TextureInfo FromPicaRegister(const Pica::Regs::TextureConfig& config, | 24 | static TextureInfo FromPicaRegister(const TexturingRegs::TextureConfig& config, |
| 25 | const Pica::Regs::TextureFormat& format); | 25 | const TexturingRegs::TextureFormat& format); |
| 26 | 26 | ||
| 27 | /// Calculates stride from format and width, assuming that the entire texture is contiguous. | 27 | /// Calculates stride from format and width, assuming that the entire texture is contiguous. |
| 28 | void SetDefaultStride() { | 28 | void SetDefaultStride() { |
| 29 | stride = Pica::Texture::CalculateTileSize(format) * (width / 8); | 29 | stride = CalculateTileSize(format) * (width / 8); |
| 30 | } | 30 | } |
| 31 | }; | 31 | }; |
| 32 | 32 | ||