Direct3D11: Now with 1.23% less memory leaking

This commit is contained in:
UnknownShadow200 2021-11-04 20:13:56 +11:00
parent 2e72ffefa2
commit 65e51cc4ec

View File

@ -35,15 +35,11 @@ static IDXGIFactory1* dxgi_factory;
static IDXGISwapChain* swapchain; static IDXGISwapChain* swapchain;
struct ShaderDesc { const void* data; int len; }; struct ShaderDesc { const void* data; int len; };
static void IA_Init(void);
static void IA_UpdateLayout(void); static void IA_UpdateLayout(void);
static void VS_Init(void);
static void VS_UpdateShader(void); static void VS_UpdateShader(void);
static void RS_Init(void);
static void PS_Init(void);
static void PS_UpdateShader(void); static void PS_UpdateShader(void);
static void OM_Init(void); static void InitPipeline(void);
static void OM_Free(void); static void FreePipeline(void);
static void CreateDeviceAndSwapChain(void) { static void CreateDeviceAndSwapChain(void) {
// https://docs.microsoft.com/en-us/windows/uwp/gaming/simple-port-from-direct3d-9-to-11-1-part-1--initializing-direct3d // https://docs.microsoft.com/en-us/windows/uwp/gaming/simple-port-from-direct3d-9-to-11-1-part-1--initializing-direct3d
@ -84,13 +80,7 @@ void Gfx_Create(void) {
CreateDeviceAndSwapChain(); CreateDeviceAndSwapChain();
Gfx.Created = true; Gfx.Created = true;
customMipmapsLevels = true; customMipmapsLevels = true;
Gfx_RestoreState();
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-graphics-pipeline
IA_Init();
VS_Init();
RS_Init();
PS_Init();
OM_Init();
// TODO need a better solution // TODO need a better solution
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-resources-limits // https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-resources-limits
@ -99,25 +89,43 @@ void Gfx_Create(void) {
Gfx.MaxTexHeight = 8192; Gfx.MaxTexHeight = 8192;
} }
cc_bool Gfx_TryRestoreContext(void) {
return true;
}
void Gfx_Free(void) { void Gfx_Free(void) {
Gfx_FreeState();
ID3D11DeviceContext_ClearState(context); ID3D11DeviceContext_ClearState(context);
OM_Free();
IDXGISwapChain_Release(swapchain); IDXGISwapChain_Release(swapchain);
ID3D11DeviceContext_Release(context); ID3D11DeviceContext_Release(context);
ID3D11Device_Release(device); ID3D11Device_Release(device);
} }
static cc_bool inited;
cc_bool Gfx_TryRestoreContext(void) {
return true;
}
static void Gfx_FreeState(void) { static void Gfx_FreeState(void) {
if (!inited) return;
inited = false;
FreeDefaultResources(); FreeDefaultResources();
FreePipeline();
#ifdef _DEBUG
ID3D11Debug *d3dDebug;
static const GUID guid_d3dDebug = { 0x79cf2233, 0x7536, 0x4948,{ 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } };
HRESULT hr = ID3D11Device_QueryInterface(device, &guid_d3dDebug, &d3dDebug);
if (SUCCEEDED(hr))
{
hr = ID3D11Debug_ReportLiveDeviceObjects(d3dDebug, D3D11_RLDO_DETAIL);
}
#endif
} }
static void Gfx_RestoreState(void) { static void Gfx_RestoreState(void) {
if (inited) return;
inited = true;
InitDefaultResources(); InitDefaultResources();
gfx_format = -1; gfx_format = -1;
InitPipeline();
} }
@ -398,17 +406,6 @@ void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zFar, struct Matri
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-input-assembler-stage // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-input-assembler-stage
static ID3D11InputLayout* input_textured; static ID3D11InputLayout* input_textured;
void Gfx_BindIb(GfxResourceID ib) {
ID3D11Buffer* buffer = (ID3D11Buffer*)ib;
ID3D11DeviceContext_IASetIndexBuffer(context, buffer, DXGI_FORMAT_R16_UINT, 0);
}
void Gfx_BindVb(GfxResourceID vb) {
ID3D11Buffer* buffer = (ID3D11Buffer*)vb;
static UINT32 offset[] = { 0 };
ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &buffer, &gfx_stride, offset);
}
static void IA_CreateLayouts(void) { static void IA_CreateLayouts(void) {
ID3D11InputLayout* input = NULL; ID3D11InputLayout* input = NULL;
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-input-assembler-stage-getting-started // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-input-assembler-stage-getting-started
@ -435,6 +432,21 @@ static void IA_Init(void) {
ID3D11DeviceContext_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ID3D11DeviceContext_IASetPrimitiveTopology(context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
} }
static void IA_Free(void) {
ID3D11InputLayout_Release(input_textured);
}
void Gfx_BindIb(GfxResourceID ib) {
ID3D11Buffer* buffer = (ID3D11Buffer*)ib;
ID3D11DeviceContext_IASetIndexBuffer(context, buffer, DXGI_FORMAT_R16_UINT, 0);
}
void Gfx_BindVb(GfxResourceID vb) {
ID3D11Buffer* buffer = (ID3D11Buffer*)vb;
static UINT32 offset[] = { 0 };
ID3D11DeviceContext_IASetVertexBuffers(context, 0, 1, &buffer, &gfx_stride, offset);
}
//######################################################################################################################## //########################################################################################################################
//--------------------------------------------------------Vertex shader--------------------------------------------------- //--------------------------------------------------------Vertex shader---------------------------------------------------
@ -493,16 +505,31 @@ static void VS_UpdateShader(void) {
ID3D11DeviceContext_VSSetShader(context, vs_shaders[idx], NULL, 0); ID3D11DeviceContext_VSSetShader(context, vs_shaders[idx], NULL, 0);
} }
static void VS_FreeShaders(void) {
for (int i = 0; i < Array_Elems(vs_shaders); i++) {
ID3D11VertexShader_Release(vs_shaders[i]);
}
}
static void VS_UpdateConstants(void) { static void VS_UpdateConstants(void) {
ID3D11DeviceContext_UpdateSubresource(context, vs_cBuffer, 0, NULL, &vs_constants, 0, 0); ID3D11DeviceContext_UpdateSubresource(context, vs_cBuffer, 0, NULL, &vs_constants, 0, 0);
} }
static void VS_FreeConstants(void) {
ID3D11Buffer_Release(vs_cBuffer);
}
static void VS_Init(void) { static void VS_Init(void) {
VS_CreateShaders(); VS_CreateShaders();
VS_CreateConstants(); VS_CreateConstants();
VS_UpdateShader(); VS_UpdateShader();
} }
static void VS_Free(void) {
VS_FreeShaders();
VS_FreeConstants();
}
static struct Matrix _view, _proj; static struct Matrix _view, _proj;
void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) { void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) {
if (type == MATRIX_VIEW) _view = *matrix; if (type == MATRIX_VIEW) _view = *matrix;
@ -565,12 +592,22 @@ static void RS_UpdateRasterState(void) {
ID3D11DeviceContext_RSSetState(context, rs_states[rs_culling]); ID3D11DeviceContext_RSSetState(context, rs_states[rs_culling]);
} }
static void RS_FreeRasterStates(void) {
for (int i = 0; i < Array_Elems(rs_states); i++) {
ID3D11RasterizerState_Release(rs_states[i]);
}
}
static void RS_Init(void) { static void RS_Init(void) {
RS_CreateRasterState(); RS_CreateRasterState();
RS_UpdateViewport(); RS_UpdateViewport();
RS_UpdateRasterState(); RS_UpdateRasterState();
} }
static void RS_Free(void) {
RS_FreeRasterStates();
}
void Gfx_SetFaceCulling(cc_bool enabled) { void Gfx_SetFaceCulling(cc_bool enabled) {
rs_culling = enabled; rs_culling = enabled;
RS_UpdateRasterState(); RS_UpdateRasterState();
@ -615,21 +652,6 @@ static void PS_CreateShaders(void) {
} }
} }
static void PS_CreateConstants(void) {
D3D11_BUFFER_DESC desc = { 0 }; // TODO see notes in VS_CreateConstants
desc.ByteWidth = sizeof(ps_constants);
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
D3D11_SUBRESOURCE_DATA data;
data.pSysMem = &ps_constants;
data.SysMemPitch = 0;
data.SysMemSlicePitch = 0;
HRESULT hr = ID3D11Device_CreateBuffer(device, &desc, &data, &ps_cBuffer);
ID3D11DeviceContext_PSSetConstantBuffers(context, 0, 1, &ps_cBuffer);
}
static int PS_CalcShaderIndex(void) { static int PS_CalcShaderIndex(void) {
int idx = gfx_format == VERTEX_FORMAT_COLOURED ? 0 : 1; int idx = gfx_format == VERTEX_FORMAT_COLOURED ? 0 : 1;
if (ps_alphaTesting) idx += 2; if (ps_alphaTesting) idx += 2;
@ -647,6 +669,12 @@ static void PS_UpdateShader(void) {
ID3D11DeviceContext_PSSetShader(context, ps_shaders[idx], NULL, 0); ID3D11DeviceContext_PSSetShader(context, ps_shaders[idx], NULL, 0);
} }
static void PS_FreeShaders(void) {
for (int i = 0; i < Array_Elems(ps_shaders); i++) {
ID3D11PixelShader_Release(ps_shaders[i]);
}
}
static void PS_CreateSamplers(void) { static void PS_CreateSamplers(void) {
// https://docs.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11device-createsamplerstate // https://docs.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11device-createsamplerstate
// https://gamedev.stackexchange.com/questions/18026/directx11-how-do-i-manage-and-update-multiple-shader-constant-buffers // https://gamedev.stackexchange.com/questions/18026/directx11-how-do-i-manage-and-update-multiple-shader-constant-buffers
@ -668,6 +696,31 @@ static void PS_CreateSamplers(void) {
HRESULT hr2 = ID3D11Device_CreateSamplerState(device, &desc, &ps_samplers[1]); HRESULT hr2 = ID3D11Device_CreateSamplerState(device, &desc, &ps_samplers[1]);
} }
static void PS_UpdateSampler(void) {
ID3D11DeviceContext_PSSetSamplers(context, 0, 1, &ps_samplers[ps_mipmaps]);
}
static void PS_FreeSamplers(void) {
for (int i = 0; i < Array_Elems(ps_samplers); i++) {
ID3D11SamplerState_Release(ps_samplers[i]);
}
}
static void PS_CreateConstants(void) {
D3D11_BUFFER_DESC desc = { 0 }; // TODO see notes in VS_CreateConstants
desc.ByteWidth = sizeof(ps_constants);
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
D3D11_SUBRESOURCE_DATA data;
data.pSysMem = &ps_constants;
data.SysMemPitch = 0;
data.SysMemSlicePitch = 0;
HRESULT hr = ID3D11Device_CreateBuffer(device, &desc, &data, &ps_cBuffer);
ID3D11DeviceContext_PSSetConstantBuffers(context, 0, 1, &ps_cBuffer);
}
static void PS_UpdateConstants(void) { static void PS_UpdateConstants(void) {
ps_constants.fogR = PackedCol_R(ps_fogColor) / 255.0f; ps_constants.fogR = PackedCol_R(ps_fogColor) / 255.0f;
ps_constants.fogG = PackedCol_G(ps_fogColor) / 255.0f; ps_constants.fogG = PackedCol_G(ps_fogColor) / 255.0f;
@ -678,8 +731,8 @@ static void PS_UpdateConstants(void) {
ID3D11DeviceContext_UpdateSubresource(context, ps_cBuffer, 0, NULL, &ps_constants, 0, 0); ID3D11DeviceContext_UpdateSubresource(context, ps_cBuffer, 0, NULL, &ps_constants, 0, 0);
} }
static void PS_UpdateSampler(void) { static void PS_FreeConstants(void) {
ID3D11DeviceContext_PSSetSamplers(context, 0, 1, &ps_samplers[ps_mipmaps]); ID3D11Buffer_Release(ps_cBuffer);
} }
static void PS_Init(void) { static void PS_Init(void) {
@ -690,6 +743,12 @@ static void PS_Init(void) {
PS_UpdateShader(); PS_UpdateShader();
} }
static void PS_Free(void) {
PS_FreeShaders();
PS_FreeSamplers();
PS_FreeConstants();
}
void Gfx_SetAlphaTest(cc_bool enabled) { void Gfx_SetAlphaTest(cc_bool enabled) {
ps_alphaTesting = enabled; ps_alphaTesting = enabled;
PS_UpdateShader(); PS_UpdateShader();
@ -808,6 +867,12 @@ static void OM_UpdateDepthState(void) {
ID3D11DeviceContext_OMSetDepthStencilState(context, depthState, 0); ID3D11DeviceContext_OMSetDepthStencilState(context, depthState, 0);
} }
static void OM_FreeDepthStates(void) {
for (int i = 0; i < Array_Elems(om_depthStates); i++) {
ID3D11DepthStencilState_Release(om_depthStates[i]);
}
}
static void OM_CreateBlendStates(void) { static void OM_CreateBlendStates(void) {
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-blend-state // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-blend-state
D3D11_BLEND_DESC desc = { 0 }; D3D11_BLEND_DESC desc = { 0 };
@ -833,6 +898,12 @@ static void OM_UpdateBlendState(void) {
ID3D11DeviceContext_OMSetBlendState(context, blendState, NULL, 0xffffffff); ID3D11DeviceContext_OMSetBlendState(context, blendState, NULL, 0xffffffff);
} }
static void OM_FreeBlendStates(void) {
for (int i = 0; i < Array_Elems(om_blendStates); i++) {
ID3D11BlendState_Release(om_blendStates[i]);
}
}
static void OM_Init(void) { static void OM_Init(void) {
OM_InitTargets(); OM_InitTargets();
OM_CreateDepthStates(); OM_CreateDepthStates();
@ -850,6 +921,8 @@ static void OM_FreeTargets(void) {
static void OM_Free(void) { static void OM_Free(void) {
OM_FreeTargets(); OM_FreeTargets();
OM_FreeDepthStates();
OM_FreeBlendStates();
} }
void Gfx_ClearCol(PackedCol col) { void Gfx_ClearCol(PackedCol col) {
@ -992,4 +1065,21 @@ void Gfx_OnWindowResize(void) {
OM_InitTargets(); OM_InitTargets();
RS_UpdateViewport(); RS_UpdateViewport();
} }
static void InitPipeline(void) {
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-graphics-pipeline
IA_Init();
VS_Init();
RS_Init();
PS_Init();
OM_Init();
}
static void FreePipeline(void) {
IA_Free();
VS_Free();
RS_Free();
PS_Free();
OM_Free();
}
#endif #endif