From 0fba1d48a6ab7a9fa19ce65ec864da212ceb501a Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Thu, 4 Dec 2014 17:37:59 +0100 Subject: Pica: Implement texture wrapping. --- src/video_core/pica.h | 12 +++++++++++- src/video_core/rasterizer.cpp | 21 ++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) (limited to 'src') 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(texture.config.width))).ToFloat32(); int t = (int)(uv[i].v() * float24::FromFloat32(static_cast(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; -- cgit v1.2.3