diff --git a/README.md b/README.md
index 5f5c956243..98ab65c04a 100644
--- a/README.md
+++ b/README.md
@@ -28,9 +28,13 @@ Direct OpenGL Usage:
[vitaVoyager](https://vitadb.rinnegatamante.it/#/info/367) - Port of lilium-voyager (Star Trek Voyager: Elite Force)
[Daedalus X64](https://github.com/Rinnegatamante/daedalusx64-vitagl) - Port of Daedalus X64 (N64 Emulator)
[RetroArch](https://github.com/libretro/RetroArch) - Vita's GL1 video driver of RetroArch
-[vitaET](https://github.com/Rinnegatamante/vitaET) - Port of ET:Legacy (Wolfenstein: Enemy Territory)
+[vitaET](https://github.com/Rinnegatamante/vitaET) - Port of ET: Legacy (Wolfenstein: Enemy Territory)
[flycast](https://github.com/Rinnegatamante/flycast) - Port of flycast (Dreamcast Emulator)
[AvP Gold](https://github.com/Rinnegatamante/AvP-Gold-Vita) - Port of Aliens versus Predator: Gold Edition
+[re3-vita](https://vitadb.rinnegatamante.it/#/info/589) - Port of Grand Theft Auto III
+[prboom-plus](https://vitadb.rinnegatamante.it/#/info/591) - Port of PrBoom Plus (Doom engine sourceport)
+[VITAlbum](https://vitadb.rinnegatamante.it/#/info/566) - Filebrowser and image viewer app
+[sm64-vita](https://github.com/bythos14/sm64-vita) - Port of Super Mario 64
Libraries:
[sdl12_gl](https://github.com/Rinnegatamante/SDL-Vita/tree/sdl12_gl/src) - SDL 1.2 Vita port adapted to work with vitaGL as renderer
@@ -42,5 +46,5 @@ sdl12_gl Apps:
[ZeldaROTH](https://vitadb.rinnegatamante.it/#/info/109) - Port of Zelda: Return of the Hylian
[Zelda3T](https://vitadb.rinnegatamante.it/#/info/334) - Port of Zelda: Time to Triumph
[ZeldaNSQ](https://vitadb.rinnegatamante.it/#/info/350) - Port of Zelda: Navi's Quest
-[vitaWolfen](https://vitadb.rinnegatamante.it/#/info/31) - Port of Wolf4SDL
+[vitaWolfen](https://vitadb.rinnegatamante.it/#/info/31) - Port of Wolf4SDL (Wolfenstein 3D)
[meritous](https://vitadb.rinnegatamante.it/#/info/411) - Port of meritous
diff --git a/source/custom_shaders.c b/source/custom_shaders.c
index b86fdbae76..398cb2a8c3 100644
--- a/source/custom_shaders.c
+++ b/source/custom_shaders.c
@@ -136,19 +136,24 @@ void _vglDrawObjects_CustomShadersIMPL(GLenum mode, GLsizei count, GLboolean imp
static char *shark_log = NULL;
void shark_log_cb(const char *msg, shark_log_level msg_level, int line) {
uint8_t append = shark_log != NULL;
- uint32_t size = (append ? strlen(shark_log) : 0) + strlen(msg);
- shark_log = append ? realloc(shark_log, size) : malloc(size);
+ char newline[1024];
switch (msg_level) {
case SHARK_LOG_INFO:
- sprintf(shark_log, "%s%sI] %s on line %d", append ? shark_log : "", append ? "\n" : "", msg, line);
+ sprintf(newline, "%sI] %s on line %d", append ? "\n" : "", msg, line);
break;
case SHARK_LOG_WARNING:
- sprintf(shark_log, "%s%sW] %s on line %d", append ? shark_log : "", append ? "\n" : "", msg, line);
+ sprintf(newline, "%sW] %s on line %d", append ? "\n" : "", msg, line);
break;
case SHARK_LOG_ERROR:
- sprintf(shark_log, "%s%sE] %s on line %d", append ? shark_log : "", append ? "\n" : "", msg, line);
+ sprintf(newline, "%sE] %s on line %d", append ? "\n" : "", msg, line);
break;
}
+ uint32_t size = (append ? strlen(shark_log) : 0) + strlen(newline);
+ shark_log = realloc(shark_log, size + 1);
+ if (append)
+ sprintf(shark_log, "%s%s", shark_log, newline);
+ else
+ strcpy(shark_log, newline);
}
#endif
@@ -165,7 +170,7 @@ void vglSetupRuntimeShaderCompiler(shark_opt opt_level, int32_t use_fastmath, in
compiler_fastint = use_fastint;
#endif
}
-
+
void vglEnableRuntimeShaderCompiler(GLboolean usage) {
use_shark = usage;
}
@@ -205,7 +210,7 @@ GLuint glCreateShader(GLenum shaderType) {
void glGetShaderiv(GLuint handle, GLenum pname, GLint *params) {
// Grabbing passed shader
shader *s = &shaders[handle - 1];
-
+
switch (pname) {
case GL_SHADER_TYPE:
*params = s->type;
@@ -231,26 +236,26 @@ void glGetShaderInfoLog(GLuint handle, GLsizei maxLength, GLsizei *length, GLcha
// Grabbing passed shader
shader *s = &shaders[handle - 1];
-
+
if (s->log) {
*length = min(strlen(s->log), maxLength);
memcpy_neon(infoLog, s->log, *length);
}
}
-void glShaderSource(GLuint handle, GLsizei count, const GLchar * const *string, const GLint *length) {
+void glShaderSource(GLuint handle, GLsizei count, const GLchar *const *string, const GLint *length) {
#ifndef SKIP_ERROR_HANDLING
if (count < 0) {
SET_GL_ERROR(GL_INVALID_VALUE)
}
#endif
- if (!is_shark_online) {
+ if (!is_shark_online) {
SET_GL_ERROR(GL_INVALID_OPERATION)
}
-
+
// Grabbing passed shader
shader *s = &shaders[handle - 1];
-
+
// Temporarily setting prog to point to the shader source
s->prog = (SceGxmProgram *)*string;
s->size = length ? *length : strlen(*string);
@@ -276,9 +281,9 @@ void glCompileShader(GLuint handle) {
#ifdef HAVE_SHARK
// Grabbing passed shader
shader *s = &shaders[handle - 1];
-
+
// Compiling shader source
- s->prog = shark_compile_shader_extended((const char*)s->prog, &s->size, s->type == GL_FRAGMENT_SHADER ? SHARK_FRAGMENT_SHADER : SHARK_VERTEX_SHADER, compiler_opts, compiler_fastmath, compiler_fastprecision, compiler_fastint);
+ s->prog = shark_compile_shader_extended((const char *)s->prog, &s->size, s->type == GL_FRAGMENT_SHADER ? SHARK_FRAGMENT_SHADER : SHARK_VERTEX_SHADER, compiler_opts, compiler_fastmath, compiler_fastprecision, compiler_fastint);
if (s->prog) {
SceGxmProgram *res = (SceGxmProgram *)malloc(s->size);
memcpy_neon((void *)res, (void *)s->prog, s->size);
@@ -302,7 +307,8 @@ void glDeleteShader(GLuint shad) {
if (s->valid) {
sceGxmShaderPatcherForceUnregisterProgram(gxm_shader_patcher, s->id);
free((void *)s->prog);
- if (s->log) free(s->log);
+ if (s->log)
+ free(s->log);
}
s->log = NULL;
s->valid = GL_FALSE;
@@ -386,7 +392,7 @@ void glLinkProgram(GLuint progr) {
void glUseProgram(GLuint prog) {
// Setting current custom program to passed program
cur_program = prog;
-
+
// Setting in-use vertex and fragment program in sceGxm
reloadCustomShader();
}
@@ -405,12 +411,12 @@ GLint glGetUniformLocation(GLuint prog, const GLchar *name) {
res->ptr = sceGxmProgramFindParameterByName(p->fshader->prog, name);
res->isVertex = GL_FALSE;
}
-
+
if (res->ptr == NULL) {
free(res);
return -1;
}
-
+
if (p->last_uniform != NULL)
p->last_uniform->chain = (void *)res;
p->last_uniform = res;
@@ -422,7 +428,7 @@ void glUniform1i(GLint location, GLint v0) {
// Checking if the uniform does exist
if (location == -1)
return;
-
+
// Grabbing passed uniform
uniform *u = (uniform *)location;
if (u->ptr == NULL)
@@ -446,7 +452,7 @@ void glUniform2i(GLint location, GLint v0, GLint v1) {
// Checking if the uniform does exist
if (location == -1)
return;
-
+
// Grabbing passed uniform
uniform *u = (uniform *)location;
if (u->ptr == NULL)
@@ -474,7 +480,7 @@ void glUniform1f(GLint location, GLfloat v0) {
// Checking if the uniform does exist
if (location == -1)
return;
-
+
// Grabbing passed uniform
uniform *u = (uniform *)location;
if (u->ptr == NULL)
@@ -496,7 +502,7 @@ void glUniform2f(GLint location, GLfloat v0, GLfloat v1) {
// Checking if the uniform does exist
if (location == -1)
return;
-
+
// Grabbing passed uniform
uniform *u = (uniform *)location;
if (u->ptr == NULL)
@@ -524,7 +530,7 @@ void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) {
// Checking if the uniform does exist
if (location == -1)
return;
-
+
// Grabbing passed uniform
uniform *u = (uniform *)location;
if (u->ptr == NULL)
@@ -546,7 +552,7 @@ void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) {
// Checking if the uniform does exist
if (location == -1)
return;
-
+
// Grabbing passed uniform
uniform *u = (uniform *)location;
if (u->ptr == NULL)
@@ -568,14 +574,14 @@ void glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
// Checking if the uniform does exist
if (location == -1)
return;
-
+
// Grabbing passed uniform
uniform *u = (uniform *)location;
if (u->ptr == NULL)
return;
// Setting passed value to desired uniform
- float v[4] = {v0, v1, v2, v3};
+ float v[4] = { v0, v1, v2, v3 };
if (u->isVertex) {
if (vert_uniforms == NULL)
sceGxmReserveVertexDefaultUniformBuffer(gxm_context, &vert_uniforms);
@@ -591,7 +597,7 @@ void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) {
// Checking if the uniform does exist
if (location == -1)
return;
-
+
// Grabbing passed uniform
uniform *u = (uniform *)location;
if (u->ptr == NULL)
@@ -613,7 +619,7 @@ void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, cons
// Checking if the uniform does exist
if (location == -1)
return;
-
+
// Grabbing passed uniform
uniform *u = (uniform *)location;
if (u->ptr == NULL)
@@ -646,7 +652,8 @@ void vglBindAttribLocation(GLuint prog, GLuint index, const GLchar *name, const
// Looking for desired parameter in requested program
const SceGxmProgramParameter *param = sceGxmProgramFindParameterByName(p->vshader->prog, name);
- if (param == NULL) return;
+ if (param == NULL)
+ return;
// Setting stream index and offset values
attributes->streamIndex = index;
@@ -684,7 +691,7 @@ void vglBindAttribLocation(GLuint prog, GLuint index, const GLchar *name, const
}
// Equivalent of glBindAttribLocation but for sceGxm architecture when packed attributes are used
-void vglBindPackedAttribLocation(GLuint prog, const GLchar *name, const GLuint num, const GLenum type, GLuint offset, GLint stride) {
+GLint vglBindPackedAttribLocation(GLuint prog, const GLchar *name, const GLuint num, const GLenum type, GLuint offset, GLint stride) {
// Grabbing passed program
program *p = &progs[prog - 1];
SceGxmVertexAttribute *attributes = &p->attr[p->attr_num];
@@ -692,7 +699,8 @@ void vglBindPackedAttribLocation(GLuint prog, const GLchar *name, const GLuint n
// Looking for desired parameter in requested program
const SceGxmProgramParameter *param = sceGxmProgramFindParameterByName(p->vshader->prog, name);
- if (param == NULL) return;
+ if (param == NULL)
+ return GL_FALSE;
// Setting stream index and offset values
attributes->streamIndex = 0;
@@ -714,7 +722,8 @@ void vglBindPackedAttribLocation(GLuint prog, const GLchar *name, const GLuint n
bpe = sizeof(uint8_t);
break;
default:
- SET_GL_ERROR(GL_INVALID_ENUM)
+ vgl_error = GL_INVALID_ENUM;
+ return GL_FALSE;
break;
}
@@ -725,6 +734,8 @@ void vglBindPackedAttribLocation(GLuint prog, const GLchar *name, const GLuint n
streams->indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
p->stream_num = 1;
p->attr_num++;
+
+ return GL_TRUE;
}
// Equivalent of glVertexAttribPointer but for sceGxm architecture
diff --git a/source/framebuffers.c b/source/framebuffers.c
index 4c50145ab6..8fa39e0db8 100644
--- a/source/framebuffers.c
+++ b/source/framebuffers.c
@@ -89,16 +89,18 @@ void glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) {
#endif
while (n > 0) {
framebuffer *fb = (framebuffer *)framebuffers[n--];
- fb->active = 0;
- if (fb->target) {
- sceGxmDestroyRenderTarget(fb->target);
- fb->target = NULL;
- }
- if (fb->depth_buffer_addr) {
- mempool_free(fb->depth_buffer_addr, fb->depth_buffer_mem_type);
- mempool_free(fb->stencil_buffer_addr, fb->stencil_buffer_mem_type);
- fb->depth_buffer_addr = NULL;
- fb->stencil_buffer_addr = NULL;
+ if (fb) {
+ fb->active = 0;
+ if (fb->target) {
+ sceGxmDestroyRenderTarget(fb->target);
+ fb->target = NULL;
+ }
+ if (fb->depth_buffer_addr) {
+ mempool_free(fb->depth_buffer_addr, fb->depth_buffer_mem_type);
+ mempool_free(fb->stencil_buffer_addr, fb->stencil_buffer_mem_type);
+ fb->depth_buffer_addr = NULL;
+ fb->stencil_buffer_addr = NULL;
+ }
}
}
}
@@ -187,7 +189,7 @@ void vglTexImageDepthBuffer(GLenum target) {
texture_unit *tex_unit = &texture_units[server_texture_unit];
int texture2d_idx = tex_unit->tex_id;
texture *tex = &textures[texture2d_idx];
-
+
switch (target) {
case GL_TEXTURE_2D:
{
diff --git a/source/gxm.c b/source/gxm.c
index f565593209..2e70c820be 100644
--- a/source/gxm.c
+++ b/source/gxm.c
@@ -32,10 +32,10 @@ static void *fragment_usse_ring_buffer_addr; // fragment USSE ring buffer memblo
static SceGxmRenderTarget *gxm_render_target; // Display render target
static SceGxmColorSurface gxm_color_surfaces[DISPLAY_BUFFER_COUNT]; // Display color surfaces
-static void *gxm_color_surfaces_addr[DISPLAY_BUFFER_COUNT]; // Display color surfaces memblock starting addresses
+void *gxm_color_surfaces_addr[DISPLAY_BUFFER_COUNT]; // Display color surfaces memblock starting addresses
static SceGxmSyncObject *gxm_sync_objects[DISPLAY_BUFFER_COUNT]; // Display sync objects
-static unsigned int gxm_front_buffer_index; // Display front buffer id
-static unsigned int gxm_back_buffer_index; // Display back buffer id
+unsigned int gxm_front_buffer_index; // Display front buffer id
+unsigned int gxm_back_buffer_index; // Display back buffer id
static unsigned int gxm_scene_flags = 0; // Current gxm scene flags
static void *gxm_shader_patcher_buffer_addr; // Shader PAtcher buffer memblock starting address
@@ -105,7 +105,7 @@ static void display_queue_callback(const void *callbackData) {
void initGxm(void) {
if (gxm_initialized)
return;
-
+
// Initializing runtime shader compiler
if (use_shark) {
#ifdef HAVE_SHARK
@@ -119,7 +119,7 @@ void initGxm(void) {
#endif
is_shark_online = 0;
}
-
+
// Checking if the running application is a system one
SceAppMgrBudgetInfo info;
info.size = sizeof(SceAppMgrBudgetInfo);
@@ -197,7 +197,8 @@ void termGxmContext(void) {
}
#ifdef HAVE_SHARK
// Shutting down runtime shader compiler
- if (is_shark_online) shark_end();
+ if (is_shark_online)
+ shark_end();
#endif
}
diff --git a/source/misc.c b/source/misc.c
index b5e71277c2..3c1d41d50b 100644
--- a/source/misc.c
+++ b/source/misc.c
@@ -22,6 +22,7 @@
*/
#include "shared.h"
+GLboolean fast_texture_compression = GL_FALSE; // Hints for texture compression
static void update_fogging_state() {
if (fogging) {
@@ -547,3 +548,21 @@ void glClipPlane(GLenum plane, const GLdouble *equation) {
break;
}
}
+
+void glHint(GLenum target, GLenum mode) {
+ switch (target) {
+ case GL_TEXTURE_COMPRESSION_HINT:
+ switch (mode) {
+ case GL_FASTEST:
+ fast_texture_compression = GL_TRUE;
+ break;
+ default:
+ fast_texture_compression = GL_FALSE;
+ break;
+ }
+ break;
+ default:
+ SET_GL_ERROR(GL_INVALID_ENUM)
+ break;
+ }
+}
diff --git a/source/shared.h b/source/shared.h
index f3ade4792b..5a1f41f11e 100644
--- a/source/shared.h
+++ b/source/shared.h
@@ -57,7 +57,9 @@ extern float DISPLAY_HEIGHT_FLOAT; // Display height in pixels (float)
#include "state.h"
#include "texture_callbacks.h"
-#define SET_GL_ERROR(x) vgl_error = x; return;
+#define SET_GL_ERROR(x) \
+ vgl_error = x; \
+ return;
// Texture environment mode
typedef enum texEnvMode {
@@ -164,6 +166,8 @@ extern uint16_t *depth_clear_indices; // Memblock starting address for clear scr
extern SceGxmVertexProgram *clear_vertex_program_patched; // Patched vertex program for clearing screen
extern vector4f *clear_vertices; // Memblock starting address for clear screen vertices
+extern GLboolean fast_texture_compression; // Hints for texture compression
+
/* gxm.c */
void initGxm(void); // Inits sceGxm
void initGxmContext(void); // Inits sceGxm context
diff --git a/source/state.h b/source/state.h
index 67f49e5fe7..3e62939d92 100644
--- a/source/state.h
+++ b/source/state.h
@@ -91,12 +91,6 @@ typedef struct texture_unit {
void *index_object;
int env_mode;
int tex_id;
- SceGxmTextureFilter min_filter;
- SceGxmTextureFilter mag_filter;
- SceGxmTextureAddrMode u_mode;
- SceGxmTextureAddrMode v_mode;
- SceGxmTextureMipFilter mip_filter;
- uint32_t lod_bias;
} texture_unit;
// Framebuffer struct
diff --git a/source/textures.c b/source/textures.c
index efc5937432..67f7679b6e 100644
--- a/source/textures.c
+++ b/source/textures.c
@@ -47,10 +47,18 @@ void glGenTextures(GLsizei n, GLuint *res) {
// Reserving a texture and returning its id if available
int i, j = 0;
- for (i = 0; i < TEXTURES_NUM; i++) {
+ for (i = 1; i < TEXTURES_NUM; i++) {
if (!(textures[i].used)) {
res[j++] = i;
textures[i].used = 1;
+
+ // Resetting texture parameters to their default values
+ textures[i].min_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
+ textures[i].mag_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
+ textures[i].mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
+ textures[i].u_mode = SCE_GXM_TEXTURE_ADDR_REPEAT;
+ textures[i].v_mode = SCE_GXM_TEXTURE_ADDR_REPEAT;
+ textures[i].lod_bias = GL_MAX_TEXTURE_LOD_BIAS; // sceGxm range is 0 - (GL_MAX_TEXTURE_LOD_BIAS*2 + 1)
}
if (j >= n)
break;
@@ -87,8 +95,21 @@ void glDeleteTextures(GLsizei n, const GLuint *gl_textures) {
int j;
for (j = 0; j < n; j++) {
GLuint i = gl_textures[j];
- textures[i].used = 0;
- gpu_free_texture(&textures[i]);
+ if (i > 0) {
+ textures[i].used = 0;
+
+ // Resetting texture parameters to their default values
+ textures[i].min_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
+ textures[i].mag_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
+ textures[i].mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
+ textures[i].u_mode = SCE_GXM_TEXTURE_ADDR_REPEAT;
+ textures[i].v_mode = SCE_GXM_TEXTURE_ADDR_REPEAT;
+ textures[i].lod_bias = GL_MAX_TEXTURE_LOD_BIAS; // sceGxm range is 0 - (GL_MAX_TEXTURE_LOD_BIAS*2 + 1)
+
+ gpu_free_texture(&textures[i]);
+ if (i == tex_unit->tex_id)
+ tex_unit->tex_id = 0;
+ }
}
}
@@ -293,12 +314,12 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
gpu_alloc_mipmaps(level, tex);
// Setting texture parameters
- sceGxmTextureSetUAddrMode(&tex->gxm_tex, tex_unit->u_mode);
- sceGxmTextureSetVAddrMode(&tex->gxm_tex, tex_unit->v_mode);
- sceGxmTextureSetMinFilter(&tex->gxm_tex, tex_unit->min_filter);
- sceGxmTextureSetMagFilter(&tex->gxm_tex, tex_unit->mag_filter);
- sceGxmTextureSetMipFilter(&tex->gxm_tex, tex_unit->mip_filter);
- sceGxmTextureSetLodBias(&tex->gxm_tex, tex_unit->lod_bias);
+ sceGxmTextureSetUAddrMode(&tex->gxm_tex, tex->u_mode);
+ sceGxmTextureSetVAddrMode(&tex->gxm_tex, tex->v_mode);
+ sceGxmTextureSetMinFilter(&tex->gxm_tex, tex->min_filter);
+ sceGxmTextureSetMagFilter(&tex->gxm_tex, tex->mag_filter);
+ sceGxmTextureSetMipFilter(&tex->gxm_tex, tex->mip_filter);
+ sceGxmTextureSetLodBias(&tex->gxm_tex, tex->lod_bias);
// Setting palette if the format requests one
if (tex->valid && tex->palette_UID)
@@ -557,12 +578,12 @@ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat, G
gpu_alloc_compressed_texture(width, height, tex_format, imageSize, data, tex, 0, NULL);
// Setting texture parameters
- sceGxmTextureSetUAddrMode(&tex->gxm_tex, tex_unit->u_mode);
- sceGxmTextureSetVAddrMode(&tex->gxm_tex, tex_unit->v_mode);
- sceGxmTextureSetMinFilter(&tex->gxm_tex, tex_unit->min_filter);
- sceGxmTextureSetMagFilter(&tex->gxm_tex, tex_unit->mag_filter);
- sceGxmTextureSetMipFilter(&tex->gxm_tex, tex_unit->mip_filter);
- sceGxmTextureSetLodBias(&tex->gxm_tex, tex_unit->lod_bias);
+ sceGxmTextureSetUAddrMode(&tex->gxm_tex, tex->u_mode);
+ sceGxmTextureSetVAddrMode(&tex->gxm_tex, tex->v_mode);
+ sceGxmTextureSetMinFilter(&tex->gxm_tex, tex->min_filter);
+ sceGxmTextureSetMagFilter(&tex->gxm_tex, tex->mag_filter);
+ sceGxmTextureSetMipFilter(&tex->gxm_tex, tex->mip_filter);
+ sceGxmTextureSetLodBias(&tex->gxm_tex, tex->lod_bias);
break;
default:
@@ -612,92 +633,92 @@ void glTexParameteri(GLenum target, GLenum pname, GLint param) {
case GL_TEXTURE_MIN_FILTER: // Min filter
switch (param) {
case GL_NEAREST: // Point
- tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
- tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_POINT;
+ tex->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
+ tex->min_filter = SCE_GXM_TEXTURE_FILTER_POINT;
break;
case GL_LINEAR: // Linear
- tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
- tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
+ tex->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
+ tex->min_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
break;
case GL_NEAREST_MIPMAP_NEAREST:
- tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
- tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_POINT;
+ tex->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
+ tex->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_POINT;
break;
case GL_LINEAR_MIPMAP_NEAREST:
- tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_ENABLED;
- tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_POINT;
+ tex->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_ENABLED;
+ tex->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_POINT;
break;
case GL_NEAREST_MIPMAP_LINEAR:
- tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
- tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_LINEAR;
+ tex->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
+ tex->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_LINEAR;
break;
case GL_LINEAR_MIPMAP_LINEAR:
- tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_ENABLED;
- tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_LINEAR;
+ tex->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_ENABLED;
+ tex->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_LINEAR;
break;
default:
SET_GL_ERROR(GL_INVALID_ENUM)
break;
}
- sceGxmTextureSetMinFilter(&tex->gxm_tex, tex_unit->min_filter);
+ sceGxmTextureSetMinFilter(&tex->gxm_tex, tex->min_filter);
break;
case GL_TEXTURE_MAG_FILTER: // Mag Filter
switch (param) {
case GL_NEAREST:
- tex_unit->mag_filter = SCE_GXM_TEXTURE_FILTER_POINT;
+ tex->mag_filter = SCE_GXM_TEXTURE_FILTER_POINT;
break;
case GL_LINEAR:
- tex_unit->mag_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
+ tex->mag_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
break;
default:
SET_GL_ERROR(GL_INVALID_ENUM)
break;
}
- sceGxmTextureSetMagFilter(&tex->gxm_tex, tex_unit->mag_filter);
+ sceGxmTextureSetMagFilter(&tex->gxm_tex, tex->mag_filter);
break;
case GL_TEXTURE_WRAP_S: // U Mode
switch (param) {
case GL_CLAMP_TO_EDGE: // Clamp
- tex_unit->u_mode = SCE_GXM_TEXTURE_ADDR_CLAMP;
+ tex->u_mode = SCE_GXM_TEXTURE_ADDR_CLAMP;
break;
case GL_REPEAT: // Repeat
- tex_unit->u_mode = SCE_GXM_TEXTURE_ADDR_REPEAT;
+ tex->u_mode = SCE_GXM_TEXTURE_ADDR_REPEAT;
break;
case GL_MIRRORED_REPEAT: // Mirror
- tex_unit->u_mode = SCE_GXM_TEXTURE_ADDR_MIRROR;
+ tex->u_mode = SCE_GXM_TEXTURE_ADDR_MIRROR;
break;
case GL_MIRROR_CLAMP_EXT: // Mirror Clamp
- tex_unit->u_mode = SCE_GXM_TEXTURE_ADDR_MIRROR_CLAMP;
+ tex->u_mode = SCE_GXM_TEXTURE_ADDR_MIRROR_CLAMP;
break;
default:
SET_GL_ERROR(GL_INVALID_ENUM)
break;
}
- sceGxmTextureSetUAddrMode(&tex->gxm_tex, tex_unit->u_mode);
+ sceGxmTextureSetUAddrMode(&tex->gxm_tex, tex->u_mode);
break;
case GL_TEXTURE_WRAP_T: // V Mode
switch (param) {
case GL_CLAMP_TO_EDGE: // Clamp
- tex_unit->v_mode = SCE_GXM_TEXTURE_ADDR_CLAMP;
+ tex->v_mode = SCE_GXM_TEXTURE_ADDR_CLAMP;
break;
case GL_REPEAT: // Repeat
- tex_unit->v_mode = SCE_GXM_TEXTURE_ADDR_REPEAT;
+ tex->v_mode = SCE_GXM_TEXTURE_ADDR_REPEAT;
break;
case GL_MIRRORED_REPEAT: // Mirror
- tex_unit->v_mode = SCE_GXM_TEXTURE_ADDR_MIRROR;
+ tex->v_mode = SCE_GXM_TEXTURE_ADDR_MIRROR;
break;
case GL_MIRROR_CLAMP_EXT: // Mirror Clamp
- tex_unit->v_mode = SCE_GXM_TEXTURE_ADDR_MIRROR_CLAMP;
+ tex->v_mode = SCE_GXM_TEXTURE_ADDR_MIRROR_CLAMP;
break;
default:
SET_GL_ERROR(GL_INVALID_ENUM)
break;
}
- sceGxmTextureSetVAddrMode(&tex->gxm_tex, tex_unit->v_mode);
+ sceGxmTextureSetVAddrMode(&tex->gxm_tex, tex->v_mode);
break;
case GL_TEXTURE_LOD_BIAS: // Distant LOD bias
- tex_unit->lod_bias = (uint32_t)(param + GL_MAX_TEXTURE_LOD_BIAS);
- sceGxmTextureSetLodBias(&tex->gxm_tex, tex_unit->lod_bias);
+ tex->lod_bias = (uint32_t)(param + GL_MAX_TEXTURE_LOD_BIAS);
+ sceGxmTextureSetLodBias(&tex->gxm_tex, tex->lod_bias);
break;
default:
SET_GL_ERROR(GL_INVALID_ENUM)
@@ -721,64 +742,64 @@ void glTexParameterf(GLenum target, GLenum pname, GLfloat param) {
switch (pname) {
case GL_TEXTURE_MIN_FILTER: // Min Filter
if (param == GL_NEAREST) {
- tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
- tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_POINT;
+ tex->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
+ tex->min_filter = SCE_GXM_TEXTURE_FILTER_POINT;
}
if (param == GL_LINEAR) {
- tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
- tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
+ tex->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
+ tex->min_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
}
if (param == GL_NEAREST_MIPMAP_NEAREST) {
- tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
- tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_POINT;
+ tex->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
+ tex->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_POINT;
}
if (param == GL_LINEAR_MIPMAP_NEAREST) {
- tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_ENABLED;
- tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_POINT;
+ tex->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_ENABLED;
+ tex->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_POINT;
}
if (param == GL_NEAREST_MIPMAP_LINEAR) {
- tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
- tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_LINEAR;
+ tex->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
+ tex->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_LINEAR;
}
if (param == GL_LINEAR_MIPMAP_LINEAR) {
- tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_ENABLED;
- tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_LINEAR;
+ tex->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_ENABLED;
+ tex->min_filter = SCE_GXM_TEXTURE_FILTER_MIPMAP_LINEAR;
}
- sceGxmTextureSetMinFilter(&tex->gxm_tex, tex_unit->min_filter);
- sceGxmTextureSetMipFilter(&tex->gxm_tex, tex_unit->mip_filter);
+ sceGxmTextureSetMinFilter(&tex->gxm_tex, tex->min_filter);
+ sceGxmTextureSetMipFilter(&tex->gxm_tex, tex->mip_filter);
break;
case GL_TEXTURE_MAG_FILTER: // Mag filter
if (param == GL_NEAREST)
- tex_unit->mag_filter = SCE_GXM_TEXTURE_FILTER_POINT;
+ tex->mag_filter = SCE_GXM_TEXTURE_FILTER_POINT;
else if (param == GL_LINEAR)
- tex_unit->mag_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
- sceGxmTextureSetMagFilter(&tex->gxm_tex, tex_unit->mag_filter);
+ tex->mag_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
+ sceGxmTextureSetMagFilter(&tex->gxm_tex, tex->mag_filter);
break;
case GL_TEXTURE_WRAP_S: // U Mode
if (param == GL_CLAMP_TO_EDGE)
- tex_unit->u_mode = SCE_GXM_TEXTURE_ADDR_CLAMP; // Clamp
+ tex->u_mode = SCE_GXM_TEXTURE_ADDR_CLAMP; // Clamp
else if (param == GL_REPEAT)
- tex_unit->u_mode = SCE_GXM_TEXTURE_ADDR_REPEAT; // Repeat
+ tex->u_mode = SCE_GXM_TEXTURE_ADDR_REPEAT; // Repeat
else if (param == GL_MIRRORED_REPEAT)
- tex_unit->u_mode = SCE_GXM_TEXTURE_ADDR_MIRROR; // Mirror
+ tex->u_mode = SCE_GXM_TEXTURE_ADDR_MIRROR; // Mirror
else if (param == GL_MIRROR_CLAMP_EXT)
- tex_unit->u_mode = SCE_GXM_TEXTURE_ADDR_MIRROR_CLAMP; // Mirror Clamp
- sceGxmTextureSetUAddrMode(&tex->gxm_tex, tex_unit->u_mode);
+ tex->u_mode = SCE_GXM_TEXTURE_ADDR_MIRROR_CLAMP; // Mirror Clamp
+ sceGxmTextureSetUAddrMode(&tex->gxm_tex, tex->u_mode);
break;
case GL_TEXTURE_WRAP_T: // V Mode
if (param == GL_CLAMP_TO_EDGE)
- tex_unit->v_mode = SCE_GXM_TEXTURE_ADDR_CLAMP; // Clamp
+ tex->v_mode = SCE_GXM_TEXTURE_ADDR_CLAMP; // Clamp
else if (param == GL_REPEAT)
- tex_unit->v_mode = SCE_GXM_TEXTURE_ADDR_REPEAT; // Repeat
+ tex->v_mode = SCE_GXM_TEXTURE_ADDR_REPEAT; // Repeat
else if (param == GL_MIRRORED_REPEAT)
- tex_unit->v_mode = SCE_GXM_TEXTURE_ADDR_MIRROR; // Mirror
+ tex->v_mode = SCE_GXM_TEXTURE_ADDR_MIRROR; // Mirror
else if (param == GL_MIRROR_CLAMP_EXT)
- tex_unit->v_mode = SCE_GXM_TEXTURE_ADDR_MIRROR_CLAMP; // Mirror Clamp
- sceGxmTextureSetVAddrMode(&tex->gxm_tex, tex_unit->v_mode);
+ tex->v_mode = SCE_GXM_TEXTURE_ADDR_MIRROR_CLAMP; // Mirror Clamp
+ sceGxmTextureSetVAddrMode(&tex->gxm_tex, tex->v_mode);
break;
case GL_TEXTURE_LOD_BIAS: // Distant LOD bias
- tex_unit->lod_bias = (uint32_t)(param + GL_MAX_TEXTURE_LOD_BIAS);
- sceGxmTextureSetLodBias(&tex->gxm_tex, tex_unit->lod_bias);
+ tex->lod_bias = (uint32_t)(param + GL_MAX_TEXTURE_LOD_BIAS);
+ sceGxmTextureSetLodBias(&tex->gxm_tex, tex->lod_bias);
break;
default:
SET_GL_ERROR(GL_INVALID_ENUM)
@@ -820,12 +841,12 @@ void glGenerateMipmap(GLenum target) {
gpu_alloc_mipmaps(-1, tex);
// Setting texture parameters
- sceGxmTextureSetUAddrMode(&tex->gxm_tex, tex_unit->u_mode);
- sceGxmTextureSetVAddrMode(&tex->gxm_tex, tex_unit->v_mode);
- sceGxmTextureSetMinFilter(&tex->gxm_tex, tex_unit->min_filter);
- sceGxmTextureSetMagFilter(&tex->gxm_tex, tex_unit->mag_filter);
- sceGxmTextureSetMipFilter(&tex->gxm_tex, tex_unit->mip_filter);
- sceGxmTextureSetLodBias(&tex->gxm_tex, tex_unit->lod_bias);
+ sceGxmTextureSetUAddrMode(&tex->gxm_tex, tex->u_mode);
+ sceGxmTextureSetVAddrMode(&tex->gxm_tex, tex->v_mode);
+ sceGxmTextureSetMinFilter(&tex->gxm_tex, tex->min_filter);
+ sceGxmTextureSetMagFilter(&tex->gxm_tex, tex->mag_filter);
+ sceGxmTextureSetMipFilter(&tex->gxm_tex, tex->mip_filter);
+ sceGxmTextureSetLodBias(&tex->gxm_tex, tex->lod_bias);
break;
default:
diff --git a/source/utils/gpu_utils.c b/source/utils/gpu_utils.c
index 3dc922bde3..10807f0629 100644
--- a/source/utils/gpu_utils.c
+++ b/source/utils/gpu_utils.c
@@ -81,7 +81,7 @@ void dxt_compress(uint8_t *dst, uint8_t *src, int w, int h, int isdxt5) {
if (offs_y * 4 >= w)
continue;
extract_block(src + offs_y * 16 + offs_x * w * 16, w, block);
- stb_compress_dxt_block(dst, block, isdxt5, STB_DXT_HIGHQUAL);
+ stb_compress_dxt_block(dst, block, isdxt5, fast_texture_compression ? STB_DXT_NORMAL : STB_DXT_HIGHQUAL);
dst += isdxt5 ? 16 : 8;
}
}
@@ -369,30 +369,31 @@ void gpu_alloc_compressed_texture(uint32_t w, uint32_t h, SceGxmTextureFormat fo
// Allocating texture data buffer
void *texture_data = gpu_alloc_mapped(tex_size, &tex->mtype);
- // NOTE: Supports only GL_RGBA source format for now
-
// Initializing texture data buffer
if (texture_data != NULL) {
- // Initializing texture data buffer
if (data != NULL) {
if (read_cb != NULL) {
- //void *tmp = malloc(w * h * 4);
- //void *tmp2 = malloc(tex_size);
- /*int i, j;
- uint8_t *src = (uint8_t *)data;
- uint32_t *dst = (uint32_t*)tmp;
- for (i = 0; i < h * w; i++) {
- uint32_t clr = read_cb(src);
- writeRGBA(dst++, src);
- src += src_bpp;
- }*/
+ void *temp = (void *)data;
+
+ // stb_dxt expects input as RGBA8888, so we convert input texture if necessary
+ if (read_cb != readRGBA) {
+ temp = malloc(w * h * 4);
+ uint8_t *src = (uint8_t *)data;
+ uint32_t *dst = (uint32_t *)temp;
+ int i;
+ for (i = 0; i < w * h; i++) {
+ uint32_t clr = read_cb(src);
+ writeRGBA(dst++, clr);
+ src += src_bpp;
+ }
+ }
// Performing swizzling and DXT compression
- dxt_compress(texture_data, (void *)data, w, h, alignment == 16);
+ dxt_compress(texture_data, temp, w, h, alignment == 16);
- //swizzle(texture_data, tmp2, w, h, alignment << 3);
- //free(tmp);
- //free(tmp2);
+ // Freeing temporary data if necessary
+ if (read_cb != readRGBA)
+ free(temp);
} else {
// Perform swizzling if necessary.
switch (format) {
diff --git a/source/utils/gpu_utils.h b/source/utils/gpu_utils.h
index 51d59a0b8d..33d9a965ed 100644
--- a/source/utils/gpu_utils.h
+++ b/source/utils/gpu_utils.h
@@ -40,6 +40,12 @@ typedef struct texture {
uint8_t valid;
uint32_t type;
void (*write_cb)(void *, uint32_t);
+ SceGxmTextureFilter min_filter;
+ SceGxmTextureFilter mag_filter;
+ SceGxmTextureAddrMode u_mode;
+ SceGxmTextureAddrMode v_mode;
+ SceGxmTextureMipFilter mip_filter;
+ uint32_t lod_bias;
} texture;
// Palette object struct
diff --git a/source/vitaGL.c b/source/vitaGL.c
index 709890de81..6f602f4194 100644
--- a/source/vitaGL.c
+++ b/source/vitaGL.c
@@ -679,12 +679,6 @@ void vglInitWithCustomSizes(uint32_t gpu_pool_size, int width, int height, int r
texture_units[i].env_mode = MODULATE;
texture_units[i].tex_id = 0;
texture_units[i].enabled = GL_FALSE;
- texture_units[i].min_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
- texture_units[i].mag_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
- texture_units[i].mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
- texture_units[i].u_mode = SCE_GXM_TEXTURE_ADDR_REPEAT;
- texture_units[i].v_mode = SCE_GXM_TEXTURE_ADDR_REPEAT;
- texture_units[i].lod_bias = GL_MAX_TEXTURE_LOD_BIAS; // sceGxm range is 0 - (GL_MAX_TEXTURE_LOD_BIAS*2 + 1)
}
// Init texture slots
@@ -711,6 +705,9 @@ void vglInitWithCustomSizes(uint32_t gpu_pool_size, int width, int height, int r
// Mapping newlib heap into sceGxm
sceGxmMapMemory(addr, _newlib_heap_size, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE);
+
+ // Allocating default texture object
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
void vglInitExtended(uint32_t gpu_pool_size, int width, int height, int ram_threshold, SceGxmMultisampleMode msaa) {
diff --git a/source/vitaGL.h b/source/vitaGL.h
index 1cb602d10b..b739267308 100644
--- a/source/vitaGL.h
+++ b/source/vitaGL.h
@@ -127,6 +127,9 @@ extern "C" {
#define GL_DEPTH_BITS 0x0D56
#define GL_STENCIL_BITS 0x0D57
#define GL_TEXTURE_2D 0x0DE1
+#define GL_DONT_CARE 0x1100
+#define GL_FASTEST 0x1101
+#define GL_NICEST 0x1102
#define GL_BYTE 0x1400
#define GL_UNSIGNED_BYTE 0x1401
#define GL_SHORT 0x1402
@@ -238,6 +241,7 @@ extern "C" {
#define GL_TEXTURE30 0x84DE
#define GL_TEXTURE31 0x84DF
#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
#define GL_TEXTURE_LOD_BIAS 0x8501
#define GL_INCR_WRAP 0x8507
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
@@ -356,6 +360,7 @@ void glGetShaderInfoLog(GLuint handle, GLsizei maxLength, GLsizei *length, GLcha
void glGetShaderiv(GLuint handle, GLenum pname, GLint *params);
const GLubyte *glGetString(GLenum name);
GLint glGetUniformLocation(GLuint prog, const GLchar *name);
+void glHint(GLenum target, GLenum mode);
GLboolean glIsEnabled(GLenum cap);
void glLineWidth(GLfloat width);
void glLinkProgram(GLuint progr);
@@ -425,7 +430,7 @@ void vglVertexPointerMapped(const GLvoid *pointer);
// VGL_EXT_gxp_shaders extension implementation
void vglBindAttribLocation(GLuint prog, GLuint index, const GLchar *name, const GLuint num, const GLenum type);
-void vglBindPackedAttribLocation(GLuint prog, const GLchar *name, const GLuint num, const GLenum type, GLuint offset, GLint stride);
+GLint vglBindPackedAttribLocation(GLuint prog, const GLchar *name, const GLuint num, const GLenum type, GLuint offset, GLint stride);
void vglVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint count, const GLvoid *pointer);
void vglVertexAttribPointerMapped(GLuint index, const GLvoid *pointer);