hopefully actually fix uniform buffers

This commit is contained in:
olebeck 2025-07-01 00:05:02 +02:00
parent 00cd13d5f1
commit 13c269eacf
5 changed files with 93 additions and 78 deletions

View File

@ -5,12 +5,6 @@
#include <SDL3/SDL_stdinc.h> #include <SDL3/SDL_stdinc.h>
#include <psp2/gxm.h> #include <psp2/gxm.h>
#include <assert.h>
static SceUID cdramPoolUID = -1;
static SceClibMspace cdramPool = NULL;
void* patcher_host_alloc(void* user_data, unsigned int size) void* patcher_host_alloc(void* user_data, unsigned int size)
{ {
void* mem = SDL_malloc(size); void* mem = SDL_malloc(size);

View File

@ -17,6 +17,7 @@
bool with_razor = false; bool with_razor = false;
bool with_razor_hud = false; bool with_razor_hud = false;
bool gxm_initialized = false;
#define VITA_GXM_SCREEN_WIDTH 960 #define VITA_GXM_SCREEN_WIDTH 960
#define VITA_GXM_SCREEN_HEIGHT 544 #define VITA_GXM_SCREEN_HEIGHT 544
@ -133,9 +134,12 @@ static void load_razor()
if (with_razor) { if (with_razor) {
sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx"); sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx");
} }
if(with_razor_hud) {
sceRazorGpuTraceSetFilename("ux0:data/gpu_trace", 3);
}
} }
bool gxm_initialized = false;
bool gxm_init() bool gxm_init()
{ {
if (gxm_initialized) { if (gxm_initialized) {
@ -203,7 +207,6 @@ bool cdram_allocator_create() {
} }
int inuse_mem = 0; int inuse_mem = 0;
inline void* cdram_alloc(size_t size, size_t align) { inline void* cdram_alloc(size_t size, size_t align) {
sceClibPrintf("cdram_alloc(%d, %d) inuse=%d ", size, align, inuse_mem); sceClibPrintf("cdram_alloc(%d, %d) inuse=%d ", size, align, inuse_mem);
void* ptr = tlsf_memalign(cdramAllocator, align, size); void* ptr = tlsf_memalign(cdramAllocator, align, size);
@ -423,7 +426,7 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
return; return;
} }
for (int i = 0; i < VITA_GXM_DISPLAY_BUFFER_COUNT; i++) { for (int i = 0; i < GXM_DISPLAY_BUFFER_COUNT; i++) {
this->displayBuffers[i] = vita_mem_alloc( this->displayBuffers[i] = vita_mem_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT, 4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
@ -632,8 +635,11 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
// clear uniforms // clear uniforms
this->colorShader_uColor = sceGxmProgramFindParameterByName(colorFragmentProgramGxp, "uColor"); // vec4 this->colorShader_uColor = sceGxmProgramFindParameterByName(colorFragmentProgramGxp, "uColor"); // vec4
this->lights = static_cast<decltype(this->lights)>(cdram_alloc(sizeof(*this->lights), 4));
for (int i = 0; i < VITA_GXM_UNIFORM_BUFFER_COUNT; i++) { for (int i = 0; i < GXM_FRAGMENT_BUFFER_COUNT; i++) {
this->lights[i] = static_cast<GXMSceneLightUniform*>(cdram_alloc(sizeof(GXMSceneLightUniform), 4));
}
for (int i = 0; i < GXM_VERTEX_BUFFER_COUNT; i++) {
this->quadVertices[i] = static_cast<Vertex*>(cdram_alloc(sizeof(Vertex) * 4 * 50, 4)); this->quadVertices[i] = static_cast<Vertex*>(cdram_alloc(sizeof(Vertex) * 4 * 50, 4));
} }
this->quadIndices = static_cast<uint16_t*>(cdram_alloc(sizeof(uint16_t) * 4, 4)); this->quadIndices = static_cast<uint16_t*>(cdram_alloc(sizeof(uint16_t) * 4, 4));
@ -642,13 +648,18 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
this->quadIndices[2] = 2; this->quadIndices[2] = 2;
this->quadIndices[3] = 3; this->quadIndices[3] = 3;
volatile uint32_t* const notificationMem = sceGxmGetNotificationRegion(); volatile uint32_t* notificationMem = sceGxmGetNotificationRegion();
for (uint32_t i = 0; i < VITA_GXM_UNIFORM_BUFFER_COUNT; i++) { for(uint32_t i = 0; i < GXM_FRAGMENT_BUFFER_COUNT; i++) {
this->fragmentNotifications[i].address = notificationMem + (i * 2); this->fragmentNotifications[i].address = notificationMem++;
this->fragmentNotifications[i].value = 0; this->fragmentNotifications[i].value = 0;
//this->vertexNotifications[i].address = notificationMem + (i * 2) + 1;
//this->vertexNotifications[i].value = 0;
} }
this->currentFragmentBufferIndex = 0;
for(uint32_t i = 0; i < GXM_VERTEX_BUFFER_COUNT; i++) {
this->vertexNotifications[i].address = notificationMem++;
this->vertexNotifications[i].value = 0;
}
this->currentVertexBufferIndex = 0;
int count; int count;
auto ids = SDL_GetGamepads(&count); auto ids = SDL_GetGamepads(&count);
@ -661,10 +672,6 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
} }
} }
if(with_razor_hud) {
sceRazorGpuTraceSetFilename("ux0:data/gpu_trace", 3);
}
m_initialized = true; m_initialized = true;
} }
@ -1088,8 +1095,8 @@ void GXMRenderer::StartScene()
this->sceneStarted = true; this->sceneStarted = true;
this->quadsUsed = 0; this->quadsUsed = 0;
this->activeUniformBuffer = (this->activeUniformBuffer + 1) % VITA_GXM_UNIFORM_BUFFER_COUNT; sceGxmNotificationWait(&this->vertexNotifications[this->currentVertexBufferIndex]);
sceGxmNotificationWait(&this->fragmentNotifications[this->activeUniformBuffer]); sceGxmNotificationWait(&this->fragmentNotifications[this->currentFragmentBufferIndex]);
} }
@ -1268,13 +1275,17 @@ void GXMRenderer::Flip()
this->Clear(0, 0, 0); this->Clear(0, 0, 0);
} }
// end scene ++this->vertexNotifications[this->currentVertexBufferIndex].value;
++this->fragmentNotifications[this->activeUniformBuffer].value; ++this->fragmentNotifications[this->currentFragmentBufferIndex].value;
sceGxmEndScene( sceGxmEndScene(
this->context, this->context,
nullptr, &this->vertexNotifications[this->currentVertexBufferIndex],
&this->fragmentNotifications[this->activeUniformBuffer] &this->fragmentNotifications[this->currentFragmentBufferIndex]
); );
this->currentVertexBufferIndex = (this->currentVertexBufferIndex + 1) % GXM_VERTEX_BUFFER_COUNT;
this->currentFragmentBufferIndex = (this->currentFragmentBufferIndex + 1) % GXM_FRAGMENT_BUFFER_COUNT;
sceGxmPadHeartbeat( sceGxmPadHeartbeat(
&this->displayBuffersSurface[this->backBufferIndex], &this->displayBuffersSurface[this->backBufferIndex],
this->displayBuffersSync[this->backBufferIndex] this->displayBuffersSync[this->backBufferIndex]
@ -1284,7 +1295,6 @@ void GXMRenderer::Flip()
// display // display
GXMDisplayData displayData; GXMDisplayData displayData;
displayData.address = this->displayBuffers[this->backBufferIndex]; displayData.address = this->displayBuffers[this->backBufferIndex];
sceGxmDisplayQueueAddEntry( sceGxmDisplayQueueAddEntry(
this->displayBuffersSync[this->frontBufferIndex], this->displayBuffersSync[this->frontBufferIndex],
this->displayBuffersSync[this->backBufferIndex], this->displayBuffersSync[this->backBufferIndex],
@ -1292,7 +1302,7 @@ void GXMRenderer::Flip()
); );
this->frontBufferIndex = this->backBufferIndex; this->frontBufferIndex = this->backBufferIndex;
this->backBufferIndex = (this->backBufferIndex + 1) % VITA_GXM_DISPLAY_BUFFER_COUNT; this->backBufferIndex = (this->backBufferIndex + 1) % GXM_DISPLAY_BUFFER_COUNT;
} }
void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect) void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect)

View File

@ -11,10 +11,10 @@
** **
** This implementation was written to the specification ** This implementation was written to the specification
** of the document, therefore no GPL restrictions apply. ** of the document, therefore no GPL restrictions apply.
** **
** Copyright (c) 2006-2016, Matthew Conte ** Copyright (c) 2006-2016, Matthew Conte
** All rights reserved. ** All rights reserved.
** **
** Redistribution and use in source and binary forms, with or without ** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met: ** modification, are permitted provided that the following conditions are met:
** * Redistributions of source code must retain the above copyright ** * Redistributions of source code must retain the above copyright
@ -25,7 +25,7 @@
** * Neither the name of the copyright holder nor the ** * Neither the name of the copyright holder nor the
** names of its contributors may be used to endorse or promote products ** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission. ** derived from this software without specific prior written permission.
** **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@ -41,50 +41,51 @@
#include <stddef.h> #include <stddef.h>
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C"
{
#endif #endif
/* tlsf_t: a TLSF structure. Can contain 1 to N pools. */ /* tlsf_t: a TLSF structure. Can contain 1 to N pools. */
/* pool_t: a block of memory that TLSF can manage. */ /* pool_t: a block of memory that TLSF can manage. */
typedef void* tlsf_t; typedef void* tlsf_t;
typedef void* pool_t; typedef void* pool_t;
/* Create/destroy a memory pool. */ /* Create/destroy a memory pool. */
tlsf_t tlsf_create(void* mem); tlsf_t tlsf_create(void* mem);
tlsf_t tlsf_create_with_pool(void* mem, size_t bytes); tlsf_t tlsf_create_with_pool(void* mem, size_t bytes);
void tlsf_destroy(tlsf_t tlsf); void tlsf_destroy(tlsf_t tlsf);
pool_t tlsf_get_pool(tlsf_t tlsf); pool_t tlsf_get_pool(tlsf_t tlsf);
/* Add/remove memory pools. */ /* Add/remove memory pools. */
pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes); pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes);
void tlsf_remove_pool(tlsf_t tlsf, pool_t pool); void tlsf_remove_pool(tlsf_t tlsf, pool_t pool);
/* malloc/memalign/realloc/free replacements. */ /* malloc/memalign/realloc/free replacements. */
void* tlsf_malloc(tlsf_t tlsf, size_t bytes); void* tlsf_malloc(tlsf_t tlsf, size_t bytes);
void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t bytes); void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t bytes);
void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size); void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size);
void tlsf_free(tlsf_t tlsf, void* ptr); void tlsf_free(tlsf_t tlsf, void* ptr);
/* Returns internal block size, not original request size */ /* Returns internal block size, not original request size */
size_t tlsf_block_size(void* ptr); size_t tlsf_block_size(void* ptr);
/* Overheads/limits of internal structures. */ /* Overheads/limits of internal structures. */
size_t tlsf_size(void); size_t tlsf_size(void);
size_t tlsf_align_size(void); size_t tlsf_align_size(void);
size_t tlsf_block_size_min(void); size_t tlsf_block_size_min(void);
size_t tlsf_block_size_max(void); size_t tlsf_block_size_max(void);
size_t tlsf_pool_overhead(void); size_t tlsf_pool_overhead(void);
size_t tlsf_alloc_overhead(void); size_t tlsf_alloc_overhead(void);
/* Debugging. */ /* Debugging. */
typedef void (*tlsf_walker)(void* ptr, size_t size, int used, void* user); typedef void (*tlsf_walker)(void* ptr, size_t size, int used, void* user);
void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user); void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user);
/* Returns nonzero if any internal consistency check fails. */ /* Returns nonzero if any internal consistency check fails. */
int tlsf_check(tlsf_t tlsf); int tlsf_check(tlsf_t tlsf);
int tlsf_check_pool(pool_t pool); int tlsf_check_pool(pool_t pool);
#if defined(__cplusplus) #if defined(__cplusplus)
}; };
#endif #endif
#endif #endif

View File

@ -4,9 +4,15 @@
#include <psp2/gxm.h> #include <psp2/gxm.h>
#include <psp2/kernel/clib.h> #include <psp2/kernel/clib.h>
#ifdef DEBUG
#define DEBUG_ONLY_PRINTF(...) sceClibPrintf(__VA_ARGS__)
#else
#define DEBUG_ONLY_PRINTF(...)
#endif
#define SCE_ERR(func, ...) \ #define SCE_ERR(func, ...) \
({ \ ({ \
sceClibPrintf(#func "\n"); \ DEBUG_ONLY_PRINTF("%s\n", func); \
int __sce_err_ret_val = func(__VA_ARGS__); \ int __sce_err_ret_val = func(__VA_ARGS__); \
if (__sce_err_ret_val < 0) { \ if (__sce_err_ret_val < 0) { \
sceClibPrintf(#func " error: 0x%x\n", __sce_err_ret_val); \ sceClibPrintf(#func " error: 0x%x\n", __sce_err_ret_val); \

View File

@ -16,8 +16,9 @@
DEFINE_GUID(GXM_GUID, 0x682656F3, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x58, 0x4D); DEFINE_GUID(GXM_GUID, 0x682656F3, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x58, 0x4D);
#define VITA_GXM_DISPLAY_BUFFER_COUNT 3 #define GXM_DISPLAY_BUFFER_COUNT 3
#define VITA_GXM_UNIFORM_BUFFER_COUNT 2 #define GXM_VERTEX_BUFFER_COUNT 2
#define GXM_FRAGMENT_BUFFER_COUNT 3
struct GXMTextureCacheEntry { struct GXMTextureCacheEntry {
IDirect3DRMTexture* texture; IDirect3DRMTexture* texture;
@ -133,7 +134,7 @@ class GXMRenderer : public Direct3DRMRenderer {
void StartScene(); void StartScene();
inline Vertex* QuadVerticesBuffer() { inline Vertex* QuadVerticesBuffer() {
Vertex* verts = &this->quadVertices[this->activeUniformBuffer][this->quadsUsed*4]; Vertex* verts = &this->quadVertices[this->currentVertexBufferIndex][this->quadsUsed*4];
this->quadsUsed += 1; this->quadsUsed += 1;
if(this->quadsUsed >= 50) { if(this->quadsUsed >= 50) {
SDL_Log("QuadVerticesBuffer overflow"); SDL_Log("QuadVerticesBuffer overflow");
@ -143,7 +144,7 @@ class GXMRenderer : public Direct3DRMRenderer {
} }
inline GXMSceneLightUniform* LightsBuffer() { inline GXMSceneLightUniform* LightsBuffer() {
return this->lights[this->activeUniformBuffer]; return this->lights[this->currentFragmentBufferIndex];
} }
std::vector<GXMTextureCacheEntry> m_textures; std::vector<GXMTextureCacheEntry> m_textures;
@ -158,10 +159,10 @@ class GXMRenderer : public Direct3DRMRenderer {
SceGxmShaderPatcher* shaderPatcher; SceGxmShaderPatcher* shaderPatcher;
SceGxmRenderTarget* renderTarget; SceGxmRenderTarget* renderTarget;
void* displayBuffers[VITA_GXM_DISPLAY_BUFFER_COUNT]; void* displayBuffers[GXM_DISPLAY_BUFFER_COUNT];
SceUID displayBuffersUid[VITA_GXM_DISPLAY_BUFFER_COUNT]; SceUID displayBuffersUid[GXM_DISPLAY_BUFFER_COUNT];
SceGxmColorSurface displayBuffersSurface[VITA_GXM_DISPLAY_BUFFER_COUNT]; SceGxmColorSurface displayBuffersSurface[GXM_DISPLAY_BUFFER_COUNT];
SceGxmSyncObject* displayBuffersSync[VITA_GXM_DISPLAY_BUFFER_COUNT]; SceGxmSyncObject* displayBuffersSync[GXM_DISPLAY_BUFFER_COUNT];
int backBufferIndex = 0; int backBufferIndex = 0;
int frontBufferIndex = 1; int frontBufferIndex = 1;
@ -200,12 +201,15 @@ class GXMRenderer : public Direct3DRMRenderer {
const SceGxmProgramParameter* colorShader_uColor; const SceGxmProgramParameter* colorShader_uColor;
// uniforms / quad meshes // uniforms / quad meshes
GXMSceneLightUniform (*lights)[VITA_GXM_UNIFORM_BUFFER_COUNT]; GXMSceneLightUniform* lights[GXM_FRAGMENT_BUFFER_COUNT];
Vertex* quadVertices[VITA_GXM_UNIFORM_BUFFER_COUNT]; Vertex* quadVertices[GXM_VERTEX_BUFFER_COUNT];
uint16_t* quadIndices; uint16_t* quadIndices;
int quadsUsed = 0; int quadsUsed = 0;
int activeUniformBuffer = 0;
SceGxmNotification fragmentNotifications[VITA_GXM_UNIFORM_BUFFER_COUNT]; SceGxmNotification vertexNotifications[GXM_VERTEX_BUFFER_COUNT];
SceGxmNotification fragmentNotifications[GXM_FRAGMENT_BUFFER_COUNT];
int currentFragmentBufferIndex = 0;
int currentVertexBufferIndex = 0;
SDL_Gamepad* gamepad; SDL_Gamepad* gamepad;