Fix a bunch of mipmap issues

This commit is contained in:
Luke Benstead 2019-09-24 21:26:17 +01:00
parent 2b53f50c46
commit e14db20a41
3 changed files with 43 additions and 27 deletions

View File

@ -1,4 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <assert.h>
#include "private.h" #include "private.h"
#include "../include/glkos.h" #include "../include/glkos.h"
#include "../include/glext.h" #include "../include/glext.h"
@ -156,37 +158,37 @@ GLboolean _glCalculateAverageTexel(const GLubyte* src, const GLuint srcWidth, co
if((pvrFormat & PVR_TXRFMT_ARGB1555) == PVR_TXRFMT_ARGB1555) { if((pvrFormat & PVR_TXRFMT_ARGB1555) == PVR_TXRFMT_ARGB1555) {
a = A1555(*s1) + A1555(*s2) + A1555(*s3) + A1555(*s4); a = A1555(*s1) + A1555(*s2) + A1555(*s3) + A1555(*s4);
r = R1555(*s1) + R1555(*s2) + R1555(*s3) + R1555(*s4); r = R1555(*s1) + R1555(*s2) + R1555(*s3) + R1555(*s4);
g = G1555(*s1) + R1555(*s2) + R1555(*s3) + R1555(*s4); g = G1555(*s1) + G1555(*s2) + G1555(*s3) + G1555(*s4);
b = B1555(*s1) + R1555(*s2) + R1555(*s3) + R1555(*s4); b = B1555(*s1) + B1555(*s2) + B1555(*s3) + B1555(*s4);
a /= 4; a /= 4;
r /= 4; r /= 4;
g /= 4; g /= 4;
b /= 4; b /= 4;
*d1 = (a << 15 | r << 10 | g << 5 | b); *d1 = PACK_ARGB1555(a, r, g, b);
} else if((pvrFormat & PVR_TXRFMT_ARGB4444) == PVR_TXRFMT_ARGB4444) { } else if((pvrFormat & PVR_TXRFMT_ARGB4444) == PVR_TXRFMT_ARGB4444) {
a = A4444(*s1) + A4444(*s2) + A4444(*s3) + A4444(*s4); a = A4444(*s1) + A4444(*s2) + A4444(*s3) + A4444(*s4);
r = R4444(*s1) + R4444(*s2) + R4444(*s3) + R4444(*s4); r = R4444(*s1) + R4444(*s2) + R4444(*s3) + R4444(*s4);
g = G4444(*s1) + R4444(*s2) + R4444(*s3) + R4444(*s4); g = G4444(*s1) + G4444(*s2) + G4444(*s3) + G4444(*s4);
b = B4444(*s1) + R4444(*s2) + R4444(*s3) + R4444(*s4); b = B4444(*s1) + B4444(*s2) + B4444(*s3) + B4444(*s4);
a /= 4; a /= 4;
r /= 4; r /= 4;
g /= 4; g /= 4;
b /= 4; b /= 4;
*d1 = (a << 12 | r << 8 | g << 4 | b); *d1 = PACK_ARGB4444(a, r, g, b);
} else if((pvrFormat & PVR_TXRFMT_RGB565) == PVR_TXRFMT_ARGB4444) { } else if((pvrFormat & PVR_TXRFMT_RGB565) == PVR_TXRFMT_RGB565) {
r = R565(*s1) + R565(*s2) + R565(*s3) + R565(*s4); r = R565(*s1) + R565(*s2) + R565(*s3) + R565(*s4);
g = G565(*s1) + R565(*s2) + R565(*s3) + R565(*s4); g = G565(*s1) + G565(*s2) + G565(*s3) + G565(*s4);
b = B565(*s1) + R565(*s2) + R565(*s3) + R565(*s4); b = B565(*s1) + B565(*s2) + B565(*s3) + B565(*s4);
r /= 4; r /= 4;
g /= 4; g /= 4;
b /= 4; b /= 4;
*d1 = (r << 11 | g << 5 | b); *d1 = PACK_RGB565(r, g, b);
} else { } else {
fprintf(stderr, "ERROR: Unsupported PVR format for mipmap generation"); fprintf(stderr, "ERROR: Unsupported PVR format for mipmap generation");
_glKosThrowError(GL_INVALID_OPERATION, __func__); _glKosThrowError(GL_INVALID_OPERATION, __func__);
@ -239,7 +241,6 @@ void APIENTRY glGenerateMipmapEXT(GLenum target) {
GLuint thisWidth = (prevWidth > 1) ? prevWidth / 2 : 1; GLuint thisWidth = (prevWidth > 1) ? prevWidth / 2 : 1;
GLuint thisHeight = (prevHeight > 1) ? prevHeight / 2 : 1; GLuint thisHeight = (prevHeight > 1) ? prevHeight / 2 : 1;
/* Do the minification */
for(sx = 0, dx = 0; sx < prevWidth; sx += 2, dx += 1) { for(sx = 0, dx = 0; sx < prevWidth; sx += 2, dx += 1) {
for(sy = 0, dy = 0; sy < prevHeight; sy += 2, dy += 1) { for(sy = 0, dy = 0; sy < prevHeight; sy += 2, dy += 1) {
GLubyte* srcTexel = &prevData[ GLubyte* srcTexel = &prevData[
@ -266,6 +267,8 @@ void APIENTRY glGenerateMipmapEXT(GLenum target) {
prevWidth = thisWidth; prevWidth = thisWidth;
prevHeight = thisHeight; prevHeight = thisHeight;
} }
assert(_glIsMipmapComplete(tex));
} }
GLenum APIENTRY glCheckFramebufferStatusEXT(GLenum target) { GLenum APIENTRY glCheckFramebufferStatusEXT(GLenum target) {

View File

@ -15,6 +15,14 @@
#define FASTCPY(dst, src, bytes) \ #define FASTCPY(dst, src, bytes) \
(bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy(dst, src, bytes); (bytes % 32 == 0) ? sq_cpy(dst, src, bytes) : memcpy(dst, src, bytes);
#define _PACK4(v) ((v * 0xF) / 0xFF)
#define PACK_ARGB4444(a,r,g,b) (_PACK4(a) << 12) | (_PACK4(r) << 8) | (_PACK4(g) << 4) | (_PACK4(b))
#define PACK_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) )
#define PACK_ARGB1555(a,r,g, b) \
(a > 0 | (r >> 3) << 10 | (g >> 3) << 5 | (b >> 3))
#define PACK_RGB565(r,g,b) \
((r >> 3) << 15 | (g >> 2) << 11 | b >> 3)
#define TRACE_ENABLED 0 #define TRACE_ENABLED 0
#define TRACE() if(TRACE_ENABLED) {fprintf(stderr, "%s\n", __func__);} #define TRACE() if(TRACE_ENABLED) {fprintf(stderr, "%s\n", __func__);}

View File

@ -23,12 +23,6 @@ static TexturePalette* SHARED_PALETTES[4] = {NULL, NULL, NULL, NULL};
static GLuint _determinePVRFormat(GLint internalFormat, GLenum type); static GLuint _determinePVRFormat(GLint internalFormat, GLenum type);
#define PACK_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) )
#define _PACK4(v) ((v * 0xF) / 0xFF)
#define PACK_ARGB4444(a,r,g,b) (_PACK4(a) << 12) | (_PACK4(r) << 8) | (_PACK4(g) << 4) | (_PACK4(b))
static GLboolean BANKS_USED[4]; // Each time a 256 colour bank is used, this is set to true static GLboolean BANKS_USED[4]; // Each time a 256 colour bank is used, this is set to true
static GLboolean SUBBANKS_USED[4][16]; // 4 counts of the used 16 colour banks within the 256 ones static GLboolean SUBBANKS_USED[4][16]; // 4 counts of the used 16 colour banks within the 256 ones
static GLenum INTERNAL_PALETTE_FORMAT = GL_RGBA4; static GLenum INTERNAL_PALETTE_FORMAT = GL_RGBA4;
@ -172,37 +166,48 @@ static GLuint _glGetMipmapDataOffset(TextureObject* obj, GLuint level) {
if(obj->isPaletted){ if(obj->isPaletted){
switch(size >> level) { switch(size >> level) {
case 1024:
offset = 0x15556;
break;
case 512:
offset = 0x05556;
break;
case 256: case 256:
offset = 0x05558; offset = 0x01556;
break; break;
case 128: case 128:
offset = 0x01558; offset = 0x00556;
break; break;
case 64: case 64:
offset = 0x00558; offset = 0x00156;
break; break;
case 32: case 32:
offset = 0x00158; offset = 0x00056;
break; break;
case 16: case 16:
offset = 0x00058; offset = 0x00016;
break; break;
case 8: case 8:
offset = 0x00018; offset = 0x00006;
break; break;
case 4: case 4:
offset = 0x00008; offset = 0x00002;
break; break;
case 2: case 2:
offset = 0x00004; offset = 0x00001;
break; break;
case 1: case 1:
case 0:
offset = 0x00000; offset = 0x00000;
break; break;
} }
} else { } else {
switch(size >> level) { switch(size >> level) {
case 1024:
offset = 0xAAAB0;
break;
case 512:
offset = 0x2AAB0;
break;
case 256: case 256:
offset = 0x0AAB0; offset = 0x0AAB0;
break; break;
@ -248,7 +253,7 @@ static GLuint _glGetMipmapDataSize(TextureObject* obj) {
/* The mipmap data size is the offset + the size of the /* The mipmap data size is the offset + the size of the
* image */ * image */
GLuint imageSize = obj->width * obj->height * obj->dataStride; GLuint imageSize = obj->baseDataSize;
GLuint offset = _glGetMipmapDataOffset(obj, 0); GLuint offset = _glGetMipmapDataOffset(obj, 0);
return imageSize + offset; return imageSize + offset;