From 3a3986ad65830b745ccf2a37b042448f89049bf3 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Tue, 13 Jun 2023 00:17:31 +1000 Subject: [PATCH 1/2] WIP on new Gfx_CreateIB2 which takes a callback function to initialise the index buffer, instead of requiring all the data to be allocated by the caller (on the stack with current InitDefaultResources implementation) This was problematic for the Wii/Gamecube, as while the default index buffer is 192 kb in size, libogc only initialises the stack to be ~128 kb in size --- src/Graphics.h | 4 +++- src/Graphics_3DS.c | 8 ++++---- src/Graphics_D3D11.c | 6 ++++-- src/Graphics_D3D9.c | 12 ++++++------ src/Graphics_GCWii.c | 21 +++++---------------- src/Graphics_GL1.c | 10 ++++++---- src/Graphics_GL2.c | 7 +++++-- src/Graphics_PSP.c | 11 +++++++---- src/_GraphicsBase.h | 8 +++----- 9 files changed, 43 insertions(+), 44 deletions(-) diff --git a/src/Graphics.h b/src/Graphics.h index 2bd8dda26..025f12da1 100644 --- a/src/Graphics.h +++ b/src/Graphics.h @@ -134,8 +134,10 @@ CC_API void Gfx_SetDepthWrite(cc_bool enabled); /* NOTE: Implicitly calls Gfx_SetColWriteMask */ CC_API void Gfx_DepthOnlyRendering(cc_bool depthOnly); +/* Callback function to initialise/fill out the contents of an index buffer */ +typedef void (*Gfx_FillIBFunc)(cc_uint16* indices, int count, void* obj); /* Creates a new index buffer and fills out its contents. */ -CC_API GfxResourceID Gfx_CreateIb(void* indices, int indicesCount); +CC_API GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj); /* Sets the currently active index buffer. */ CC_API void Gfx_BindIb(GfxResourceID ib); /* Deletes the given index buffer, then sets it to 0. */ diff --git a/src/Graphics_3DS.c b/src/Graphics_3DS.c index 51ad4a490..e048cd74e 100644 --- a/src/Graphics_3DS.c +++ b/src/Graphics_3DS.c @@ -381,10 +381,10 @@ static void FreeBuffer(GfxResourceID* buffer) { *buffer = 0; } -GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) { - void* ptr = AllocBuffer(indicesCount, 2); - Mem_Copy(ptr, indices, indicesCount * 2); - return ptr; +GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { + void* ib = AllocBuffer(count, 2); + fillFunc(ib, count * sizeof(cc_uint16), obj); + return ib; } void Gfx_BindIb(GfxResourceID ib) { gfx_indices = ib; } diff --git a/src/Graphics_D3D11.c b/src/Graphics_D3D11.c index 5c14ad9af..50b2c4f13 100644 --- a/src/Graphics_D3D11.c +++ b/src/Graphics_D3D11.c @@ -302,12 +302,14 @@ void Gfx_SetTexturing(cc_bool enabled) { } /*########################################################################################################################* *-------------------------------------------------------Index buffers-----------------------------------------------------* *#########################################################################################################################*/ -GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) { +GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { ID3D11Buffer* buffer = NULL; + cc_uint16 indices[GFX_MAX_INDICES]; + fillFunc(indices, count, obj); D3D11_BUFFER_DESC desc = { 0 }; desc.Usage = D3D11_USAGE_DEFAULT; - desc.ByteWidth = sizeof(cc_uint16) * indicesCount; + desc.ByteWidth = count * sizeof(cc_uint16); desc.BindFlags = D3D11_BIND_INDEX_BUFFER; D3D11_SUBRESOURCE_DATA data; diff --git a/src/Graphics_D3D9.c b/src/Graphics_D3D9.c index 0ed900be4..8a02e3e24 100644 --- a/src/Graphics_D3D9.c +++ b/src/Graphics_D3D9.c @@ -533,23 +533,23 @@ static void D3D9_RestoreRenderStates(void) { /*########################################################################################################################* *-------------------------------------------------------Index buffers-----------------------------------------------------* *#########################################################################################################################*/ -static void D3D9_SetIbData(IDirect3DIndexBuffer9* buffer, void* data, int size) { +static void D3D9_SetIbData(IDirect3DIndexBuffer9* buffer, int count, Gfx_FillIBFunc fillFunc, void* obj) { void* dst = NULL; - cc_result res = IDirect3DIndexBuffer9_Lock(buffer, 0, size, &dst, 0); + cc_result res = IDirect3DIndexBuffer9_Lock(buffer, 0, count * 2, &dst, 0); if (res) Logger_Abort2(res, "D3D9_LockIb"); - Mem_Copy(dst, data, size); + fillFunc((cc_uint16*)dst, count, obj); res = IDirect3DIndexBuffer9_Unlock(buffer); if (res) Logger_Abort2(res, "D3D9_UnlockIb"); } -GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) { - int size = indicesCount * 2; +GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { + int size = count * 2; IDirect3DIndexBuffer9* ibuffer; cc_result res = IDirect3DDevice9_CreateIndexBuffer(device, size, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ibuffer, NULL); if (res) Logger_Abort2(res, "D3D9_CreateIb"); - D3D9_SetIbData(ibuffer, indices, size); + D3D9_SetIbData(ibuffer, count, fillFunc, obj); return ibuffer; } diff --git a/src/Graphics_GCWii.c b/src/Graphics_GCWii.c index 1a673ba13..bd298d043 100644 --- a/src/Graphics_GCWii.c +++ b/src/Graphics_GCWii.c @@ -276,25 +276,14 @@ cc_bool Gfx_WarnIfNecessary(void) { return false; } /*########################################################################################################################* *-------------------------------------------------------Index Buffers-----------------------------------------------------* *#########################################################################################################################*/ -static cc_uint16* gfx_indices; +static cc_uint16 __attribute__((aligned(16))) gfx_indices[GFX_MAX_INDICES]; -GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) { - void* data = memalign(16, indicesCount * 2); - if (!data) Logger_Abort("Failed to allocate memory for GFX VB"); - - Mem_Copy(data, indices, indicesCount * 2); - return data; +GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { + fillFunc(gfx_indices, count * sizeof(cc_uint16), obj); } -void Gfx_BindIb(GfxResourceID ib) { - gfx_indices = ib; -} - -void Gfx_DeleteIb(GfxResourceID* ib) { - GfxResourceID data = *ib; - if (data) Mem_Free(data); - *ib = 0; -} +void Gfx_BindIb(GfxResourceID ib) { } +void Gfx_DeleteIb(GfxResourceID* ib) { } /*########################################################################################################################* diff --git a/src/Graphics_GL1.c b/src/Graphics_GL1.c index 483a7e3c4..1bdb88471 100644 --- a/src/Graphics_GL1.c +++ b/src/Graphics_GL1.c @@ -213,10 +213,12 @@ static void GL_DelBuffer(GfxResourceID id) { static GfxResourceID (*_genBuffer)(void) = GL_GenBuffer; static void (*_delBuffer)(GfxResourceID id) = GL_DelBuffer; -GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) { +GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { + cc_uint16 indices[GFX_MAX_INDICES]; GfxResourceID id = _genBuffer(); - cc_uint32 size = indicesCount * 2; + cc_uint32 size = count * sizeof(cc_uint16); + fillFunc(indices, count, obj); _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); _glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STATIC_DRAW); return id; @@ -231,7 +233,7 @@ void Gfx_DeleteIb(GfxResourceID* ib) { *ib = 0; } #else -GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) { return 0; } +GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { return 0; } void Gfx_BindIb(GfxResourceID ib) { } void Gfx_DeleteIb(GfxResourceID* ib) { } #endif @@ -504,7 +506,7 @@ cc_bool Gfx_WarnIfNecessary(void) { *-------------------------------------------------------Compatibility-----------------------------------------------------* *#########################################################################################################################*/ #ifdef CC_BUILD_GL11 -static void GLBackend_Init(void) { MakeIndices(gl_indices, GFX_MAX_INDICES); } +static void GLBackend_Init(void) { MakeIndices(gl_indices, GFX_MAX_INDICES, NULL); } #else #if defined CC_BUILD_WIN diff --git a/src/Graphics_GL2.c b/src/Graphics_GL2.c index 5a2edecce..9b5e8455c 100644 --- a/src/Graphics_GL2.c +++ b/src/Graphics_GL2.c @@ -102,9 +102,12 @@ static GLuint GL_GenAndBind(GLenum target) { return id; } -GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) { +GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { + cc_uint16 indices[GFX_MAX_INDICES]; GLuint id = GL_GenAndBind(GL_ELEMENT_ARRAY_BUFFER); - cc_uint32 size = indicesCount * 2; + cc_uint32 size = count * sizeof(cc_uint16); + + fillFunc(indices, count, obj); glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STATIC_DRAW); return id; } diff --git a/src/Graphics_PSP.c b/src/Graphics_PSP.c index fd5b7f61a..f45f10a77 100644 --- a/src/Graphics_PSP.c +++ b/src/Graphics_PSP.c @@ -24,7 +24,6 @@ static unsigned int __attribute__((aligned(16))) list[262144]; /*########################################################################################################################* *---------------------------------------------------------General---------------------------------------------------------* *#########################################################################################################################*/ -static cc_uint16 __attribute__((aligned(16))) gfx_indices[GFX_MAX_INDICES]; static int formatFields[] = { GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_3D, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_3D @@ -77,7 +76,6 @@ void Gfx_Create(void) { Gfx.MaxTexWidth = 512; Gfx.MaxTexHeight = 512; Gfx.Created = true; - MakeIndices(gfx_indices, GFX_MAX_INDICES); guInit(); InitDefaultResources(); @@ -267,10 +265,15 @@ static int gfx_stride, gfx_format = -1, gfx_fields; /*########################################################################################################################* *----------------------------------------------------------Buffers--------------------------------------------------------* *#########################################################################################################################*/ -GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) { return 0; } +static cc_uint16 __attribute__((aligned(16))) gfx_indices[GFX_MAX_INDICES]; +static int vb_size; + +GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { + fillFunc(gfx_indices, count * sizeof(cc_uint16), obj); +} + void Gfx_BindIb(GfxResourceID ib) { } void Gfx_DeleteIb(GfxResourceID* ib) { } -static int vb_size; GfxResourceID Gfx_CreateVb(VertexFormat fmt, int count) { diff --git a/src/_GraphicsBase.h b/src/_GraphicsBase.h index c0ae478d5..7a75d0d71 100644 --- a/src/_GraphicsBase.h +++ b/src/_GraphicsBase.h @@ -32,10 +32,10 @@ CC_NOINLINE static void Gfx_FreeState(void); *------------------------------------------------------Generic/Common-----------------------------------------------------* *#########################################################################################################################*/ /* Fills out indices array with {0,1,2} {2,3,0}, {4,5,6} {6,7,4} etc */ -static void MakeIndices(cc_uint16* indices, int iCount) { +static void MakeIndices(cc_uint16* indices, int count, void* obj) { int element = 0, i; - for (i = 0; i < iCount; i += 6) { + for (i = 0; i < count; i += 6) { indices[0] = (cc_uint16)(element + 0); indices[1] = (cc_uint16)(element + 1); indices[2] = (cc_uint16)(element + 2); @@ -49,9 +49,7 @@ static void MakeIndices(cc_uint16* indices, int iCount) { } static void InitDefaultResources(void) { - cc_uint16 indices[GFX_MAX_INDICES]; - MakeIndices(indices, GFX_MAX_INDICES); - Gfx_defaultIb = Gfx_CreateIb(indices, GFX_MAX_INDICES); + Gfx_defaultIb = Gfx_CreateIb2(GFX_MAX_INDICES, MakeIndices, NULL); Gfx_RecreateDynamicVb(&Gfx_quadVb, VERTEX_FORMAT_COLOURED, 4); Gfx_RecreateDynamicVb(&Gfx_texVb, VERTEX_FORMAT_TEXTURED, 4); From ea2e57907fa4cdbec13e1bc51178948f9c3051ec Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Tue, 13 Jun 2023 18:30:56 +1000 Subject: [PATCH 2/2] Fix buffer overflow when creating default indices on 3DS/PSP/Wii/GC --- src/Graphics_3DS.c | 4 ++-- src/Graphics_GCWii.c | 2 +- src/Graphics_PSP.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Graphics_3DS.c b/src/Graphics_3DS.c index e048cd74e..a94c11ea2 100644 --- a/src/Graphics_3DS.c +++ b/src/Graphics_3DS.c @@ -382,8 +382,8 @@ static void FreeBuffer(GfxResourceID* buffer) { } GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { - void* ib = AllocBuffer(count, 2); - fillFunc(ib, count * sizeof(cc_uint16), obj); + void* ib = AllocBuffer(count, sizeof(cc_uint16)); + fillFunc(ib, count, obj); return ib; } diff --git a/src/Graphics_GCWii.c b/src/Graphics_GCWii.c index bd298d043..6ba0ae81d 100644 --- a/src/Graphics_GCWii.c +++ b/src/Graphics_GCWii.c @@ -279,7 +279,7 @@ cc_bool Gfx_WarnIfNecessary(void) { return false; } static cc_uint16 __attribute__((aligned(16))) gfx_indices[GFX_MAX_INDICES]; GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { - fillFunc(gfx_indices, count * sizeof(cc_uint16), obj); + fillFunc(gfx_indices, count, obj); } void Gfx_BindIb(GfxResourceID ib) { } diff --git a/src/Graphics_PSP.c b/src/Graphics_PSP.c index f45f10a77..edb7ce298 100644 --- a/src/Graphics_PSP.c +++ b/src/Graphics_PSP.c @@ -269,7 +269,7 @@ static cc_uint16 __attribute__((aligned(16))) gfx_indices[GFX_MAX_INDICES]; static int vb_size; GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) { - fillFunc(gfx_indices, count * sizeof(cc_uint16), obj); + fillFunc(gfx_indices, count, obj); } void Gfx_BindIb(GfxResourceID ib) { }