feat(gx): handle texture creation in d3d backend

This commit is contained in:
fallenoak 2023-03-07 00:03:03 -06:00 committed by GitHub
parent a490cc7be7
commit 0419802663
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 147 additions and 1 deletions

View File

@ -69,6 +69,7 @@ class CGxDevice {
int32_t m_shaderProfiles[GxShTargets_Last] = { 6, 0, 0, 0, 12, 0 }; // TODO placeholder
TSHashTable<CGxShader, HASHKEY_STRI> m_shaderList[GxShTargets_Last];
int32_t m_context = 0;
int32_t intF64 = 0;
CBoundingBox m_viewport;
C44Matrix m_projection;
C44Matrix m_projNative;

View File

@ -1,4 +1,5 @@
#include "gx/d3d/CGxDeviceD3d.hpp"
#include "gx/texture/CGxTex.hpp"
D3DFORMAT CGxDeviceD3d::s_GxFormatToD3dFormat[] = {
D3DFMT_R5G6B5, // Fmt_Rgb565
@ -11,6 +12,54 @@ D3DFORMAT CGxDeviceD3d::s_GxFormatToD3dFormat[] = {
D3DFMT_D32, // Fmt_Ds320
};
D3DFORMAT CGxDeviceD3d::s_GxTexFmtToD3dFmt[] = {
D3DFMT_UNKNOWN, // GxTex_Unknown
D3DFMT_A8B8G8R8, // GxTex_Abgr8888
D3DFMT_A8R8G8B8, // GxTex_Argb8888
D3DFMT_A4R4G4B4, // GxTex_Argb4444
D3DFMT_A1R5G5B5, // GxTex_Argb1555
D3DFMT_R5G6B5, // GxTex_Rgb565
D3DFMT_DXT1, // GxTex_Dxt1
D3DFMT_DXT3, // GxTex_Dxt3
D3DFMT_DXT5, // GxTex_Dxt5
D3DFMT_V8U8, // GxTex_Uv88
D3DFMT_G16R16F, // GxTex_Gr1616F
D3DFMT_R32F, // GxTex_R32F
D3DFMT_D24X8, // GxTex_D24X8
};
EGxTexFormat CGxDeviceD3d::s_GxTexFmtToUse[] = {
GxTex_Unknown,
GxTex_Abgr8888,
GxTex_Argb8888,
GxTex_Argb4444,
GxTex_Argb1555,
GxTex_Rgb565,
GxTex_Dxt1,
GxTex_Dxt3,
GxTex_Dxt5,
GxTex_Uv88,
GxTex_Gr1616F,
GxTex_R32F,
GxTex_D24X8,
};
EGxTexFormat CGxDeviceD3d::s_tolerableTexFmtMapping[] = {
GxTex_Unknown, // GxTex_Unknown
GxTex_Argb4444, // GxTex_Abgr8888
GxTex_Argb4444, // GxTex_Argb8888
GxTex_Argb4444, // GxTex_Argb4444
GxTex_Argb4444, // GxTex_Argb1555
GxTex_Argb4444, // GxTex_Rgb565
GxTex_Dxt1, // GxTex_Dxt1
GxTex_Dxt3, // GxTex_Dxt3
GxTex_Dxt5, // GxTex_Dxt5
GxTex_Uv88, // GxTex_Uv88
GxTex_Gr1616F, // GxTex_Gr1616F
GxTex_R32F, // GxTex_R32F
GxTex_D24X8, // GxTex_D24X8
};
ATOM WindowClassCreate() {
auto instance = GetModuleHandle(nullptr);
@ -223,7 +272,7 @@ int32_t CGxDeviceD3d::DeviceSetFormat(const CGxFormat& format) {
CGxFormat createFormat = format;
if (this->ICreateWindow(createFormat) && this->ICreateD3dDevice(createFormat) && this->CGxDevice::DeviceSetFormat(format)) {
this->m_context = 1;
this->intF64 = 1;
// TODO
@ -282,6 +331,10 @@ int32_t CGxDeviceD3d::ICreateD3dDevice(const CGxFormat& format) {
if (SUCCEEDED(this->m_d3d->CreateDevice(0, D3DDEVTYPE_HAL, this->m_hwnd, behaviorFlags, &d3dpp, &this->m_d3dDevice))) {
// TODO
this->m_context = 1;
// TODO
return 1;
}
@ -417,7 +470,94 @@ void CGxDeviceD3d::IShaderCreate(CGxShader* shader) {
// TODO
}
void CGxDeviceD3d::ITexCreate(CGxTex* texId) {
uint32_t width, height, startLevel, endLevel;
this->ITexWHDStartEnd(texId, width, height, startLevel, endLevel);
texId->m_format = CGxDeviceD3d::s_GxTexFmtToUse[texId->m_format];
uint32_t d3dUsage = 0;
D3DPOOL d3dPool = D3DPOOL_MANAGED;
if (texId->m_flags.m_renderTarget) {
d3dUsage = D3DUSAGE_RENDERTARGET;
d3dPool = D3DPOOL_DEFAULT;
}
if (texId->m_flags.m_generateMipMaps) {
d3dUsage |= D3DUSAGE_AUTOGENMIPMAP;
}
// Cube map
if (texId->m_target == GxTex_CubeMap) {
auto d3dFormat = CGxDeviceD3d::s_GxTexFmtToD3dFmt[texId->m_format];
LPDIRECT3DCUBETEXTURE9 d3dTexture;
if (SUCCEEDED(this->m_d3dDevice->CreateCubeTexture(width, endLevel - startLevel, d3dUsage, d3dFormat, d3dPool, &d3dTexture, nullptr))) {
texId->m_apiSpecificData = d3dTexture;
texId->m_needsCreation = 0;
}
return;
}
// Depth stencil
if (texId->m_format == GxTex_D24X8) {
d3dUsage = D3DUSAGE_DEPTHSTENCIL;
auto d3dFormat = D3DFMT_D24X8;
LPDIRECT3DTEXTURE9 d3dTexture;
if (SUCCEEDED(this->m_d3dDevice->CreateTexture(width, height, 1, d3dUsage, d3dFormat, d3dPool, &d3dTexture, nullptr))) {
texId->m_apiSpecificData = d3dTexture;
texId->m_needsCreation = 0;
}
return;
}
// Ordinary texture
LPDIRECT3DTEXTURE9 d3dTexture;
auto d3dFormat = CGxDeviceD3d::s_GxTexFmtToD3dFmt[texId->m_format];
if (SUCCEEDED(this->m_d3dDevice->CreateTexture(width, height, endLevel - startLevel, d3dUsage, d3dFormat, d3dPool, &d3dTexture, nullptr))) {
texId->m_apiSpecificData = d3dTexture;
texId->m_needsCreation = 0;
return;
}
// TODO flag check SLOBYTE(texId->m_flags)
// If texture creation failed, try again with a fallback format
CGxDeviceD3d::s_GxTexFmtToUse[texId->m_format] = CGxDeviceD3d::s_tolerableTexFmtMapping[texId->m_format];
texId->m_format = CGxDeviceD3d::s_GxTexFmtToUse[texId->m_format];
d3dFormat = CGxDeviceD3d::s_GxTexFmtToD3dFmt[texId->m_format];
if (SUCCEEDED(this->m_d3dDevice->CreateTexture(width, height, endLevel - startLevel, d3dUsage, d3dFormat, d3dPool, &d3dTexture, nullptr))) {
texId->m_apiSpecificData = d3dTexture;
texId->m_needsCreation = 0;
}
}
void CGxDeviceD3d::ITexMarkAsUpdated(CGxTex* texId) {
if (!texId->m_needsUpdate || !this->m_context) {
return;
}
if (texId->m_needsCreation || (!texId->m_apiSpecificData && !texId->m_apiSpecificData2)) {
this->ITexCreate(texId);
}
if (!texId->m_needsCreation && (texId->m_apiSpecificData || texId->m_apiSpecificData2)) {
if (texId->m_userFunc) {
this->ITexUpload(texId);
}
CGxDevice::ITexMarkAsUpdated(texId);
}
}
void CGxDeviceD3d::ITexUpload(CGxTex* texId) {
// TODO
}

View File

@ -10,6 +10,9 @@ class CGxDeviceD3d : public CGxDevice {
public:
// Static variables
static D3DFORMAT s_GxFormatToD3dFormat[];
static D3DFORMAT s_GxTexFmtToD3dFmt[];
static EGxTexFormat s_GxTexFmtToUse[];
static EGxTexFormat s_tolerableTexFmtMapping[];
// Static functions
static int32_t ILoadD3dLib(HINSTANCE& d3dLib, LPDIRECT3D9& d3d);
@ -46,6 +49,8 @@ class CGxDeviceD3d : public CGxDevice {
void ISetPresentParms(D3DPRESENT_PARAMETERS& d3dpp, const CGxFormat& format);
void IDestroyD3d();
void IDestroyD3dDevice();
void ITexCreate(CGxTex* texId);
void ITexUpload(CGxTex* texId);
};
#endif