mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-06-08 12:01:39 +12:00
Add Helpers:{getBits,getBit}
`constexpr` functions for extractint bitfields that lends itself a bit better to emitting instructions like `bextr` on x86 or `ubfx` on arm64. And may subjectively make things a bit more readable. "Extract `5` bits" rather than `& 0x1F`.
This commit is contained in:
parent
c7e3343974
commit
2c94d0d683
9 changed files with 180 additions and 147 deletions
|
@ -3,6 +3,8 @@
|
|||
#include "renderer_gl/renderer_gl.hpp"
|
||||
#include "renderer_gl/textures.hpp"
|
||||
|
||||
using namespace Helpers;
|
||||
|
||||
static constexpr u32 signExtend3To32(u32 val) {
|
||||
return (u32)(s32(val) << 29 >> 29);
|
||||
}
|
||||
|
@ -58,14 +60,14 @@ u32 Texture::decodeETC(u32 alpha, u32 u, u32 v, u64 colourData) {
|
|||
};
|
||||
|
||||
// Parse colour data for 4x4 block
|
||||
const u32 subindices = colourData & 0xffff;
|
||||
const u32 negationFlags = (colourData >> 16) & 0xffff;
|
||||
const bool flip = (colourData >> 32) & 1;
|
||||
const bool diffMode = (colourData >> 33) & 1;
|
||||
const u32 subindices = getBits<0, 16>(colourData);
|
||||
const u32 negationFlags = getBits<16, 16>(colourData);
|
||||
const bool flip = getBit<32>(colourData);
|
||||
const bool diffMode = getBit<33>(colourData);
|
||||
|
||||
// Note: index1 is indeed stored on the higher bits, with index2 in the lower bits
|
||||
const u32 tableIndex1 = (colourData >> 37) & 7;
|
||||
const u32 tableIndex2 = (colourData >> 34) & 7;
|
||||
const u32 tableIndex1 = getBits<37, 3>(colourData);
|
||||
const u32 tableIndex2 = getBits<34, 3>(colourData);
|
||||
const u32 texelIndex = u * 4 + v; // Index of the texel in the block
|
||||
|
||||
if (flip)
|
||||
|
@ -73,14 +75,14 @@ u32 Texture::decodeETC(u32 alpha, u32 u, u32 v, u64 colourData) {
|
|||
|
||||
s32 r, g, b;
|
||||
if (diffMode) {
|
||||
r = (colourData >> 59) & 0x1f;
|
||||
g = (colourData >> 51) & 0x1f;
|
||||
b = (colourData >> 43) & 0x1f;
|
||||
r = getBits<59, 5>(colourData);
|
||||
g = getBits<51, 5>(colourData);
|
||||
b = getBits<43, 5>(colourData);
|
||||
|
||||
if (u >= 2) {
|
||||
r += signExtend3To32((colourData >> 56) & 0x7);
|
||||
g += signExtend3To32((colourData >> 48) & 0x7);
|
||||
b += signExtend3To32((colourData >> 40) & 0x7);
|
||||
r += signExtend3To32(getBits<56, 3>(colourData));
|
||||
g += signExtend3To32(getBits<48, 3>(colourData));
|
||||
b += signExtend3To32(getBits<40, 3>(colourData));
|
||||
}
|
||||
|
||||
// Expand from 5 to 8 bits per channel
|
||||
|
@ -89,13 +91,13 @@ u32 Texture::decodeETC(u32 alpha, u32 u, u32 v, u64 colourData) {
|
|||
b = Colour::convert5To8Bit(b);
|
||||
} else {
|
||||
if (u < 2) {
|
||||
r = (colourData >> 60) & 0xf;
|
||||
g = (colourData >> 52) & 0xf;
|
||||
b = (colourData >> 44) & 0xf;
|
||||
r = getBits<60, 4>(colourData);
|
||||
g = getBits<52, 4>(colourData);
|
||||
b = getBits<44, 4>(colourData);
|
||||
} else {
|
||||
r = (colourData >> 56) & 0xf;
|
||||
g = (colourData >> 48) & 0xf;
|
||||
b = (colourData >> 40) & 0xf;
|
||||
r = getBits<56, 4>(colourData);
|
||||
g = getBits<48, 4>(colourData);
|
||||
b = getBits<40, 4>(colourData);
|
||||
}
|
||||
|
||||
// Expand from 4 to 8 bits per channel
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "PICA/regs.hpp"
|
||||
|
||||
using namespace Floats;
|
||||
using namespace Helpers;
|
||||
|
||||
// This is all hacked up to display our first triangle
|
||||
|
||||
|
@ -243,19 +244,19 @@ void Renderer::setupBlending() {
|
|||
// Get blending equations
|
||||
const u32 blendControl = regs[PICAInternalRegs::BlendFunc];
|
||||
const u32 rgbEquation = blendControl & 0x7;
|
||||
const u32 alphaEquation = (blendControl >> 8) & 0x7;
|
||||
const u32 alphaEquation = getBits<8, 3>(blendControl);
|
||||
|
||||
// Get blending functions
|
||||
const u32 rgbSourceFunc = (blendControl >> 16) & 0xf;
|
||||
const u32 rgbDestFunc = (blendControl >> 20) & 0xf;
|
||||
const u32 alphaSourceFunc = (blendControl >> 24) & 0xf;
|
||||
const u32 alphaDestFunc = (blendControl >> 28) & 0xf;
|
||||
const u32 rgbSourceFunc = getBits<16, 4>(blendControl);
|
||||
const u32 rgbDestFunc = getBits<20, 4>(blendControl);
|
||||
const u32 alphaSourceFunc = getBits<24, 4>(blendControl);
|
||||
const u32 alphaDestFunc = getBits<28, 4>(blendControl);
|
||||
|
||||
const u32 constantColor = regs[PICAInternalRegs::BlendColour];
|
||||
const u32 r = constantColor & 0xff;
|
||||
const u32 g = (constantColor >> 8) & 0xff;
|
||||
const u32 b = (constantColor >> 16) & 0xff;
|
||||
const u32 a = (constantColor >> 24) & 0xff;
|
||||
const u32 g = getBits<8, 8>(constantColor);
|
||||
const u32 b = getBits<16, 8>(constantColor);
|
||||
const u32 a = getBits<24, 8>(constantColor);
|
||||
OpenGL::setBlendColor(float(r) / 255.f, float(g) / 255.f, float(b) / 255.f, float(a) / 255.f);
|
||||
|
||||
// Translate equations and funcs to their GL equivalents and set them
|
||||
|
@ -278,9 +279,9 @@ void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 c
|
|||
|
||||
const u32 depthControl = regs[PICAInternalRegs::DepthAndColorMask];
|
||||
const bool depthEnable = depthControl & 1;
|
||||
const bool depthWriteEnable = (depthControl >> 12) & 1;
|
||||
const int depthFunc = (depthControl >> 4) & 7;
|
||||
const int colourMask = (depthControl >> 8) & 0xf;
|
||||
const bool depthWriteEnable = getBit<12>(depthControl);
|
||||
const int depthFunc = getBits<4, 3>(depthControl);
|
||||
const int colourMask = getBits<8, 4>(depthControl);
|
||||
glColorMask(colourMask & 1, colourMask & 2, colourMask & 4, colourMask & 8);
|
||||
|
||||
static constexpr std::array<GLenum, 8> depthModes = {
|
||||
|
@ -312,7 +313,7 @@ void Renderer::drawVertices(OpenGL::Primitives primType, Vertex* vertices, u32 c
|
|||
const u32 dim = regs[0x82];
|
||||
const u32 config = regs[0x83];
|
||||
const u32 height = dim & 0x7ff;
|
||||
const u32 width = (dim >> 16) & 0x7ff;
|
||||
const u32 width = getBits<16, 11>(dim);
|
||||
const u32 addr = (regs[0x85] & 0x0FFFFFFF) << 3;
|
||||
const u32 format = regs[0x8E] & 0xF;
|
||||
|
||||
|
@ -379,9 +380,9 @@ void Renderer::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 cont
|
|||
return;
|
||||
log("GPU: Clear buffer\nStart: %08X End: %08X\nValue: %08X Control: %08X\n", startAddress, endAddress, value, control);
|
||||
|
||||
const float r = float((value >> 24) & 0xff) / 255.0;
|
||||
const float g = float((value >> 16) & 0xff) / 255.0;
|
||||
const float b = float((value >> 8) & 0xff) / 255.0;
|
||||
const float r = float(getBits<24, 8>(value)) / 255.0;
|
||||
const float g = float(getBits<16, 8>(value)) / 255.0;
|
||||
const float b = float(getBits<8, 8>(value)) / 255.0;
|
||||
const float a = float(value & 0xff) / 255.0;
|
||||
|
||||
if (startAddress == topScreenBuffer) {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "colour.hpp"
|
||||
#include <array>
|
||||
|
||||
using namespace Helpers;
|
||||
|
||||
void Texture::allocate() {
|
||||
glGenTextures(1, &texture.m_handle);
|
||||
texture.create(size.u(), size.v(), GL_RGBA8);
|
||||
|
@ -21,8 +23,8 @@ void Texture::setNewConfig(u32 cfg) {
|
|||
|
||||
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];
|
||||
const auto wrapT = wrappingModes[getBits<8, 3>(cfg)];
|
||||
const auto wrapS = wrappingModes[getBits<12, 3>(cfg)];
|
||||
|
||||
texture.setMinFilter(minFilter);
|
||||
texture.setMagFilter(magFilter);
|
||||
|
@ -116,10 +118,10 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) {
|
|||
auto ptr = static_cast<const u8*>(data);
|
||||
u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8);
|
||||
|
||||
u8 alpha = Colour::convert4To8Bit(texel & 0xf);
|
||||
u8 b = Colour::convert4To8Bit((texel >> 4) & 0xf);
|
||||
u8 g = Colour::convert4To8Bit((texel >> 8) & 0xf);
|
||||
u8 r = Colour::convert4To8Bit((texel >> 12) & 0xf);
|
||||
u8 alpha = Colour::convert4To8Bit(getBits<0, 4>(texel));
|
||||
u8 b = Colour::convert4To8Bit(getBits<4, 4>(texel));
|
||||
u8 g = Colour::convert4To8Bit(getBits<8, 4>(texel));
|
||||
u8 r = Colour::convert4To8Bit(getBits<12, 4>(texel));
|
||||
|
||||
return (alpha << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
@ -129,10 +131,10 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) {
|
|||
auto ptr = static_cast<const u8*>(data);
|
||||
u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8);
|
||||
|
||||
u8 alpha = (texel & 1) ? 0xff : 0;
|
||||
u8 b = Colour::convert5To8Bit((texel >> 1) & 0x1f);
|
||||
u8 g = Colour::convert5To8Bit((texel >> 6) & 0x1f);
|
||||
u8 r = Colour::convert5To8Bit((texel >> 11) & 0x1f);
|
||||
u8 alpha = getBit<0>(texel) ? 0xff : 0;
|
||||
u8 b = Colour::convert5To8Bit(getBits<1, 5>(texel));
|
||||
u8 g = Colour::convert5To8Bit(getBits<6, 5>(texel));
|
||||
u8 r = Colour::convert5To8Bit(getBits<11, 5>(texel));
|
||||
|
||||
return (alpha << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
@ -142,9 +144,9 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) {
|
|||
auto ptr = static_cast<const u8*>(data);
|
||||
u16 texel = u16(ptr[offset]) | (u16(ptr[offset + 1]) << 8);
|
||||
|
||||
u8 b = Colour::convert5To8Bit(texel & 0x1f);
|
||||
u8 g = Colour::convert6To8Bit((texel >> 5) & 0x3f);
|
||||
u8 r = Colour::convert5To8Bit((texel >> 11) & 0x1f);
|
||||
u8 b = Colour::convert5To8Bit(getBits<0, 5>(texel));
|
||||
u8 g = Colour::convert6To8Bit(getBits<5, 6>(texel));
|
||||
u8 r = Colour::convert5To8Bit(getBits<11, 5>(texel));
|
||||
|
||||
return (0xff << 24) | (b << 16) | (g << 8) | r;
|
||||
}
|
||||
|
@ -201,7 +203,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) {
|
|||
|
||||
// For odd U coordinates, grab the top 4 bits, and the low 4 bits for even coordinates
|
||||
u8 alpha = ptr[offset] >> ((u % 2) ? 4 : 0);
|
||||
alpha = Colour::convert4To8Bit(alpha & 0xf);
|
||||
alpha = Colour::convert4To8Bit(getBits<0, 4>(alpha));
|
||||
|
||||
// A8 sets RGB to 0
|
||||
return (alpha << 24) | (0 << 16) | (0 << 8) | 0;
|
||||
|
@ -222,7 +224,7 @@ u32 Texture::decodeTexel(u32 u, u32 v, Texture::Formats fmt, const void* data) {
|
|||
|
||||
// For odd U coordinates, grab the top 4 bits, and the low 4 bits for even coordinates
|
||||
u8 intensity = ptr[offset] >> ((u % 2) ? 4 : 0);
|
||||
intensity = Colour::convert4To8Bit(intensity & 0xf);
|
||||
intensity = Colour::convert4To8Bit(getBits<0, 4>(intensity));
|
||||
|
||||
// Intensity formats just copy the intensity value to every colour channel
|
||||
return (0xff << 24) | (intensity << 16) | (intensity << 8) | intensity;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue