summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/pica.h12
-rw-r--r--src/video_core/rasterizer.cpp21
2 files changed, 31 insertions, 2 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 7ed49caed..ec20114fe 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -104,6 +104,11 @@ struct Regs {
INSERT_PADDING_WORDS(0x17);
struct TextureConfig {
+ enum WrapMode : u32 {
+ ClampToEdge = 0,
+ Repeat = 2,
+ };
+
INSERT_PADDING_WORDS(0x1);
union {
@@ -111,7 +116,12 @@ struct Regs {
BitField<16, 16, u32> width;
};
- INSERT_PADDING_WORDS(0x2);
+ union {
+ BitField< 8, 2, WrapMode> wrap_s;
+ BitField<11, 2, WrapMode> wrap_t;
+ };
+
+ INSERT_PADDING_WORDS(0x1);
u32 address;
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index 2ff6d19a6..e12f68a7f 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -181,7 +181,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
if (!texture.enabled)
continue;
- _dbg_assert_(GPU, 0 != texture.config.address);
+ _dbg_assert_(HW_GPU, 0 != texture.config.address);
// Images are split into 8x8 tiles. Each tile is composed of four 4x4 subtiles each
// of which is composed of four 2x2 subtiles each of which is composed of four texels.
@@ -206,6 +206,25 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
// somewhat inefficient code around for now.
int s = (int)(uv[i].u() * float24::FromFloat32(static_cast<float>(texture.config.width))).ToFloat32();
int t = (int)(uv[i].v() * float24::FromFloat32(static_cast<float>(texture.config.height))).ToFloat32();
+ auto GetWrappedTexCoord = [](Regs::TextureConfig::WrapMode mode, int val, unsigned size) {
+ switch (mode) {
+ case Regs::TextureConfig::ClampToEdge:
+ val = std::max(val, 0);
+ val = std::min(val, (int)size - 1);
+ return val;
+
+ case Regs::TextureConfig::Repeat:
+ return (int)(((unsigned)val) % size);
+
+ default:
+ LOG_ERROR(HW_GPU, "Unknown texture coordinate wrapping mode %x\n", (int)mode);
+ _dbg_assert_(HW_GPU, 0);
+ return 0;
+ }
+ };
+ s = GetWrappedTexCoord(registers.texture0.wrap_s, s, registers.texture0.width);
+ t = GetWrappedTexCoord(registers.texture0.wrap_t, t, registers.texture0.height);
+
int texel_index_within_tile = 0;
for (int block_size_index = 0; block_size_index < 3; ++block_size_index) {
int sub_tile_width = 1 << block_size_index;