[PICA] Proper texture wrapping

This commit is contained in:
wheremyfoodat 2023-04-03 21:08:31 +03:00
parent 84db6052b3
commit 4632a62da2
4 changed files with 34 additions and 13 deletions

View file

@ -29,6 +29,7 @@ struct Texture {
}; };
u32 location; u32 location;
u32 config; // Magnification/minification filter, wrapping configs, etc
Formats format; Formats format;
OpenGL::uvec2 size; OpenGL::uvec2 size;
bool valid; bool valid;
@ -40,8 +41,8 @@ struct Texture {
Texture() : valid(false) {} Texture() : valid(false) {}
Texture(u32 loc, Formats format, u32 x, u32 y, bool valid = true) Texture(u32 loc, Formats format, u32 x, u32 y, u32 config, bool valid = true)
: location(loc), format(format), size({x, y}), valid(valid) { : location(loc), format(format), size({x, y}), config(config), valid(valid) {
u64 endLoc = (u64)loc + sizeInBytes(); u64 endLoc = (u64)loc + sizeInBytes();
// Check if start and end are valid here // Check if start and end are valid here
@ -56,6 +57,7 @@ struct Texture {
} }
void allocate(); void allocate();
void setNewConfig(u32 newConfig);
void decodeTexture(const void* data); void decodeTexture(const void* data);
void free(); void free();
u64 sizeInBytes(); u64 sizeInBytes();

View file

@ -310,13 +310,14 @@ void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 c
// Hack for rendering texture 1 // Hack for rendering texture 1
if (regs[0x80] & 1) { if (regs[0x80] & 1) {
u32 dim = regs[0x82]; const u32 dim = regs[0x82];
u32 height = dim & 0x7ff; const u32 config = regs[0x83];
u32 width = (dim >> 16) & 0x7ff; const u32 height = dim & 0x7ff;
u32 addr = (regs[0x85] & 0x0FFFFFFF) << 3; const u32 width = (dim >> 16) & 0x7ff;
u32 format = regs[0x8E] & 0xF; const u32 addr = (regs[0x85] & 0x0FFFFFFF) << 3;
const u32 format = regs[0x8E] & 0xF;
Texture targetTex(addr, static_cast<Texture::Formats>(format), width, height); Texture targetTex(addr, static_cast<Texture::Formats>(format), width, height, config);
OpenGL::Texture tex = getTexture(targetTex); OpenGL::Texture tex = getTexture(targetTex);
tex.bind(); tex.bind();
} }

View file

@ -1,15 +1,33 @@
#include "renderer_gl/textures.hpp" #include "renderer_gl/textures.hpp"
#include "colour.hpp" #include "colour.hpp"
#include <array>
void Texture::allocate() { void Texture::allocate() {
glGenTextures(1, &texture.m_handle); glGenTextures(1, &texture.m_handle);
texture.create(size.u(), size.v(), GL_RGBA8); texture.create(size.u(), size.v(), GL_RGBA8);
texture.bind(); texture.bind();
texture.setMinFilter(OpenGL::Nearest); setNewConfig(config);
texture.setMagFilter(OpenGL::Nearest); }
texture.setWrapS(OpenGL::Repeat);
texture.setWrapT(OpenGL::Repeat); // Set the texture's configuration, which includes min/mag filters, wrapping S/T modes, and so on
void Texture::setNewConfig(u32 cfg) {
config = cfg;
// The wrapping mode field is 3 bits instead of 2 bits. The bottom 4 undocumented wrapping modes are taken from Citra.
static constexpr std::array<OpenGL::WrappingMode, 8> wrappingModes = {
OpenGL::ClampToEdge, OpenGL::ClampToBorder, OpenGL::Repeat, OpenGL::RepeatMirrored,
OpenGL::ClampToEdge, OpenGL::ClampToBorder, OpenGL::Repeat, OpenGL::Repeat
};
const auto magFilter = (cfg & 0x2) != 0 ? OpenGL::Linear : OpenGL::Nearest;
const auto minFilter = (cfg & 0x4) != 0 ? OpenGL::Linear : OpenGL::Nearest;
const auto wrapT = wrappingModes[(cfg >> 8) & 0x7];
const auto wrapS = wrappingModes[(cfg >> 12) & 0x7];
texture.setMinFilter(minFilter);
texture.setMagFilter(magFilter);
texture.setWrapS(wrapS);
texture.setWrapT(wrapT);
} }
void Texture::free() { void Texture::free() {

View file

@ -164,7 +164,7 @@ void FSService::handleSyncRequest(u32 messagePointer) {
case FSCommands::OpenFile: [[likely]] openFile(messagePointer); break; case FSCommands::OpenFile: [[likely]] openFile(messagePointer); break;
case FSCommands::OpenFileDirectly: [[likely]] openFileDirectly(messagePointer); break; case FSCommands::OpenFileDirectly: [[likely]] openFileDirectly(messagePointer); break;
case FSCommands::SetPriority: setPriority(messagePointer); break; case FSCommands::SetPriority: setPriority(messagePointer); break;
default: Helpers::panic("FS service requested. Command: %08X\n", command); default: mem.write32(messagePointer + 4, 0); break; Helpers::panic("FS service requested. Command: %08X\n", command);
} }
} }