Pica: Implement texture wrapping.
This commit is contained in:
parent
c81f1a9ebc
commit
0fba1d48a6
|
@ -104,6 +104,11 @@ struct Regs {
|
||||||
INSERT_PADDING_WORDS(0x17);
|
INSERT_PADDING_WORDS(0x17);
|
||||||
|
|
||||||
struct TextureConfig {
|
struct TextureConfig {
|
||||||
|
enum WrapMode : u32 {
|
||||||
|
ClampToEdge = 0,
|
||||||
|
Repeat = 2,
|
||||||
|
};
|
||||||
|
|
||||||
INSERT_PADDING_WORDS(0x1);
|
INSERT_PADDING_WORDS(0x1);
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
@ -111,7 +116,12 @@ struct Regs {
|
||||||
BitField<16, 16, u32> width;
|
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;
|
u32 address;
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0,
|
||||||
if (!texture.enabled)
|
if (!texture.enabled)
|
||||||
continue;
|
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
|
// 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.
|
// 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.
|
// somewhat inefficient code around for now.
|
||||||
int s = (int)(uv[i].u() * float24::FromFloat32(static_cast<float>(texture.config.width))).ToFloat32();
|
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();
|
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;
|
int texel_index_within_tile = 0;
|
||||||
for (int block_size_index = 0; block_size_index < 3; ++block_size_index) {
|
for (int block_size_index = 0; block_size_index < 3; ++block_size_index) {
|
||||||
int sub_tile_width = 1 << block_size_index;
|
int sub_tile_width = 1 << block_size_index;
|
||||||
|
|
Loading…
Reference in New Issue