mirror of
https://github.com/libretro/RetroArch
synced 2025-03-25 16:44:01 +00:00
Squashed 'deps/vitaGL/' changes from 2934af8af0..81403e2751
81403e2751 Fix error requiring HAVE_SHARK to be enabled to build. (#45) 58551e1f52 Added possibility to change runtime shader compiler optimization flags. 77ab50a7b1 Added GL_BGR and GL_BGRA texture formats support. 0ac2793bcf Fix error in texture wrapping options. (#42) 0d2110ac7b Improvements to GL buffer support. (#41) cf86149a85 Added proper compressed texture support. (#40) 8b0a0f735a Unbinded textures and texture units concepts. 1b04851efc Added glUniform2i and glUniform2f implementations. 9a65397ef6 Properly checking for uniform locations existence. 91c557f35d Added support for GL_SHORT attribute types for shaders. 3237fd3fe3 Added vglTexImageDepthBuffer function. f58b3818f2 Typo fix on mag filter setting. ee11f7e1d0 Added vglHasRuntimeShaderCompiler function. 3596242f73 Add PowerVR texture compression (PVRTC) support (#39) 2ae694df4b Added support for mipmaps filtering. af7804b44c Added vglGetGxmTexture implementation. 54b1df4ca2 Removed unused arguments. 7c2ed742ee Allow to call vglBind*Location funcs with wrong param names. 8be84ff698 Fixed RGB565 color conversion. 234ff57f65 Properly setting a single stream with packed attributes. d3b28a5e32 Fix for correct vglBindAttribLocation behaviour. 46e72d3564 Use a single stream for packed attributes. 72a39315e9 Properly dealing with missing attrs in glGetUniformLocation. a6269ce574 Added TEXUNIT1 support for custom shaders. 824d43073e Resetting custom shaders uniforms only when invalidated. d242570161 Minor fix in glShaderSource. bc28bd946d Added glGetShaderInfoLog implementation. git-subtree-dir: deps/vitaGL git-subtree-split: 81403e2751c4dc28cf17cc89a5ab053eb2c5af67
This commit is contained in:
parent
51922ea5be
commit
8838992085
4
Makefile
4
Makefile
@ -26,6 +26,10 @@ ifeq ($(HAVE_SHARK),1)
|
||||
CFLAGS += -DHAVE_SHARK
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SHARK),2)
|
||||
CFLAGS += -DHAVE_SHARK -DHAVE_SHARK_LOG
|
||||
endif
|
||||
|
||||
all: $(TARGET).a
|
||||
|
||||
$(TARGET).a: $(OBJS)
|
||||
|
@ -29,6 +29,8 @@ Direct OpenGL Usage:<br>
|
||||
[Daedalus X64](https://github.com/Rinnegatamante/daedalusx64-vitagl) - Port of Daedalus X64 (N64 Emulator)<br>
|
||||
[RetroArch](https://github.com/libretro/RetroArch) - Vita's GL1 video driver of RetroArch<br>
|
||||
[vitaET](https://github.com/Rinnegatamante/vitaET) - Port of ET:Legacy (Wolfenstein: Enemy Territory)<br>
|
||||
[flycast](https://github.com/Rinnegatamante/flycast) - Port of flycast (Dreamcast Emulator)<br>
|
||||
[AvP Gold](https://github.com/Rinnegatamante/AvP-Gold-Vita) - Port of Aliens versus Predator: Gold Edition<br>
|
||||
|
||||
Libraries:<br>
|
||||
[sdl12_gl](https://github.com/Rinnegatamante/SDL-Vita/tree/sdl12_gl/src) - SDL 1.2 Vita port adapted to work with vitaGL as renderer<br>
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
#define MAX_CUSTOM_SHADERS 64 // Maximum number of linkable custom shaders
|
||||
#define MAX_CUSTOM_SHADERS 128 // Maximum number of linkable custom shaders
|
||||
#define MAX_SHADER_PARAMS 8 // Maximum number of parameters per custom shader
|
||||
|
||||
// Internal stuffs
|
||||
@ -32,6 +32,14 @@ void *vert_uniforms = NULL;
|
||||
uint8_t use_shark = 1; // Flag to check if vitaShaRK should be initialized at vitaGL boot
|
||||
uint8_t is_shark_online = 0; // Current vitaShaRK status
|
||||
|
||||
#ifdef HAVE_SHARK
|
||||
// Internal runtime shader compiler settings
|
||||
static int32_t compiler_fastmath = 0;
|
||||
static int32_t compiler_fastprecision = 0;
|
||||
static int32_t compiler_fastint = 0;
|
||||
static shark_opt compiler_opts = SHARK_OPT_DEFAULT;
|
||||
#endif
|
||||
|
||||
GLuint cur_program = 0; // Current in use custom program (0 = No custom program)
|
||||
|
||||
// Uniform struct
|
||||
@ -48,6 +56,7 @@ typedef struct shader {
|
||||
SceGxmShaderPatcherId id;
|
||||
const SceGxmProgram *prog;
|
||||
uint32_t size;
|
||||
char *log;
|
||||
} shader;
|
||||
|
||||
// Program struct holding vertex/fragment shader info
|
||||
@ -60,6 +69,7 @@ typedef struct program {
|
||||
SceGxmVertexProgram *vprog;
|
||||
SceGxmFragmentProgram *fprog;
|
||||
GLuint attr_num;
|
||||
GLuint stream_num;
|
||||
const SceGxmProgramParameter *wvp;
|
||||
uniform *uniforms;
|
||||
uniform *last_uniform;
|
||||
@ -76,6 +86,7 @@ void resetCustomShaders(void) {
|
||||
int i;
|
||||
for (i = 0; i < MAX_CUSTOM_SHADERS; i++) {
|
||||
shaders[i].valid = 0;
|
||||
shaders[i].log = NULL;
|
||||
progs[i >> 1].valid = 0;
|
||||
}
|
||||
}
|
||||
@ -102,6 +113,8 @@ void reloadCustomShader(void) {
|
||||
program *p = &progs[cur_program - 1];
|
||||
sceGxmSetVertexProgram(gxm_context, p->vprog);
|
||||
sceGxmSetFragmentProgram(gxm_context, p->fprog);
|
||||
vert_uniforms = NULL;
|
||||
frag_uniforms = NULL;
|
||||
}
|
||||
|
||||
void _vglDrawObjects_CustomShadersIMPL(GLenum mode, GLsizei count, GLboolean implicit_wvp) {
|
||||
@ -119,11 +132,39 @@ void _vglDrawObjects_CustomShadersIMPL(GLenum mode, GLsizei count, GLboolean imp
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_SHARK) && defined(HAVE_SHARK_LOG)
|
||||
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);
|
||||
switch (msg_level) {
|
||||
case SHARK_LOG_INFO:
|
||||
sprintf(shark_log, "%s%sI] %s on line %d", append ? shark_log : "", 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);
|
||||
break;
|
||||
case SHARK_LOG_ERROR:
|
||||
sprintf(shark_log, "%s%sE] %s on line %d", append ? shark_log : "", append ? "\n" : "", msg, line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ------------------------------
|
||||
* - IMPLEMENTATION STARTS HERE -
|
||||
* ------------------------------
|
||||
*/
|
||||
void vglSetupRuntimeShaderCompiler(shark_opt opt_level, int32_t use_fastmath, int32_t use_fastprecision, int32_t use_fastint) {
|
||||
#ifdef HAVE_SHARK
|
||||
compiler_opts = opt_level;
|
||||
compiler_fastmath = use_fastmath;
|
||||
compiler_fastprecision = use_fastprecision;
|
||||
compiler_fastint = use_fastint;
|
||||
#endif
|
||||
}
|
||||
|
||||
void vglEnableRuntimeShaderCompiler(GLboolean usage) {
|
||||
use_shark = usage;
|
||||
@ -172,12 +213,31 @@ void glGetShaderiv(GLuint handle, GLenum pname, GLint *params) {
|
||||
case GL_COMPILE_STATUS:
|
||||
*params = s->prog ? GL_TRUE : GL_FALSE;
|
||||
break;
|
||||
case GL_INFO_LOG_LENGTH:
|
||||
*params = s->log ? strlen(s->log) : 0;
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void glGetShaderInfoLog(GLuint handle, GLsizei maxLength, GLsizei *length, GLchar *infoLog) {
|
||||
#ifndef SKIP_ERROR_HANDLING
|
||||
if (maxLength < 0) {
|
||||
SET_GL_ERROR(GL_INVALID_VALUE)
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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) {
|
||||
#ifndef SKIP_ERROR_HANDLING
|
||||
if (count < 0) {
|
||||
@ -192,8 +252,8 @@ void glShaderSource(GLuint handle, GLsizei count, const GLchar * const *string,
|
||||
shader *s = &shaders[handle - 1];
|
||||
|
||||
// Temporarily setting prog to point to the shader source
|
||||
s->prog = (SceGxmProgram *)string;
|
||||
s->size = *length;
|
||||
s->prog = (SceGxmProgram *)*string;
|
||||
s->size = length ? *length : strlen(*string);
|
||||
}
|
||||
|
||||
void glShaderBinary(GLsizei count, const GLuint *handles, GLenum binaryFormat, const void *binary, GLsizei length) {
|
||||
@ -207,6 +267,7 @@ void glShaderBinary(GLsizei count, const GLuint *handles, GLenum binaryFormat, c
|
||||
s->prog = sceGxmShaderPatcherGetProgramFromId(s->id);
|
||||
}
|
||||
|
||||
uint8_t shader_idxs = 0;
|
||||
void glCompileShader(GLuint handle) {
|
||||
// If vitaShaRK is not enabled, we just error out
|
||||
if (!is_shark_online) {
|
||||
@ -217,7 +278,7 @@ void glCompileShader(GLuint handle) {
|
||||
shader *s = &shaders[handle - 1];
|
||||
|
||||
// Compiling shader source
|
||||
s->prog = shark_compile_shader((const char*)s->prog, &s->size, s->type == GL_FRAGMENT_SHADER ? SHARK_FRAGMENT_SHADER : SHARK_VERTEX_SHADER);
|
||||
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);
|
||||
@ -225,6 +286,10 @@ void glCompileShader(GLuint handle) {
|
||||
sceGxmShaderPatcherRegisterProgram(gxm_shader_patcher, s->prog, &s->id);
|
||||
s->prog = sceGxmShaderPatcherGetProgramFromId(s->id);
|
||||
}
|
||||
#ifdef HAVE_SHARK_LOG
|
||||
s->log = shark_log;
|
||||
shark_log = NULL;
|
||||
#endif
|
||||
shark_clear_output();
|
||||
#endif
|
||||
}
|
||||
@ -237,7 +302,9 @@ void glDeleteShader(GLuint shad) {
|
||||
if (s->valid) {
|
||||
sceGxmShaderPatcherForceUnregisterProgram(gxm_shader_patcher, s->id);
|
||||
free((void *)s->prog);
|
||||
if (s->log) free(s->log);
|
||||
}
|
||||
s->log = NULL;
|
||||
s->valid = GL_FALSE;
|
||||
}
|
||||
|
||||
@ -309,7 +376,7 @@ void glLinkProgram(GLuint progr) {
|
||||
// Creating fragment and vertex program via sceGxmShaderPatcher
|
||||
sceGxmShaderPatcherCreateVertexProgram(gxm_shader_patcher,
|
||||
p->vshader->id, p->attr, p->attr_num,
|
||||
p->stream, p->attr_num, &p->vprog);
|
||||
p->stream, p->stream_num, &p->vprog);
|
||||
sceGxmShaderPatcherCreateFragmentProgram(gxm_shader_patcher,
|
||||
p->fshader->id, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||
msaa_mode, NULL, p->vshader->prog,
|
||||
@ -330,9 +397,6 @@ GLint glGetUniformLocation(GLuint prog, const GLchar *name) {
|
||||
|
||||
uniform *res = (uniform *)malloc(sizeof(uniform));
|
||||
res->chain = NULL;
|
||||
if (p->last_uniform != NULL)
|
||||
p->last_uniform->chain = (void *)res;
|
||||
p->last_uniform = res;
|
||||
|
||||
// Checking if parameter is a vertex or fragment related one
|
||||
res->ptr = sceGxmProgramFindParameterByName(p->vshader->prog, name);
|
||||
@ -342,10 +406,23 @@ GLint glGetUniformLocation(GLuint prog, const GLchar *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;
|
||||
|
||||
return (GLint)res;
|
||||
}
|
||||
|
||||
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)
|
||||
@ -365,7 +442,39 @@ void glUniform1i(GLint location, GLint v0) {
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
// Setting passed value to desired uniform
|
||||
if (u->isVertex) {
|
||||
if (vert_uniforms == NULL)
|
||||
sceGxmReserveVertexDefaultUniformBuffer(gxm_context, &vert_uniforms);
|
||||
float v0_f[2];
|
||||
v0_f[0] = (float)v0;
|
||||
v0_f[1] = (float)v1;
|
||||
sceGxmSetUniformDataF(vert_uniforms, u->ptr, 0, 2, v0_f);
|
||||
} else {
|
||||
if (frag_uniforms == NULL)
|
||||
sceGxmReserveFragmentDefaultUniformBuffer(gxm_context, &frag_uniforms);
|
||||
float v0_f[2];
|
||||
v0_f[0] = (float)v0;
|
||||
v0_f[1] = (float)v1;
|
||||
sceGxmSetUniformDataF(frag_uniforms, u->ptr, 0, 2, v0_f);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@ -383,7 +492,39 @@ void glUniform1f(GLint location, GLfloat v0) {
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
// Setting passed value to desired uniform
|
||||
if (u->isVertex) {
|
||||
if (vert_uniforms == NULL)
|
||||
sceGxmReserveVertexDefaultUniformBuffer(gxm_context, &vert_uniforms);
|
||||
float v0_f[2];
|
||||
v0_f[0] = v0;
|
||||
v0_f[1] = v1;
|
||||
sceGxmSetUniformDataF(vert_uniforms, u->ptr, 0, 2, v0_f);
|
||||
} else {
|
||||
if (frag_uniforms == NULL)
|
||||
sceGxmReserveFragmentDefaultUniformBuffer(gxm_context, &frag_uniforms);
|
||||
float v0_f[2];
|
||||
v0_f[0] = v0;
|
||||
v0_f[1] = v1;
|
||||
sceGxmSetUniformDataF(frag_uniforms, u->ptr, 0, 2, v0_f);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@ -402,6 +543,10 @@ void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) {
|
||||
}
|
||||
|
||||
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)
|
||||
@ -420,6 +565,10 @@ void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) {
|
||||
}
|
||||
|
||||
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)
|
||||
@ -439,6 +588,10 @@ void glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
|
||||
}
|
||||
|
||||
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)
|
||||
@ -457,6 +610,10 @@ void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) {
|
||||
}
|
||||
|
||||
void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
|
||||
// Checking if the uniform does exist
|
||||
if (location == -1)
|
||||
return;
|
||||
|
||||
// Grabbing passed uniform
|
||||
uniform *u = (uniform *)location;
|
||||
if (u->ptr == NULL)
|
||||
@ -480,7 +637,8 @@ void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, cons
|
||||
* ------------------------------
|
||||
*/
|
||||
|
||||
void vglBindPackedAttribLocation(GLuint prog, GLuint index, const GLchar *name, const GLuint num, const GLenum type, GLuint offset, GLint stride) {
|
||||
// Equivalent of glBindAttribLocation but for sceGxm architecture
|
||||
void vglBindAttribLocation(GLuint prog, GLuint index, const GLchar *name, const GLuint num, const GLenum type) {
|
||||
// Grabbing passed program
|
||||
program *p = &progs[prog - 1];
|
||||
SceGxmVertexAttribute *attributes = &p->attr[index];
|
||||
@ -488,9 +646,56 @@ void vglBindPackedAttribLocation(GLuint prog, GLuint index, const GLchar *name,
|
||||
|
||||
// Looking for desired parameter in requested program
|
||||
const SceGxmProgramParameter *param = sceGxmProgramFindParameterByName(p->vshader->prog, name);
|
||||
if (param == NULL) return;
|
||||
|
||||
// Setting stream index and offset values
|
||||
attributes->streamIndex = index;
|
||||
attributes->offset = 0;
|
||||
|
||||
// Detecting attribute format and size
|
||||
int bpe;
|
||||
switch (type) {
|
||||
case GL_FLOAT:
|
||||
attributes->format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
|
||||
bpe = sizeof(float);
|
||||
break;
|
||||
case GL_SHORT:
|
||||
attributes->format = SCE_GXM_ATTRIBUTE_FORMAT_S16N;
|
||||
bpe = sizeof(int16_t);
|
||||
break;
|
||||
case GL_UNSIGNED_BYTE:
|
||||
attributes->format = SCE_GXM_ATTRIBUTE_FORMAT_U8N;
|
||||
bpe = sizeof(uint8_t);
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
}
|
||||
|
||||
// Setting various info about the stream
|
||||
attributes->componentCount = num;
|
||||
attributes->regIndex = sceGxmProgramParameterGetResourceIndex(param);
|
||||
streams->stride = bpe * num;
|
||||
streams->indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
|
||||
if (index >= p->attr_num) {
|
||||
p->attr_num = index + 1;
|
||||
p->stream_num = index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// Grabbing passed program
|
||||
program *p = &progs[prog - 1];
|
||||
SceGxmVertexAttribute *attributes = &p->attr[p->attr_num];
|
||||
SceGxmVertexStream *streams = &p->stream[0];
|
||||
|
||||
// Looking for desired parameter in requested program
|
||||
const SceGxmProgramParameter *param = sceGxmProgramFindParameterByName(p->vshader->prog, name);
|
||||
if (param == NULL) return;
|
||||
|
||||
// Setting stream index and offset values
|
||||
attributes->streamIndex = 0;
|
||||
attributes->offset = offset;
|
||||
|
||||
// Detecting attribute format and size
|
||||
@ -500,6 +705,10 @@ void vglBindPackedAttribLocation(GLuint prog, GLuint index, const GLchar *name,
|
||||
attributes->format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
|
||||
bpe = sizeof(float);
|
||||
break;
|
||||
case GL_SHORT:
|
||||
attributes->format = SCE_GXM_ATTRIBUTE_FORMAT_S16N;
|
||||
bpe = sizeof(int16_t);
|
||||
break;
|
||||
case GL_UNSIGNED_BYTE:
|
||||
attributes->format = SCE_GXM_ATTRIBUTE_FORMAT_U8N;
|
||||
bpe = sizeof(uint8_t);
|
||||
@ -514,13 +723,8 @@ void vglBindPackedAttribLocation(GLuint prog, GLuint index, const GLchar *name,
|
||||
attributes->regIndex = sceGxmProgramParameterGetResourceIndex(param);
|
||||
streams->stride = stride ? stride : bpe * num;
|
||||
streams->indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
|
||||
if (index >= p->attr_num)
|
||||
p->attr_num = index + 1;
|
||||
}
|
||||
|
||||
// Equivalent of glBindAttribLocation but for sceGxm architecture
|
||||
void vglBindAttribLocation(GLuint prog, GLuint index, const GLchar *name, const GLuint num, const GLenum type) {
|
||||
vglBindPackedAttribLocation(prog, index, name, num, type, 0, 0);
|
||||
p->stream_num = 1;
|
||||
p->attr_num++;
|
||||
}
|
||||
|
||||
// Equivalent of glVertexAttribPointer but for sceGxm architecture
|
||||
|
@ -137,12 +137,11 @@ void glFramebufferTexture(GLenum target, GLenum attachment, GLuint tex_id, GLint
|
||||
}
|
||||
|
||||
// Aliasing to make code more readable
|
||||
texture_unit *tex_unit = &texture_units[server_texture_unit];
|
||||
texture *tex = &tex_unit->textures[tex_id];
|
||||
texture *tex = &textures[tex_id];
|
||||
|
||||
// Extracting texture sizes
|
||||
int tex_w = sceGxmTextureGetWidth(&tex->gxm_tex);
|
||||
int tex_h = sceGxmTextureGetHeight(&tex->gxm_tex);
|
||||
fb->width = sceGxmTextureGetWidth(&tex->gxm_tex);
|
||||
fb->height = sceGxmTextureGetHeight(&tex->gxm_tex);
|
||||
|
||||
// Detecting requested attachment
|
||||
switch (attachment) {
|
||||
@ -155,13 +154,13 @@ void glFramebufferTexture(GLenum target, GLenum attachment, GLuint tex_id, GLint
|
||||
SCE_GXM_COLOR_SURFACE_LINEAR,
|
||||
msaa_mode == SCE_GXM_MULTISAMPLE_NONE ? SCE_GXM_COLOR_SURFACE_SCALE_NONE : SCE_GXM_COLOR_SURFACE_SCALE_MSAA_DOWNSCALE,
|
||||
SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,
|
||||
tex_w,
|
||||
tex_h,
|
||||
tex_w,
|
||||
fb->width,
|
||||
fb->height,
|
||||
fb->width,
|
||||
sceGxmTextureGetData(&tex->gxm_tex));
|
||||
|
||||
// Allocating depth and stencil buffer (FIXME: This probably shouldn't be here)
|
||||
initDepthStencilBuffer(tex_w, tex_h, &fb->depthbuffer, &fb->depth_buffer_addr, &fb->stencil_buffer_addr, &fb->depth_buffer_mem_type, &fb->stencil_buffer_mem_type);
|
||||
initDepthStencilBuffer(fb->width, fb->height, &fb->depthbuffer, &fb->depth_buffer_addr, &fb->stencil_buffer_addr, &fb->depth_buffer_mem_type, &fb->stencil_buffer_mem_type);
|
||||
|
||||
// Creating rendertarget
|
||||
SceGxmRenderTargetParams renderTargetParams;
|
||||
@ -180,3 +179,27 @@ void glFramebufferTexture(GLenum target, GLenum attachment, GLuint tex_id, GLint
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* vgl* */
|
||||
|
||||
void vglTexImageDepthBuffer(GLenum target) {
|
||||
// Setting some aliases to make code more readable
|
||||
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:
|
||||
{
|
||||
if (active_read_fb)
|
||||
sceGxmTextureInitLinear(&tex->gxm_tex, active_read_fb->depth_buffer_addr, SCE_GXM_TEXTURE_FORMAT_DF32M, active_read_fb->width, active_read_fb->height, 0);
|
||||
else
|
||||
sceGxmTextureInitLinear(&tex->gxm_tex, gxm_depth_surface_addr, SCE_GXM_TEXTURE_FORMAT_DF32M, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0);
|
||||
tex->valid = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +167,20 @@ void glGetIntegerv(GLenum pname, GLint *data) {
|
||||
case GL_STENCIL_BITS:
|
||||
data[0] = 8;
|
||||
break;
|
||||
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
|
||||
*data = COMPRESSED_TEXTURE_FORMATS_NUM;
|
||||
break;
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS:
|
||||
data[0] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
data[1] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
data[2] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
data[3] = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
|
||||
data[4] = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
|
||||
data[5] = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
|
||||
data[6] = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
|
||||
data[7] = GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG;
|
||||
data[8] = GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG;
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
|
10
source/gxm.c
10
source/gxm.c
@ -42,7 +42,7 @@ static void *gxm_shader_patcher_buffer_addr; // Shader PAtcher buffer memblock s
|
||||
static void *gxm_shader_patcher_vertex_usse_addr; // Shader Patcher vertex USSE memblock starting address
|
||||
static void *gxm_shader_patcher_fragment_usse_addr; // Shader Patcher fragment USSE memblock starting address
|
||||
|
||||
static void *gxm_depth_surface_addr; // Depth surface memblock starting address
|
||||
void *gxm_depth_surface_addr; // Depth surface memblock starting address
|
||||
static void *gxm_stencil_surface_addr; // Stencil surface memblock starting address
|
||||
static SceGxmDepthStencilSurface gxm_depth_stencil_surface; // Depth/Stencil surfaces setup for sceGxm
|
||||
|
||||
@ -109,9 +109,13 @@ void initGxm(void) {
|
||||
// Initializing runtime shader compiler
|
||||
if (use_shark) {
|
||||
#ifdef HAVE_SHARK
|
||||
if (shark_init(NULL) >= 0)
|
||||
if (shark_init(NULL) >= 0) {
|
||||
is_shark_online = 1;
|
||||
else
|
||||
#ifdef HAVE_SHARK_LOG
|
||||
shark_install_log_cb(shark_log_cb);
|
||||
shark_set_warnings_level(SHARK_WARN_MAX);
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
is_shark_online = 0;
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ void glEnd(void) {
|
||||
}
|
||||
|
||||
// Checking if we have to write a texture
|
||||
if ((server_texture_unit >= 0) && (tex_unit->enabled) && (model_uv != NULL) && (tex_unit->textures[texture2d_idx].valid)) {
|
||||
if ((server_texture_unit >= 0) && (tex_unit->enabled) && (model_uv != NULL) && (textures[texture2d_idx].valid)) {
|
||||
// Setting proper vertex and fragment programs
|
||||
sceGxmSetVertexProgram(gxm_context, texture2d_vertex_program_patched);
|
||||
sceGxmSetFragmentProgram(gxm_context, texture2d_fragment_program_patched);
|
||||
@ -474,7 +474,7 @@ void glEnd(void) {
|
||||
sceGxmSetUniformDataF(vertex_wvp_buffer, texture2d_mv, 0, 16, (const float *)modelview_matrix);
|
||||
|
||||
// Setting in use texture
|
||||
sceGxmSetFragmentTexture(gxm_context, 0, &tex_unit->textures[texture2d_idx].gxm_tex);
|
||||
sceGxmSetFragmentTexture(gxm_context, 0, &textures[texture2d_idx].gxm_tex);
|
||||
|
||||
// Properly generating vertices, uv map and indices buffers
|
||||
vector3f *vertices;
|
||||
|
@ -26,7 +26,8 @@
|
||||
#define _SHARED_H_
|
||||
|
||||
// Internal constants
|
||||
#define TEXTURES_NUM 4096 // Available textures per texture unit
|
||||
#define TEXTURES_NUM 16384 // Available textures
|
||||
#define COMPRESSED_TEXTURE_FORMATS_NUM 9 // The number of supported texture formats.
|
||||
#define MODELVIEW_STACK_DEPTH 32 // Depth of modelview matrix stack
|
||||
#define GENERIC_STACK_DEPTH 2 // Depth of generic matrix stack
|
||||
#define DISPLAY_WIDTH_DEF 960 // Default display width in pixels
|
||||
@ -104,10 +105,18 @@ extern GLboolean use_extra_mem;
|
||||
void LOG(const char *format, ...);
|
||||
#endif
|
||||
|
||||
// Depending on SDK, that could be or not defined
|
||||
// Logging callback for vitaShaRK
|
||||
#if defined(HAVE_SHARK) && defined(HAVE_SHARK_LOG)
|
||||
void shark_log_cb(const char *msg, shark_log_level msg_level, int line);
|
||||
#endif
|
||||
|
||||
// Depending on SDK, these could be or not defined
|
||||
#ifndef max
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
extern uint8_t use_shark; // Flag to check if vitaShaRK should be initialized at vitaGL boot
|
||||
extern uint8_t is_shark_online; // Current vitaShaRK status
|
||||
@ -131,6 +140,7 @@ extern float fullscreen_z_scale;
|
||||
extern SceGxmContext *gxm_context; // sceGxm context instance
|
||||
extern GLenum vgl_error; // Error returned by glGetError
|
||||
extern SceGxmShaderPatcher *gxm_shader_patcher; // sceGxmShaderPatcher shader patcher instance
|
||||
extern void *gxm_depth_surface_addr; // Depth surface memblock starting address
|
||||
extern uint8_t system_app_mode; // Flag for system app mode usage
|
||||
|
||||
extern matrix4x4 mvp_matrix; // ModelViewProjection Matrix
|
||||
|
@ -81,7 +81,6 @@ typedef struct texture_unit {
|
||||
GLboolean color_array_state;
|
||||
GLboolean texture_array_state;
|
||||
matrix4x4 stack[GENERIC_STACK_DEPTH];
|
||||
texture textures[TEXTURES_NUM];
|
||||
vertexArray vertex_array;
|
||||
vertexArray color_array;
|
||||
vertexArray texture_array;
|
||||
@ -96,6 +95,7 @@ typedef struct texture_unit {
|
||||
SceGxmTextureFilter mag_filter;
|
||||
SceGxmTextureAddrMode u_mode;
|
||||
SceGxmTextureAddrMode v_mode;
|
||||
SceGxmTextureMipFilter mip_filter;
|
||||
uint32_t lod_bias;
|
||||
} texture_unit;
|
||||
|
||||
@ -109,6 +109,8 @@ typedef struct framebuffer {
|
||||
vglMemType depth_buffer_mem_type;
|
||||
void *stencil_buffer_addr;
|
||||
vglMemType stencil_buffer_mem_type;
|
||||
int width;
|
||||
int height;
|
||||
} framebuffer;
|
||||
|
||||
// Blending
|
||||
@ -159,6 +161,7 @@ extern GLfloat pol_units; // Current units for glPolygonOffset
|
||||
|
||||
// Texture Units
|
||||
extern texture_unit texture_units[GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS]; // Available texture units
|
||||
extern texture textures[TEXTURES_NUM]; // Available texture slots
|
||||
extern int8_t server_texture_unit; // Current in use server side texture unit
|
||||
extern int8_t client_texture_unit; // Current in use client side texture unit
|
||||
extern palette *color_table; // Current in-use color table
|
||||
|
@ -29,6 +29,17 @@
|
||||
|
||||
#define convert_u16_to_u32_cspace(color, lshift, rshift, mask) ((((color << lshift) >> rshift) & mask) * 0xFF) / mask
|
||||
|
||||
// Read callback for 32bpp unsigned ABGR format
|
||||
uint32_t readBGRA(void *data) {
|
||||
uint32_t res;
|
||||
memcpy_neon(&res, data, 4);
|
||||
uint8_t *p = (uint8_t *)&res;
|
||||
uint8_t tmp = p[0];
|
||||
p[0] = p[2];
|
||||
p[2] = tmp;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Read callback for 32bpp unsigned RGBA format
|
||||
uint32_t readRGBA(void *data) {
|
||||
uint32_t res;
|
||||
@ -66,11 +77,22 @@ uint32_t readRGB565(void *data) {
|
||||
uint32_t r, g, b;
|
||||
memcpy_neon(&clr, data, 2);
|
||||
r = convert_u16_to_u32_cspace(clr, 0, 11, 0x1F);
|
||||
g = convert_u16_to_u32_cspace(clr, 5, 11, 0x3F);
|
||||
g = convert_u16_to_u32_cspace(clr, 5, 10, 0x3F);
|
||||
b = convert_u16_to_u32_cspace(clr, 11, 11, 0x1F);
|
||||
return ((0xFF << 24) | (b << 16) | (g << 8) | r);
|
||||
}
|
||||
|
||||
// Read callback for 24bpp unsigned BGR format
|
||||
uint32_t readBGR(void *data) {
|
||||
uint32_t res = 0xFFFFFFFF;
|
||||
uint8_t *src = (uint8_t *)data;
|
||||
uint8_t *dst = (uint8_t *)res;
|
||||
dst[0] = src[2];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[0];
|
||||
return res;
|
||||
}
|
||||
|
||||
// Read callback for 24bpp unsigned RGB format
|
||||
uint32_t readRGB(void *data) {
|
||||
uint32_t res = 0xFFFFFFFF;
|
||||
@ -97,11 +119,29 @@ void writeRGBA(void *data, uint32_t color) {
|
||||
memcpy_neon(data, &color, 4);
|
||||
}
|
||||
|
||||
// Write callback for 32bpp unsigned BGRA format
|
||||
void writeBGRA(void *data, uint32_t color) {
|
||||
memcpy_neon(data, &color, 4);
|
||||
uint8_t *p = (uint8_t *)data;
|
||||
uint8_t tmp = p[0];
|
||||
p[0] = p[2];
|
||||
p[2] = tmp;
|
||||
}
|
||||
|
||||
// Write callback for 24bpp unsigned RGB format
|
||||
void writeRGB(void *data, uint32_t color) {
|
||||
memcpy_neon(data, &color, 3);
|
||||
}
|
||||
|
||||
// Write callback for 24bpp unsigned BGR format
|
||||
void writeBGR(void *data, uint32_t color) {
|
||||
uint8_t *src = (uint8_t *)&color;
|
||||
uint8_t *dst = (uint8_t *)data;
|
||||
dst[0] = src[2];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[0];
|
||||
}
|
||||
|
||||
// Write callback for 16bpp unsigned RG format
|
||||
void writeRG(void *data, uint32_t color) {
|
||||
memcpy_neon(data, &color, 2);
|
||||
|
@ -28,8 +28,10 @@
|
||||
uint32_t readR(void *data);
|
||||
uint32_t readRG(void *data);
|
||||
uint32_t readRGB(void *data);
|
||||
uint32_t readBGR(void *data);
|
||||
uint32_t readRGB565(void *data);
|
||||
uint32_t readRGBA(void *data);
|
||||
uint32_t readBGRA(void *data);
|
||||
uint32_t readRGBA5551(void *data);
|
||||
uint32_t readRGBA4444(void *data);
|
||||
|
||||
@ -38,6 +40,8 @@ void writeR(void *data, uint32_t color);
|
||||
void writeRG(void *data, uint32_t color);
|
||||
void writeRA(void *data, uint32_t color);
|
||||
void writeRGB(void *data, uint32_t color);
|
||||
void writeBGR(void *data, uint32_t color);
|
||||
void writeRGBA(void *data, uint32_t color);
|
||||
void writeBGRA(void *data, uint32_t color);
|
||||
|
||||
#endif
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "shared.h"
|
||||
|
||||
texture_unit texture_units[GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS]; // Available texture units
|
||||
texture textures[TEXTURES_NUM]; // Available texture slots
|
||||
palette *color_table = NULL; // Current in-use color table
|
||||
int8_t server_texture_unit = 0; // Current in use server side texture unit
|
||||
|
||||
@ -47,9 +48,9 @@ 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++) {
|
||||
if (!(tex_unit->textures[i].used)) {
|
||||
if (!(textures[i].used)) {
|
||||
res[j++] = i;
|
||||
tex_unit->textures[i].used = 1;
|
||||
textures[i].used = 1;
|
||||
}
|
||||
if (j >= n)
|
||||
break;
|
||||
@ -86,8 +87,8 @@ void glDeleteTextures(GLsizei n, const GLuint *gl_textures) {
|
||||
int j;
|
||||
for (j = 0; j < n; j++) {
|
||||
GLuint i = gl_textures[j];
|
||||
tex_unit->textures[i].used = 0;
|
||||
gpu_free_texture(&tex_unit->textures[i]);
|
||||
textures[i].used = 0;
|
||||
gpu_free_texture(&textures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +96,7 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
|
||||
// Setting some aliases to make code more readable
|
||||
texture_unit *tex_unit = &texture_units[server_texture_unit];
|
||||
int texture2d_idx = tex_unit->tex_id;
|
||||
texture *tex = &tex_unit->textures[texture2d_idx];
|
||||
texture *tex = &textures[texture2d_idx];
|
||||
|
||||
SceGxmTextureFormat tex_format;
|
||||
uint8_t data_bpp = 0;
|
||||
@ -152,6 +153,20 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GL_BGR:
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
data_bpp = 3;
|
||||
if (internalFormat == GL_BGR)
|
||||
fast_store = GL_TRUE;
|
||||
else
|
||||
read_cb = readBGR;
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GL_RGB:
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
@ -170,6 +185,20 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GL_BGRA:
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
data_bpp = 4;
|
||||
if (internalFormat == GL_BGRA)
|
||||
fast_store = GL_TRUE;
|
||||
else
|
||||
read_cb = readBGRA;
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GL_RGBA:
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
@ -210,10 +239,18 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
|
||||
write_cb = writeRGB;
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_U8U8U8_BGR;
|
||||
break;
|
||||
case GL_BGR:
|
||||
write_cb = writeBGR;
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_U8U8U8_RGB;
|
||||
break;
|
||||
case GL_RGBA:
|
||||
write_cb = writeRGBA;
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
|
||||
break;
|
||||
case GL_BGRA:
|
||||
write_cb = writeBGRA;
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB;
|
||||
break;
|
||||
case GL_LUMINANCE:
|
||||
write_cb = writeR;
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_L8;
|
||||
@ -251,17 +288,16 @@ void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei widt
|
||||
if (tex->write_cb)
|
||||
gpu_alloc_texture(width, height, tex_format, data, tex, data_bpp, read_cb, write_cb, fast_store);
|
||||
else
|
||||
gpu_alloc_compressed_texture(width, height, tex_format, data, tex, data_bpp, read_cb);
|
||||
else {
|
||||
gpu_alloc_compressed_texture(width, height, tex_format, 0, data, tex, data_bpp, read_cb);
|
||||
else
|
||||
gpu_alloc_mipmaps(level, tex);
|
||||
sceGxmTextureSetMipFilter(&tex->gxm_tex, SCE_GXM_TEXTURE_MIP_FILTER_ENABLED);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Setting palette if the format requests one
|
||||
@ -279,7 +315,7 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, G
|
||||
// Setting some aliases to make code more readable
|
||||
texture_unit *tex_unit = &texture_units[server_texture_unit];
|
||||
int texture2d_idx = tex_unit->tex_id;
|
||||
texture *target_texture = &tex_unit->textures[texture2d_idx];
|
||||
texture *target_texture = &textures[texture2d_idx];
|
||||
|
||||
// Calculating implicit texture stride and start address of requested texture modification
|
||||
uint32_t orig_w = sceGxmTextureGetWidth(&target_texture->gxm_tex);
|
||||
@ -363,6 +399,17 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, G
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GL_BGR:
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
data_bpp = 3;
|
||||
read_cb = readBGR;
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GL_RGBA:
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
@ -382,6 +429,17 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, G
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GL_BGRA:
|
||||
switch (type) {
|
||||
case GL_UNSIGNED_BYTE:
|
||||
data_bpp = 4;
|
||||
read_cb = readBGRA;
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (target) {
|
||||
@ -392,9 +450,15 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, G
|
||||
case GL_RGB:
|
||||
write_cb = writeRGB;
|
||||
break;
|
||||
case GL_BGR:
|
||||
write_cb = writeBGR;
|
||||
break;
|
||||
case GL_RGBA:
|
||||
write_cb = writeRGBA;
|
||||
break;
|
||||
case GL_BGRA:
|
||||
write_cb = writeBGRA;
|
||||
break;
|
||||
case GL_LUMINANCE:
|
||||
write_cb = writeR;
|
||||
break;
|
||||
@ -429,6 +493,84 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, G
|
||||
}
|
||||
}
|
||||
|
||||
void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) {
|
||||
// Setting some aliases to make code more readable
|
||||
texture_unit *tex_unit = &texture_units[server_texture_unit];
|
||||
int texture2d_idx = tex_unit->tex_id;
|
||||
texture *tex = &textures[texture2d_idx];
|
||||
|
||||
SceGxmTextureFormat tex_format;
|
||||
|
||||
#ifndef SKIP_ERROR_HANDLING
|
||||
// Checking if texture is too big for sceGxm
|
||||
if (width > GXM_TEX_MAX_SIZE || height > GXM_TEX_MAX_SIZE) {
|
||||
SET_GL_ERROR(GL_INVALID_VALUE)
|
||||
}
|
||||
|
||||
// Checking if texture dimensions are not a power of two
|
||||
if (((width & (width - 1)) != 0) || ((height & (height - 1)) != 0)) {
|
||||
SET_GL_ERROR(GL_INVALID_VALUE)
|
||||
}
|
||||
|
||||
// Ensure imageSize isn't zero.
|
||||
if (imageSize == 0) {
|
||||
SET_GL_ERROR(GL_INVALID_VALUE)
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
// Detecting proper write callback and texture format
|
||||
switch (internalFormat) {
|
||||
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_UBC1_ABGR;
|
||||
break;
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_UBC3_ABGR;
|
||||
break;
|
||||
case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_PVRT2BPP_1BGR;
|
||||
break;
|
||||
case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_PVRT2BPP_ABGR;
|
||||
break;
|
||||
case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_PVRT4BPP_1BGR;
|
||||
break;
|
||||
case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_PVRT4BPP_ABGR;
|
||||
break;
|
||||
case GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG:
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_PVRTII2BPP_ABGR;
|
||||
break;
|
||||
case GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG:
|
||||
tex_format = SCE_GXM_TEXTURE_FORMAT_PVRTII4BPP_ABGR;
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
}
|
||||
|
||||
// Allocating texture/mipmaps depending on user call
|
||||
tex->type = internalFormat;
|
||||
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);
|
||||
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *data) {
|
||||
// Checking if a color table is already enabled, if so, deallocating it
|
||||
if (color_table != NULL) {
|
||||
@ -462,7 +604,7 @@ void glTexParameteri(GLenum target, GLenum pname, GLint param) {
|
||||
// Setting some aliases to make code more readable
|
||||
texture_unit *tex_unit = &texture_units[server_texture_unit];
|
||||
int texture2d_idx = tex_unit->tex_id;
|
||||
texture *tex = &tex_unit->textures[texture2d_idx];
|
||||
texture *tex = &textures[texture2d_idx];
|
||||
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
@ -470,18 +612,28 @@ 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;
|
||||
break;
|
||||
case GL_LINEAR: // Linear
|
||||
tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
|
||||
tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_NEAREST: // TODO: Implement this
|
||||
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;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_NEAREST: // TODO: Implement this
|
||||
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;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_LINEAR: // TODO: Implement this
|
||||
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;
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_LINEAR: // TODO: Implement this
|
||||
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;
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
@ -491,20 +643,12 @@ void glTexParameteri(GLenum target, GLenum pname, GLint param) {
|
||||
break;
|
||||
case GL_TEXTURE_MAG_FILTER: // Mag Filter
|
||||
switch (param) {
|
||||
case GL_NEAREST: // Point
|
||||
case GL_NEAREST:
|
||||
tex_unit->mag_filter = SCE_GXM_TEXTURE_FILTER_POINT;
|
||||
break;
|
||||
case GL_LINEAR: // Linear
|
||||
case GL_LINEAR:
|
||||
tex_unit->mag_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_NEAREST: // TODO: Implement this
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_NEAREST: // TODO: Implement this
|
||||
break;
|
||||
case GL_NEAREST_MIPMAP_LINEAR: // TODO: Implement this
|
||||
break;
|
||||
case GL_LINEAR_MIPMAP_LINEAR: // TODO: Implement this
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
@ -543,7 +687,7 @@ void glTexParameteri(GLenum target, GLenum pname, GLint param) {
|
||||
tex_unit->v_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_unit->v_mode = SCE_GXM_TEXTURE_ADDR_MIRROR_CLAMP;
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
@ -570,23 +714,44 @@ void glTexParameterf(GLenum target, GLenum pname, GLfloat param) {
|
||||
// Setting some aliases to make code more readable
|
||||
texture_unit *tex_unit = &texture_units[server_texture_unit];
|
||||
int texture2d_idx = tex_unit->tex_id;
|
||||
texture *tex = &tex_unit->textures[texture2d_idx];
|
||||
texture *tex = &textures[texture2d_idx];
|
||||
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
switch (pname) {
|
||||
case GL_TEXTURE_MIN_FILTER: // Min Filter
|
||||
if (param == GL_NEAREST)
|
||||
tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_POINT; // Point
|
||||
if (param == GL_LINEAR)
|
||||
tex_unit->min_filter = SCE_GXM_TEXTURE_FILTER_LINEAR; // Linear
|
||||
if (param == GL_NEAREST) {
|
||||
tex_unit->mip_filter = SCE_GXM_TEXTURE_MIP_FILTER_DISABLED;
|
||||
tex_unit->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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
sceGxmTextureSetMinFilter(&tex->gxm_tex, tex_unit->min_filter);
|
||||
sceGxmTextureSetMipFilter(&tex->gxm_tex, tex_unit->mip_filter);
|
||||
break;
|
||||
case GL_TEXTURE_MAG_FILTER: // Mag filter
|
||||
if (param == GL_NEAREST)
|
||||
tex_unit->mag_filter = SCE_GXM_TEXTURE_FILTER_POINT; // Point
|
||||
tex_unit->mag_filter = SCE_GXM_TEXTURE_FILTER_POINT;
|
||||
else if (param == GL_LINEAR)
|
||||
tex_unit->mag_filter = SCE_GXM_TEXTURE_FILTER_LINEAR; // Linear
|
||||
tex_unit->mag_filter = SCE_GXM_TEXTURE_FILTER_LINEAR;
|
||||
sceGxmTextureSetMagFilter(&tex->gxm_tex, tex_unit->mag_filter);
|
||||
break;
|
||||
case GL_TEXTURE_WRAP_S: // U Mode
|
||||
@ -608,7 +773,7 @@ void glTexParameterf(GLenum target, GLenum pname, GLfloat param) {
|
||||
else if (param == GL_MIRRORED_REPEAT)
|
||||
tex_unit->v_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
|
||||
tex_unit->v_mode = SCE_GXM_TEXTURE_ADDR_MIRROR_CLAMP; // Mirror Clamp
|
||||
sceGxmTextureSetVAddrMode(&tex->gxm_tex, tex_unit->v_mode);
|
||||
break;
|
||||
case GL_TEXTURE_LOD_BIAS: // Distant LOD bias
|
||||
@ -640,7 +805,7 @@ void glGenerateMipmap(GLenum target) {
|
||||
// Setting some aliases to make code more readable
|
||||
texture_unit *tex_unit = &texture_units[server_texture_unit];
|
||||
int texture2d_idx = tex_unit->tex_id;
|
||||
texture *tex = &tex_unit->textures[texture2d_idx];
|
||||
texture *tex = &textures[texture2d_idx];
|
||||
|
||||
#ifndef SKIP_ERROR_HANDLING
|
||||
// Checking if current texture is valid
|
||||
@ -659,7 +824,8 @@ void glGenerateMipmap(GLenum target) {
|
||||
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, SCE_GXM_TEXTURE_MIP_FILTER_ENABLED);
|
||||
sceGxmTextureSetMipFilter(&tex->gxm_tex, tex_unit->mip_filter);
|
||||
sceGxmTextureSetLodBias(&tex->gxm_tex, tex_unit->lod_bias);
|
||||
|
||||
break;
|
||||
default:
|
||||
@ -760,7 +926,7 @@ void *vglGetTexDataPointer(GLenum target) {
|
||||
// Aliasing texture unit for cleaner code
|
||||
texture_unit *tex_unit = &texture_units[server_texture_unit];
|
||||
int texture2d_idx = tex_unit->tex_id;
|
||||
texture *tex = &tex_unit->textures[texture2d_idx];
|
||||
texture *tex = &textures[texture2d_idx];
|
||||
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
@ -773,3 +939,21 @@ void *vglGetTexDataPointer(GLenum target) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SceGxmTexture *vglGetGxmTexture(GLenum target) {
|
||||
// Aliasing texture unit for cleaner code
|
||||
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:
|
||||
return &tex->gxm_tex;
|
||||
break;
|
||||
default:
|
||||
vgl_error = GL_INVALID_ENUM;
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
|
||||
#define CEIL(a) ((a - (int)a) == 0 ? (int)a : (int)a + 1)
|
||||
#endif
|
||||
|
||||
// VRAM usage setting
|
||||
@ -85,6 +86,23 @@ void dxt_compress(uint8_t *dst, uint8_t *src, int w, int h, int isdxt5) {
|
||||
}
|
||||
}
|
||||
|
||||
void swizzle_compressed_texture(uint8_t *dst, uint8_t *src, int w, int h, int isdxt5, int ispvrt2bpp) {
|
||||
int blocksize = isdxt5 ? 16 : 8;
|
||||
|
||||
int s = MAX(w, h);
|
||||
uint32_t num_blocks = (s * s) / 16;
|
||||
uint64_t d, offs_x, offs_y;
|
||||
for (d = 0; d < num_blocks; d++) {
|
||||
d2xy_morton(d, &offs_x, &offs_y);
|
||||
if (offs_x * 4 >= h)
|
||||
continue;
|
||||
if (offs_y * (ispvrt2bpp ? 8 : 4) >= w)
|
||||
continue;
|
||||
memcpy(dst, src + offs_y * blocksize + offs_x * (w / (ispvrt2bpp ? 8 : 4)) * blocksize, blocksize);
|
||||
dst += isdxt5 ? 16 : 8;
|
||||
}
|
||||
}
|
||||
|
||||
void *gpu_alloc_mapped(size_t size, vglMemType *type) {
|
||||
// Allocating requested memblock
|
||||
void *res = mempool_alloc(size, *type);
|
||||
@ -306,7 +324,7 @@ void gpu_alloc_texture(uint32_t w, uint32_t h, SceGxmTextureFormat format, const
|
||||
}
|
||||
}
|
||||
|
||||
void gpu_alloc_compressed_texture(uint32_t w, uint32_t h, SceGxmTextureFormat format, const void *data, texture *tex, uint8_t src_bpp, uint32_t (*read_cb)(void *)) {
|
||||
void gpu_alloc_compressed_texture(uint32_t w, uint32_t h, SceGxmTextureFormat format, uint32_t image_size, const void *data, texture *tex, uint8_t src_bpp, uint32_t (*read_cb)(void *)) {
|
||||
// If there's already a texture in passed texture object we first dealloc it
|
||||
if (tex->valid)
|
||||
gpu_free_texture(tex);
|
||||
@ -316,9 +334,37 @@ void gpu_alloc_compressed_texture(uint32_t w, uint32_t h, SceGxmTextureFormat fo
|
||||
|
||||
// Calculating swizzled compressed texture size on memory
|
||||
tex->mtype = use_vram ? VGL_MEM_VRAM : VGL_MEM_RAM;
|
||||
int tex_size = w * h;
|
||||
if (alignment == 8)
|
||||
tex_size /= 2;
|
||||
|
||||
int tex_size = 0;
|
||||
switch (format) {
|
||||
case SCE_GXM_TEXTURE_FORMAT_PVRT2BPP_1BGR:
|
||||
case SCE_GXM_TEXTURE_FORMAT_PVRT2BPP_ABGR:
|
||||
tex_size = (MAX(w, 8) * MAX(h, 8) * 2 + 7) / 8;
|
||||
break;
|
||||
case SCE_GXM_TEXTURE_FORMAT_PVRT4BPP_1BGR:
|
||||
case SCE_GXM_TEXTURE_FORMAT_PVRT4BPP_ABGR:
|
||||
tex_size = (MAX(w, 8) * MAX(h, 8) * 4 + 7) / 8;
|
||||
break;
|
||||
case SCE_GXM_TEXTURE_FORMAT_PVRTII2BPP_ABGR:
|
||||
tex_size = CEIL(w / 8.0) * CEIL(h / 4.0) * 8.0;
|
||||
break;
|
||||
case SCE_GXM_TEXTURE_FORMAT_PVRTII4BPP_ABGR:
|
||||
tex_size = CEIL(w / 4.0) * CEIL(h / 4.0) * 8.0;
|
||||
break;
|
||||
case SCE_GXM_TEXTURE_FORMAT_UBC1_ABGR:
|
||||
tex_size = (w * h) / 2;
|
||||
break;
|
||||
case SCE_GXM_TEXTURE_FORMAT_UBC3_ABGR:
|
||||
tex_size = w * h;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef SKIP_ERROR_HANDLING
|
||||
// Check the given texture data size.
|
||||
if (image_size != 0 && image_size != tex_size) {
|
||||
SET_GL_ERROR(GL_INVALID_VALUE)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Allocating texture data buffer
|
||||
void *texture_data = gpu_alloc_mapped(tex_size, &tex->mtype);
|
||||
@ -329,6 +375,7 @@ void gpu_alloc_compressed_texture(uint32_t w, uint32_t h, SceGxmTextureFormat fo
|
||||
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;
|
||||
@ -346,6 +393,27 @@ void gpu_alloc_compressed_texture(uint32_t w, uint32_t h, SceGxmTextureFormat fo
|
||||
//swizzle(texture_data, tmp2, w, h, alignment << 3);
|
||||
//free(tmp);
|
||||
//free(tmp2);
|
||||
} else {
|
||||
// Perform swizzling if necessary.
|
||||
switch (format) {
|
||||
case SCE_GXM_TEXTURE_FORMAT_PVRT2BPP_1BGR:
|
||||
case SCE_GXM_TEXTURE_FORMAT_PVRT2BPP_ABGR:
|
||||
case SCE_GXM_TEXTURE_FORMAT_PVRT4BPP_1BGR:
|
||||
case SCE_GXM_TEXTURE_FORMAT_PVRT4BPP_ABGR:
|
||||
memcpy_neon(texture_data, data, tex_size);
|
||||
break;
|
||||
case SCE_GXM_TEXTURE_FORMAT_UBC3_ABGR:
|
||||
swizzle_compressed_texture(texture_data, (void *)data, w, h, 1, 0);
|
||||
break;
|
||||
case SCE_GXM_TEXTURE_FORMAT_PVRTII2BPP_ABGR:
|
||||
swizzle_compressed_texture(texture_data, (void *)data, w, h, 0, 1);
|
||||
break;
|
||||
default:
|
||||
swizzle_compressed_texture(texture_data, (void *)data, w, h, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
memset(texture_data, 0, tex_size);
|
||||
|
||||
|
@ -85,7 +85,7 @@ int tex_format_to_bytespp(SceGxmTextureFormat format);
|
||||
void gpu_alloc_texture(uint32_t w, uint32_t h, SceGxmTextureFormat format, const void *data, texture *tex, uint8_t src_bpp, uint32_t (*read_cb)(void *), void (*write_cb)(void *, uint32_t), uint8_t fast_store);
|
||||
|
||||
// Alloc a compresseed texture
|
||||
void gpu_alloc_compressed_texture(uint32_t w, uint32_t h, SceGxmTextureFormat format, const void *data, texture *tex, uint8_t src_bpp, uint32_t (*read_cb)(void *));
|
||||
void gpu_alloc_compressed_texture(uint32_t w, uint32_t h, SceGxmTextureFormat format, uint32_t image_size, const void *data, texture *tex, uint8_t src_bpp, uint32_t (*read_cb)(void *));
|
||||
|
||||
// Dealloc a texture
|
||||
void gpu_free_texture(texture *tex);
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include "../shared.h"
|
||||
|
||||
#define MEM_ALIGNMENT 8 // seems to be enough, set to 16 if something explodes
|
||||
#define MEM_ALIGNMENT 16
|
||||
|
||||
typedef struct tm_block_s {
|
||||
struct tm_block_s *next; // next block in list (either free or allocated)
|
||||
|
@ -116,6 +116,7 @@ const SceGxmProgram *texture2d_rgba_fragment_program;
|
||||
|
||||
typedef struct gpubuffer {
|
||||
void *ptr;
|
||||
int32_t size;
|
||||
} gpubuffer;
|
||||
|
||||
// sceGxm viewport setup (NOTE: origin is on center screen)
|
||||
@ -675,20 +676,23 @@ void vglInitWithCustomSizes(uint32_t gpu_pool_size, int width, int height, int r
|
||||
// Init texture units
|
||||
int i, j;
|
||||
for (i = 0; i < GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++) {
|
||||
for (j = 0; j < TEXTURES_NUM; j++) {
|
||||
texture_units[i].textures[j].used = 0;
|
||||
texture_units[i].textures[j].valid = 0;
|
||||
}
|
||||
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
|
||||
for (j = 0; j < TEXTURES_NUM; j++) {
|
||||
textures[j].used = 0;
|
||||
textures[j].valid = 0;
|
||||
}
|
||||
|
||||
// Init custom shaders
|
||||
resetCustomShaders();
|
||||
|
||||
@ -838,17 +842,13 @@ void glDeleteBuffers(GLsizei n, const GLuint *gl_buffers) {
|
||||
if (gpu_buffers[idx].ptr != NULL) {
|
||||
mempool_free(gpu_buffers[idx].ptr, VGL_MEM_VRAM);
|
||||
gpu_buffers[idx].ptr = NULL;
|
||||
gpu_buffers[idx].size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void glBufferData(GLenum target, GLsizei size, const GLvoid *data, GLenum usage) {
|
||||
#ifndef SKIP_ERROR_HANDLING
|
||||
if (size < 0) {
|
||||
SET_GL_ERROR(GL_INVALID_VALUE)
|
||||
}
|
||||
#endif
|
||||
int idx = 0;
|
||||
switch (target) {
|
||||
case GL_ARRAY_BUFFER:
|
||||
@ -861,11 +861,60 @@ void glBufferData(GLenum target, GLsizei size, const GLvoid *data, GLenum usage)
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
}
|
||||
vglMemType type = VGL_MEM_VRAM;
|
||||
#ifndef SKIP_ERROR_HANDLING
|
||||
if (size < 0) {
|
||||
SET_GL_ERROR(GL_INVALID_VALUE)
|
||||
}
|
||||
|
||||
if (idx < 0) {
|
||||
SET_GL_ERROR(GL_INVALID_OPERATION)
|
||||
}
|
||||
#endif
|
||||
vglMemType type = use_vram ? VGL_MEM_VRAM : VGL_MEM_RAM;
|
||||
|
||||
// Free buffer if already existing.
|
||||
if (gpu_buffers[idx].ptr != NULL)
|
||||
mempool_free(gpu_buffers[idx].ptr, type);
|
||||
|
||||
gpu_buffers[idx].ptr = gpu_alloc_mapped(size, &type);
|
||||
gpu_buffers[idx].size = size;
|
||||
|
||||
#ifndef SKIP_ERROR_HANDLING
|
||||
if (gpu_buffers[idx].ptr == NULL) {
|
||||
gpu_buffers[idx].size = 0;
|
||||
SET_GL_ERROR(GL_OUT_OF_MEMORY)
|
||||
}
|
||||
#endif
|
||||
|
||||
memcpy_neon(gpu_buffers[idx].ptr, data, size);
|
||||
}
|
||||
|
||||
void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data) {
|
||||
int idx = 0;
|
||||
switch (target) {
|
||||
case GL_ARRAY_BUFFER:
|
||||
idx = vertex_array_unit;
|
||||
break;
|
||||
case GL_ELEMENT_ARRAY_BUFFER:
|
||||
idx = index_array_unit;
|
||||
break;
|
||||
default:
|
||||
SET_GL_ERROR(GL_INVALID_ENUM)
|
||||
break;
|
||||
}
|
||||
#ifndef SKIP_ERROR_HANDLING
|
||||
if ((size < 0) || (offset < 0) || ((offset + size) > gpu_buffers[idx].size)) {
|
||||
SET_GL_ERROR(GL_INVALID_VALUE)
|
||||
}
|
||||
|
||||
if (idx < 0) {
|
||||
SET_GL_ERROR(GL_INVALID_OPERATION)
|
||||
}
|
||||
#endif
|
||||
|
||||
memcpy_neon(gpu_buffers[idx].ptr + offset, data, size);
|
||||
}
|
||||
|
||||
void glBlendFunc(GLenum sfactor, GLenum dfactor) {
|
||||
switch (sfactor) {
|
||||
case GL_ZERO:
|
||||
@ -1305,7 +1354,7 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
}
|
||||
|
||||
if (tex_unit->texture_array_state) {
|
||||
if (!(tex_unit->textures[texture2d_idx].valid))
|
||||
if (!(textures[texture2d_idx].valid))
|
||||
return;
|
||||
if (tex_unit->color_array_state) {
|
||||
sceGxmSetVertexProgram(gxm_context, texture2d_rgba_vertex_program_patched);
|
||||
@ -1368,7 +1417,7 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
|
||||
sceGxmSetUniformDataF(vertex_wvp_buffer, texture2d_clip_plane0_eq, 0, 4, &clip_plane0_eq.x);
|
||||
sceGxmSetUniformDataF(vertex_wvp_buffer, texture2d_mv, 0, 16, (const float *)modelview_matrix);
|
||||
}
|
||||
sceGxmSetFragmentTexture(gxm_context, 0, &tex_unit->textures[texture2d_idx].gxm_tex);
|
||||
sceGxmSetFragmentTexture(gxm_context, 0, &textures[texture2d_idx].gxm_tex);
|
||||
vector3f *vertices = NULL;
|
||||
vector2f *uv_map = NULL;
|
||||
vector4f *colors = NULL;
|
||||
@ -1597,7 +1646,7 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *gl_in
|
||||
}
|
||||
|
||||
if (tex_unit->texture_array_state) {
|
||||
if (!(tex_unit->textures[texture2d_idx].valid))
|
||||
if (!(textures[texture2d_idx].valid))
|
||||
return;
|
||||
if (tex_unit->color_array_state) {
|
||||
sceGxmSetVertexProgram(gxm_context, texture2d_rgba_vertex_program_patched);
|
||||
@ -1660,7 +1709,7 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *gl_in
|
||||
sceGxmSetUniformDataF(vertex_wvp_buffer, texture2d_clip_plane0_eq, 0, 4, &clip_plane0_eq.x);
|
||||
sceGxmSetUniformDataF(vertex_wvp_buffer, texture2d_mv, 0, 16, (const float *)modelview_matrix);
|
||||
}
|
||||
sceGxmSetFragmentTexture(gxm_context, 0, &texture_units[client_texture_unit].textures[texture2d_idx].gxm_tex);
|
||||
sceGxmSetFragmentTexture(gxm_context, 0, &textures[texture2d_idx].gxm_tex);
|
||||
vector3f *vertices = NULL;
|
||||
vector2f *uv_map = NULL;
|
||||
vector4f *colors = NULL;
|
||||
@ -2057,10 +2106,15 @@ void vglDrawObjects(GLenum mode, GLsizei count, GLboolean implicit_wvp) {
|
||||
if (!skip_draw) {
|
||||
if (cur_program != 0) {
|
||||
_vglDrawObjects_CustomShadersIMPL(mode, count, implicit_wvp);
|
||||
sceGxmSetFragmentTexture(gxm_context, 0, &tex_unit->textures[texture2d_idx].gxm_tex);
|
||||
sceGxmSetFragmentTexture(gxm_context, 0, &textures[texture2d_idx].gxm_tex);
|
||||
|
||||
// TEXUNIT1 support for custom shaders
|
||||
texture_unit *tex_unit2 = &texture_units[client_texture_unit + 1];
|
||||
int texture2d_idx2 = tex_unit2->tex_id;
|
||||
if (textures[texture2d_idx2].valid)
|
||||
sceGxmSetFragmentTexture(gxm_context, 1, &textures[texture2d_idx2].gxm_tex);
|
||||
|
||||
sceGxmDraw(gxm_context, gxm_p, SCE_GXM_INDEX_FORMAT_U16, tex_unit->index_object, count);
|
||||
vert_uniforms = NULL;
|
||||
frag_uniforms = NULL;
|
||||
} else {
|
||||
if (tex_unit->vertex_array_state) {
|
||||
if (mvp_modified) {
|
||||
@ -2068,7 +2122,7 @@ void vglDrawObjects(GLenum mode, GLsizei count, GLboolean implicit_wvp) {
|
||||
mvp_modified = GL_FALSE;
|
||||
}
|
||||
if (tex_unit->texture_array_state) {
|
||||
if (!(tex_unit->textures[texture2d_idx].valid))
|
||||
if (!(textures[texture2d_idx].valid))
|
||||
return;
|
||||
if (tex_unit->color_array_state) {
|
||||
if (tex_unit->color_object_type == GL_FLOAT)
|
||||
@ -2139,7 +2193,7 @@ void vglDrawObjects(GLenum mode, GLsizei count, GLboolean implicit_wvp) {
|
||||
sceGxmSetUniformDataF(vertex_wvp_buffer, texture2d_clip_plane0_eq, 0, 4, &clip_plane0_eq.x);
|
||||
sceGxmSetUniformDataF(vertex_wvp_buffer, texture2d_mv, 0, 16, (const float *)modelview_matrix);
|
||||
}
|
||||
sceGxmSetFragmentTexture(gxm_context, 0, &tex_unit->textures[texture2d_idx].gxm_tex);
|
||||
sceGxmSetFragmentTexture(gxm_context, 0, &textures[texture2d_idx].gxm_tex);
|
||||
sceGxmSetVertexStream(gxm_context, 0, tex_unit->vertex_object);
|
||||
sceGxmSetVertexStream(gxm_context, 1, tex_unit->texture_object);
|
||||
if (tex_unit->color_array_state)
|
||||
@ -2188,3 +2242,7 @@ void vglFree(void *addr) {
|
||||
void vglUseExtraMem(GLboolean use) {
|
||||
use_extra_mem = use;
|
||||
}
|
||||
|
||||
GLboolean vglHasRuntimeShaderCompiler(void) {
|
||||
return is_shark_online;
|
||||
}
|
@ -26,6 +26,8 @@ extern "C" {
|
||||
#include <vitasdk.h>
|
||||
#ifdef HAVE_SHARK
|
||||
#include <vitashark.h>
|
||||
#else
|
||||
#define shark_opt int32_t
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
@ -193,6 +195,8 @@ extern "C" {
|
||||
#define GL_BLEND_DST_ALPHA 0x80CA
|
||||
#define GL_BLEND_SRC_ALPHA 0x80CB
|
||||
#define GL_COLOR_TABLE 0x80D0
|
||||
#define GL_BGR 0x80E0
|
||||
#define GL_BGRA 0x80E1
|
||||
#define GL_COLOR_INDEX8_EXT 0x80E5
|
||||
#define GL_CLAMP_TO_EDGE 0x812F
|
||||
#define GL_RG 0x8227
|
||||
@ -236,6 +240,8 @@ extern "C" {
|
||||
#define GL_ACTIVE_TEXTURE 0x84E0
|
||||
#define GL_TEXTURE_LOD_BIAS 0x8501
|
||||
#define GL_INCR_WRAP 0x8507
|
||||
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
|
||||
#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
|
||||
#define GL_MIRROR_CLAMP_EXT 0x8742
|
||||
#define GL_DECR_WRAP 0x8508
|
||||
#define GL_ARRAY_BUFFER 0x8892
|
||||
@ -253,12 +259,19 @@ extern "C" {
|
||||
#define GL_VERTEX_SHADER 0x8B31
|
||||
#define GL_SHADER_TYPE 0x8B4F
|
||||
#define GL_COMPILE_STATUS 0x8B81
|
||||
#define GL_INFO_LOG_LENGTH 0x8B84
|
||||
#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
|
||||
#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
|
||||
#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
|
||||
#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
|
||||
#define GL_READ_FRAMEBUFFER 0x8CA8
|
||||
#define GL_DRAW_FRAMEBUFFER 0x8CA9
|
||||
#define GL_COLOR_ATTACHMENT0 0x8CE0
|
||||
#define GL_FRAMEBUFFER 0x8D40
|
||||
#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137
|
||||
#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138
|
||||
|
||||
#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 32
|
||||
#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 2
|
||||
#define GL_MAX_TEXTURE_LOD_BIAS 31
|
||||
|
||||
// Aliases
|
||||
@ -285,6 +298,7 @@ void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
|
||||
void glBlendFunc(GLenum sfactor, GLenum dfactor);
|
||||
void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
|
||||
void glBufferData(GLenum target, GLsizei size, const GLvoid *data, GLenum usage);
|
||||
void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
|
||||
void glClear(GLbitfield mask);
|
||||
void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
void glClearDepth(GLdouble depth);
|
||||
@ -303,6 +317,7 @@ void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha
|
||||
void glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *data);
|
||||
void glCompileShader(GLuint shader);
|
||||
void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); // Mipmap levels are ignored currently
|
||||
GLuint glCreateProgram(void);
|
||||
GLuint glCreateShader(GLenum shaderType);
|
||||
void glCullFace(GLenum mode);
|
||||
@ -337,6 +352,7 @@ void glGetBooleanv(GLenum pname, GLboolean *params);
|
||||
void glGetFloatv(GLenum pname, GLfloat *data);
|
||||
GLenum glGetError(void);
|
||||
void glGetIntegerv(GLenum pname, GLint *data);
|
||||
void glGetShaderInfoLog(GLuint handle, GLsizei maxLength, GLsizei *length, GLchar *infoLog);
|
||||
void glGetShaderiv(GLuint handle, GLenum pname, GLint *params);
|
||||
const GLubyte *glGetString(GLenum name);
|
||||
GLint glGetUniformLocation(GLuint prog, const GLchar *name);
|
||||
@ -358,7 +374,7 @@ void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
|
||||
void glScalef(GLfloat x, GLfloat y, GLfloat z);
|
||||
void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void glShaderBinary(GLsizei count, const GLuint *handles, GLenum binaryFormat, const void *binary, GLsizei length); // NOTE: Uses GXP shaders
|
||||
void glShaderSource(GLuint handle, GLsizei count, const GLchar * const *string, const GLint *length); // NOTE: Uses CG shader sources
|
||||
void glShaderSource(GLuint handle, GLsizei count, const GLchar *const *string, const GLint *length); // NOTE: Uses CG shader sources
|
||||
void glStencilFunc(GLenum func, GLint ref, GLuint mask);
|
||||
void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
|
||||
void glStencilMask(GLuint mask);
|
||||
@ -379,6 +395,8 @@ void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, G
|
||||
void glTranslatef(GLfloat x, GLfloat y, GLfloat z);
|
||||
void glUniform1f(GLint location, GLfloat v0);
|
||||
void glUniform1i(GLint location, GLint v0);
|
||||
void glUniform2f(GLint location, GLfloat v0, GLfloat v1);
|
||||
void glUniform2i(GLint location, GLint v0, GLint v1);
|
||||
void glUniform2fv(GLint location, GLsizei count, const GLfloat *value);
|
||||
void glUniform3fv(GLint location, GLsizei count, const GLfloat *value);
|
||||
void glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
|
||||
@ -407,7 +425,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, GLuint index, const GLchar *name, const GLuint num, const GLenum type, GLuint offset, GLint stride);
|
||||
void 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);
|
||||
|
||||
@ -425,16 +443,20 @@ void *vglAlloc(uint32_t size, vglMemType type);
|
||||
void vglEnableRuntimeShaderCompiler(GLboolean usage);
|
||||
void vglEnd(void);
|
||||
void vglFree(void *addr);
|
||||
SceGxmTexture *vglGetGxmTexture(GLenum target);
|
||||
void *vglGetTexDataPointer(GLenum target);
|
||||
GLboolean vglHasRuntimeShaderCompiler(void);
|
||||
void vglInit(uint32_t gpu_pool_size);
|
||||
void vglInitExtended(uint32_t gpu_pool_size, int width, int height, int ram_threshold, SceGxmMultisampleMode msaa);
|
||||
void vglInitWithCustomSizes(uint32_t gpu_pool_size, int width, int height, int ram_pool_size, int cdram_pool_size, int phycont_pool_size, SceGxmMultisampleMode msaa);
|
||||
size_t vglMemFree(vglMemType type);
|
||||
void vglSetParamBufferSize(uint32_t size);
|
||||
void vglSetupRuntimeShaderCompiler(shark_opt opt_level, int32_t use_fastmath, int32_t use_fastprecision, int32_t use_fastint);
|
||||
void vglStartRendering();
|
||||
void vglStopRendering();
|
||||
void vglStopRenderingInit();
|
||||
void vglStopRenderingTerm();
|
||||
void vglTexImageDepthBuffer(GLenum target);
|
||||
void vglUpdateCommonDialog();
|
||||
void vglUseVram(GLboolean usage);
|
||||
void vglUseVramForUSSE(GLboolean usage);
|
||||
|
Loading…
x
Reference in New Issue
Block a user