mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-07-02 05:16:19 +12:00
Add optional texture hashing
This commit is contained in:
parent
6182d4cfe9
commit
a0aa11dac0
10 changed files with 106 additions and 54 deletions
|
@ -62,9 +62,13 @@ struct EmulatorConfig {
|
|||
static constexpr RendererType rendererDefault = RendererType::OpenGL;
|
||||
#endif
|
||||
|
||||
static constexpr bool hashTexturesDefault = true;
|
||||
|
||||
bool shaderJitEnabled = shaderJitDefault;
|
||||
bool useUbershaders = ubershaderDefault;
|
||||
bool accelerateShaders = accelerateShadersDefault;
|
||||
bool hashTextures = hashTexturesDefault;
|
||||
|
||||
bool accurateShaderMul = false;
|
||||
bool discordRpcEnabled = false;
|
||||
|
||||
|
|
|
@ -51,6 +51,9 @@ class Renderer {
|
|||
u32 outputWindowWidth = 400;
|
||||
u32 outputWindowHeight = 240 * 2;
|
||||
|
||||
// Should hw renderers hash textures? Stored separately from emulatorConfig because we'll be accessing it constantly, might be merged eventually
|
||||
bool hashTextures = false;
|
||||
|
||||
EmulatorConfig* emulatorConfig = nullptr;
|
||||
|
||||
void doSoftwareTextureCopy(u32 inputAddr, u32 outputAddr, u32 copySize, u32 inputWidth, u32 inputGap, u32 outputWidth, u32 outputGap);
|
||||
|
@ -123,4 +126,5 @@ class Renderer {
|
|||
}
|
||||
|
||||
void setConfig(EmulatorConfig* config) { emulatorConfig = config; }
|
||||
void setHashTextures(bool setting) { hashTextures = setting; }
|
||||
};
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "PICA/pica_hash.hpp"
|
||||
#include "PICA/regs.hpp"
|
||||
#include "boost/icl/interval.hpp"
|
||||
#include "helpers.hpp"
|
||||
|
@ -11,55 +13,55 @@ template <typename T>
|
|||
using Interval = boost::icl::right_open_interval<T>;
|
||||
|
||||
struct Texture {
|
||||
u32 location;
|
||||
u32 config; // Magnification/minification filter, wrapping configs, etc
|
||||
PICA::TextureFmt format;
|
||||
OpenGL::uvec2 size;
|
||||
bool valid;
|
||||
using Hash = PICAHash::HashType;
|
||||
|
||||
// Range of VRAM taken up by buffer
|
||||
Interval<u32> range;
|
||||
// OpenGL resources allocated to buffer
|
||||
OpenGL::Texture texture;
|
||||
u32 location;
|
||||
u32 config; // Magnification/minification filter, wrapping configs, etc
|
||||
Hash hash = Hash(0);
|
||||
|
||||
Texture() : valid(false) {}
|
||||
PICA::TextureFmt format;
|
||||
OpenGL::uvec2 size;
|
||||
bool valid;
|
||||
|
||||
Texture(u32 loc, PICA::TextureFmt format, u32 x, u32 y, u32 config, bool valid = true)
|
||||
: location(loc), format(format), size({x, y}), config(config), valid(valid) {
|
||||
// Range of VRAM taken up by buffer
|
||||
Interval<u32> range;
|
||||
// OpenGL resources allocated to buffer
|
||||
OpenGL::Texture texture;
|
||||
|
||||
u64 endLoc = (u64)loc + sizeInBytes();
|
||||
// Check if start and end are valid here
|
||||
range = Interval<u32>(loc, (u32)endLoc);
|
||||
}
|
||||
Texture() : valid(false) {}
|
||||
|
||||
// For 2 textures to "match" we only care about their locations, formats, and dimensions to match
|
||||
// For other things, such as filtering mode, etc, we can just switch the attributes of the cached texture
|
||||
bool matches(Texture& other) {
|
||||
return location == other.location && format == other.format &&
|
||||
size.x() == other.size.x() && size.y() == other.size.y();
|
||||
}
|
||||
Texture(u32 loc, PICA::TextureFmt format, u32 x, u32 y, u32 config, bool valid = true)
|
||||
: location(loc), format(format), size({x, y}), config(config), valid(valid) {
|
||||
u64 endLoc = (u64)loc + sizeInBytes();
|
||||
// Check if start and end are valid here
|
||||
range = Interval<u32>(loc, (u32)endLoc);
|
||||
}
|
||||
|
||||
void allocate();
|
||||
void setNewConfig(u32 newConfig);
|
||||
void decodeTexture(std::span<const u8> data);
|
||||
void free();
|
||||
u64 sizeInBytes();
|
||||
// For 2 textures to "match" we only care about their locations, formats, and dimensions to match
|
||||
// For other things, such as filtering mode, etc, we can just switch the attributes of the cached texture
|
||||
bool matches(Texture& other) {
|
||||
return location == other.location && hash == other.hash && format == other.format && size.x() == other.size.x() && size.y() == other.size.y();
|
||||
}
|
||||
|
||||
u32 decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
|
||||
void allocate();
|
||||
void setNewConfig(u32 newConfig);
|
||||
void decodeTexture(std::span<const u8> data);
|
||||
void free();
|
||||
u64 sizeInBytes();
|
||||
|
||||
// Get the morton interleave offset of a texel based on its U and V values
|
||||
static u32 mortonInterleave(u32 u, u32 v);
|
||||
// Get the byte offset of texel (u, v) in the texture
|
||||
static u32 getSwizzledOffset(u32 u, u32 v, u32 width, u32 bytesPerPixel);
|
||||
static u32 getSwizzledOffset_4bpp(u32 u, u32 v, u32 width);
|
||||
u32 decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
|
||||
|
||||
// Returns the format of this texture as a string
|
||||
std::string_view formatToString() {
|
||||
return PICA::textureFormatToString(format);
|
||||
}
|
||||
// Get the morton interleave offset of a texel based on its U and V values
|
||||
static u32 mortonInterleave(u32 u, u32 v);
|
||||
// Get the byte offset of texel (u, v) in the texture
|
||||
static u32 getSwizzledOffset(u32 u, u32 v, u32 width, u32 bytesPerPixel);
|
||||
static u32 getSwizzledOffset_4bpp(u32 u, u32 v, u32 width);
|
||||
|
||||
// Returns the texel at coordinates (u, v) of an ETC1(A4) texture
|
||||
// TODO: Make hasAlpha a template parameter
|
||||
u32 getTexelETC(bool hasAlpha, u32 u, u32 v, u32 width, std::span<const u8> data);
|
||||
u32 decodeETC(u32 alpha, u32 u, u32 v, u64 colourData);
|
||||
// Returns the format of this texture as a string
|
||||
std::string_view formatToString() { return PICA::textureFormatToString(format); }
|
||||
|
||||
// Returns the texel at coordinates (u, v) of an ETC1(A4) texture
|
||||
// TODO: Make hasAlpha a template parameter
|
||||
u32 getTexelETC(bool hasAlpha, u32 u, u32 v, u32 width, std::span<const u8> data);
|
||||
u32 decodeETC(u32 alpha, u32 u, u32 v, u64 colourData);
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "PICA/pica_hash.hpp"
|
||||
#include "PICA/regs.hpp"
|
||||
#include "boost/icl/interval.hpp"
|
||||
#include "helpers.hpp"
|
||||
|
@ -17,10 +18,14 @@ using Interval = boost::icl::right_open_interval<T>;
|
|||
|
||||
namespace Metal {
|
||||
struct Texture {
|
||||
using Hash = PICAHash::HashType;
|
||||
|
||||
MTL::Device* device;
|
||||
|
||||
u32 location;
|
||||
u32 config; // Magnification/minification filter, wrapping configs, etc
|
||||
Hash hash = Hash(0);
|
||||
|
||||
PICA::TextureFmt format;
|
||||
OpenGL::uvec2 size;
|
||||
bool valid;
|
||||
|
@ -45,7 +50,8 @@ namespace Metal {
|
|||
// For 2 textures to "match" we only care about their locations, formats, and dimensions to match
|
||||
// For other things, such as filtering mode, etc, we can just switch the attributes of the cached texture
|
||||
bool matches(Texture& other) {
|
||||
return location == other.location && format == other.format && size.x() == other.size.x() && size.y() == other.size.y();
|
||||
return location == other.location && hash == other.hash && format == other.format && size.x() == other.size.x() &&
|
||||
size.y() == other.size.y();
|
||||
}
|
||||
|
||||
void allocate();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue