diff options
| author | 2017-01-27 20:51:59 -0800 | |
|---|---|---|
| committer | 2017-02-04 13:59:09 -0800 | |
| commit | 9017093f58fb08b85cfb842f305efa667d62cecb (patch) | |
| tree | 98a1e77b197a562a8f13565e62f2e8bb9220ff94 /src/video_core/regs_texturing.h | |
| 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/video_core/regs_texturing.h')
| -rw-r--r-- | src/video_core/regs_texturing.h | 328 |
1 files changed, 328 insertions, 0 deletions
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 | ||