Skip to content

Commit

Permalink
Add pure luminance and alpha textures
Browse files Browse the repository at this point in the history
There should be a difference between these two, but for now we lack a
test case. At the moment they both act as alpha textures.
  • Loading branch information
mardy committed May 23, 2024
1 parent 9832564 commit 12d9d6b
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 3 deletions.
21 changes: 18 additions & 3 deletions src/gc_gl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1458,6 +1458,14 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
} else if (internalFormat == GL_LUMINANCE_ALPHA) {
bytesperpixelinternal = 2;
gx_format = GX_TF_IA8;
} else if (internalFormat == GL_LUMINANCE) {
bytesperpixelinternal = 1;
gx_format = GX_TF_I8;
} else if (internalFormat == GL_ALPHA) {
bytesperpixelinternal = 1;
/* GX_TF_A8 is not supported by Dolphin and if not properly handed by a
* real Wii either. */
gx_format = GX_TF_I8;
} else {
gx_format = GX_TF_CMPR;
}
Expand Down Expand Up @@ -1534,7 +1542,9 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
// Inconditionally convert to 565 all inputs without alpha channel
// Alpha inputs may be stripped if the user specifies an alpha-free internal format
if (bytesperpixelinternal > 0) {
unsigned char *tempbuf = malloc(width * height * bytesperpixelinternal);
/* Add pixels on each direction so that the scrambling functions can
* read whole 4x4 (or 8x4) tiles without bound checking */
unsigned char *tempbuf = malloc((width + 7) * (height + 3) * bytesperpixelinternal);
if (!tempbuf) {
warning("Failed to allocate memory for texture (%d)", errno);
set_error(GL_OUT_OF_MEMORY);
Expand All @@ -1557,10 +1567,13 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
} else if (internalFormat == GL_LUMINANCE_ALPHA) {
_ogx_conv_luminance_alpha_to_ia8(data, type, tempbuf, width, height);
}
} else if (format == GL_ALPHA || format == GL_LUMINANCE) {
_ogx_conv_intensity_to_i8(data, type, tempbuf, width, height);
}

// Swap R<->B if necessary
if (needswap && internalFormat != GL_LUMINANCE_ALPHA) {
if (needswap && bytesperpixelinternal > 1 &&
internalFormat != GL_LUMINANCE_ALPHA) {
if (bytesperpixelinternal == 4)
_ogx_swap_rgba(tempbuf, width * height);
else
Expand All @@ -1575,8 +1588,10 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
// Finally write to the dest. buffer scrambling the data
if (bytesperpixelinternal == 4) {
_ogx_scramble_4b(tempbuf, dst_addr, width, height);
} else {
} else if (bytesperpixelinternal == 2) {
_ogx_scramble_2b((unsigned short *)tempbuf, dst_addr, width, height);
} else if (bytesperpixelinternal == 1) {
_ogx_scramble_1b(tempbuf, dst_addr, width, height);
}
free(tempbuf);

Expand Down
44 changes: 44 additions & 0 deletions src/pixels.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "debug.h"
#include <math.h>
#include <string.h>
#include <sys/param.h>

#define FLOAT_TO_BYTE(f) ((GLbyte)(f * 255.0) & 0xff)

Expand Down Expand Up @@ -164,6 +165,32 @@ void _ogx_conv_rgba_to_rgba32(const void *data, GLenum type,
}
}

static void conv_intensityf_to_i8(const float *src, void *dst, int numpixels)
{
uint32_t *out = dst;
while (numpixels--) {
*out++ = FLOAT_TO_BYTE(src[0]);
src++;
}
}

void _ogx_conv_intensity_to_i8(const void *data, GLenum type,
void *dest, int width, int height)
{
int numpixels = width * height;
switch (type) {
case GL_BYTE:
case GL_UNSIGNED_BYTE:
memcpy(dest, data, numpixels);
break;
case GL_FLOAT:
conv_intensityf_to_i8(data, dest, numpixels);
break;
default:
warning("Unsupported texture format %d", type);
}
}

static void conv_laf_to_ia8(const float *src, void *dst, int numpixels)
{
uint16_t *out = dst;
Expand Down Expand Up @@ -206,6 +233,23 @@ void _ogx_conv_rgba_to_luminance_alpha(unsigned char *src, void *dst,
}

// 4x4 tile scrambling
/* 1b texel scrambling */
void _ogx_scramble_1b(void *src, void *dst, int width, int height)
{
uint64_t *s = src;
uint64_t *p = dst;

int width_blocks = (width + 7) / 8;
for (int y = 0; y < height; y += 4) {
int rows = MIN(height - y, 4);
for (int x = 0; x < width_blocks; x++) {
for (int row = 0; row < rows; row++) {
*p++ = s[(y + row) * width_blocks + x];
}
}
}
}

// 2b texel scrambling
void _ogx_scramble_2b(unsigned short *src, void *dst,
const unsigned int width, const unsigned int height)
Expand Down
3 changes: 3 additions & 0 deletions src/pixels.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ void _ogx_conv_luminance_alpha_to_ia8(const void *data, GLenum type,
void *dest, int width, int height);
void _ogx_conv_rgba_to_luminance_alpha(unsigned char *src, void *dst,
const unsigned int width, const unsigned int height);
void _ogx_conv_intensity_to_i8(const void *data, GLenum type,
void *dest, int width, int height);
void _ogx_scramble_1b(void *src, void *dst, int width, int height);
void _ogx_scramble_2b(unsigned short *src, void *dst,
const unsigned int width, const unsigned int height);
void _ogx_scramble_4b(unsigned char *src, void *dst,
Expand Down

0 comments on commit 12d9d6b

Please sign in to comment.