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 <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* mem = SDL_malloc(size);

View File

@ -17,6 +17,7 @@
bool with_razor = false;
bool with_razor_hud = false;
bool gxm_initialized = false;
#define VITA_GXM_SCREEN_WIDTH 960
#define VITA_GXM_SCREEN_HEIGHT 544
@ -133,9 +134,12 @@ static void load_razor()
if (with_razor) {
sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx");
}
if(with_razor_hud) {
sceRazorGpuTraceSetFilename("ux0:data/gpu_trace", 3);
}
}
bool gxm_initialized = false;
bool gxm_init()
{
if (gxm_initialized) {
@ -203,7 +207,6 @@ bool cdram_allocator_create() {
}
int inuse_mem = 0;
inline void* cdram_alloc(size_t size, size_t align) {
sceClibPrintf("cdram_alloc(%d, %d) inuse=%d ", size, align, inuse_mem);
void* ptr = tlsf_memalign(cdramAllocator, align, size);
@ -423,7 +426,7 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
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(
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
@ -632,8 +635,11 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
// clear uniforms
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->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[3] = 3;
volatile uint32_t* const notificationMem = sceGxmGetNotificationRegion();
for (uint32_t i = 0; i < VITA_GXM_UNIFORM_BUFFER_COUNT; i++) {
this->fragmentNotifications[i].address = notificationMem + (i * 2);
volatile uint32_t* notificationMem = sceGxmGetNotificationRegion();
for(uint32_t i = 0; i < GXM_FRAGMENT_BUFFER_COUNT; i++) {
this->fragmentNotifications[i].address = notificationMem++;
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;
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;
}
@ -1088,8 +1095,8 @@ void GXMRenderer::StartScene()
this->sceneStarted = true;
this->quadsUsed = 0;
this->activeUniformBuffer = (this->activeUniformBuffer + 1) % VITA_GXM_UNIFORM_BUFFER_COUNT;
sceGxmNotificationWait(&this->fragmentNotifications[this->activeUniformBuffer]);
sceGxmNotificationWait(&this->vertexNotifications[this->currentVertexBufferIndex]);
sceGxmNotificationWait(&this->fragmentNotifications[this->currentFragmentBufferIndex]);
}
@ -1268,13 +1275,17 @@ void GXMRenderer::Flip()
this->Clear(0, 0, 0);
}
// end scene
++this->fragmentNotifications[this->activeUniformBuffer].value;
++this->vertexNotifications[this->currentVertexBufferIndex].value;
++this->fragmentNotifications[this->currentFragmentBufferIndex].value;
sceGxmEndScene(
this->context,
nullptr,
&this->fragmentNotifications[this->activeUniformBuffer]
&this->vertexNotifications[this->currentVertexBufferIndex],
&this->fragmentNotifications[this->currentFragmentBufferIndex]
);
this->currentVertexBufferIndex = (this->currentVertexBufferIndex + 1) % GXM_VERTEX_BUFFER_COUNT;
this->currentFragmentBufferIndex = (this->currentFragmentBufferIndex + 1) % GXM_FRAGMENT_BUFFER_COUNT;
sceGxmPadHeartbeat(
&this->displayBuffersSurface[this->backBufferIndex],
this->displayBuffersSync[this->backBufferIndex]
@ -1284,7 +1295,6 @@ void GXMRenderer::Flip()
// display
GXMDisplayData displayData;
displayData.address = this->displayBuffers[this->backBufferIndex];
sceGxmDisplayQueueAddEntry(
this->displayBuffersSync[this->frontBufferIndex],
this->displayBuffersSync[this->backBufferIndex],
@ -1292,7 +1302,7 @@ void GXMRenderer::Flip()
);
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)

View File

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

View File

@ -4,9 +4,15 @@
#include <psp2/gxm.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, ...) \
({ \
sceClibPrintf(#func "\n"); \
DEBUG_ONLY_PRINTF("%s\n", func); \
int __sce_err_ret_val = func(__VA_ARGS__); \
if (__sce_err_ret_val < 0) { \
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 VITA_GXM_DISPLAY_BUFFER_COUNT 3
#define VITA_GXM_UNIFORM_BUFFER_COUNT 2
#define GXM_DISPLAY_BUFFER_COUNT 3
#define GXM_VERTEX_BUFFER_COUNT 2
#define GXM_FRAGMENT_BUFFER_COUNT 3
struct GXMTextureCacheEntry {
IDirect3DRMTexture* texture;
@ -133,7 +134,7 @@ class GXMRenderer : public Direct3DRMRenderer {
void StartScene();
inline Vertex* QuadVerticesBuffer() {
Vertex* verts = &this->quadVertices[this->activeUniformBuffer][this->quadsUsed*4];
Vertex* verts = &this->quadVertices[this->currentVertexBufferIndex][this->quadsUsed*4];
this->quadsUsed += 1;
if(this->quadsUsed >= 50) {
SDL_Log("QuadVerticesBuffer overflow");
@ -143,7 +144,7 @@ class GXMRenderer : public Direct3DRMRenderer {
}
inline GXMSceneLightUniform* LightsBuffer() {
return this->lights[this->activeUniformBuffer];
return this->lights[this->currentFragmentBufferIndex];
}
std::vector<GXMTextureCacheEntry> m_textures;
@ -158,10 +159,10 @@ class GXMRenderer : public Direct3DRMRenderer {
SceGxmShaderPatcher* shaderPatcher;
SceGxmRenderTarget* renderTarget;
void* displayBuffers[VITA_GXM_DISPLAY_BUFFER_COUNT];
SceUID displayBuffersUid[VITA_GXM_DISPLAY_BUFFER_COUNT];
SceGxmColorSurface displayBuffersSurface[VITA_GXM_DISPLAY_BUFFER_COUNT];
SceGxmSyncObject* displayBuffersSync[VITA_GXM_DISPLAY_BUFFER_COUNT];
void* displayBuffers[GXM_DISPLAY_BUFFER_COUNT];
SceUID displayBuffersUid[GXM_DISPLAY_BUFFER_COUNT];
SceGxmColorSurface displayBuffersSurface[GXM_DISPLAY_BUFFER_COUNT];
SceGxmSyncObject* displayBuffersSync[GXM_DISPLAY_BUFFER_COUNT];
int backBufferIndex = 0;
int frontBufferIndex = 1;
@ -200,12 +201,15 @@ class GXMRenderer : public Direct3DRMRenderer {
const SceGxmProgramParameter* colorShader_uColor;
// uniforms / quad meshes
GXMSceneLightUniform (*lights)[VITA_GXM_UNIFORM_BUFFER_COUNT];
Vertex* quadVertices[VITA_GXM_UNIFORM_BUFFER_COUNT];
GXMSceneLightUniform* lights[GXM_FRAGMENT_BUFFER_COUNT];
Vertex* quadVertices[GXM_VERTEX_BUFFER_COUNT];
uint16_t* quadIndices;
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;