Vita: Now clearing works at least

This commit is contained in:
UnknownShadow200 2023-08-19 16:21:20 +10:00
parent 0517f72867
commit 0d8c1054eb

View File

@ -7,12 +7,13 @@
#include <vitasdk.h>
/* Current format and size of vertices */
static int gfx_stride, gfx_format = -1;
static int frontBufferIndex, backBufferIndex;
#define DISPLAY_WIDTH 960
#define DISPLAY_HEIGHT 544
#define DISPLAY_STRIDE 1024
#define NUM_DISPLAY_BUFFERS 2
#define NUM_DISPLAY_BUFFERS 3 // TODO: or just 2?
#define MAX_PENDING_SWAPS (NUM_DISPLAY_BUFFERS - 1)
static SceGxmContext* gxm_context;
@ -37,6 +38,33 @@ static SceUID gxm_depth_stencil_surface_uid;
static void* gxm_depth_stencil_surface_addr;
static SceGxmDepthStencilSurface gxm_depth_stencil_surface;
static SceGxmShaderPatcher *gxm_shader_patcher;
static const int shader_patcher_buffer_size = 64 * 1024;;
static SceUID gxm_shader_patcher_buffer_uid;
static void* gxm_shader_patcher_buffer_addr;
static const int shader_patcher_vertex_usse_size = 64 * 1024;
static SceUID gxm_shader_patcher_vertex_usse_uid;
static void* gxm_shader_patcher_vertex_usse_addr;
static unsigned int shader_patcher_vertex_usse_offset;
static const int shader_patcher_fragment_usse_size = 64 * 1024;
static SceUID gxm_shader_patcher_fragment_usse_uid;
static void* gxm_shader_patcher_fragment_usse_addr;
static unsigned int shader_patcher_fragment_usse_offset;
static SceGxmShaderPatcherId gxm_clear_vertex_program_id;
static SceGxmShaderPatcherId gxm_clear_fragment_program_id;
static const SceGxmProgramParameter* gxm_clear_vertex_program_position_param;
static const SceGxmProgramParameter* gxm_clear_fragment_program_clear_color_param;
static SceGxmVertexProgram* gxm_clear_vertex_program_patched;
static SceGxmFragmentProgram* gxm_clear_fragment_program_patched;
#include "../misc/vita/clear_fs.h"
#include "../misc/vita/clear_vs.h"
static SceGxmProgram* gxm_program_clear_vs = (SceGxmProgram *)&clear_vs;
static SceGxmProgram* gxm_program_clear_fs = (SceGxmProgram *)&clear_fs;
/*########################################################################################################################*
*---------------------------------------------------------Memory----------------------------------------------------------*
*#########################################################################################################################*/
@ -107,30 +135,51 @@ void* AllocGPUFragmentUSSE(size_t size, SceUID* ret_uid, unsigned int* ret_usse_
return addr;
}
static void FreeGPUMemory(SceUID uid) {
void *addr;
if (sceKernelGetMemBlockBase(uid, &addr) < 0)
return;
sceGxmUnmapMemory(addr);
sceKernelFreeMemBlock(uid);
}
static void* AllocShaderPatcherMem(void* user_data, unsigned int size) {
return Mem_TryAlloc(1, size);
}
static void FreeShaderPatcherMem(void* user_data, void* mem) {
Mem_Free(mem);
}
/*########################################################################################################################*
*-----------------------------------------------------Initialisation------------------------------------------------------*
*#########################################################################################################################*/
static void DisplayQueueCallback(const void *callback_data) {
SceDisplayFrameBuf fb = { 0 };
void* addr = *((void **)callback_data);
struct DQCallbackData { void* addr; };
static void DQCallback(const void *callback_data) {
SceDisplayFrameBuf fb = { 0 };
fb.size = sizeof(SceDisplayFrameBuf);
fb.base = addr;
fb.base = ((struct DQCallbackData*)callback_data)->addr;
fb.pitch = DISPLAY_STRIDE;
fb.pixelformat = SCE_DISPLAY_PIXELFORMAT_A8B8G8R8;
fb.width = DISPLAY_WIDTH;
fb.height = DISPLAY_HEIGHT;
sceDisplaySetFrameBuf(&fb, SCE_DISPLAY_SETBUF_NEXTFRAME);
if (gfx_vsync) sceDisplayWaitVblankStart();
}
static void InitGXM(void) {
SceGxmInitializeParams params = { 0 };
params.displayQueueMaxPendingCount = MAX_PENDING_SWAPS;
params.displayQueueCallback = DisplayQueueCallback;
params.displayQueueCallbackDataSize = sizeof(void*);
params.displayQueueCallback = DQCallback;
params.displayQueueCallbackDataSize = sizeof(struct DQCallbackData);
params.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE;
sceGxmInitialize(&params);
@ -156,7 +205,7 @@ static void AllocRingBuffers(void) {
static void AllocGXMContext(void) {
SceGxmContextParams params = { 0 };
params.hostMem = Mem_TryAlloc(SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE, 1);
params.hostMem = Mem_TryAlloc(1, SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE);
params.hostMemSize = SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE;
params.vdmRingBufferMem = vdm_ring_buffer_addr;
@ -217,6 +266,81 @@ static void AllocDepthBuffer(void) {
width, gxm_depth_stencil_surface_addr, NULL);
}
static void AllocShaderPatcherMemory(void) {
gxm_shader_patcher_buffer_addr = AllocGPUMemory(shader_patcher_buffer_size,
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, SCE_GXM_MEMORY_ATTRIB_READ,
&gxm_shader_patcher_buffer_uid);
gxm_shader_patcher_vertex_usse_addr = AllocGPUVertexUSSE(
shader_patcher_vertex_usse_size, &gxm_shader_patcher_vertex_usse_uid,
&shader_patcher_vertex_usse_offset);
gxm_shader_patcher_fragment_usse_addr = AllocGPUFragmentUSSE(
shader_patcher_fragment_usse_size, &gxm_shader_patcher_fragment_usse_uid,
&shader_patcher_fragment_usse_offset);
}
static void AllocShaderPatcher(void) {
SceGxmShaderPatcherParams params = { 0 };
params.hostAllocCallback = AllocShaderPatcherMem;
params.hostFreeCallback = FreeShaderPatcherMem;
params.bufferMem = gxm_shader_patcher_buffer_addr;
params.bufferMemSize = shader_patcher_buffer_size;
params.vertexUsseMem = gxm_shader_patcher_vertex_usse_addr;
params.vertexUsseMemSize = shader_patcher_vertex_usse_size;
params.vertexUsseOffset = shader_patcher_vertex_usse_offset;
params.fragmentUsseMem = gxm_shader_patcher_fragment_usse_addr;
params.fragmentUsseMemSize = shader_patcher_fragment_usse_size;
params.fragmentUsseOffset = shader_patcher_fragment_usse_offset;
sceGxmShaderPatcherCreate(&params, &gxm_shader_patcher);
}
struct clear_vertex {
float x, y, z;
};
static void AllocClearShader(void) {
sceGxmShaderPatcherRegisterProgram(gxm_shader_patcher, gxm_program_clear_vs,
&gxm_clear_vertex_program_id);
sceGxmShaderPatcherRegisterProgram(gxm_shader_patcher, gxm_program_clear_fs,
&gxm_clear_fragment_program_id);
const SceGxmProgram *clear_vertex_program =
sceGxmShaderPatcherGetProgramFromId(gxm_clear_vertex_program_id);
const SceGxmProgram *clear_fragment_program =
sceGxmShaderPatcherGetProgramFromId(gxm_clear_fragment_program_id);
gxm_clear_vertex_program_position_param = sceGxmProgramFindParameterByName(
clear_vertex_program, "position");
gxm_clear_fragment_program_clear_color_param = sceGxmProgramFindParameterByName(
clear_fragment_program, "clearColor");
SceGxmVertexAttribute clear_vertex_attribute;
SceGxmVertexStream clear_vertex_stream;
clear_vertex_attribute.streamIndex = 0;
clear_vertex_attribute.offset = 0;
clear_vertex_attribute.format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
clear_vertex_attribute.componentCount = 2;
clear_vertex_attribute.regIndex = sceGxmProgramParameterGetResourceIndex(
gxm_clear_vertex_program_position_param);
clear_vertex_stream.stride = sizeof(struct clear_vertex);
clear_vertex_stream.indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
sceGxmShaderPatcherCreateVertexProgram(gxm_shader_patcher,
gxm_clear_vertex_program_id, &clear_vertex_attribute,
1, &clear_vertex_stream, 1, &gxm_clear_vertex_program_patched);
sceGxmShaderPatcherCreateFragmentProgram(gxm_shader_patcher,
gxm_clear_fragment_program_id, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
SCE_GXM_MULTISAMPLE_NONE, NULL, clear_fragment_program,
&gxm_clear_fragment_program_patched);
}
/*########################################################################################################################*
*---------------------------------------------------------General---------------------------------------------------------*
@ -228,17 +352,34 @@ void Gfx_Create(void) {
Gfx.Created = true;
InitGXM();
Platform_LogConst("clear shader 1");
AllocRingBuffers();
Platform_LogConst("clear shader 2");
AllocGXMContext();
Platform_LogConst("clear shader 3");
AllocRenderTarget();
Platform_LogConst("clear shader4");
for (int i = 0; i < NUM_DISPLAY_BUFFERS; i++)
{
AllocColorBuffer(i);
}
Platform_LogConst("clear shader 5");
AllocDepthBuffer();
Platform_LogConst("clear shader 6");
AllocShaderPatcherMemory();
Platform_LogConst("clear shader 7");
AllocShaderPatcher();
Platform_LogConst("clear shader 8");
AllocClearShader();
Platform_LogConst("clear shader 9");
InitDefaultResources();
Platform_LogConst("clear shader 10");
frontBufferIndex = NUM_DISPLAY_BUFFERS - 1;
backBufferIndex = 0;
// 1x1 dummy white texture
struct Bitmap bmp;
@ -292,8 +433,12 @@ void Gfx_SetFaceCulling(cc_bool enabled) { } // TODO
void Gfx_SetAlphaBlending(cc_bool enabled) { } // TODO
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
static float clear_color[4];
void Gfx_ClearCol(PackedCol color) {
// TODO
clear_color[0] = PackedCol_R(color) / 255.0f;
clear_color[1] = PackedCol_G(color) / 255.0f;
clear_color[2] = PackedCol_B(color) / 255.0f;
clear_color[3] = PackedCol_A(color) / 255.0f;
}
void Gfx_SetColWriteMask(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
@ -363,57 +508,90 @@ void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMs) {
}
void Gfx_BeginFrame(void) {
// TODO
sceGxmBeginScene(gxm_context,
0, gxm_render_target,
NULL, NULL,
gxm_sync_objects[backBufferIndex],
&gxm_color_surfaces[backBufferIndex],
&gxm_depth_stencil_surface);
}
void Gfx_Clear(void) { } // TODO
void Gfx_EndFrame(void) {
Platform_LogConst("SWAP BUFFERS");
// TODO
sceGxmEndScene(gxm_context, NULL, NULL);
struct DQCallbackData cb_data;
cb_data.addr = gxm_color_surfaces_addr[backBufferIndex];
sceGxmDisplayQueueAddEntry(gxm_sync_objects[frontBufferIndex],
gxm_sync_objects[backBufferIndex], &cb_data);
// Cycle through to next buffer pair
frontBufferIndex = backBufferIndex;
backBufferIndex = (backBufferIndex + 1) % NUM_DISPLAY_BUFFERS;
if (gfx_minFrameMs) LimitFPS();
}
void Gfx_OnWindowResize(void) { }
/*########################################################################################################################*
*-------------------------------------------------------Index buffers-----------------------------------------------------*
*#########################################################################################################################*/
GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) {
//fillFunc(gfx_indices, count, obj);
return 1;
}
void Gfx_BindIb(GfxResourceID ib) { }
void Gfx_DeleteIb(GfxResourceID* ib) { }
/*########################################################################################################################*
*----------------------------------------------------------Buffers--------------------------------------------------------*
*#########################################################################################################################*/
static void* gfx_vertices;
static int vb_size;
struct GPUBuffer {
void* data;
SceUID uid;
};
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
void* data = memalign(16, count * strideSizes[fmt]);
if (!data) Logger_Abort("Failed to allocate memory for GFX VB");
return data;
struct GPUBuffer* GPUBuffer_Alloc(int size) {
struct GPUBuffer* buffer = Mem_Alloc(1, sizeof(struct GPUBuffer), "GPU buffer");
buffer->data = AllocGPUMemory(size,
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_GXM_MEMORY_ATTRIB_READ,
&buffer->uid);
return buffer;
}
static void GPUBuffer_Free(GfxResourceID* resource) {
GfxResourceID raw = *resource;
if (!raw) return;
struct GPUBuffer* buffer = (struct GPUBuffer*)raw;
FreeGPUMemory(buffer->uid);
Mem_Free(buffer);
*resource = NULL;
}
static void* gfx_indices;
GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) {
struct GPUBuffer* buffer = GPUBuffer_Alloc(count * 2);
fillFunc(buffer->data, count, obj);
return buffer;
}
void Gfx_BindIb(GfxResourceID ib) {
// TODO
gfx_indices = ib;
}
void Gfx_DeleteIb(GfxResourceID* ib) { GPUBuffer_Free(ib); }
static void* gfx_vertices;
GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) {
return GPUBuffer_Alloc(count * strideSizes[fmt]);
}
void Gfx_BindVb(GfxResourceID vb) { gfx_vertices = vb; }
void Gfx_DeleteVb(GfxResourceID* vb) {
GfxResourceID data = *vb;
if (data) Mem_Free(data);
*vb = 0;
// TODO
}
void Gfx_DeleteVb(GfxResourceID* vb) { GPUBuffer_Free(vb); }
void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) {
vb_size = count * strideSizes[fmt];
return vb;
// TODO
struct GPUBuffer* buffer = (struct GPUBuffer*)vb;
return buffer->data;
}
void Gfx_UnlockVb(GfxResourceID vb) {
@ -423,26 +601,23 @@ void Gfx_UnlockVb(GfxResourceID vb) {
GfxResourceID Gfx_CreateDynamicVb(VertexFormat fmt, int maxVertices) {
void* data = memalign(16, maxVertices * strideSizes[fmt]);
if (!data) Logger_Abort("Failed to allocate memory for GFX VB");
return data;
// TODO
return GPUBuffer_Alloc(maxVertices * strideSizes[fmt]);
}
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
vb_size = count * strideSizes[fmt];
return vb;
// TODO
struct GPUBuffer* buffer = (struct GPUBuffer*)vb;
return buffer->data;
}
void Gfx_UnlockDynamicVb(GfxResourceID vb) {
gfx_vertices = vb;
gfx_vertices = vb;
// TODO
}
void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
struct GPUBuffer* buffer = (struct GPUBuffer*)vb;
gfx_vertices = vb;
Mem_Copy(vb, vertices, vCount * gfx_stride);
Mem_Copy(buffer->data, vertices, vCount * gfx_stride);
// TODO
}
@ -526,4 +701,43 @@ void Gfx_DrawVb_IndexedTris(int verticesCount) {
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {
// TODO
}
void Gfx_Clear(void) {
static struct GPUBuffer* clear_vertices;
static struct GPUBuffer* clear_indices;
if (!clear_vertices) {
clear_vertices = GPUBuffer_Alloc(4 * sizeof(struct clear_vertex));
clear_indices = GPUBuffer_Alloc(4 * sizeof(unsigned short));
struct clear_vertex* clear_vertices_data = clear_vertices->data;
clear_vertices_data[0] = (struct clear_vertex){-1.0f, -1.0f};
clear_vertices_data[1] = (struct clear_vertex){ 1.0f, -1.0f};
clear_vertices_data[2] = (struct clear_vertex){-1.0f, 1.0f};
clear_vertices_data[3] = (struct clear_vertex){ 1.0f, 1.0f};
unsigned short* clear_indices_data = clear_indices->data;
clear_indices_data[0] = 0;
clear_indices_data[1] = 1;
clear_indices_data[2] = 2;
clear_indices_data[3] = 3;
}
sceGxmSetVertexProgram(gxm_context, gxm_clear_vertex_program_patched);
sceGxmSetFragmentProgram(gxm_context, gxm_clear_fragment_program_patched);
void *uniform_buffer;
sceGxmReserveFragmentDefaultUniformBuffer(gxm_context, &uniform_buffer);
sceGxmSetUniformDataF(uniform_buffer, gxm_clear_fragment_program_clear_color_param,
0, sizeof(clear_color) / sizeof(float), clear_color);
sceGxmSetVertexStream(gxm_context, 0, clear_vertices->data);
sceGxmDraw(gxm_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP,
SCE_GXM_INDEX_FORMAT_U16, clear_indices->data, 4);
}
#endif