mirror of
https://github.com/libretro/RetroArch
synced 2025-03-25 07:43:52 +00:00
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
477 lines
18 KiB
C
477 lines
18 KiB
C
/*
|
|
* This file is part of vitaGL
|
|
* Copyright 2017, 2018, 2019, 2020 Rinnegatamante
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published
|
|
* by the Free Software Foundation, version 3 of the License, or (at your
|
|
* option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/*
|
|
* gxm.c:
|
|
* Implementation for setup and cleanup for sceGxm specific stuffs
|
|
*/
|
|
|
|
#include "shared.h"
|
|
|
|
static uint32_t gxm_param_buf_size = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE; // Param buffer size for sceGxm
|
|
|
|
static void *vdm_ring_buffer_addr; // VDM ring buffer memblock starting address
|
|
static void *vertex_ring_buffer_addr; // vertex ring buffer memblock starting address
|
|
static void *fragment_ring_buffer_addr; // fragment ring buffer memblock starting address
|
|
static void *fragment_usse_ring_buffer_addr; // fragment USSE ring buffer memblock starting address
|
|
|
|
static SceGxmRenderTarget *gxm_render_target; // Display render target
|
|
static SceGxmColorSurface gxm_color_surfaces[DISPLAY_BUFFER_COUNT]; // Display color surfaces
|
|
static void *gxm_color_surfaces_addr[DISPLAY_BUFFER_COUNT]; // Display color surfaces memblock starting addresses
|
|
static SceGxmSyncObject *gxm_sync_objects[DISPLAY_BUFFER_COUNT]; // Display sync objects
|
|
static unsigned int gxm_front_buffer_index; // Display front buffer id
|
|
static unsigned int gxm_back_buffer_index; // Display back buffer id
|
|
static unsigned int gxm_scene_flags = 0; // Current gxm scene flags
|
|
|
|
static void *gxm_shader_patcher_buffer_addr; // Shader PAtcher buffer memblock starting address
|
|
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
|
|
|
|
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
|
|
|
|
static SceUID shared_fb; // In-use hared framebuffer identifier
|
|
static SceSharedFbInfo shared_fb_info; // In-use shared framebuffer info struct
|
|
|
|
SceGxmContext *gxm_context; // sceGxm context instance
|
|
GLenum vgl_error = GL_NO_ERROR; // Error returned by glGetError
|
|
SceGxmShaderPatcher *gxm_shader_patcher; // sceGxmShaderPatcher shader patcher instance
|
|
|
|
matrix4x4 mvp_matrix; // ModelViewProjection Matrix
|
|
matrix4x4 projection_matrix; // Projection Matrix
|
|
matrix4x4 modelview_matrix; // ModelView Matrix
|
|
|
|
int DISPLAY_WIDTH; // Display width in pixels
|
|
int DISPLAY_HEIGHT; // Display height in pixels
|
|
int DISPLAY_STRIDE; // Display stride in pixels
|
|
float DISPLAY_WIDTH_FLOAT; // Display width in pixels (float)
|
|
float DISPLAY_HEIGHT_FLOAT; // Display height in pixels (float)
|
|
|
|
uint8_t system_app_mode = 0; // Flag for system app mode usage
|
|
static uint8_t gxm_initialized = 0; // Current sceGxm state
|
|
|
|
// sceDisplay callback data
|
|
struct display_queue_callback_data {
|
|
void *addr;
|
|
};
|
|
|
|
// sceGxmShaderPatcher custom allocator
|
|
static void *shader_patcher_host_alloc_cb(void *user_data, unsigned int size) {
|
|
return malloc(size);
|
|
}
|
|
|
|
// sceGxmShaderPatcher custom deallocator
|
|
static void shader_patcher_host_free_cb(void *user_data, void *mem) {
|
|
free(mem);
|
|
}
|
|
|
|
// sceDisplay callback
|
|
static void display_queue_callback(const void *callbackData) {
|
|
// Populating sceDisplay framebuffer parameters
|
|
SceDisplayFrameBuf display_fb;
|
|
const struct display_queue_callback_data *cb_data = callbackData;
|
|
memset(&display_fb, 0, sizeof(SceDisplayFrameBuf));
|
|
display_fb.size = sizeof(SceDisplayFrameBuf);
|
|
display_fb.base = cb_data->addr;
|
|
display_fb.pitch = DISPLAY_STRIDE;
|
|
display_fb.pixelformat = SCE_DISPLAY_PIXELFORMAT_A8B8G8R8;
|
|
display_fb.width = DISPLAY_WIDTH;
|
|
display_fb.height = DISPLAY_HEIGHT;
|
|
|
|
// Setting sceDisplay framebuffer
|
|
sceDisplaySetFrameBuf(&display_fb, SCE_DISPLAY_SETBUF_NEXTFRAME);
|
|
|
|
// Performing VSync if enabled
|
|
if (vblank)
|
|
sceDisplayWaitVblankStart();
|
|
}
|
|
|
|
void initGxm(void) {
|
|
if (gxm_initialized)
|
|
return;
|
|
|
|
// Initializing runtime shader compiler
|
|
if (use_shark) {
|
|
#ifdef HAVE_SHARK
|
|
if (shark_init(NULL) >= 0) {
|
|
is_shark_online = 1;
|
|
#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;
|
|
}
|
|
|
|
// Checking if the running application is a system one
|
|
SceAppMgrBudgetInfo info;
|
|
info.size = sizeof(SceAppMgrBudgetInfo);
|
|
if (!sceAppMgrGetBudgetInfo(&info))
|
|
system_app_mode = 1;
|
|
|
|
// Initializing sceGxm init parameters
|
|
SceGxmInitializeParams gxm_init_params;
|
|
memset(&gxm_init_params, 0, sizeof(SceGxmInitializeParams));
|
|
gxm_init_params.flags = system_app_mode ? 0x0A : 0;
|
|
gxm_init_params.displayQueueMaxPendingCount = DISPLAY_BUFFER_COUNT - 1;
|
|
gxm_init_params.displayQueueCallback = display_queue_callback;
|
|
gxm_init_params.displayQueueCallbackDataSize = sizeof(struct display_queue_callback_data);
|
|
gxm_init_params.parameterBufferSize = gxm_param_buf_size;
|
|
|
|
// Initializing sceGxm
|
|
if (system_app_mode)
|
|
sceGxmVshInitialize(&gxm_init_params);
|
|
else
|
|
sceGxmInitialize(&gxm_init_params);
|
|
gxm_initialized = 1;
|
|
}
|
|
|
|
void initGxmContext(void) {
|
|
vglMemType type = VGL_MEM_VRAM;
|
|
|
|
// Allocating VDM ring buffer
|
|
vdm_ring_buffer_addr = gpu_alloc_mapped(SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE, &type);
|
|
|
|
// Allocating vertex ring buffer
|
|
vertex_ring_buffer_addr = gpu_alloc_mapped(SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE, &type);
|
|
|
|
// Allocating fragment ring buffer
|
|
fragment_ring_buffer_addr = gpu_alloc_mapped(SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE, &type);
|
|
|
|
// Allocating fragment USSE ring buffer
|
|
unsigned int fragment_usse_offset;
|
|
fragment_usse_ring_buffer_addr = gpu_fragment_usse_alloc_mapped(
|
|
SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE, &fragment_usse_offset);
|
|
|
|
// Setting sceGxm context parameters
|
|
SceGxmContextParams gxm_context_params;
|
|
memset(&gxm_context_params, 0, sizeof(SceGxmContextParams));
|
|
gxm_context_params.hostMem = malloc(SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE);
|
|
gxm_context_params.hostMemSize = SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE;
|
|
gxm_context_params.vdmRingBufferMem = vdm_ring_buffer_addr;
|
|
gxm_context_params.vdmRingBufferMemSize = SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE;
|
|
gxm_context_params.vertexRingBufferMem = vertex_ring_buffer_addr;
|
|
gxm_context_params.vertexRingBufferMemSize = SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE;
|
|
gxm_context_params.fragmentRingBufferMem = fragment_ring_buffer_addr;
|
|
gxm_context_params.fragmentRingBufferMemSize = SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE;
|
|
gxm_context_params.fragmentUsseRingBufferMem = fragment_usse_ring_buffer_addr;
|
|
gxm_context_params.fragmentUsseRingBufferMemSize = SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE;
|
|
gxm_context_params.fragmentUsseRingBufferOffset = fragment_usse_offset;
|
|
|
|
// Initializing sceGxm context
|
|
sceGxmCreateContext(&gxm_context_params, &gxm_context);
|
|
}
|
|
|
|
void termGxmContext(void) {
|
|
// Deallocating ring buffers
|
|
mempool_free(vdm_ring_buffer_addr, VGL_MEM_VRAM);
|
|
mempool_free(vertex_ring_buffer_addr, VGL_MEM_VRAM);
|
|
mempool_free(fragment_ring_buffer_addr, VGL_MEM_VRAM);
|
|
gpu_fragment_usse_free_mapped(fragment_usse_ring_buffer_addr);
|
|
|
|
// Destroying sceGxm context
|
|
sceGxmDestroyContext(gxm_context);
|
|
|
|
if (system_app_mode) {
|
|
sceSharedFbBegin(shared_fb, &shared_fb_info);
|
|
sceGxmUnmapMemory(shared_fb_info.fb_base);
|
|
sceSharedFbEnd(shared_fb);
|
|
sceSharedFbClose(shared_fb);
|
|
}
|
|
#ifdef HAVE_SHARK
|
|
// Shutting down runtime shader compiler
|
|
if (is_shark_online) shark_end();
|
|
#endif
|
|
}
|
|
|
|
void createDisplayRenderTarget(void) {
|
|
// Populating sceGxmRenderTarget parameters
|
|
SceGxmRenderTargetParams render_target_params;
|
|
memset(&render_target_params, 0, sizeof(SceGxmRenderTargetParams));
|
|
render_target_params.flags = 0;
|
|
render_target_params.width = DISPLAY_WIDTH;
|
|
render_target_params.height = DISPLAY_HEIGHT;
|
|
render_target_params.scenesPerFrame = 1;
|
|
render_target_params.multisampleMode = msaa_mode;
|
|
render_target_params.multisampleLocations = 0;
|
|
render_target_params.driverMemBlock = -1;
|
|
|
|
// Creating render target for the display
|
|
sceGxmCreateRenderTarget(&render_target_params, &gxm_render_target);
|
|
}
|
|
|
|
void destroyDisplayRenderTarget(void) {
|
|
// Destroying render target for the display
|
|
sceGxmDestroyRenderTarget(gxm_render_target);
|
|
}
|
|
|
|
void initDisplayColorSurfaces(void) {
|
|
// Getting access to the shared framebuffer on system app mode
|
|
while (system_app_mode) {
|
|
shared_fb = sceSharedFbOpen(1);
|
|
memset(&shared_fb_info, 0, sizeof(SceSharedFbInfo));
|
|
sceSharedFbGetInfo(shared_fb, &shared_fb_info);
|
|
if (shared_fb_info.index == 1)
|
|
sceSharedFbClose(shared_fb);
|
|
else {
|
|
sceGxmMapMemory(shared_fb_info.fb_base, shared_fb_info.fb_size, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE);
|
|
gxm_color_surfaces_addr[0] = shared_fb_info.fb_base;
|
|
gxm_color_surfaces_addr[1] = shared_fb_info.fb_base2;
|
|
memset(&shared_fb_info, 0, sizeof(SceSharedFbInfo));
|
|
break;
|
|
}
|
|
}
|
|
|
|
vglMemType type = VGL_MEM_VRAM;
|
|
int i;
|
|
for (i = 0; i < DISPLAY_BUFFER_COUNT; i++) {
|
|
// Allocating color surface memblock
|
|
if (!system_app_mode) {
|
|
gxm_color_surfaces_addr[i] = gpu_alloc_mapped(
|
|
ALIGN(4 * DISPLAY_STRIDE * DISPLAY_HEIGHT, 1 * 1024 * 1024),
|
|
&type);
|
|
memset(gxm_color_surfaces_addr[i], 0, DISPLAY_STRIDE * DISPLAY_HEIGHT);
|
|
}
|
|
|
|
// Initializing allocated color surface
|
|
sceGxmColorSurfaceInit(&gxm_color_surfaces[i],
|
|
SCE_GXM_COLOR_FORMAT_A8B8G8R8,
|
|
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,
|
|
DISPLAY_WIDTH,
|
|
DISPLAY_HEIGHT,
|
|
DISPLAY_STRIDE,
|
|
gxm_color_surfaces_addr[i]);
|
|
|
|
// Creating a display sync object for the allocated color surface
|
|
sceGxmSyncObjectCreate(&gxm_sync_objects[i]);
|
|
}
|
|
}
|
|
|
|
void termDisplayColorSurfaces(void) {
|
|
// Deallocating display's color surfaces and destroying sync objects
|
|
int i;
|
|
for (i = 0; i < DISPLAY_BUFFER_COUNT; i++) {
|
|
if (!system_app_mode)
|
|
mempool_free(gxm_color_surfaces_addr[i], VGL_MEM_VRAM);
|
|
sceGxmSyncObjectDestroy(gxm_sync_objects[i]);
|
|
}
|
|
}
|
|
|
|
void initDepthStencilBuffer(uint32_t w, uint32_t h, SceGxmDepthStencilSurface *surface, void **depth_buffer, void **stencil_buffer, vglMemType *depth_type, vglMemType *stencil_type) {
|
|
// Calculating sizes for depth and stencil surfaces
|
|
unsigned int depth_stencil_width = ALIGN(w, SCE_GXM_TILE_SIZEX);
|
|
unsigned int depth_stencil_height = ALIGN(h, SCE_GXM_TILE_SIZEY);
|
|
unsigned int depth_stencil_samples = depth_stencil_width * depth_stencil_height;
|
|
if (msaa_mode == SCE_GXM_MULTISAMPLE_2X)
|
|
depth_stencil_samples = depth_stencil_samples * 2;
|
|
else if (msaa_mode == SCE_GXM_MULTISAMPLE_4X)
|
|
depth_stencil_samples = depth_stencil_samples * 4;
|
|
|
|
// Allocating depth surface
|
|
*depth_type = VGL_MEM_VRAM;
|
|
*depth_buffer = gpu_alloc_mapped(4 * depth_stencil_samples, depth_type);
|
|
|
|
// Allocating stencil surface
|
|
*stencil_type = VGL_MEM_VRAM;
|
|
*stencil_buffer = gpu_alloc_mapped(1 * depth_stencil_samples, stencil_type);
|
|
|
|
// Initializing depth and stencil surfaces
|
|
sceGxmDepthStencilSurfaceInit(surface,
|
|
SCE_GXM_DEPTH_STENCIL_FORMAT_DF32M_S8,
|
|
SCE_GXM_DEPTH_STENCIL_SURFACE_LINEAR,
|
|
msaa_mode == SCE_GXM_MULTISAMPLE_4X ? depth_stencil_width * 2 : depth_stencil_width,
|
|
*depth_buffer,
|
|
*stencil_buffer);
|
|
}
|
|
|
|
void initDepthStencilSurfaces(void) {
|
|
vglMemType t1, t2;
|
|
initDepthStencilBuffer(DISPLAY_WIDTH, DISPLAY_HEIGHT, &gxm_depth_stencil_surface, &gxm_depth_surface_addr, &gxm_stencil_surface_addr, &t1, &t2);
|
|
}
|
|
|
|
void termDepthStencilSurfaces(void) {
|
|
// Deallocating depth and stencil surfaces memblocks
|
|
mempool_free(gxm_depth_surface_addr, VGL_MEM_VRAM);
|
|
mempool_free(gxm_stencil_surface_addr, VGL_MEM_VRAM);
|
|
}
|
|
|
|
void startShaderPatcher(void) {
|
|
// Constants for shader patcher buffers
|
|
static const unsigned int shader_patcher_buffer_size = 1024 * 1024;
|
|
static const unsigned int shader_patcher_vertex_usse_size = 1024 * 1024;
|
|
static const unsigned int shader_patcher_fragment_usse_size = 1024 * 1024;
|
|
vglMemType type = VGL_MEM_VRAM;
|
|
|
|
// Allocating Shader Patcher buffer
|
|
gxm_shader_patcher_buffer_addr = gpu_alloc_mapped(
|
|
shader_patcher_buffer_size, &type);
|
|
|
|
// Allocating Shader Patcher vertex USSE buffer
|
|
unsigned int shader_patcher_vertex_usse_offset;
|
|
gxm_shader_patcher_vertex_usse_addr = gpu_vertex_usse_alloc_mapped(
|
|
shader_patcher_vertex_usse_size, &shader_patcher_vertex_usse_offset);
|
|
|
|
// Allocating Shader Patcher fragment USSE buffer
|
|
unsigned int shader_patcher_fragment_usse_offset;
|
|
gxm_shader_patcher_fragment_usse_addr = gpu_fragment_usse_alloc_mapped(
|
|
shader_patcher_fragment_usse_size, &shader_patcher_fragment_usse_offset);
|
|
|
|
// Populating shader patcher parameters
|
|
SceGxmShaderPatcherParams shader_patcher_params;
|
|
memset(&shader_patcher_params, 0, sizeof(SceGxmShaderPatcherParams));
|
|
shader_patcher_params.userData = NULL;
|
|
shader_patcher_params.hostAllocCallback = shader_patcher_host_alloc_cb;
|
|
shader_patcher_params.hostFreeCallback = shader_patcher_host_free_cb;
|
|
shader_patcher_params.bufferAllocCallback = NULL;
|
|
shader_patcher_params.bufferFreeCallback = NULL;
|
|
shader_patcher_params.bufferMem = gxm_shader_patcher_buffer_addr;
|
|
shader_patcher_params.bufferMemSize = shader_patcher_buffer_size;
|
|
shader_patcher_params.vertexUsseAllocCallback = NULL;
|
|
shader_patcher_params.vertexUsseFreeCallback = NULL;
|
|
shader_patcher_params.vertexUsseMem = gxm_shader_patcher_vertex_usse_addr;
|
|
shader_patcher_params.vertexUsseMemSize = shader_patcher_vertex_usse_size;
|
|
shader_patcher_params.vertexUsseOffset = shader_patcher_vertex_usse_offset;
|
|
shader_patcher_params.fragmentUsseAllocCallback = NULL;
|
|
shader_patcher_params.fragmentUsseFreeCallback = NULL;
|
|
shader_patcher_params.fragmentUsseMem = gxm_shader_patcher_fragment_usse_addr;
|
|
shader_patcher_params.fragmentUsseMemSize = shader_patcher_fragment_usse_size;
|
|
shader_patcher_params.fragmentUsseOffset = shader_patcher_fragment_usse_offset;
|
|
|
|
// Creating shader patcher instance
|
|
sceGxmShaderPatcherCreate(&shader_patcher_params, &gxm_shader_patcher);
|
|
}
|
|
|
|
void stopShaderPatcher(void) {
|
|
// Destroying shader patcher instance
|
|
sceGxmShaderPatcherDestroy(gxm_shader_patcher);
|
|
|
|
// Freeing shader patcher buffers
|
|
mempool_free(gxm_shader_patcher_buffer_addr, VGL_MEM_VRAM);
|
|
gpu_vertex_usse_free_mapped(gxm_shader_patcher_vertex_usse_addr);
|
|
gpu_fragment_usse_free_mapped(gxm_shader_patcher_fragment_usse_addr);
|
|
}
|
|
|
|
void waitRenderingDone(void) {
|
|
// Wait for rendering to be finished
|
|
sceGxmDisplayQueueFinish();
|
|
sceGxmFinish(gxm_context);
|
|
}
|
|
|
|
/*
|
|
* ------------------------------
|
|
* - IMPLEMENTATION STARTS HERE -
|
|
* ------------------------------
|
|
*/
|
|
|
|
void vglSetParamBufferSize(uint32_t size) {
|
|
gxm_param_buf_size = size;
|
|
}
|
|
|
|
void vglStartRendering(void) {
|
|
// Starting drawing scene
|
|
if (active_write_fb == NULL) { // Default framebuffer is used
|
|
if (system_app_mode) {
|
|
sceSharedFbBegin(shared_fb, &shared_fb_info);
|
|
shared_fb_info.vsync = vblank;
|
|
gxm_back_buffer_index = (shared_fb_info.index + 1) % 2;
|
|
}
|
|
sceGxmBeginScene(gxm_context, gxm_scene_flags, gxm_render_target,
|
|
NULL, NULL,
|
|
gxm_sync_objects[gxm_back_buffer_index],
|
|
&gxm_color_surfaces[gxm_back_buffer_index],
|
|
&gxm_depth_stencil_surface);
|
|
gxm_scene_flags &= ~SCE_GXM_SCENE_VERTEX_WAIT_FOR_DEPENDENCY;
|
|
} else {
|
|
gxm_scene_flags |= SCE_GXM_SCENE_FRAGMENT_SET_DEPENDENCY;
|
|
sceGxmBeginScene(gxm_context, gxm_scene_flags, active_write_fb->target,
|
|
NULL, NULL, NULL,
|
|
&active_write_fb->colorbuffer,
|
|
&active_write_fb->depthbuffer);
|
|
gxm_scene_flags |= SCE_GXM_SCENE_VERTEX_WAIT_FOR_DEPENDENCY;
|
|
gxm_scene_flags &= ~SCE_GXM_SCENE_FRAGMENT_SET_DEPENDENCY;
|
|
}
|
|
|
|
// Setting back current viewport if enabled cause sceGxm will reset it at sceGxmEndScene call
|
|
sceGxmSetViewport(gxm_context, x_port, x_scale, y_port, y_scale, z_port, z_scale);
|
|
|
|
if (scissor_test_state)
|
|
sceGxmSetRegionClip(gxm_context, SCE_GXM_REGION_CLIP_OUTSIDE, region.x, region.y, region.x + region.w - 1, region.y + region.h - 1);
|
|
else
|
|
sceGxmSetRegionClip(gxm_context, SCE_GXM_REGION_CLIP_OUTSIDE, 0, 0, DISPLAY_WIDTH - 1, DISPLAY_HEIGHT - 1);
|
|
}
|
|
|
|
void vglStopRenderingInit(void) {
|
|
// Ending drawing scene
|
|
sceGxmEndScene(gxm_context, NULL, NULL);
|
|
if (system_app_mode && vblank)
|
|
sceDisplayWaitVblankStart();
|
|
}
|
|
|
|
void vglStopRenderingTerm(void) {
|
|
if (active_write_fb == NULL) { // Default framebuffer is used
|
|
// Properly requesting a display update
|
|
if (system_app_mode)
|
|
sceSharedFbEnd(shared_fb);
|
|
else {
|
|
struct display_queue_callback_data queue_cb_data;
|
|
queue_cb_data.addr = gxm_color_surfaces_addr[gxm_back_buffer_index];
|
|
sceGxmDisplayQueueAddEntry(gxm_sync_objects[gxm_front_buffer_index],
|
|
gxm_sync_objects[gxm_back_buffer_index], &queue_cb_data);
|
|
gxm_front_buffer_index = gxm_back_buffer_index;
|
|
gxm_back_buffer_index = (gxm_back_buffer_index + 1) % DISPLAY_BUFFER_COUNT;
|
|
}
|
|
}
|
|
|
|
// Resetting vitaGL mempool
|
|
gpu_pool_reset();
|
|
}
|
|
|
|
void vglStopRendering() {
|
|
// Ending drawing scene
|
|
vglStopRenderingInit();
|
|
|
|
// Updating display and resetting vitaGL mempool
|
|
vglStopRenderingTerm();
|
|
}
|
|
|
|
void vglUpdateCommonDialog() {
|
|
// Populating SceCommonDialog parameters
|
|
SceCommonDialogUpdateParam updateParam;
|
|
memset(&updateParam, 0, sizeof(updateParam));
|
|
updateParam.renderTarget.colorFormat = SCE_GXM_COLOR_FORMAT_A8B8G8R8;
|
|
updateParam.renderTarget.surfaceType = SCE_GXM_COLOR_SURFACE_LINEAR;
|
|
updateParam.renderTarget.width = DISPLAY_WIDTH;
|
|
updateParam.renderTarget.height = DISPLAY_HEIGHT;
|
|
updateParam.renderTarget.strideInPixels = DISPLAY_STRIDE;
|
|
updateParam.renderTarget.colorSurfaceData = gxm_color_surfaces_addr[gxm_back_buffer_index];
|
|
updateParam.renderTarget.depthSurfaceData = gxm_depth_surface_addr;
|
|
updateParam.displaySyncObject = gxm_sync_objects[gxm_back_buffer_index];
|
|
|
|
// Updating sceCommonDialog
|
|
sceCommonDialogUpdate(&updateParam);
|
|
}
|
|
|
|
void glFinish(void) {
|
|
// Waiting for GPU to finish drawing jobs
|
|
sceGxmFinish(gxm_context);
|
|
}
|