|
@@ -117,6 +117,8 @@ tex_format_to_bytespp(SceGxmTextureFormat format)
|
|
|
case SCE_GXM_TEXTURE_BASE_FORMAT_U8:
|
|
|
case SCE_GXM_TEXTURE_BASE_FORMAT_S8:
|
|
|
case SCE_GXM_TEXTURE_BASE_FORMAT_P8:
|
|
|
+ case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2: // YUV actually uses 12 bits per pixel. UV planes bits/mem are handled elsewhere
|
|
|
+ case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3:
|
|
|
return 1;
|
|
|
case SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4:
|
|
|
case SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2:
|
|
@@ -414,28 +416,28 @@ gxm_init(SDL_Renderer *renderer)
|
|
|
}
|
|
|
|
|
|
// allocate ring buffer memory using default sizes
|
|
|
- vdmRingBuffer = mem_gpu_alloc(
|
|
|
+ vdmRingBuffer = vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
|
|
SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE,
|
|
|
4,
|
|
|
SCE_GXM_MEMORY_ATTRIB_READ,
|
|
|
&data->vdmRingBufferUid);
|
|
|
|
|
|
- vertexRingBuffer = mem_gpu_alloc(
|
|
|
+ vertexRingBuffer = vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
|
|
SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE,
|
|
|
4,
|
|
|
SCE_GXM_MEMORY_ATTRIB_READ,
|
|
|
&data->vertexRingBufferUid);
|
|
|
|
|
|
- fragmentRingBuffer = mem_gpu_alloc(
|
|
|
+ fragmentRingBuffer = vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
|
|
SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE,
|
|
|
4,
|
|
|
SCE_GXM_MEMORY_ATTRIB_READ,
|
|
|
&data->fragmentRingBufferUid);
|
|
|
|
|
|
- fragmentUsseRingBuffer = mem_fragment_usse_alloc(
|
|
|
+ fragmentUsseRingBuffer = vita_mem_fragment_usse_alloc(
|
|
|
SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE,
|
|
|
&data->fragmentUsseRingBufferUid,
|
|
|
&fragmentUsseRingBufferOffset);
|
|
@@ -480,7 +482,7 @@ gxm_init(SDL_Renderer *renderer)
|
|
|
for (i = 0; i < VITA_GXM_BUFFERS; i++) {
|
|
|
|
|
|
// allocate memory for display
|
|
|
- data->displayBufferData[i] = mem_gpu_alloc(
|
|
|
+ data->displayBufferData[i] = vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
|
|
|
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
|
|
|
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
|
|
@@ -525,7 +527,7 @@ gxm_init(SDL_Renderer *renderer)
|
|
|
|
|
|
|
|
|
// allocate the depth buffer
|
|
|
- data->depthBufferData = mem_gpu_alloc(
|
|
|
+ data->depthBufferData = vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
|
|
4 * sampleCount,
|
|
|
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
|
@@ -533,7 +535,7 @@ gxm_init(SDL_Renderer *renderer)
|
|
|
&data->depthBufferUid);
|
|
|
|
|
|
// allocate the stencil buffer
|
|
|
- data->stencilBufferData = mem_gpu_alloc(
|
|
|
+ data->stencilBufferData = vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
|
|
4 * sampleCount,
|
|
|
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
|
@@ -565,19 +567,19 @@ gxm_init(SDL_Renderer *renderer)
|
|
|
|
|
|
|
|
|
// allocate memory for buffers and USSE code
|
|
|
- patcherBuffer = mem_gpu_alloc(
|
|
|
+ patcherBuffer = vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
|
|
patcherBufferSize,
|
|
|
4,
|
|
|
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
|
|
&data->patcherBufferUid);
|
|
|
|
|
|
- patcherVertexUsse = mem_vertex_usse_alloc(
|
|
|
+ patcherVertexUsse = vita_mem_vertex_usse_alloc(
|
|
|
patcherVertexUsseSize,
|
|
|
&data->patcherVertexUsseUid,
|
|
|
&patcherVertexUsseOffset);
|
|
|
|
|
|
- patcherFragmentUsse = mem_fragment_usse_alloc(
|
|
|
+ patcherFragmentUsse = vita_mem_fragment_usse_alloc(
|
|
|
patcherFragmentUsseSize,
|
|
|
&data->patcherFragmentUsseUid,
|
|
|
&patcherFragmentUsseOffset);
|
|
@@ -728,7 +730,7 @@ gxm_init(SDL_Renderer *renderer)
|
|
|
}
|
|
|
|
|
|
// create the clear triangle vertex/index data
|
|
|
- data->clearVertices = (clear_vertex *)mem_gpu_alloc(
|
|
|
+ data->clearVertices = (clear_vertex *)vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
|
|
3*sizeof(clear_vertex),
|
|
|
4,
|
|
@@ -740,7 +742,7 @@ gxm_init(SDL_Renderer *renderer)
|
|
|
// Allocate a 64k * 2 bytes = 128 KiB buffer and store all possible
|
|
|
// 16-bit indices in linear ascending order, so we can use this for
|
|
|
// all drawing operations where we don't want to use indexing.
|
|
|
- data->linearIndices = (uint16_t *)mem_gpu_alloc(
|
|
|
+ data->linearIndices = (uint16_t *)vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
|
|
UINT16_MAX*sizeof(uint16_t),
|
|
|
sizeof(uint16_t),
|
|
@@ -871,7 +873,7 @@ gxm_init(SDL_Renderer *renderer)
|
|
|
data->textureWvpParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(textureVertexProgramGxp, "wvp");
|
|
|
|
|
|
// Allocate memory for the memory pool
|
|
|
- data->pool_addr[0] = mem_gpu_alloc(
|
|
|
+ data->pool_addr[0] = vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW,
|
|
|
VITA_GXM_POOL_SIZE,
|
|
|
sizeof(void *),
|
|
@@ -879,7 +881,7 @@ gxm_init(SDL_Renderer *renderer)
|
|
|
&data->poolUid[0]
|
|
|
);
|
|
|
|
|
|
- data->pool_addr[1] = mem_gpu_alloc(
|
|
|
+ data->pool_addr[1] = vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW,
|
|
|
VITA_GXM_POOL_SIZE,
|
|
|
sizeof(void *),
|
|
@@ -918,28 +920,28 @@ void gxm_finish(SDL_Renderer *renderer)
|
|
|
free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mod);
|
|
|
free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mul);
|
|
|
|
|
|
- mem_gpu_free(data->linearIndicesUid);
|
|
|
- mem_gpu_free(data->clearVerticesUid);
|
|
|
+ vita_mem_free(data->linearIndicesUid);
|
|
|
+ vita_mem_free(data->clearVerticesUid);
|
|
|
|
|
|
// wait until display queue is finished before deallocating display buffers
|
|
|
sceGxmDisplayQueueFinish();
|
|
|
|
|
|
// clean up display queue
|
|
|
- mem_gpu_free(data->depthBufferUid);
|
|
|
+ vita_mem_free(data->depthBufferUid);
|
|
|
|
|
|
for (size_t i = 0; i < VITA_GXM_BUFFERS; i++)
|
|
|
{
|
|
|
// clear the buffer then deallocate
|
|
|
SDL_memset(data->displayBufferData[i], 0, VITA_GXM_SCREEN_HEIGHT * VITA_GXM_SCREEN_STRIDE * 4);
|
|
|
- mem_gpu_free(data->displayBufferUid[i]);
|
|
|
+ vita_mem_free(data->displayBufferUid[i]);
|
|
|
|
|
|
// destroy the sync object
|
|
|
sceGxmSyncObjectDestroy(data->displayBufferSync[i]);
|
|
|
}
|
|
|
|
|
|
// Free the depth and stencil buffer
|
|
|
- mem_gpu_free(data->depthBufferUid);
|
|
|
- mem_gpu_free(data->stencilBufferUid);
|
|
|
+ vita_mem_free(data->depthBufferUid);
|
|
|
+ vita_mem_free(data->stencilBufferUid);
|
|
|
|
|
|
// unregister programs and destroy shader patcher
|
|
|
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->clearFragmentProgramId);
|
|
@@ -950,23 +952,24 @@ void gxm_finish(SDL_Renderer *renderer)
|
|
|
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureVertexProgramId);
|
|
|
|
|
|
sceGxmShaderPatcherDestroy(data->shaderPatcher);
|
|
|
- mem_fragment_usse_free(data->patcherFragmentUsseUid);
|
|
|
- mem_vertex_usse_free(data->patcherVertexUsseUid);
|
|
|
- mem_gpu_free(data->patcherBufferUid);
|
|
|
+ vita_mem_fragment_usse_free(data->patcherFragmentUsseUid);
|
|
|
+ vita_mem_vertex_usse_free(data->patcherVertexUsseUid);
|
|
|
+ vita_mem_free(data->patcherBufferUid);
|
|
|
|
|
|
// destroy the render target
|
|
|
sceGxmDestroyRenderTarget(data->renderTarget);
|
|
|
|
|
|
// destroy the gxm context
|
|
|
sceGxmDestroyContext(data->gxm_context);
|
|
|
- mem_fragment_usse_free(data->fragmentUsseRingBufferUid);
|
|
|
- mem_gpu_free(data->fragmentRingBufferUid);
|
|
|
- mem_gpu_free(data->vertexRingBufferUid);
|
|
|
- mem_gpu_free(data->vdmRingBufferUid);
|
|
|
+ vita_mem_fragment_usse_free(data->fragmentUsseRingBufferUid);
|
|
|
+ vita_mem_free(data->fragmentRingBufferUid);
|
|
|
+ vita_mem_free(data->vertexRingBufferUid);
|
|
|
+ vita_mem_free(data->vdmRingBufferUid);
|
|
|
SDL_free(data->contextParams.hostMem);
|
|
|
|
|
|
- mem_gpu_free(data->poolUid[0]);
|
|
|
- mem_gpu_free(data->poolUid[1]);
|
|
|
+ vita_mem_free(data->poolUid[0]);
|
|
|
+ vita_mem_free(data->poolUid[1]);
|
|
|
+ vita_gpu_mem_destroy(data);
|
|
|
|
|
|
// terminate libgxm
|
|
|
sceGxmTerminate();
|
|
@@ -975,16 +978,20 @@ void gxm_finish(SDL_Renderer *renderer)
|
|
|
// textures
|
|
|
|
|
|
void
|
|
|
-free_gxm_texture(gxm_texture *texture)
|
|
|
+free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture)
|
|
|
{
|
|
|
if (texture) {
|
|
|
if (texture->gxm_rendertarget) {
|
|
|
sceGxmDestroyRenderTarget(texture->gxm_rendertarget);
|
|
|
}
|
|
|
if (texture->depth_UID) {
|
|
|
- mem_gpu_free(texture->depth_UID);
|
|
|
+ vita_mem_free(texture->depth_UID);
|
|
|
+ }
|
|
|
+ if (texture->cdram) {
|
|
|
+ vita_gpu_mem_free(data, sceGxmTextureGetData(&texture->gxm_tex));
|
|
|
+ } else {
|
|
|
+ vita_mem_free(texture->data_UID);
|
|
|
}
|
|
|
- mem_gpu_free(texture->data_UID);
|
|
|
SDL_free(texture);
|
|
|
}
|
|
|
}
|
|
@@ -995,25 +1002,6 @@ gxm_texture_get_format(const gxm_texture *texture)
|
|
|
return sceGxmTextureGetFormat(&texture->gxm_tex);
|
|
|
}
|
|
|
|
|
|
-unsigned int
|
|
|
-gxm_texture_get_width(const gxm_texture *texture)
|
|
|
-{
|
|
|
- return sceGxmTextureGetWidth(&texture->gxm_tex);
|
|
|
-}
|
|
|
-
|
|
|
-unsigned int
|
|
|
-gxm_texture_get_height(const gxm_texture *texture)
|
|
|
-{
|
|
|
- return sceGxmTextureGetHeight(&texture->gxm_tex);
|
|
|
-}
|
|
|
-
|
|
|
-unsigned int
|
|
|
-gxm_texture_get_stride(const gxm_texture *texture)
|
|
|
-{
|
|
|
- return ((gxm_texture_get_width(texture) + 7) & ~7)
|
|
|
- * tex_format_to_bytespp(gxm_texture_get_format(texture));
|
|
|
-}
|
|
|
-
|
|
|
void *
|
|
|
gxm_texture_get_datap(const gxm_texture *texture)
|
|
|
{
|
|
@@ -1021,34 +1009,53 @@ gxm_texture_get_datap(const gxm_texture *texture)
|
|
|
}
|
|
|
|
|
|
gxm_texture *
|
|
|
-create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget)
|
|
|
+create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale)
|
|
|
{
|
|
|
gxm_texture *texture = SDL_calloc(1, sizeof(gxm_texture));
|
|
|
- const int tex_size = ((w + 7) & ~ 7) * h * tex_format_to_bytespp(format);
|
|
|
+ int aligned_w = ALIGN(w, 8);
|
|
|
+ int texture_w = w;
|
|
|
+ int tex_size = aligned_w * h * tex_format_to_bytespp(format);
|
|
|
void *texture_data;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ *return_wscale = 1.0f;
|
|
|
+
|
|
|
+ // SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3/P2 based formats require width aligned to 16
|
|
|
+ if ( (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 || (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2) {
|
|
|
+ aligned_w = ALIGN(w, 16);
|
|
|
+ texture_w = aligned_w;
|
|
|
+ tex_size = aligned_w * h * tex_format_to_bytespp(format);
|
|
|
+ *return_wscale = (float) (w) / texture_w;
|
|
|
+ // add storage for UV planes
|
|
|
+ tex_size += (((aligned_w + 1) / 2) * ((h + 1) / 2)) * 2;
|
|
|
+ }
|
|
|
|
|
|
if (!texture)
|
|
|
return NULL;
|
|
|
|
|
|
+ *return_w = w;
|
|
|
+ *return_h = h;
|
|
|
+ *return_pitch = aligned_w * tex_format_to_bytespp(format);
|
|
|
+
|
|
|
/* Allocate a GPU buffer for the texture */
|
|
|
- texture_data = mem_gpu_alloc(
|
|
|
- SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
|
|
|
- tex_size,
|
|
|
- SCE_GXM_TEXTURE_ALIGNMENT,
|
|
|
- SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
|
|
- &texture->data_UID
|
|
|
+ texture_data = vita_gpu_mem_alloc(
|
|
|
+ data,
|
|
|
+ tex_size
|
|
|
);
|
|
|
|
|
|
/* Try SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE in case we're out of VRAM */
|
|
|
if (!texture_data) {
|
|
|
SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "CDRAM texture allocation failed\n");
|
|
|
- texture_data = mem_gpu_alloc(
|
|
|
+ texture_data = vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
|
|
tex_size,
|
|
|
SCE_GXM_TEXTURE_ALIGNMENT,
|
|
|
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
|
|
&texture->data_UID
|
|
|
);
|
|
|
+ texture->cdram = 0;
|
|
|
+ } else {
|
|
|
+ texture->cdram = 1;
|
|
|
}
|
|
|
|
|
|
if (!texture_data) {
|
|
@@ -1060,7 +1067,12 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|
|
SDL_memset(texture_data, 0, tex_size);
|
|
|
|
|
|
/* Create the gxm texture */
|
|
|
- sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, w, h, 0);
|
|
|
+ ret = sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, texture_w, h, 0);
|
|
|
+ if (ret < 0) {
|
|
|
+ free_gxm_texture(data, texture);
|
|
|
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "texture init failed: %x\n", ret);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
|
|
|
if (isRenderTarget) {
|
|
|
void *depthBufferData;
|
|
@@ -1083,13 +1095,13 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|
|
);
|
|
|
|
|
|
if (err < 0) {
|
|
|
- free_gxm_texture(texture);
|
|
|
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %d\n", err);
|
|
|
+ free_gxm_texture(data, texture);
|
|
|
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %x\n", err);
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
// allocate it
|
|
|
- depthBufferData = mem_gpu_alloc(
|
|
|
+ depthBufferData = vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
|
|
4*sampleCount,
|
|
|
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
|
@@ -1106,8 +1118,8 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|
|
NULL);
|
|
|
|
|
|
if (err < 0) {
|
|
|
- free_gxm_texture(texture);
|
|
|
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %d\n", err);
|
|
|
+ free_gxm_texture(data, texture);
|
|
|
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %x\n", err);
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
@@ -1131,8 +1143,8 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|
|
texture->gxm_rendertarget = tgt;
|
|
|
|
|
|
if (err < 0) {
|
|
|
- free_gxm_texture(texture);
|
|
|
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %d\n", err);
|
|
|
+ free_gxm_texture(data, texture);
|
|
|
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %x\n", err);
|
|
|
return NULL;
|
|
|
}
|
|
|
}
|
|
@@ -1181,7 +1193,7 @@ void gxm_init_for_common_dialog(void)
|
|
|
for (int i = 0; i < VITA_GXM_BUFFERS; i += 1)
|
|
|
{
|
|
|
buffer_for_common_dialog[i].displayData.wait_vblank = SDL_TRUE;
|
|
|
- buffer_for_common_dialog[i].displayData.address = mem_gpu_alloc(
|
|
|
+ buffer_for_common_dialog[i].displayData.address = vita_mem_alloc(
|
|
|
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
|
|
|
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
|
|
|
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
|
|
@@ -1229,7 +1241,7 @@ void gxm_term_for_common_dialog(void)
|
|
|
sceGxmDisplayQueueFinish();
|
|
|
for (int i = 0; i < VITA_GXM_BUFFERS; i += 1)
|
|
|
{
|
|
|
- mem_gpu_free(buffer_for_common_dialog[i].uid);
|
|
|
+ vita_mem_free(buffer_for_common_dialog[i].uid);
|
|
|
sceGxmSyncObjectDestroy(buffer_for_common_dialog[i].sync);
|
|
|
}
|
|
|
}
|