From 169ad6fa52457a67975bfe4491a0412b5069d822 Mon Sep 17 00:00:00 2001 From: frangarcj Date: Fri, 13 Nov 2020 14:29:36 +0100 Subject: [PATCH] Squashed 'deps/vitaGL/' changes from 81403e2..34bc720 34bc720 Added more hbs to the vitaGL showcase section. 9904e7f Added GL_TEXTURE_COMPRESSION_HINT support. bf5a136 Run clang-format. 65c509e Fix for HAVE_SHARK=2 build crashing when compiling a shader. 2b263af Added support for non GL_RGBA textures to the DXT compressor. 9c963ab Exposing internal gxm surface addresses. 778c67b Properly set texture parameters scope to mimic GL. cda15fc Added sanity check to framebuffer pointer. 45fa81b Properly reserving texture id 0. 38c8715 Added return value to vglBindPackedAttribLocation. git-subtree-dir: deps/vitaGL git-subtree-split: 34bc7201f3929203b0e549633dfaae26fd09fe8e --- README.md | 8 +- source/custom_shaders.c | 75 ++++++++++------- source/framebuffers.c | 24 +++--- source/gxm.c | 13 +-- source/misc.c | 19 +++++ source/shared.h | 6 +- source/state.h | 6 -- source/textures.c | 177 ++++++++++++++++++++++----------------- source/utils/gpu_utils.c | 37 ++++---- source/utils/gpu_utils.h | 6 ++ source/vitaGL.c | 9 +- source/vitaGL.h | 7 +- 12 files changed, 226 insertions(+), 161 deletions(-) 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);