Replace the texture linked list with a new NamedArray container type
This commit is contained in:
parent
42d2a1e091
commit
493c078b19
93
containers/named_array.h
Normal file
93
containers/named_array.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
#ifndef NAMED_ARRAY_H
|
||||
#define NAMED_ARRAY_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned int element_size;
|
||||
unsigned int max_element_count;
|
||||
unsigned char* elements;
|
||||
unsigned char* used_markers;
|
||||
unsigned char marker_count;
|
||||
} NamedArray;
|
||||
|
||||
|
||||
inline void named_array_init(NamedArray* array, unsigned int element_size, unsigned int max_elements) {
|
||||
array->element_size = element_size;
|
||||
array->max_element_count = max_elements;
|
||||
|
||||
float c = (float) max_elements / 8.0f;
|
||||
array->marker_count = (unsigned char) ceil(c);
|
||||
|
||||
#ifdef _arch_dreamcast
|
||||
// Use 32-bit aligned memory on the Dreamcast
|
||||
array->elements = (unsigned char*) memalign(0x20, element_size * max_elements);
|
||||
array->used_markers = (unsigned char*) memalign(0x20, array->marker_count);
|
||||
#else
|
||||
array->elements = (unsigned char*) malloc(element_size * max_elements);
|
||||
array->used_markers = (unsigned char*) malloc(array->marker_count);
|
||||
#endif
|
||||
memset(array->used_markers, 0, sizeof(array->marker_count));
|
||||
}
|
||||
|
||||
inline char named_array_used(NamedArray* array, unsigned int id) {
|
||||
id--;
|
||||
|
||||
unsigned int i = id / 8;
|
||||
unsigned int j = id % 8;
|
||||
|
||||
unsigned char v = array->used_markers[i] & (unsigned char) (1 << j);
|
||||
return !!(v);
|
||||
}
|
||||
|
||||
inline void* named_array_alloc(NamedArray* array, unsigned int* new_id) {
|
||||
for(unsigned int i = 0; i < array->marker_count; ++i) {
|
||||
for(unsigned int j = 0; j < 8; ++j) {
|
||||
unsigned int id = (i * 8) + j + 1;
|
||||
if(!named_array_used(array, id)) {
|
||||
array->used_markers[i] |= (unsigned char) 1 << j;
|
||||
*new_id = id;
|
||||
unsigned char* ptr = &array->elements[(id - 1) * array->element_size];
|
||||
memset(ptr, 0, array->element_size);
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline void named_array_release(NamedArray* array, unsigned int new_id) {
|
||||
new_id--;
|
||||
|
||||
unsigned int i = new_id / 8;
|
||||
unsigned int j = new_id % 8;
|
||||
|
||||
array->used_markers[i] &= (unsigned char) ~(1 << j);
|
||||
}
|
||||
|
||||
inline void* named_array_get(NamedArray* array, unsigned int id) {
|
||||
if(id == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!named_array_used(array, id)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &array->elements[(id - 1) * array->element_size];
|
||||
}
|
||||
|
||||
inline void named_array_cleanup(NamedArray* array) {
|
||||
free(array->elements);
|
||||
free(array->used_markers);
|
||||
array->elements = NULL;
|
||||
array->used_markers = NULL;
|
||||
array->element_size = array->max_element_count = 0;
|
||||
array->marker_count = 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // NAMED_ARRAY_H
|
1
gl-api.h
1
gl-api.h
|
@ -35,7 +35,6 @@ typedef struct {
|
|||
GLubyte uv_clamp;
|
||||
GLuint index;
|
||||
GLvoid *data;
|
||||
GLvoid *link;
|
||||
} GL_TEXTURE_OBJECT; /* KOS Open GL Texture Object */
|
||||
|
||||
typedef struct {
|
||||
|
|
94
gl-texture.c
94
gl-texture.c
|
@ -5,16 +5,17 @@
|
|||
Copyright (C) 2016 Joe Fenton
|
||||
|
||||
Open GL Texture Submission implementation.
|
||||
This implementation uses a dynamic linked list to store the texture objects.
|
||||
*/
|
||||
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gl.h"
|
||||
#include "glext.h"
|
||||
#include "gl-api.h"
|
||||
#include "gl-rgb.h"
|
||||
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include "containers/named_array.h"
|
||||
|
||||
//========================================================================================//
|
||||
//== Internal KOS Open GL Texture Unit Structures / Global Variables ==//
|
||||
|
@ -23,8 +24,9 @@
|
|||
#define GL_KOS_CLAMP_U (1<<1)
|
||||
#define GL_KOS_CLAMP_V (1<<0)
|
||||
|
||||
static GL_TEXTURE_OBJECT *TEXTURE_OBJ = NULL;
|
||||
|
||||
static GL_TEXTURE_OBJECT *GL_KOS_TEXTURE_UNIT[GL_KOS_MAX_TEXTURE_UNITS] = { NULL, NULL };
|
||||
static NamedArray TEXTURE_OBJECTS;
|
||||
|
||||
static GLubyte GL_KOS_ACTIVE_TEXTURE = GL_TEXTURE0_ARB & 0xF;
|
||||
|
||||
|
@ -33,47 +35,12 @@ static GLubyte GL_KOS_ACTIVE_TEXTURE = GL_TEXTURE0_ARB & 0xF;
|
|||
static GLuint _determinePVRFormat(GLint internalFormat, GLenum type);
|
||||
|
||||
GLubyte _glKosInitTextures() {
|
||||
TEXTURE_OBJ = malloc(sizeof(GL_TEXTURE_OBJECT));
|
||||
|
||||
if(TEXTURE_OBJ == NULL)
|
||||
return 0;
|
||||
|
||||
TEXTURE_OBJ->index = 0;
|
||||
TEXTURE_OBJ->data = NULL;
|
||||
TEXTURE_OBJ->link = NULL;
|
||||
|
||||
named_array_init(&TEXTURE_OBJECTS, sizeof(GL_TEXTURE_OBJECT), 256);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static GLsizei _glKosGetLastTextureIndex() {
|
||||
GL_TEXTURE_OBJECT *ptr = TEXTURE_OBJ;
|
||||
|
||||
while(ptr->link != NULL)
|
||||
ptr = (GL_TEXTURE_OBJECT *)ptr->link;
|
||||
|
||||
return ptr->index;
|
||||
}
|
||||
|
||||
static void _glKosInsertTextureObj(GL_TEXTURE_OBJECT *obj) {
|
||||
GL_TEXTURE_OBJECT *ptr = TEXTURE_OBJ;
|
||||
|
||||
while(ptr->link != NULL)
|
||||
ptr = (GL_TEXTURE_OBJECT *)ptr->link;
|
||||
|
||||
ptr->link = obj;
|
||||
}
|
||||
|
||||
static GL_TEXTURE_OBJECT *_glKosGetTextureObj(GLuint index) {
|
||||
GL_TEXTURE_OBJECT *ptr = TEXTURE_OBJ;
|
||||
|
||||
while(ptr->link != NULL && ptr->index != index)
|
||||
ptr = (GL_TEXTURE_OBJECT *)ptr->link;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void _glKosBindTexture(GLuint index) {
|
||||
GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = _glKosGetTextureObj(index);
|
||||
GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = (GL_TEXTURE_OBJECT*) named_array_get(&TEXTURE_OBJECTS, index);
|
||||
}
|
||||
|
||||
static void _glKosUnbindTexture() {
|
||||
|
@ -81,17 +48,17 @@ static void _glKosUnbindTexture() {
|
|||
}
|
||||
|
||||
GLuint _glKosTextureWidth(GLuint index) {
|
||||
GL_TEXTURE_OBJECT *tex = _glKosGetTextureObj(index);
|
||||
GL_TEXTURE_OBJECT *tex = (GL_TEXTURE_OBJECT*) named_array_get(&TEXTURE_OBJECTS, index);
|
||||
return tex->width;
|
||||
}
|
||||
|
||||
GLuint _glKosTextureHeight(GLuint index) {
|
||||
GL_TEXTURE_OBJECT *tex = _glKosGetTextureObj(index);
|
||||
GL_TEXTURE_OBJECT *tex = (GL_TEXTURE_OBJECT*) named_array_get(&TEXTURE_OBJECTS, index);
|
||||
return tex->height;
|
||||
}
|
||||
|
||||
GLvoid *_glKosTextureData(GLuint index) {
|
||||
GL_TEXTURE_OBJECT *tex = _glKosGetTextureObj(index);
|
||||
GL_TEXTURE_OBJECT *tex = (GL_TEXTURE_OBJECT*) named_array_get(&TEXTURE_OBJECTS, index);
|
||||
return tex->data;
|
||||
}
|
||||
|
||||
|
@ -126,49 +93,36 @@ GLubyte _glKosMaxTextureUnits() {
|
|||
//== Public KOS Open GL API Texture Unit Functionality ==//
|
||||
|
||||
void APIENTRY glGenTextures(GLsizei n, GLuint *textures) {
|
||||
GLsizei index = _glKosGetLastTextureIndex();
|
||||
|
||||
while(n--) {
|
||||
GL_TEXTURE_OBJECT *txr = malloc(sizeof(GL_TEXTURE_OBJECT));
|
||||
txr->index = ++index;
|
||||
txr->data = NULL;
|
||||
txr->link = NULL;
|
||||
|
||||
GLuint id = 0;
|
||||
GL_TEXTURE_OBJECT* txr = (GL_TEXTURE_OBJECT*) named_array_alloc(&TEXTURE_OBJECTS, &id);
|
||||
txr->index = id;
|
||||
txr->width = txr->height = 0;
|
||||
txr->mip_map = 0;
|
||||
txr->uv_clamp = 0;
|
||||
txr->env = PVR_TXRENV_MODULATEALPHA;
|
||||
txr->filter = PVR_FILTER_NONE;
|
||||
txr->data = NULL;
|
||||
|
||||
_glKosInsertTextureObj(txr);
|
||||
*textures = id;
|
||||
|
||||
*textures++ = txr->index;
|
||||
textures++;
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) {
|
||||
while(n--) {
|
||||
GL_TEXTURE_OBJECT *txr = TEXTURE_OBJ, *ltxr = NULL;
|
||||
GL_TEXTURE_OBJECT* txr = (GL_TEXTURE_OBJECT*) named_array_get(&TEXTURE_OBJECTS, *textures);
|
||||
|
||||
while(txr->index != *textures && txr->link != NULL) {
|
||||
ltxr = txr;
|
||||
txr = txr->link;
|
||||
if(txr == GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]) {
|
||||
GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = NULL;
|
||||
}
|
||||
|
||||
ltxr->link = txr->link;
|
||||
|
||||
if(txr->index == *textures) {
|
||||
if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE])
|
||||
if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->index == txr->index)
|
||||
GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = NULL;
|
||||
|
||||
if(txr->data != NULL)
|
||||
pvr_mem_free(txr->data);
|
||||
|
||||
free(txr);
|
||||
if(txr->data) {
|
||||
pvr_mem_free(txr->data);
|
||||
}
|
||||
|
||||
++textures;
|
||||
named_array_release(&TEXTURE_OBJECTS, *textures++);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user