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:
Francisco José García García 2020-10-16 20:24:43 +02:00
parent 51922ea5be
commit 8838992085
17 changed files with 963 additions and 323 deletions

View File

@ -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)

View File

@ -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>

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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);