17 changed files with 548 additions and 507 deletions
-
22src/citra_qt/debugger/graphics/graphics_cmdlists.cpp
-
7src/citra_qt/debugger/graphics/graphics_surface.cpp
-
1src/video_core/CMakeLists.txt
-
24src/video_core/command_processor.cpp
-
35src/video_core/debug_utils/debug_utils.cpp
-
8src/video_core/debug_utils/debug_utils.h
-
352src/video_core/pica.h
-
52src/video_core/rasterizer.cpp
-
328src/video_core/regs_texturing.h
-
129src/video_core/renderer_opengl/gl_rasterizer.cpp
-
25src/video_core/renderer_opengl/gl_rasterizer.h
-
4src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
-
4src/video_core/renderer_opengl/gl_rasterizer_cache.h
-
10src/video_core/renderer_opengl/gl_shader_gen.cpp
-
4src/video_core/renderer_opengl/pica_to_gl.h
-
38src/video_core/texture/texture_decode.cpp
-
12src/video_core/texture/texture_decode.h
@ -0,0 +1,328 @@ |
|||
// Copyright 2017 Citra Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
|
|||
#include "common/assert.h" |
|||
#include "common/bit_field.h" |
|||
#include "common/common_funcs.h" |
|||
#include "common/common_types.h" |
|||
|
|||
namespace Pica { |
|||
|
|||
struct TexturingRegs { |
|||
struct TextureConfig { |
|||
enum TextureType : u32 { |
|||
Texture2D = 0, |
|||
TextureCube = 1, |
|||
Shadow2D = 2, |
|||
Projection2D = 3, |
|||
ShadowCube = 4, |
|||
Disabled = 5, |
|||
}; |
|||
|
|||
enum WrapMode : u32 { |
|||
ClampToEdge = 0, |
|||
ClampToBorder = 1, |
|||
Repeat = 2, |
|||
MirroredRepeat = 3, |
|||
}; |
|||
|
|||
enum TextureFilter : u32 { |
|||
Nearest = 0, |
|||
Linear = 1, |
|||
}; |
|||
|
|||
union { |
|||
u32 raw; |
|||
BitField<0, 8, u32> r; |
|||
BitField<8, 8, u32> g; |
|||
BitField<16, 8, u32> b; |
|||
BitField<24, 8, u32> a; |
|||
} border_color; |
|||
|
|||
union { |
|||
BitField<0, 16, u32> height; |
|||
BitField<16, 16, u32> width; |
|||
}; |
|||
|
|||
union { |
|||
BitField<1, 1, TextureFilter> mag_filter; |
|||
BitField<2, 1, TextureFilter> min_filter; |
|||
BitField<8, 2, WrapMode> wrap_t; |
|||
BitField<12, 2, WrapMode> wrap_s; |
|||
BitField<28, 2, TextureType> |
|||
type; ///< @note Only valid for texture 0 according to 3DBrew. |
|||
}; |
|||
|
|||
INSERT_PADDING_WORDS(0x1); |
|||
|
|||
u32 address; |
|||
|
|||
PAddr GetPhysicalAddress() const { |
|||
return address * 8; |
|||
} |
|||
|
|||
// texture1 and texture2 store the texture format directly after the address |
|||
// whereas texture0 inserts some additional flags inbetween. |
|||
// Hence, we store the format separately so that all other parameters can be described |
|||
// in a single structure. |
|||
}; |
|||
|
|||
enum class TextureFormat : u32 { |
|||
RGBA8 = 0, |
|||
RGB8 = 1, |
|||
RGB5A1 = 2, |
|||
RGB565 = 3, |
|||
RGBA4 = 4, |
|||
IA8 = 5, |
|||
RG8 = 6, ///< @note Also called HILO8 in 3DBrew. |
|||
I8 = 7, |
|||
A8 = 8, |
|||
IA4 = 9, |
|||
I4 = 10, |
|||
A4 = 11, |
|||
ETC1 = 12, // compressed |
|||
ETC1A4 = 13, // compressed |
|||
}; |
|||
|
|||
static unsigned NibblesPerPixel(TextureFormat format) { |
|||
switch (format) { |
|||
case TextureFormat::RGBA8: |
|||
return 8; |
|||
|
|||
case TextureFormat::RGB8: |
|||
return 6; |
|||
|
|||
case TextureFormat::RGB5A1: |
|||
case TextureFormat::RGB565: |
|||
case TextureFormat::RGBA4: |
|||
case TextureFormat::IA8: |
|||
case TextureFormat::RG8: |
|||
return 4; |
|||
|
|||
case TextureFormat::I4: |
|||
case TextureFormat::A4: |
|||
return 1; |
|||
|
|||
case TextureFormat::I8: |
|||
case TextureFormat::A8: |
|||
case TextureFormat::IA4: |
|||
|
|||
default: // placeholder for yet unknown formats |
|||
UNIMPLEMENTED(); |
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
union { |
|||
BitField<0, 1, u32> texture0_enable; |
|||
BitField<1, 1, u32> texture1_enable; |
|||
BitField<2, 1, u32> texture2_enable; |
|||
}; |
|||
TextureConfig texture0; |
|||
INSERT_PADDING_WORDS(0x8); |
|||
BitField<0, 4, TextureFormat> texture0_format; |
|||
BitField<0, 1, u32> fragment_lighting_enable; |
|||
INSERT_PADDING_WORDS(0x1); |
|||
TextureConfig texture1; |
|||
BitField<0, 4, TextureFormat> texture1_format; |
|||
INSERT_PADDING_WORDS(0x2); |
|||
TextureConfig texture2; |
|||
BitField<0, 4, TextureFormat> texture2_format; |
|||
INSERT_PADDING_WORDS(0x21); |
|||
|
|||
struct FullTextureConfig { |
|||
const bool enabled; |
|||
const TextureConfig config; |
|||
const TextureFormat format; |
|||
}; |
|||
const std::array<FullTextureConfig, 3> GetTextures() const { |
|||
return {{ |
|||
{texture0_enable.ToBool(), texture0, texture0_format}, |
|||
{texture1_enable.ToBool(), texture1, texture1_format}, |
|||
{texture2_enable.ToBool(), texture2, texture2_format}, |
|||
}}; |
|||
} |
|||
|
|||
// 0xc0-0xff: Texture Combiner (akin to glTexEnv) |
|||
struct TevStageConfig { |
|||
enum class Source : u32 { |
|||
PrimaryColor = 0x0, |
|||
PrimaryFragmentColor = 0x1, |
|||
SecondaryFragmentColor = 0x2, |
|||
|
|||
Texture0 = 0x3, |
|||
Texture1 = 0x4, |
|||
Texture2 = 0x5, |
|||
Texture3 = 0x6, |
|||
|
|||
PreviousBuffer = 0xd, |
|||
Constant = 0xe, |
|||
Previous = 0xf, |
|||
}; |
|||
|
|||
enum class ColorModifier : u32 { |
|||
SourceColor = 0x0, |
|||
OneMinusSourceColor = 0x1, |
|||
SourceAlpha = 0x2, |
|||
OneMinusSourceAlpha = 0x3, |
|||
SourceRed = 0x4, |
|||
OneMinusSourceRed = 0x5, |
|||
|
|||
SourceGreen = 0x8, |
|||
OneMinusSourceGreen = 0x9, |
|||
|
|||
SourceBlue = 0xc, |
|||
OneMinusSourceBlue = 0xd, |
|||
}; |
|||
|
|||
enum class AlphaModifier : u32 { |
|||
SourceAlpha = 0x0, |
|||
OneMinusSourceAlpha = 0x1, |
|||
SourceRed = 0x2, |
|||
OneMinusSourceRed = 0x3, |
|||
SourceGreen = 0x4, |
|||
OneMinusSourceGreen = 0x5, |
|||
SourceBlue = 0x6, |
|||
OneMinusSourceBlue = 0x7, |
|||
}; |
|||
|
|||
enum class Operation : u32 { |
|||
Replace = 0, |
|||
Modulate = 1, |
|||
Add = 2, |
|||
AddSigned = 3, |
|||
Lerp = 4, |
|||
Subtract = 5, |
|||
Dot3_RGB = 6, |
|||
|
|||
MultiplyThenAdd = 8, |
|||
AddThenMultiply = 9, |
|||
}; |
|||
|
|||
union { |
|||
u32 sources_raw; |
|||
BitField<0, 4, Source> color_source1; |
|||
BitField<4, 4, Source> color_source2; |
|||
BitField<8, 4, Source> color_source3; |
|||
BitField<16, 4, Source> alpha_source1; |
|||
BitField<20, 4, Source> alpha_source2; |
|||
BitField<24, 4, Source> alpha_source3; |
|||
}; |
|||
|
|||
union { |
|||
u32 modifiers_raw; |
|||
BitField<0, 4, ColorModifier> color_modifier1; |
|||
BitField<4, 4, ColorModifier> color_modifier2; |
|||
BitField<8, 4, ColorModifier> color_modifier3; |
|||
BitField<12, 3, AlphaModifier> alpha_modifier1; |
|||
BitField<16, 3, AlphaModifier> alpha_modifier2; |
|||
BitField<20, 3, AlphaModifier> alpha_modifier3; |
|||
}; |
|||
|
|||
union { |
|||
u32 ops_raw; |
|||
BitField<0, 4, Operation> color_op; |
|||
BitField<16, 4, Operation> alpha_op; |
|||
}; |
|||
|
|||
union { |
|||
u32 const_color; |
|||
BitField<0, 8, u32> const_r; |
|||
BitField<8, 8, u32> const_g; |
|||
BitField<16, 8, u32> const_b; |
|||
BitField<24, 8, u32> const_a; |
|||
}; |
|||
|
|||
union { |
|||
u32 scales_raw; |
|||
BitField<0, 2, u32> color_scale; |
|||
BitField<16, 2, u32> alpha_scale; |
|||
}; |
|||
|
|||
inline unsigned GetColorMultiplier() const { |
|||
return (color_scale < 3) ? (1 << color_scale) : 1; |
|||
} |
|||
|
|||
inline unsigned GetAlphaMultiplier() const { |
|||
return (alpha_scale < 3) ? (1 << alpha_scale) : 1; |
|||
} |
|||
}; |
|||
|
|||
TevStageConfig tev_stage0; |
|||
INSERT_PADDING_WORDS(0x3); |
|||
TevStageConfig tev_stage1; |
|||
INSERT_PADDING_WORDS(0x3); |
|||
TevStageConfig tev_stage2; |
|||
INSERT_PADDING_WORDS(0x3); |
|||
TevStageConfig tev_stage3; |
|||
INSERT_PADDING_WORDS(0x3); |
|||
|
|||
enum class FogMode : u32 { |
|||
None = 0, |
|||
Fog = 5, |
|||
Gas = 7, |
|||
}; |
|||
|
|||
union { |
|||
BitField<0, 3, FogMode> fog_mode; |
|||
BitField<16, 1, u32> fog_flip; |
|||
|
|||
union { |
|||
// Tev stages 0-3 write their output to the combiner buffer if the corresponding bit in |
|||
// these masks are set |
|||
BitField<8, 4, u32> update_mask_rgb; |
|||
BitField<12, 4, u32> update_mask_a; |
|||
|
|||
bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const { |
|||
return (stage_index < 4) && (update_mask_rgb & (1 << stage_index)); |
|||
} |
|||
|
|||
bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const { |
|||
return (stage_index < 4) && (update_mask_a & (1 << stage_index)); |
|||
} |
|||
} tev_combiner_buffer_input; |
|||
}; |
|||
|
|||
union { |
|||
u32 raw; |
|||
BitField<0, 8, u32> r; |
|||
BitField<8, 8, u32> g; |
|||
BitField<16, 8, u32> b; |
|||
} fog_color; |
|||
|
|||
INSERT_PADDING_WORDS(0x4); |
|||
|
|||
BitField<0, 16, u32> fog_lut_offset; |
|||
|
|||
INSERT_PADDING_WORDS(0x1); |
|||
|
|||
u32 fog_lut_data[8]; |
|||
|
|||
TevStageConfig tev_stage4; |
|||
INSERT_PADDING_WORDS(0x3); |
|||
TevStageConfig tev_stage5; |
|||
|
|||
union { |
|||
u32 raw; |
|||
BitField<0, 8, u32> r; |
|||
BitField<8, 8, u32> g; |
|||
BitField<16, 8, u32> b; |
|||
BitField<24, 8, u32> a; |
|||
} tev_combiner_buffer_color; |
|||
|
|||
INSERT_PADDING_WORDS(0x2); |
|||
|
|||
const std::array<TevStageConfig, 6> GetTevStages() const { |
|||
return {{tev_stage0, tev_stage1, tev_stage2, tev_stage3, tev_stage4, tev_stage5}}; |
|||
}; |
|||
}; |
|||
|
|||
static_assert(sizeof(TexturingRegs) == 0x80 * sizeof(u32), |
|||
"TexturingRegs struct has incorrect size"); |
|||
|
|||
} // namespace Pica |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue