diff options
| author | 2014-12-06 19:10:08 +0100 | |
|---|---|---|
| committer | 2014-12-20 18:05:53 +0100 | |
| commit | fd2539121cddd6177a964770a6985f8880ca1646 (patch) | |
| tree | 67d2e0e33ee435569e3a82eaa891c2154ed83d53 /src/video_core/rasterizer.cpp | |
| parent | BitField: Add an explicit Assign method. (diff) | |
| download | yuzu-fd2539121cddd6177a964770a6985f8880ca1646.tar.gz yuzu-fd2539121cddd6177a964770a6985f8880ca1646.tar.xz yuzu-fd2539121cddd6177a964770a6985f8880ca1646.zip | |
Pica: Initial support for multitexturing.
Diffstat (limited to 'src/video_core/rasterizer.cpp')
| -rw-r--r-- | src/video_core/rasterizer.cpp | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index b7e04a560..2ff6d19a6 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -167,10 +167,22 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 167 | (u8)(GetInterpolatedAttribute(v0.color.a(), v1.color.a(), v2.color.a()).ToFloat32() * 255) | 167 | (u8)(GetInterpolatedAttribute(v0.color.a(), v1.color.a(), v2.color.a()).ToFloat32() * 255) |
| 168 | }; | 168 | }; |
| 169 | 169 | ||
| 170 | Math::Vec4<u8> texture_color{}; | 170 | Math::Vec2<float24> uv[3]; |
| 171 | float24 u = GetInterpolatedAttribute(v0.tc0.u(), v1.tc0.u(), v2.tc0.u()); | 171 | uv[0].u() = GetInterpolatedAttribute(v0.tc0.u(), v1.tc0.u(), v2.tc0.u()); |
| 172 | float24 v = GetInterpolatedAttribute(v0.tc0.v(), v1.tc0.v(), v2.tc0.v()); | 172 | uv[0].v() = GetInterpolatedAttribute(v0.tc0.v(), v1.tc0.v(), v2.tc0.v()); |
| 173 | if (registers.texturing_enable) { | 173 | uv[1].u() = GetInterpolatedAttribute(v0.tc1.u(), v1.tc1.u(), v2.tc1.u()); |
| 174 | uv[1].v() = GetInterpolatedAttribute(v0.tc1.v(), v1.tc1.v(), v2.tc1.v()); | ||
| 175 | uv[2].u() = GetInterpolatedAttribute(v0.tc2.u(), v1.tc2.u(), v2.tc2.u()); | ||
| 176 | uv[2].v() = GetInterpolatedAttribute(v0.tc2.v(), v1.tc2.v(), v2.tc2.v()); | ||
| 177 | |||
| 178 | Math::Vec4<u8> texture_color[3]{}; | ||
| 179 | for (int i = 0; i < 3; ++i) { | ||
| 180 | auto texture = registers.GetTextures()[i]; | ||
| 181 | if (!texture.enabled) | ||
| 182 | continue; | ||
| 183 | |||
| 184 | _dbg_assert_(GPU, 0 != texture.config.address); | ||
| 185 | |||
| 174 | // Images are split into 8x8 tiles. Each tile is composed of four 4x4 subtiles each | 186 | // Images are split into 8x8 tiles. Each tile is composed of four 4x4 subtiles each |
| 175 | // of which is composed of four 2x2 subtiles each of which is composed of four texels. | 187 | // of which is composed of four 2x2 subtiles each of which is composed of four texels. |
| 176 | // Each structure is embedded into the next-bigger one in a diagonal pattern, e.g. | 188 | // Each structure is embedded into the next-bigger one in a diagonal pattern, e.g. |
| @@ -189,14 +201,11 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 189 | // 02 03 06 07 18 19 22 23 | 201 | // 02 03 06 07 18 19 22 23 |
| 190 | // 00 01 04 05 16 17 20 21 | 202 | // 00 01 04 05 16 17 20 21 |
| 191 | 203 | ||
| 192 | // TODO: This is currently hardcoded for RGB8 | ||
| 193 | u32* texture_data = (u32*)Memory::GetPointer(registers.texture0.GetPhysicalAddress()); | ||
| 194 | |||
| 195 | // TODO(neobrain): Not sure if this swizzling pattern is used for all textures. | 204 | // TODO(neobrain): Not sure if this swizzling pattern is used for all textures. |
| 196 | // To be flexible in case different but similar patterns are used, we keep this | 205 | // To be flexible in case different but similar patterns are used, we keep this |
| 197 | // somewhat inefficient code around for now. | 206 | // somewhat inefficient code around for now. |
| 198 | int s = (int)(u * float24::FromFloat32(static_cast<float>(registers.texture0.width))).ToFloat32(); | 207 | int s = (int)(uv[i].u() * float24::FromFloat32(static_cast<float>(texture.config.width))).ToFloat32(); |
| 199 | int t = (int)(v * float24::FromFloat32(static_cast<float>(registers.texture0.height))).ToFloat32(); | 208 | int t = (int)(uv[i].v() * float24::FromFloat32(static_cast<float>(texture.config.height))).ToFloat32(); |
| 200 | int texel_index_within_tile = 0; | 209 | int texel_index_within_tile = 0; |
| 201 | for (int block_size_index = 0; block_size_index < 3; ++block_size_index) { | 210 | for (int block_size_index = 0; block_size_index < 3; ++block_size_index) { |
| 202 | int sub_tile_width = 1 << block_size_index; | 211 | int sub_tile_width = 1 << block_size_index; |
| @@ -213,14 +222,17 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 213 | int coarse_s = (s / block_width) * block_width; | 222 | int coarse_s = (s / block_width) * block_width; |
| 214 | int coarse_t = (t / block_height) * block_height; | 223 | int coarse_t = (t / block_height) * block_height; |
| 215 | 224 | ||
| 216 | const int row_stride = registers.texture0.width * 3; | 225 | // TODO: This is currently hardcoded for RGB8 |
| 226 | u32* texture_data = (u32*)Memory::GetPointer(texture.config.GetPhysicalAddress()); | ||
| 227 | |||
| 228 | const int row_stride = texture.config.width * 3; | ||
| 217 | u8* source_ptr = (u8*)texture_data + coarse_s * block_height * 3 + coarse_t * row_stride + texel_index_within_tile * 3; | 229 | u8* source_ptr = (u8*)texture_data + coarse_s * block_height * 3 + coarse_t * row_stride + texel_index_within_tile * 3; |
| 218 | texture_color.r() = source_ptr[2]; | 230 | texture_color[i].r() = source_ptr[2]; |
| 219 | texture_color.g() = source_ptr[1]; | 231 | texture_color[i].g() = source_ptr[1]; |
| 220 | texture_color.b() = source_ptr[0]; | 232 | texture_color[i].b() = source_ptr[0]; |
| 221 | texture_color.a() = 0xFF; | 233 | texture_color[i].a() = 0xFF; |
| 222 | 234 | ||
| 223 | DebugUtils::DumpTexture(registers.texture0, (u8*)texture_data); | 235 | DebugUtils::DumpTexture(texture.config, (u8*)texture_data); |
| 224 | } | 236 | } |
| 225 | 237 | ||
| 226 | // Texture environment - consists of 6 stages of color and alpha combining. | 238 | // Texture environment - consists of 6 stages of color and alpha combining. |
| @@ -243,7 +255,13 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 243 | return primary_color.rgb(); | 255 | return primary_color.rgb(); |
| 244 | 256 | ||
| 245 | case Source::Texture0: | 257 | case Source::Texture0: |
| 246 | return texture_color.rgb(); | 258 | return texture_color[0].rgb(); |
| 259 | |||
| 260 | case Source::Texture1: | ||
| 261 | return texture_color[1].rgb(); | ||
| 262 | |||
| 263 | case Source::Texture2: | ||
| 264 | return texture_color[2].rgb(); | ||
| 247 | 265 | ||
| 248 | case Source::Constant: | 266 | case Source::Constant: |
| 249 | return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b}; | 267 | return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b}; |
| @@ -263,7 +281,13 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 263 | return primary_color.a(); | 281 | return primary_color.a(); |
| 264 | 282 | ||
| 265 | case Source::Texture0: | 283 | case Source::Texture0: |
| 266 | return texture_color.a(); | 284 | return texture_color[0].a(); |
| 285 | |||
| 286 | case Source::Texture1: | ||
| 287 | return texture_color[1].a(); | ||
| 288 | |||
| 289 | case Source::Texture2: | ||
| 290 | return texture_color[2].a(); | ||
| 267 | 291 | ||
| 268 | case Source::Constant: | 292 | case Source::Constant: |
| 269 | return tev_stage.const_a; | 293 | return tev_stage.const_a; |