summaryrefslogtreecommitdiff
path: root/src/video_core/rasterizer.cpp
diff options
context:
space:
mode:
authorGravatar Tony Wasserka2014-12-06 19:10:08 +0100
committerGravatar Tony Wasserka2014-12-20 18:05:53 +0100
commitfd2539121cddd6177a964770a6985f8880ca1646 (patch)
tree67d2e0e33ee435569e3a82eaa891c2154ed83d53 /src/video_core/rasterizer.cpp
parentBitField: Add an explicit Assign method. (diff)
downloadyuzu-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.cpp58
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;