16bit palette color format support, extended 64 shared palette slots (4bpp), GL_OES_compressed_paletted_texture support

GL_ERROR generated when texture size > 1024
This commit is contained in:
OzzyOuzo 2021-12-03 09:32:53 +02:00
parent 8caee68df5
commit 1a456cb1a7
8 changed files with 375 additions and 99 deletions

View File

@ -1333,7 +1333,7 @@ GLuint _glGetActiveClientTexture() {
void APIENTRY glClientActiveTextureARB(GLenum texture) {
TRACE();
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) {
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_GLDC_TEXTURE_UNITS) {
_glKosThrowError(GL_INVALID_ENUM, __func__);
return;
}

View File

@ -46,7 +46,7 @@ void APIENTRY glKosInitConfig(GLdcConfig* config) {
config->initial_pt_capacity = 512 * 3;
config->initial_tr_capacity = 1024 * 3;
config->initial_immediate_capacity = 1024 * 3;
config->internal_palette_format = GL_RGBA4;
config->internal_palette_format = GL_RGBA8;
}
void APIENTRY glKosInitEx(GLdcConfig* config) {

View File

@ -27,7 +27,7 @@ static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE;
static GLenum COLOR_MATERIAL_MASK = AMBIENT_MASK | DIFFUSE_MASK;
static LightSource LIGHTS[MAX_LIGHTS];
static LightSource LIGHTS[MAX_GLDC_LIGHTS];
static GLuint ENABLED_LIGHT_COUNT = 0;
static Material MATERIAL;
@ -37,7 +37,7 @@ static void recalcEnabledLights() {
GLubyte i;
ENABLED_LIGHT_COUNT = 0;
for(i = 0; i < MAX_LIGHTS; ++i) {
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
if(LIGHTS[i].isEnabled) {
ENABLED_LIGHT_COUNT++;
}
@ -57,7 +57,7 @@ void _glInitLights() {
MATERIAL.exponent = 0.0f;
GLubyte i;
for(i = 0; i < MAX_LIGHTS; ++i) {
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
memcpy(LIGHTS[i].ambient, ZERO, sizeof(GLfloat) * 4);
memcpy(LIGHTS[i].diffuse, ONE, sizeof(GLfloat) * 4);
memcpy(LIGHTS[i].specular, ONE, sizeof(GLfloat) * 4);
@ -97,7 +97,7 @@ GL_FORCE_INLINE void _glPrecalcLightingValues(GLuint mask) {
GLshort i;
if(mask & AMBIENT_MASK) {
for(i = 0; i < MAX_LIGHTS; ++i) {
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
LIGHTS[i].ambientMaterial[0] = LIGHTS[i].ambient[0] * MATERIAL.ambient[0];
LIGHTS[i].ambientMaterial[1] = LIGHTS[i].ambient[1] * MATERIAL.ambient[1];
LIGHTS[i].ambientMaterial[2] = LIGHTS[i].ambient[2] * MATERIAL.ambient[2];
@ -106,7 +106,7 @@ GL_FORCE_INLINE void _glPrecalcLightingValues(GLuint mask) {
}
if(mask & DIFFUSE_MASK) {
for(i = 0; i < MAX_LIGHTS; ++i) {
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
LIGHTS[i].diffuseMaterial[0] = LIGHTS[i].diffuse[0] * MATERIAL.diffuse[0];
LIGHTS[i].diffuseMaterial[1] = LIGHTS[i].diffuse[1] * MATERIAL.diffuse[1];
LIGHTS[i].diffuseMaterial[2] = LIGHTS[i].diffuse[2] * MATERIAL.diffuse[2];
@ -115,7 +115,7 @@ GL_FORCE_INLINE void _glPrecalcLightingValues(GLuint mask) {
}
if(mask & SPECULAR_MASK) {
for(i = 0; i < MAX_LIGHTS; ++i) {
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
LIGHTS[i].specularMaterial[0] = LIGHTS[i].specular[0] * MATERIAL.specular[0];
LIGHTS[i].specularMaterial[1] = LIGHTS[i].specular[1] * MATERIAL.specular[1];
LIGHTS[i].specularMaterial[2] = LIGHTS[i].specular[2] * MATERIAL.specular[2];
@ -173,7 +173,7 @@ void APIENTRY glLightModeliv(GLenum pname, const GLint* params) {
void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) {
GLubyte idx = light & 0xF;
if(idx >= MAX_LIGHTS) {
if(idx >= MAX_GLDC_LIGHTS) {
return;
}
@ -227,7 +227,7 @@ void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) {
void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param) {
GLubyte idx = light & 0xF;
if(idx >= MAX_LIGHTS) {
if(idx >= MAX_GLDC_LIGHTS) {
return;
}
@ -495,7 +495,7 @@ void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const uint32_t count
const float Ny = data->n[1];
const float Nz = data->n[2];
for(i = 0; i < MAX_LIGHTS; ++i) {
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
if(!LIGHTS[i].isEnabled) {
continue;
}

View File

@ -14,6 +14,11 @@
#include "../containers/aligned_vector.h"
#include "../containers/named_array.h"
#define MAX_GLDC_4BPP_PALETTE_SLOTS 16
#define MAX_GLDC_PALETTE_SLOTS 4
#define MAX_GLDC_SHARED_PALETTES (MAX_GLDC_PALETTE_SLOTS*MAX_GLDC_4BPP_PALETTE_SLOTS)
extern void* memcpy4 (void *dest, const void *src, size_t count);
#define GL_NO_INSTRUMENT inline __attribute__((no_instrument_function))
@ -508,8 +513,8 @@ GLuint _glFreeContiguousTextureMemory();
void _glApplyScissor(bool force);
#define MAX_TEXTURE_UNITS 2
#define MAX_LIGHTS 8
#define MAX_GLDC_TEXTURE_UNITS 2
#define MAX_GLDC_LIGHTS 8
/* This is from KOS pvr_buffers.c */
#define PVR_MIN_Z 0.0001f

View File

@ -236,8 +236,14 @@ void _glUpdatePVRTextureContext(PolyContext *context, GLshort textureUnit) {
if(tx1->isPaletted) {
if(_glIsSharedTexturePaletteEnabled()) {
TexturePalette* palette = _glGetSharedPalette(tx1->shared_bank);
context->txr.format |= GPUPaletteSelect8BPP(palette->bank);
} else {
if (palette->size != 16){
context->txr.format |= GPUPaletteSelect8BPP(palette->bank);
}
else{
context->txr.format |= GPUPaletteSelect4BPP(palette->bank);
}
}
else {
if (tx1->palette->size != 16){
context->txr.format |= GPUPaletteSelect8BPP((tx1->palette) ? tx1->palette->bank : 0);
}
@ -295,7 +301,7 @@ void _glInitContext() {
glDisable(GL_LIGHTING);
GLubyte i;
for(i = 0; i < MAX_LIGHTS; ++i) {
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
glDisable(GL_LIGHT0 + i);
}
}
@ -719,7 +725,7 @@ void APIENTRY glGetFloatv(GLenum pname, GLfloat* params) {
void APIENTRY glGetIntegerv(GLenum pname, GLint *params) {
switch(pname) {
case GL_MAX_LIGHTS:
*params = MAX_LIGHTS;
*params = MAX_GLDC_LIGHTS;
break;
case GL_TEXTURE_BINDING_2D:
*params = (_glGetBoundTexture()) ? _glGetBoundTexture()->index : 0;
@ -779,7 +785,7 @@ const GLubyte *glGetString(GLenum name) {
return (const GLubyte*) "1.2 (partial) - GLdc 1.1";
case GL_EXTENSIONS:
return (const GLubyte*) "GL_ARB_framebuffer_object, GL_ARB_multitexture, GL_ARB_texture_rg, GL_EXT_paletted_texture, GL_EXT_shared_texture_palette, GL_KOS_multiple_shared_palette, GL_ARB_vertex_array_bgra, GL_ARB_vertex_type_2_10_10_10_rev, GL_KOS_texture_memory_management, GL_ATI_meminfo";
return (const GLubyte*)"GL_ARB_framebuffer_object, GL_ARB_multitexture, GL_ARB_texture_rg, GL_OES_compressed_paletted_texture,GL_EXT_paletted_texture, GL_EXT_shared_texture_palette, GL_KOS_multiple_shared_palette, GL_ARB_vertex_array_bgra, GL_ARB_vertex_type_2_10_10_10_rev, GL_KOS_texture_memory_management, GL_ATI_meminfo";
}
return (const GLubyte*) "GL_KOS_ERROR: ENUM Unsupported\n";

View File

@ -18,17 +18,18 @@
#define CLAMP_U (1<<1)
#define CLAMP_V (1<<0)
static TextureObject* TEXTURE_UNITS[MAX_TEXTURE_UNITS] = {NULL, NULL};
static TextureObject* TEXTURE_UNITS[MAX_GLDC_TEXTURE_UNITS] = {NULL, NULL};
static NamedArray TEXTURE_OBJECTS;
GLubyte ACTIVE_TEXTURE = 0;
static TexturePalette* SHARED_PALETTES[4] = {NULL, NULL, NULL, NULL};
static TexturePalette* SHARED_PALETTES[MAX_GLDC_SHARED_PALETTES];
static GLuint _determinePVRFormat(GLint internalFormat, GLenum type);
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 GLenum INTERNAL_PALETTE_FORMAT = GL_RGBA4;
static GLboolean BANKS_USED[MAX_GLDC_PALETTE_SLOTS]; // Each time a 256 colour bank is used, this is set to true
static GLboolean SUBBANKS_USED[MAX_GLDC_PALETTE_SLOTS][MAX_GLDC_4BPP_PALETTE_SLOTS]; // 4 counts of the used 16 colour banks within the 256 ones
static GLenum INTERNAL_PALETTE_FORMAT = GL_RGBA8;
static void* YALLOC_BASE = NULL;
static size_t YALLOC_SIZE = 0;
@ -63,20 +64,21 @@ static GLshort _glGenPaletteSlot(GLushort size) {
assert(size == 16 || size == 256);
if(size == 16) {
for(i = 0; i < 4; ++i) {
for(j = 0; j < 16; ++j) {
for(i = 0; i < MAX_GLDC_PALETTE_SLOTS; ++i) {
for(j = 0; j < MAX_GLDC_4BPP_PALETTE_SLOTS; ++j) {
if(!SUBBANKS_USED[i][j]) {
BANKS_USED[i] = GL_TRUE;
SUBBANKS_USED[i][j] = GL_TRUE;
return (i * 16) + j;
return (i * MAX_GLDC_4BPP_PALETTE_SLOTS) + j;
}
}
}
} else {
for(i = 0; i < 4; ++i) {
}
else {
for(i = 0; i < MAX_GLDC_PALETTE_SLOTS; ++i) {
if(!BANKS_USED[i]) {
BANKS_USED[i] = GL_TRUE;
for(j = 0; j < 16; ++j) {
for(j = 0; j < MAX_GLDC_4BPP_PALETTE_SLOTS; ++j) {
SUBBANKS_USED[i][j] = GL_TRUE;
}
return i;
@ -87,6 +89,7 @@ static GLshort _glGenPaletteSlot(GLushort size) {
fprintf(stderr, "GL ERROR: No palette slots remain\n");
return -1;
}
/* ozzy: used for statistics */
GLushort _glFreePaletteSlots(GLushort size)
{
@ -95,15 +98,15 @@ GLushort _glFreePaletteSlots(GLushort size)
assert(size == 16 || size == 256);
if(size == 16) {
for(i = 0; i < 4; ++i) {
for(j = 0; j < 16; ++j) {
for(i = 0; i < MAX_GLDC_PALETTE_SLOTS; ++i) {
for(j = 0; j < MAX_GLDC_4BPP_PALETTE_SLOTS; ++j) {
if(!SUBBANKS_USED[i][j]) {
slots++;
}
}
}
} else {
for(i = 0; i < 4; ++i) {
for(i = 0; i < MAX_GLDC_PALETTE_SLOTS; ++i) {
if(!BANKS_USED[i]) {
slots++;
}
@ -113,25 +116,29 @@ GLushort _glFreePaletteSlots(GLushort size)
return slots;
}
static void _glReleasePaletteSlot(GLshort slot, GLushort size) {
GLushort i;
static void _glReleasePaletteSlot(GLshort slot, GLushort size)
{
GLushort i, j;
assert(size == 16 || size == 256);
if(size == 16) {
GLushort bank = slot / 4;
GLushort subbank = slot % 4;
if (size == 16) {
GLushort bank = slot / MAX_GLDC_PALETTE_SLOTS;
GLushort subbank = slot % MAX_GLDC_PALETTE_SLOTS;
SUBBANKS_USED[bank][subbank] = GL_FALSE;
for(i = 0; i < 16; ++i) {
if(SUBBANKS_USED[bank][i]) {
for (i = 0; i < MAX_GLDC_4BPP_PALETTE_SLOTS; ++i) {
if (SUBBANKS_USED[bank][i]) {
return;
}
}
BANKS_USED[bank] = GL_FALSE;
} else {
}
else {
BANKS_USED[slot] = GL_FALSE;
for(i = 0; i < 16; ++i) {
for (i = 0; i < MAX_GLDC_4BPP_PALETTE_SLOTS; ++i) {
SUBBANKS_USED[slot][i] = GL_FALSE;
}
}
@ -221,27 +228,31 @@ static void GPUTextureTwiddle16BPP(void * src, void* dst, uint32_t w, uint32_t h
}
TexturePalette* _glGetSharedPalette(GLshort bank) {
assert(bank >= 0 && bank < 4);
assert(bank >= 0 && bank < MAX_GLDC_SHARED_PALETTES);
return SHARED_PALETTES[bank];
}
void _glSetInternalPaletteFormat(GLenum val) {
INTERNAL_PALETTE_FORMAT = val;
if(INTERNAL_PALETTE_FORMAT == GL_RGBA4) {
GPUSetPaletteFormat(GPU_PAL_ARGB4444);
} else {
assert(INTERNAL_PALETTE_FORMAT == GL_RGBA8);
GPUSetPaletteFormat(GPU_PAL_ARGB8888);
switch(INTERNAL_PALETTE_FORMAT){
case GL_RGBA8:
GPUSetPaletteFormat(GPU_PAL_ARGB8888);
break;
case GL_RGBA4:
GPUSetPaletteFormat(GPU_PAL_ARGB4444);
break;
case GL_RGB5_A1:
GPUSetPaletteFormat(GPU_PAL_ARGB1555);
break;
case GL_RGB565_KOS:
GPUSetPaletteFormat(GPU_PAL_RGB565);
break;
default:
assert(0);
}
}
void _glApplyColorTable(TexturePalette* src) {
/*
* FIXME:
*
* - Different palette formats (GL_RGB -> PVR_PAL_RGB565)
*/
if(!src || !src->data) {
return;
}
@ -251,10 +262,21 @@ void _glApplyColorTable(TexturePalette* src) {
for(i = 0; i < src->width; ++i) {
GLubyte* entry = &src->data[i * 4];
if(INTERNAL_PALETTE_FORMAT == GL_RGBA8) {
GPUSetPaletteEntry(offset + i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2]));
} else {
GPUSetPaletteEntry(offset + i, PACK_ARGB4444(entry[3], entry[0], entry[1], entry[2]));
switch(INTERNAL_PALETTE_FORMAT)
{
case GL_RGBA8:
GPUSetPaletteEntry(offset + i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2]));
break;
case GL_RGBA4:
GPUSetPaletteEntry(offset + i, PACK_ARGB4444(entry[3], entry[0], entry[1], entry[2]));
break;
case GL_RGB5_A1:
GPUSetPaletteEntry(offset + i, PACK_ARGB1555(entry[3], entry[0], entry[1], entry[2]));
break;
case GL_RGB565_KOS:
GPUSetPaletteEntry(offset + i, PACK_RGB565(entry[0], entry[1], entry[2]));
break;
}
}
}
@ -289,8 +311,6 @@ static GLuint _glGetMipmapDataOffset(const TextureObject* obj, GLuint level) {
GLuint offset = 0;
GLuint size = obj->height;
printf("\n_glGetMipmapDataOffset");
if(obj->width != obj->height) {
fprintf(stderr, "ERROR: Accessing memory location of mipmaps on non-square texture\n");
return obj->baseDataOffset;
@ -428,15 +448,17 @@ static GLuint _glGetMipmapDataSize(TextureObject* obj) {
}
GLubyte _glInitTextures() {
uint32_t i;
named_array_init(&TEXTURE_OBJECTS, sizeof(TextureObject), MAX_TEXTURE_COUNT);
// Reserve zero so that it is never given to anyone as an ID!
named_array_reserve(&TEXTURE_OBJECTS, 0);
SHARED_PALETTES[0] = _initTexturePalette();
SHARED_PALETTES[1] = _initTexturePalette();
SHARED_PALETTES[2] = _initTexturePalette();
SHARED_PALETTES[3] = _initTexturePalette();
for (i=0; i < MAX_GLDC_SHARED_PALETTES;i++){
SHARED_PALETTES[i] = _initTexturePalette();
}
memset((void*) BANKS_USED, 0x0, sizeof(BANKS_USED));
memset((void*) SUBBANKS_USED, 0x0, sizeof(SUBBANKS_USED));
@ -469,7 +491,7 @@ TextureObject* _glGetBoundTexture() {
void APIENTRY glActiveTextureARB(GLenum texture) {
TRACE();
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) {
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_GLDC_TEXTURE_UNITS) {
_glKosThrowError(GL_INVALID_ENUM, "glActiveTextureARB");
return;
}
@ -539,6 +561,11 @@ void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) {
}
if(txr->palette && txr->palette->data) {
if (txr->palette->bank > -1) {
_glReleasePaletteSlot(txr->palette->bank, txr->palette->size);
txr->palette->bank = -1;
}
free(txr->palette->data);
txr->palette->data = NULL;
}
@ -679,6 +706,8 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target,
}
GLboolean mipmapped = GL_FALSE;
//GLboolean paletted = GL_FALSE;
GLbyte *ptr = (GLbyte*)data;
switch(internalFormat) {
case GL_COMPRESSED_ARGB_1555_VQ_KOS:
@ -696,6 +725,50 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target,
case GL_COMPRESSED_RGB_565_VQ_MIPMAP_TWID_KOS:
mipmapped = GL_TRUE;
break;
case GL_PALETTE4_RGB8_OES:
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 16, internalFormat, GL_UNSIGNED_BYTE, data);
ptr += 16*3;
glTexImage2D(GL_TEXTURE_2D, level, GL_COLOR_INDEX4_EXT, width, height, border, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ptr);
return;
case GL_PALETTE4_RGBA8_OES:
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 16, internalFormat, GL_UNSIGNED_BYTE, data);
ptr += 16*4;
glTexImage2D(GL_TEXTURE_2D, level, GL_COLOR_INDEX4_EXT, width, height, border, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ptr);
return;
case GL_PALETTE4_R5_G6_B5_OES:
case GL_PALETTE4_RGBA4_OES:
case GL_PALETTE4_RGB5_A1_OES:
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 16, internalFormat, GL_UNSIGNED_BYTE, data);
ptr += 16*2;
glTexImage2D(GL_TEXTURE_2D, level, GL_COLOR_INDEX4_EXT, width, height, border, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ptr);
return;
case GL_PALETTE8_RGB8_OES:
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, internalFormat, GL_UNSIGNED_BYTE, data);
ptr += 256*3;
glTexImage2D(GL_TEXTURE_2D, level, GL_COLOR_INDEX8_EXT, width, height, border, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ptr);
return;
case GL_PALETTE8_RGBA8_OES:
//
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, internalFormat, GL_UNSIGNED_BYTE, data);
ptr += 256*4;
glTexImage2D(GL_TEXTURE_2D, level, GL_COLOR_INDEX8_EXT, width, height, border, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ptr);
return;
case GL_PALETTE8_RGBA4_OES:
case GL_PALETTE8_RGB5_A1_OES:
case GL_PALETTE8_R5_G6_B5_OES:
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, internalFormat, GL_UNSIGNED_BYTE, data);
ptr += 256*2;
glTexImage2D(GL_TEXTURE_2D, level, GL_COLOR_INDEX8_EXT, width, height, border, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ptr);
return;
default: {
_glKosThrowError(GL_INVALID_OPERATION, __func__);
return;
@ -887,9 +960,21 @@ static GLint _cleanInternalFormat(GLint internalFormat) {
typedef void (*TextureConversionFunc)(const GLubyte*, GLubyte*);
GL_FORCE_INLINE void _rgba8888_to_argb4444(const GLubyte* source, GLubyte* dest) {
*((GLushort*) dest) = (source[3] & 0xF0) << 8 | (source[0] & 0xF0) << 4 | (source[1] & 0xF0) | (source[2] & 0xF0) >> 4;
*((GLushort*) dest) = (source[1] & 0xF0) << 8 | (source[2] & 0xF0) << 4 | (source[0] & 0xF0) | (source[3] & 0xF0) >> 4;
}
GL_FORCE_INLINE void _rgba8888_to_rgba4444(const GLubyte* source, GLubyte* dest) {
*((GLushort*) dest) = (source[3] & 0xF0) << 8 | (source[2] & 0xF0) << 4 | (source[1] & 0xF0) | (source[0] & 0xF0) >> 4;
}
GL_FORCE_INLINE void _rgb888_to_argb4444(const GLubyte* source, GLubyte* dest) {
*((GLushort*) dest) = 0xF << 8 | (source[0] & 0xF0) << 4 | (source[1] & 0xF0) | (source[2] & 0xF0) >> 4;
}
GL_FORCE_INLINE void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
/* Noop */
GLubyte* dst = (GLubyte*) dest;
@ -899,7 +984,15 @@ GL_FORCE_INLINE void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest)
dst[3] = source[3];
}
GL_FORCE_INLINE void _rgba4444_to_rgba4444(const GLubyte* source, GLubyte* dest) {
/* Noop */
GLubyte* dst = (GLubyte*) dest;
dst[0] = source[0];
dst[1] = source[1];
}
GL_FORCE_INLINE void _rgba8888_to_rgb565(const GLubyte* source, GLubyte* dest) {
*((GLushort*) dest) = ((source[0] & 0b11111000) << 8) | ((source[1] & 0b11111100) << 3) | (source[2] >> 3);
}
@ -912,10 +1005,24 @@ GL_FORCE_INLINE void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
dst[3] = 255;
}
GL_FORCE_INLINE void _rgb888_to_rgba4444(const GLubyte* source, GLubyte* dest) {
/* Noop */
*((GLushort*) dest) = 0xF << 8 | (source[2] & 0xF0) << 4 | (source[1] & 0xF0) | (source[0] & 0xF0) >> 4;
}
GL_FORCE_INLINE void _rgb888_to_rgb565(const GLubyte* source, GLubyte* dest) {
*((GLushort*) dest) = ((source[0] & 0b11111000) << 8) | ((source[1] & 0b11111100) << 3) | (source[2] >> 3);
}
GL_FORCE_INLINE void _rgb565_to_rgb8888(const GLubyte* source, GLubyte* dest) {
GLushort src = *((GLushort*) source);
dest[3] = (src&0x1f)<<3;
dest[2] = ((src>>5)&0x3f)<<2;
dest[1] = ((src>>11)&0x1f)<<3;
dest[0] = 0xff;
}
GL_FORCE_INLINE void _rgba8888_to_a000(const GLubyte* source, GLubyte* dest) {
*((GLushort*) dest) = ((source[3] & 0b11111000) << 8);
}
@ -933,12 +1040,23 @@ GL_FORCE_INLINE void _rgba4444_to_rgba8888(const GLubyte* source, GLubyte* dest)
GLushort src = *((GLushort*) source);
GLubyte* dst = (GLubyte*) dest;
dst[0] = ((src & 0xF000) >> 12) * 2;
dst[1] = ((src & 0x0F00) >> 8) * 2;
dst[2] = ((src & 0x00F0) >> 4) * 2;
dst[3] = ((src & 0x000F)) * 2;
dst[0] = (src&0xf)<<4;
dst[1] = ((src>>4)&0xf) << 4;
dst[2] = ((src>>8)&0xf) << 4;
dst[3] = (src>>12) << 4;
}
GL_FORCE_INLINE void _rgba5551_to_rgba8888(const GLubyte* source, GLubyte* dest) {
GLushort src = *((GLushort*) source);
GLubyte* dst = (GLubyte*) dest;
dst[0] = (src&0x1f)<<3;
dst[1] = ((src>>5)&0x1f) << 3;
dst[2] = ((src>>5)&0x1f) << 3;
dst[3] = (src>>15) << 7;
}
GL_FORCE_INLINE void _i8_to_i8(const GLubyte* source, GLubyte* dest) {
/* For indexes */
GLubyte* dst = (GLubyte*) dest;
@ -950,6 +1068,7 @@ static inline void _alpha8_to_argb4444(const GLubyte* source, GLubyte* dest) {
/*A111*/
*((GLushort*) dest) = (*source & 0xF0) << 8 | (0xFF & 0xF0) << 4 | (0xFF & 0xF0) | (0xFF & 0xF0) >> 4;
#else
//Tested with multi-texturing sample , unit0: texture map unit1:alpha map
/* AAAA rather than A111*/
GLushort color = *source&0xf0;
color |= color>>4;
@ -997,20 +1116,43 @@ static TextureConversionFunc _determineConversion(GLint internalFormat, GLenum f
return _rgba4444_to_argb4444;
}
} break;
case GL_RGBA8: {
case GL_RGBA8:
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGB565_KOS:
if(type == GL_UNSIGNED_BYTE && format == GL_RGBA) {
return _rgba8888_to_rgba8888;
} else if (type == GL_BYTE && format == GL_RGBA) {
}
else
if (type == GL_BYTE && format == GL_RGBA) {
return _rgba8888_to_rgba8888;
} else if(type == GL_UNSIGNED_BYTE && format == GL_RGB) {
}
else
if(type == GL_UNSIGNED_BYTE && format == GL_RGB) {
return _rgb888_to_rgba8888;
} else if (type == GL_BYTE && format == GL_RGB) {
}
else
if (type == GL_BYTE && format == GL_RGB) {
return _rgb888_to_rgba8888;
} else if(type == GL_UNSIGNED_SHORT_4_4_4_4 && format == GL_RGBA) {
}
else
if(type == GL_UNSIGNED_SHORT_4_4_4_4 && format == GL_RGBA) {
return _rgba4444_to_rgba8888;
}
} break;
else
if(type == GL_UNSIGNED_BYTE && format == GL_RGBA4) {
return _rgba4444_to_rgba8888;
}
else
if(type == GL_UNSIGNED_BYTE && format == GL_RGB5_A1) {
return _rgba5551_to_rgba8888;
}
else
if(type == GL_UNSIGNED_BYTE && format == GL_RGB565_KOS) {
return _rgb565_to_rgb8888;
}
break;
case GL_COLOR_INDEX8_EXT:
if(format == GL_COLOR_INDEX) {
switch(type) {
@ -1494,27 +1636,61 @@ void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLint param) {
}
GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *data) {
GLint validTargets[] = {
GL_TEXTURE_2D,
GL_SHARED_TEXTURE_PALETTE_EXT,
GL_SHARED_TEXTURE_PALETTE_0_KOS,
GL_SHARED_TEXTURE_PALETTE_1_KOS,
GL_SHARED_TEXTURE_PALETTE_2_KOS,
GL_SHARED_TEXTURE_PALETTE_3_KOS,
0
};
GL_SHARED_TEXTURE_PALETTE_0_KOS,GL_SHARED_TEXTURE_PALETTE_1_KOS,GL_SHARED_TEXTURE_PALETTE_2_KOS,GL_SHARED_TEXTURE_PALETTE_3_KOS,GL_SHARED_TEXTURE_PALETTE_4_KOS,GL_SHARED_TEXTURE_PALETTE_5_KOS,GL_SHARED_TEXTURE_PALETTE_6_KOS,GL_SHARED_TEXTURE_PALETTE_7_KOS,GL_SHARED_TEXTURE_PALETTE_8_KOS,GL_SHARED_TEXTURE_PALETTE_9_KOS,
GL_SHARED_TEXTURE_PALETTE_10_KOS,GL_SHARED_TEXTURE_PALETTE_11_KOS,GL_SHARED_TEXTURE_PALETTE_12_KOS,GL_SHARED_TEXTURE_PALETTE_13_KOS,GL_SHARED_TEXTURE_PALETTE_14_KOS,GL_SHARED_TEXTURE_PALETTE_15_KOS,GL_SHARED_TEXTURE_PALETTE_16_KOS,GL_SHARED_TEXTURE_PALETTE_17_KOS,GL_SHARED_TEXTURE_PALETTE_18_KOS,GL_SHARED_TEXTURE_PALETTE_19_KOS,
GL_SHARED_TEXTURE_PALETTE_20_KOS,GL_SHARED_TEXTURE_PALETTE_21_KOS,GL_SHARED_TEXTURE_PALETTE_22_KOS,GL_SHARED_TEXTURE_PALETTE_23_KOS,GL_SHARED_TEXTURE_PALETTE_24_KOS,GL_SHARED_TEXTURE_PALETTE_25_KOS,GL_SHARED_TEXTURE_PALETTE_26_KOS,GL_SHARED_TEXTURE_PALETTE_27_KOS,GL_SHARED_TEXTURE_PALETTE_28_KOS,GL_SHARED_TEXTURE_PALETTE_29_KOS,
GL_SHARED_TEXTURE_PALETTE_30_KOS,GL_SHARED_TEXTURE_PALETTE_31_KOS,GL_SHARED_TEXTURE_PALETTE_32_KOS,GL_SHARED_TEXTURE_PALETTE_33_KOS,GL_SHARED_TEXTURE_PALETTE_34_KOS,GL_SHARED_TEXTURE_PALETTE_35_KOS,GL_SHARED_TEXTURE_PALETTE_36_KOS,GL_SHARED_TEXTURE_PALETTE_37_KOS,GL_SHARED_TEXTURE_PALETTE_38_KOS,GL_SHARED_TEXTURE_PALETTE_39_KOS,
GL_SHARED_TEXTURE_PALETTE_40_KOS,GL_SHARED_TEXTURE_PALETTE_41_KOS,GL_SHARED_TEXTURE_PALETTE_42_KOS,GL_SHARED_TEXTURE_PALETTE_43_KOS,GL_SHARED_TEXTURE_PALETTE_44_KOS,GL_SHARED_TEXTURE_PALETTE_45_KOS,GL_SHARED_TEXTURE_PALETTE_46_KOS,GL_SHARED_TEXTURE_PALETTE_47_KOS,GL_SHARED_TEXTURE_PALETTE_48_KOS,GL_SHARED_TEXTURE_PALETTE_49_KOS,
GL_SHARED_TEXTURE_PALETTE_50_KOS,GL_SHARED_TEXTURE_PALETTE_51_KOS,GL_SHARED_TEXTURE_PALETTE_52_KOS,GL_SHARED_TEXTURE_PALETTE_53_KOS,GL_SHARED_TEXTURE_PALETTE_54_KOS,GL_SHARED_TEXTURE_PALETTE_55_KOS,GL_SHARED_TEXTURE_PALETTE_56_KOS,GL_SHARED_TEXTURE_PALETTE_57_KOS,GL_SHARED_TEXTURE_PALETTE_58_KOS,GL_SHARED_TEXTURE_PALETTE_59_KOS,
GL_SHARED_TEXTURE_PALETTE_60_KOS,GL_SHARED_TEXTURE_PALETTE_61_KOS,GL_SHARED_TEXTURE_PALETTE_62_KOS,GL_SHARED_TEXTURE_PALETTE_63_KOS,
0};
GLint validInternalFormats[] = {GL_RGB8, GL_RGBA8, 0};
GLint validFormats[] = {GL_RGB, GL_RGBA, 0};
//GLint validInternalFormats[] = {GL_RGB8, GL_RGBA8,GL_RGBA4, 0};
GLint validFormats[] = {GL_RGB, GL_RGBA,GL_RGB5_A1,GL_RGB5_A1,GL_RGB565_KOS,GL_RGBA4, 0};
GLint validTypes[] = {GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, 0};
if(_glCheckValidEnum(target, validTargets, __func__) != 0) {
return;
}
/*ozzy:let's consider internalFormat param as a hint coz it's already set into gldcConfig
if(_glCheckValidEnum(internalFormat, validInternalFormats, __func__) != 0) {
return;
}
*/
switch(format){
case GL_PALETTE4_RGBA8_OES:
case GL_PALETTE8_RGBA8_OES:
format = GL_RGBA;
break;
case GL_PALETTE4_RGB8_OES:
case GL_PALETTE8_RGB8_OES:
format = GL_RGB;
break;
case GL_PALETTE4_R5_G6_B5_OES:
case GL_PALETTE8_R5_G6_B5_OES:
case GL_UNSIGNED_SHORT_5_6_5:
format = GL_RGB565_KOS;
break;
case GL_PALETTE4_RGB5_A1_OES:
case GL_PALETTE8_RGB5_A1_OES:
case GL_UNSIGNED_SHORT_5_5_5_1:
format = GL_RGB5_A1;
break;
case GL_PALETTE4_RGBA4_OES:
case GL_PALETTE8_RGBA4_OES:
case GL_UNSIGNED_SHORT_4_4_4_4:
format = GL_RGBA4;
break;
}
if(_glCheckValidEnum(format, validFormats, __func__) != 0) {
return;
@ -1535,7 +1711,7 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
assert(sourceStride > -1);
TextureConversionFunc convert = _determineConversion(
GL_RGBA8, /* We always store palettes in this format */
INTERNAL_PALETTE_FORMAT, //was previously forced to GL_RGBA8
format,
type
);
@ -1547,21 +1723,25 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
TexturePalette* palette = NULL;
GLboolean sharedPaletteUsed = GL_FALSE;
/* Custom extension - allow uploading to one of 4 custom palettes */
if(target == GL_SHARED_TEXTURE_PALETTE_EXT || target == GL_SHARED_TEXTURE_PALETTE_0_KOS) {
palette = SHARED_PALETTES[0];
} else if(target == GL_SHARED_TEXTURE_PALETTE_1_KOS) {
palette = SHARED_PALETTES[1];
} else if(target == GL_SHARED_TEXTURE_PALETTE_2_KOS) {
palette = SHARED_PALETTES[2];
} else if(target == GL_SHARED_TEXTURE_PALETTE_3_KOS) {
palette = SHARED_PALETTES[3];
} else {
sharedPaletteUsed = GL_TRUE;
}
for (GLbyte i = 1; i < 64; ++i) {
if (target == GL_SHARED_TEXTURE_PALETTE_0_KOS + i) {
palette = SHARED_PALETTES[i];
sharedPaletteUsed = GL_TRUE;
}
}
if (sharedPaletteUsed == GL_FALSE){
TextureObject* active = _glGetBoundTexture();
if(!active->palette) {
active->palette = _initTexturePalette();
}
palette = active->palette;
}
@ -1578,7 +1758,7 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
}
palette->data = (GLubyte*) malloc(width * 4);
palette->format = format; //Ozzy:was previously forcing to GL_RGBA for testing.
palette->format = format;
palette->width = width;
palette->size = (width > 16) ? 256 : 16;
assert(palette->size == 16 || palette->size == 256);

View File

@ -155,6 +155,20 @@ GLAPI GLboolean APIENTRY glIsFramebufferEXT(GLuint framebuffer);
#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB
/* ext OES_compressed_paletted_texture */
/* PixelInternalFormat */
#define GL_PALETTE4_RGB8_OES 0x8B90
#define GL_PALETTE4_RGBA8_OES 0x8B91
#define GL_PALETTE4_R5_G6_B5_OES 0x8B92
#define GL_PALETTE4_RGBA4_OES 0x8B93
#define GL_PALETTE4_RGB5_A1_OES 0x8B94
#define GL_PALETTE8_RGB8_OES 0x8B95
#define GL_PALETTE8_RGBA8_OES 0x8B96
#define GL_PALETTE8_R5_G6_B5_OES 0x8B97
#define GL_PALETTE8_RGBA4_OES 0x8B98
#define GL_PALETTE8_RGB5_A1_OES 0x8B99
GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *data);
GLAPI void APIENTRY glColorSubTableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
GLAPI void APIENTRY glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *data);

View File

@ -88,6 +88,7 @@ GLAPI void APIENTRY glKosInitConfig(GLdcConfig* config);
GLAPI void APIENTRY glKosInitEx(GLdcConfig* config);
GLAPI void APIENTRY glKosSwapBuffers();
/*
* CUSTOM EXTENSION multiple_shared_palette_KOS
*
@ -107,20 +108,90 @@ GLAPI void APIENTRY glKosSwapBuffers();
* by default textures use shared palette 0.
*/
#define GL_SHARED_TEXTURE_PALETTE_0_KOS 0xEEFC
#define GL_SHARED_TEXTURE_PALETTE_1_KOS 0xEEFD
#define GL_SHARED_TEXTURE_PALETTE_2_KOS 0xEEFE
#define GL_SHARED_TEXTURE_PALETTE_3_KOS 0xEEFF
#define GL_SHARED_TEXTURE_PALETTE_4_KOS 0xEF00
#define GL_SHARED_TEXTURE_PALETTE_5_KOS 0xEF01
#define GL_SHARED_TEXTURE_PALETTE_6_KOS 0xEF02
#define GL_SHARED_TEXTURE_PALETTE_7_KOS 0xEF03
#define GL_SHARED_TEXTURE_PALETTE_8_KOS 0xEF04
#define GL_SHARED_TEXTURE_PALETTE_9_KOS 0xEF05
#define GL_SHARED_TEXTURE_PALETTE_10_KOS 0xEF06
#define GL_SHARED_TEXTURE_PALETTE_11_KOS 0xEF07
#define GL_SHARED_TEXTURE_PALETTE_12_KOS 0xEF08
#define GL_SHARED_TEXTURE_PALETTE_13_KOS 0xEF09
#define GL_SHARED_TEXTURE_PALETTE_14_KOS 0xEF0A
#define GL_SHARED_TEXTURE_PALETTE_15_KOS 0xEF0B
#define GL_SHARED_TEXTURE_PALETTE_16_KOS 0xEF0C
#define GL_SHARED_TEXTURE_PALETTE_17_KOS 0xEF0D
#define GL_SHARED_TEXTURE_PALETTE_18_KOS 0xEF0E
#define GL_SHARED_TEXTURE_PALETTE_19_KOS 0xEF0F
#define GL_SHARED_TEXTURE_PALETTE_20_KOS 0xEF10
#define GL_SHARED_TEXTURE_PALETTE_21_KOS 0xEF11
#define GL_SHARED_TEXTURE_PALETTE_22_KOS 0xEF12
#define GL_SHARED_TEXTURE_PALETTE_23_KOS 0xEF13
#define GL_SHARED_TEXTURE_PALETTE_24_KOS 0xEF14
#define GL_SHARED_TEXTURE_PALETTE_25_KOS 0xEF15
#define GL_SHARED_TEXTURE_PALETTE_26_KOS 0xEF16
#define GL_SHARED_TEXTURE_PALETTE_27_KOS 0xEF17
#define GL_SHARED_TEXTURE_PALETTE_28_KOS 0xEF18
#define GL_SHARED_TEXTURE_PALETTE_29_KOS 0xEF19
#define GL_SHARED_TEXTURE_PALETTE_30_KOS 0xEF1A
#define GL_SHARED_TEXTURE_PALETTE_31_KOS 0xEF1B
#define GL_SHARED_TEXTURE_PALETTE_32_KOS 0xEF1C
#define GL_SHARED_TEXTURE_PALETTE_33_KOS 0xEF1D
#define GL_SHARED_TEXTURE_PALETTE_34_KOS 0xEF1E
#define GL_SHARED_TEXTURE_PALETTE_35_KOS 0xEF1F
#define GL_SHARED_TEXTURE_PALETTE_36_KOS 0xEF20
#define GL_SHARED_TEXTURE_PALETTE_37_KOS 0xEF21
#define GL_SHARED_TEXTURE_PALETTE_38_KOS 0xEF22
#define GL_SHARED_TEXTURE_PALETTE_39_KOS 0xEF23
#define GL_SHARED_TEXTURE_PALETTE_40_KOS 0xEF24
#define GL_SHARED_TEXTURE_PALETTE_41_KOS 0xEF25
#define GL_SHARED_TEXTURE_PALETTE_42_KOS 0xEF26
#define GL_SHARED_TEXTURE_PALETTE_43_KOS 0xEF27
#define GL_SHARED_TEXTURE_PALETTE_44_KOS 0xEF28
#define GL_SHARED_TEXTURE_PALETTE_45_KOS 0xEF29
#define GL_SHARED_TEXTURE_PALETTE_46_KOS 0xEF2A
#define GL_SHARED_TEXTURE_PALETTE_47_KOS 0xEF2B
#define GL_SHARED_TEXTURE_PALETTE_48_KOS 0xEF2C
#define GL_SHARED_TEXTURE_PALETTE_49_KOS 0xEF2D
#define GL_SHARED_TEXTURE_PALETTE_50_KOS 0xEF2E
#define GL_SHARED_TEXTURE_PALETTE_51_KOS 0xEF2F
#define GL_SHARED_TEXTURE_PALETTE_52_KOS 0xEF30
#define GL_SHARED_TEXTURE_PALETTE_53_KOS 0xEF31
#define GL_SHARED_TEXTURE_PALETTE_54_KOS 0xEF32
#define GL_SHARED_TEXTURE_PALETTE_55_KOS 0xEF33
#define GL_SHARED_TEXTURE_PALETTE_56_KOS 0xEF34
#define GL_SHARED_TEXTURE_PALETTE_57_KOS 0xEF35
#define GL_SHARED_TEXTURE_PALETTE_58_KOS 0xEF36
#define GL_SHARED_TEXTURE_PALETTE_59_KOS 0xEF37
#define GL_SHARED_TEXTURE_PALETTE_60_KOS 0xEF38
#define GL_SHARED_TEXTURE_PALETTE_61_KOS 0xEF39
#define GL_SHARED_TEXTURE_PALETTE_62_KOS 0xEF3A
#define GL_SHARED_TEXTURE_PALETTE_63_KOS 0xEF3B
/* Pass to glTexParameteri to set the shared bank */
#define GL_SHARED_TEXTURE_BANK_KOS 0xEF00
#define GL_SHARED_TEXTURE_BANK_KOS 0xEF3C
/* Memory allocation extension (GL_KOS_texture_memory_management) */
GLAPI GLvoid APIENTRY glDefragmentTextureMemory_KOS(void);
#define GL_FREE_TEXTURE_MEMORY_KOS 0xEF01
#define GL_USED_TEXTURE_MEMORY_KOS 0xEF02
#define GL_FREE_CONTIGUOUS_TEXTURE_MEMORY_KOS 0xEF03
#define GL_FREE_TEXTURE_MEMORY_KOS 0xEF3D
#define GL_USED_TEXTURE_MEMORY_KOS 0xEF3E
#define GL_FREE_CONTIGUOUS_TEXTURE_MEMORY_KOS 0xEF3F
//for palette internal format (glfcConfig)
#define GL_RGB565_KOS 0xEF40
__END_DECLS