Implement D3D9 resource methods in C, asides from resource creation.

This commit is contained in:
UnknownShadow200 2017-05-13 10:44:40 +10:00
parent 8e8e1707dd
commit f6a4df5f6a
4 changed files with 154 additions and 4 deletions

View file

@ -2,6 +2,7 @@
#include "D3D9Api.h"
#include "ErrorHandler.h"
#include "GraphicsEnums.h"
#include "Platform.h"
#ifdef USE_DX
@ -19,14 +20,79 @@ ErrorHandler_CheckOrFail(hresult, name)
hresult = IDirect3DDevice9_SetRenderState(device, state, raw); \
ErrorHandler_CheckOrFail(hresult, name)
#define D3D9_LogLeakedResource(msg, i) \
logMsg.length = 0;\
String_AppendConstant(&logMsg, msg);\
String_AppendInt32(&logMsg, i);\
Platform_Log(logMsg);
void Gfx_Init(Game* game) {
#define D3D9_NumPrimitives(mode, vertices) (mode == DrawMode_Triangles ? vertices / 3 : vertices / 2)
/* We only ever create a single index buffer internally. */
IDirect3DIndexBuffer9* d3d9_ibuffers[2];
Int32 d3d9_ibuffersCapacity = 2;
bool d3d9_ibuffersAllocated;
/* TODO: This number's probably not big enough... */
IDirect3DVertexBuffer9* d3d9_vbuffers[2048];
Int32 d3d9_vbuffersCapacity = 2048;
bool d3d9_vbuffersAllocated;
/* At most we can have 256 entities with their own texture each.
Adding another 128 gives us a lot of leeway. */
IDirect3DTexture9* d3d9_textures[384];
Int32 d3d9_texturesCapacity = 384;
bool d3d9_texturesAllocated;
void Gfx_Init() {
/* TODO: EVERYTHING ELSE */
viewStack.Type = D3DTS_VIEW;
projStack.Type = D3DTS_PROJECTION;
texStack.Type = D3DTS_TEXTURE0;
}
void Gfx_Free() {
UInt8 logMsgBuffer[String_BufferSize(63)];
String logMsg = String_FromRawBuffer(logMsgBuffer, 63);
Int32 i;
for (i = 0; i < d3d9_texturesCapacity; i++) {
if (d3d9_textures[i] == NULL) continue;
Int32 texId = i;
Gfx_DeleteTexture(&texId);
D3D9_LogLeakedResource("Texture leak! ID: ", i);
}
for (i = 0; i < d3d9_vbuffersCapacity; i++) {
if (d3d9_vbuffers[i] == NULL) continue;
Int32 vb = i;
Gfx_DeleteVb(&vb);
D3D9_LogLeakedResource("Vertex buffer leak! ID: ", i);
}
for (i = 0; i < d3d9_ibuffersCapacity; i++) {
if (d3d9_ibuffers[i] == NULL) continue;
Int32 ib = i;
Gfx_DeleteIb(&ib);
D3D9_LogLeakedResource("Index buffer leak! ID: ", i);
}
if (d3d9_ibuffersAllocated) Platform_MemFree(d3d9_ibuffers);
if (d3d9_vbuffersAllocated) Platform_MemFree(d3d9_vbuffers);
if (d3d9_texturesAllocated) Platform_MemFree(d3d9_textures);
}
void Gfx_BindTexture(Int32 texId) {
ReturnCode hresult = IDirect3DDevice9_SetTexture(device, 0, d3d9_textures[texId]);
ErrorHandler_CheckOrFail(hresult, "D3D9_BindTexture");
}
void Gfx_DeleteTexture(Int32* texId) {
D3D9_DeleteResource((void**)d3d9_textures, d3d9_texturesCapacity, texId);
}
void Gfx_SetTexturing(bool enabled) {
if (enabled) return;
@ -35,6 +101,7 @@ void Gfx_SetTexturing(bool enabled) {
}
bool d3d9_fogEnable = false;
void Gfx_SetFog(bool enabled) {
if (d3d9_fogEnable == enabled) return;
@ -141,6 +208,7 @@ void Gfx_ClearColour(FastColour col) {
}
bool d3d9_depthTest = false;
void Gfx_SetDepthTest(bool enabled) {
d3d9_depthTest = enabled;
@ -165,6 +233,59 @@ void Gfx_SetDepthWrite(bool enabled) {
}
Int32 d3d9_batchStride;
void Gfx_BindVb(Int32 vb) {
ReturnCode hresult = IDirect3DDevice9_SetStreamSource(device, 0, d3d9_vbuffers[vb], 0, d3d9_batchStride);
ErrorHandler_CheckOrFail(hresult, "D3D9_BindVb");
}
void Gfx_BindIb(Int32 ib) {
ReturnCode hresult = IDirect3DDevice9_SetIndices(device, d3d9_ibuffers[ib]);
ErrorHandler_CheckOrFail(hresult, "D3D9_BindIb");
}
void Gfx_DeleteVb(Int32* vb) {
D3D9_DeleteResource((void**)d3d9_vbuffers, d3d9_vbuffersCapacity, vb);
}
void Gfx_DeleteIb(Int32* ib) {
D3D9_DeleteResource((void**)d3d9_ibuffers, d3d9_ibuffersCapacity, ib);
}
void Gfx_SetBatchFormat(Int32 vertexFormat) {
ReturnCode hresult = IDirect3DDevice9_SetFVF(device, d3d9_formatMappings[vertexFormat]);
ErrorHandler_CheckOrFail(hresult, "D3D9_SetBatchFormat");
d3d9_batchStride = Gfx_strideSizes[vertexFormat];
}
void Gfx_DrawVb(Int32 drawMode, Int32 startVertex, Int32 vCount) {
Int32 numPrims = D3D9_NumPrimitives(drawMode, vCount);
ReturnCode hresult = IDirect3DDevice9_DrawPrimitive(device, d3d9_modeMappings[drawMode],
startVertex, numPrims);
ErrorHandler_CheckOrFail(hresult, "D3D9_DrawVb");
}
void Gfx_DrawIndexedVb(Int32 drawMode, Int32 indicesCount, Int32 startIndex) {
Int32 numPrims = D3D9_NumPrimitives(drawMode, indicesCount);
ReturnCode hresult = IDirect3DDevice9_DrawIndexedPrimitive(device, d3d9_modeMappings[drawMode], 0,
startIndex / 6 * 4, indicesCount / 6 * 4, startIndex, numPrims);
ErrorHandler_CheckOrFail(hresult, "D3D9_DrawIndexedVb");
}
void Gfx_DrawIndexedVb_TrisT2fC4b_Range(Int32 indicesCount, Int32 offsetVertex, Int32 startIndex) {
ReturnCode hresult = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, offsetVertex,
0, indicesCount / 6 * 4, startIndex, indicesCount / 3);
ErrorHandler_CheckOrFail(hresult, "D3D9_DrawIndexedVb_TrisT2fC4b_Range");
}
void Gfx_DrawIndexedVb_TrisT2fC4b(Int32 indicesCount, Int32 startIndex) {
ReturnCode hresult = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0,
startIndex / 6 * 4, indicesCount / 6 * 4, startIndex, indicesCount / 3);
ErrorHandler_CheckOrFail(hresult, "D3D9_DrawIndexedVb_TrisT2fC4b");
}
void Gfx_SetMatrixMode(Int32 matrixType) {
if (matrixType == MatrixType_Projection) {
curStack = &projStack;
@ -240,4 +361,26 @@ void Gfx_LoadOrthoMatrix(Real32 width, Real32 height) {
matrix.Row3.Z = 1.0f;
Gfx_LoadMatrix(&matrix);
}
void D3D9_DeleteResource(void** resources, Int32 capacity, Int32* id) {
Int32 resourceID = *id;
if (resourceID <= 0 || resourceID >= capacity) return;
void* value = resources[resourceID];
*id = -1;
if (value == NULL) return;
IUnknown* unk = (IUnknown*)value;
UInt32 refCount = unk->lpVtbl->Release(unk);
resources[resourceID] = NULL;
if (refCount <= 0) return;
UInt8 logMsgBuffer[String_BufferSize(127)];
String logMsg = String_FromRawBuffer(logMsgBuffer, 127);
String_AppendConstant(&logMsg, "D3D9 Resource has outstanding references! ID: ");
String_AppendInt32(&logMsg, resourceID);
Platform_Log(logMsg);
}
#endif

View file

@ -23,6 +23,7 @@ typedef struct MatrixStack {
D3DTRANSFORMSTATETYPE Type;
} MatrixStack;
D3DPRIMITIVETYPE d3d9_modeMappings[2] = { D3DPT_TRIANGLELIST, D3DPT_LINELIST };
D3DFORMAT d3d9_depthFormats[6] = { D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D16, D3DFMT_D15S1 };
D3DFORMAT d3d9_viewFormats[4] = { D3DFMT_X8R8G8B8, D3DFMT_R8G8B8, D3DFMT_R5G6B5, D3DFMT_X1R5G5B5 };
@ -31,4 +32,7 @@ D3DCMPFUNC d3d9_compareFuncs[8] = { D3DCMP_ALWAYS, D3DCMP_NOTEQUAL, D3DCMP_NEVER
D3DFOGMODE d3d9_modes[3] = { D3DFOG_LINEAR, D3DFOG_EXP, D3DFOG_EXP2 };
Int32 d3d9_formatMappings[2] = { D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2 };
static void D3D9_DeleteResource(void** resources, Int32 capacity, Int32* id);
#endif

View file

@ -14,7 +14,10 @@
/* Initalises this graphics API. */
void Gfx_Init(Game* game);
void Gfx_Init();
/* Frees memory allocated by this graphics API. */
void Gfx_Free();
/* Maximum supported length of a dimension (width and height) of a 2D texture. */
Int32 Gfx_MaxTextureDimensions;

View file

@ -33,8 +33,8 @@ void Atlas1D_UpdateState() {
void Atlas1D_Convert2DTo1D(Int32 atlasesCount, Int32 atlas1DHeight) {
Atlas1D_TexIdsCount = atlasesCount;
UInt8 logBuffer[String_BufferSize(256)];
String log = String_FromRawBuffer(logBuffer, 256);
UInt8 logBuffer[String_BufferSize(127)];
String log = String_FromRawBuffer(logBuffer, 127);
String_AppendConstant(&log, "Loaded new atlas: ");
String_AppendInt32(&log, atlasesCount);