prepare to handle other texture formats

required for DirectX 9...
This commit is contained in:
tildearrow 2024-05-15 02:48:18 -05:00
parent 540cbbd129
commit 394d5d6583
22 changed files with 131 additions and 24 deletions

View file

@ -212,7 +212,7 @@ void FurnaceGUI::drawChanOsc() {
if (chanOscUseGrad) {
if (chanOscGradTex==NULL) {
chanOscGradTex=rend->createTexture(true,chanOscGrad.width,chanOscGrad.height);
chanOscGradTex=rend->createTexture(true,chanOscGrad.width,chanOscGrad.height,true,bestTexFormat);
if (chanOscGradTex==NULL) {
logE("error while creating gradient texture!");

View file

@ -614,7 +614,7 @@ void FurnaceGUI::drawDebug() {
ImGui::Text("Create and Destroy 128 Textures");
if (ImGui::Button("No Write")) {
for (int i=0; i<128; i++) {
FurnaceGUITexture* t=rend->createTexture(false,2048,2048);
FurnaceGUITexture* t=rend->createTexture(false,2048,2048,true,bestTexFormat);
if (t==NULL) {
showError(fmt::sprintf("Failure! %d",i));
break;
@ -628,7 +628,7 @@ void FurnaceGUI::drawDebug() {
data[i]=rand();
}
for (int i=0; i<128; i++) {
FurnaceGUITexture* t=rend->createTexture(false,2048,2048);
FurnaceGUITexture* t=rend->createTexture(false,2048,2048,true,bestTexFormat);
if (t==NULL) {
showError(fmt::sprintf("Failure! %d",i));
break;
@ -642,7 +642,7 @@ void FurnaceGUI::drawDebug() {
unsigned char* data=NULL;
int pitch=0;
for (int i=0; i<128; i++) {
FurnaceGUITexture* t=rend->createTexture(false,2048,2048);
FurnaceGUITexture* t=rend->createTexture(false,2048,2048,true,bestTexFormat);
if (t==NULL) {
showError(fmt::sprintf("Failure! %d",i));
break;

View file

@ -7091,6 +7091,18 @@ bool FurnaceGUI::init() {
}
logV("render backend started");
// set best texture format
unsigned int availTexFormats=rend->getTextureFormats();
if (availTexFormats&GUI_TEXFORMAT_ABGR32) {
bestTexFormat=GUI_TEXFORMAT_ABGR32;
} else if (availTexFormats&GUI_TEXFORMAT_ARGB32) {
bestTexFormat=GUI_TEXFORMAT_ARGB32;
} else if (availTexFormats&GUI_TEXFORMAT_RGBA32) {
bestTexFormat=GUI_TEXFORMAT_RGBA32;
} else if (availTexFormats&GUI_TEXFORMAT_BGRA32) {
bestTexFormat=GUI_TEXFORMAT_BGRA32;
}
// try acquiring the canvas size
if (!rend->getOutputSize(canvasW,canvasH)) {
logW("could not get renderer output size!");

View file

@ -1443,6 +1443,14 @@ struct FurnaceGUIWaveSizeEntry {
sys(NULL) {}
};
enum FurnaceGUITextureFormat: unsigned int {
GUI_TEXFORMAT_UNKNOWN=0,
GUI_TEXFORMAT_ABGR32=1,
GUI_TEXFORMAT_ARGB32=2,
GUI_TEXFORMAT_BGRA32=4,
GUI_TEXFORMAT_RGBA32=8,
};
class FurnaceGUITexture {
};
@ -1482,10 +1490,11 @@ class FurnaceGUIRender {
virtual ImTextureID getTextureID(FurnaceGUITexture* which);
virtual float getTextureU(FurnaceGUITexture* which);
virtual float getTextureV(FurnaceGUITexture* which);
virtual FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which);
virtual bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
virtual bool unlockTexture(FurnaceGUITexture* which);
virtual bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
virtual FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true);
virtual FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
virtual bool destroyTexture(FurnaceGUITexture* which);
virtual void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
virtual void setBlendMode(FurnaceGUIBlendMode mode);
@ -1504,6 +1513,7 @@ class FurnaceGUIRender {
virtual int getWindowFlags();
virtual int getMaxTextureWidth();
virtual int getMaxTextureHeight();
virtual unsigned int getTextureFormats();
virtual const char* getBackendName();
virtual const char* getVendorName();
virtual const char* getDeviceName();
@ -1543,6 +1553,7 @@ class FurnaceGUI {
FurnaceGUIRenderBackend renderBackend;
FurnaceGUIRender* rend;
FurnaceGUITextureFormat bestTexFormat;
SDL_Window* sdlWin;
SDL_Haptic* vibrator;

View file

@ -54,7 +54,7 @@ FurnaceGUITexture* FurnaceGUI::getTexture(FurnaceGUIImages image, FurnaceGUIBlen
if (img->width<=0 || img->height<=0) return NULL;
if (img->tex==NULL) {
img->tex=rend->createTexture(false,img->width,img->height);
img->tex=rend->createTexture(false,img->width,img->height,true,bestTexFormat);
if (img->tex==NULL) {
logE("error while creating image %d texture! %s",(int)image,SDL_GetError());
return NULL;

View file

@ -31,6 +31,10 @@ float FurnaceGUIRender::getTextureV(FurnaceGUITexture* which) {
return 1.0;
}
FurnaceGUITextureFormat FurnaceGUIRender::getTextureFormat(FurnaceGUITexture* which) {
return GUI_TEXFORMAT_UNKNOWN;
}
bool FurnaceGUIRender::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) {
return false;
}
@ -43,7 +47,7 @@ bool FurnaceGUIRender::updateTexture(FurnaceGUITexture* which, void* data, int p
return false;
}
FurnaceGUITexture* FurnaceGUIRender::createTexture(bool dynamic, int width, int height, bool interpolate) {
FurnaceGUITexture* FurnaceGUIRender::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
return NULL;
}
@ -109,6 +113,10 @@ int FurnaceGUIRender::getMaxTextureHeight() {
return 0;
}
unsigned int FurnaceGUIRender::getTextureFormats() {
return 0;
}
const char* FurnaceGUIRender::getBackendName() {
return "Dummy";
}

View file

@ -200,7 +200,7 @@ bool FurnaceGUIRenderDX11::updateTexture(FurnaceGUITexture* which, void* data, i
return true;
}
FurnaceGUITexture* FurnaceGUIRenderDX11::createTexture(bool dynamic, int width, int height, bool interpolate) {
FurnaceGUITexture* FurnaceGUIRenderDX11::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
D3D11_TEXTURE2D_DESC texDesc;
D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
ID3D11Texture2D* tex=NULL;
@ -214,7 +214,23 @@ FurnaceGUITexture* FurnaceGUIRenderDX11::createTexture(bool dynamic, int width,
texDesc.Height=height;
texDesc.MipLevels=1;
texDesc.ArraySize=1;
texDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM; // ???
switch (format) {
case GUI_TEXFORMAT_ABGR32:
texDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM;
break;
case GUI_TEXFORMAT_ARGB32:
texDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM;
break;
case GUI_TEXFORMAT_BGRA32:
texDesc.Format=DXGI_FORMAT_A8R8G8B8_UNORM;
break;
case GUI_TEXFORMAT_RGBA32:
texDesc.Format=DXGI_FORMAT_A8B8G8R8_UNORM;
break;
default:
logE("unsupported texture format!");
return NULL;
}
texDesc.SampleDesc.Count=1;
texDesc.SampleDesc.Quality=0;
texDesc.Usage=dynamic?D3D11_USAGE_DYNAMIC:D3D11_USAGE_DEFAULT;
@ -377,6 +393,10 @@ int FurnaceGUIRenderDX11::getMaxTextureHeight() {
return maxHeight;
}
unsigned int FurnaceGUIRenderDX11::getTextureFormats() {
return GUI_TEXFORMAT_ABGR32|GUI_TEXFORMAT_ARGB32|GUI_TEXFORMAT_BGRA32|GUI_TEXFORMAT_RGBA32;
}
const char* FurnaceGUIRenderDX11::getBackendName() {
return "DirectX 11";
}

View file

@ -67,7 +67,7 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
bool unlockTexture(FurnaceGUITexture* which);
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
bool destroyTexture(FurnaceGUITexture* which);
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
void setBlendMode(FurnaceGUIBlendMode mode);
@ -84,6 +84,7 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
int getWindowFlags();
int getMaxTextureWidth();
int getMaxTextureHeight();
unsigned int getTextureFormats();
const char* getBackendName();
const char* getVendorName();
const char* getDeviceName();

View file

@ -144,12 +144,17 @@ bool FurnaceGUIRenderDX9::updateTexture(FurnaceGUITexture* which, void* data, in
return true;
}
FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, int height, bool interpolate) {
FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
IDirect3DTexture9* tex=NULL;
IDirect3DTexture9* texPre=NULL;
int widthReal=width;
int heightReal=height;
if (format!=GUI_TEXFORMAT_ARGB32) {
logE("unsupported texture format!");
return NULL;
}
if ((widthReal&(widthReal-1))!=0) {
widthReal=1<<bsr(width);
}
@ -339,6 +344,10 @@ int FurnaceGUIRenderDX9::getMaxTextureHeight() {
return maxHeight;
}
unsigned int FurnaceGUIRenderDX9::getTextureFormats() {
return GUI_TEXFORMAT_ARGB32;
}
const char* FurnaceGUIRenderDX9::getBackendName() {
return "DirectX 9";
}

View file

@ -52,7 +52,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender {
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
bool unlockTexture(FurnaceGUITexture* which);
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
bool destroyTexture(FurnaceGUITexture* which);
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
void setBlendMode(FurnaceGUIBlendMode mode);
@ -69,6 +69,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender {
int getWindowFlags();
int getMaxTextureWidth();
int getMaxTextureHeight();
unsigned int getTextureFormats();
const char* getBackendName();
const char* getVendorName();
const char* getDeviceName();

View file

@ -315,7 +315,11 @@ bool FurnaceGUIRenderGL::updateTexture(FurnaceGUITexture* which, void* data, int
return true;
}
FurnaceGUITexture* FurnaceGUIRenderGL::createTexture(bool dynamic, int width, int height, bool interpolate) {
FurnaceGUITexture* FurnaceGUIRenderGL::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
if (format!=GUI_TEXFORMAT_ABGR32) {
logE("unsupported texture format!");
return NULL;
}
FurnaceGLTexture* t=new FurnaceGLTexture;
C(glGenTextures(1,&t->id));
C(glBindTexture(GL_TEXTURE_2D,t->id));
@ -554,6 +558,10 @@ int FurnaceGUIRenderGL::getMaxTextureHeight() {
return maxHeight;
}
unsigned int FurnaceGUIRenderGL::getTextureFormats() {
return GUI_TEXFORMAT_ABGR32;
}
const char* FurnaceGUIRenderGL::getBackendName() {
return backendName.c_str();
}

View file

@ -59,7 +59,7 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender {
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
bool unlockTexture(FurnaceGUITexture* which);
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
bool destroyTexture(FurnaceGUITexture* which);
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
void setBlendMode(FurnaceGUIBlendMode mode);
@ -77,6 +77,7 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender {
int getWindowFlags();
int getMaxTextureWidth();
int getMaxTextureHeight();
unsigned int getTextureFormats();
const char* getBackendName();
const char* getVendorName();
const char* getDeviceName();

View file

@ -92,7 +92,11 @@ bool FurnaceGUIRenderGL1::updateTexture(FurnaceGUITexture* which, void* data, in
return true;
}
FurnaceGUITexture* FurnaceGUIRenderGL1::createTexture(bool dynamic, int width, int height, bool interpolate) {
FurnaceGUITexture* FurnaceGUIRenderGL1::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
if (format!=GUI_TEXFORMAT_ABGR32) {
logE("unsupported texture format!");
return NULL;
}
FurnaceGL1Texture* t=new FurnaceGL1Texture;
C(glGenTextures(1,&t->id));
C(glBindTexture(GL_TEXTURE_2D,t->id));
@ -221,6 +225,10 @@ int FurnaceGUIRenderGL1::getMaxTextureHeight() {
return maxHeight;
}
unsigned int FurnaceGUIRenderGL1::getTextureFormats() {
return GUI_TEXFORMAT_ABGR32;
}
const char* FurnaceGUIRenderGL1::getBackendName() {
return "OpenGL 1.1";
}

View file

@ -35,7 +35,7 @@ class FurnaceGUIRenderGL1: public FurnaceGUIRender {
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
bool unlockTexture(FurnaceGUITexture* which);
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
bool destroyTexture(FurnaceGUITexture* which);
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
void setBlendMode(FurnaceGUIBlendMode mode);
@ -51,6 +51,7 @@ class FurnaceGUIRenderGL1: public FurnaceGUIRender {
int getWindowFlags();
int getMaxTextureWidth();
int getMaxTextureHeight();
unsigned int getTextureFormats();
const char* getBackendName();
const char* getVendorName();
const char* getDeviceName();

View file

@ -31,7 +31,7 @@ class FurnaceGUIRenderMetal: public FurnaceGUIRender {
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
bool unlockTexture(FurnaceGUITexture* which);
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
bool destroyTexture(FurnaceGUITexture* which);
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
void setBlendMode(FurnaceGUIBlendMode mode);
@ -47,6 +47,7 @@ class FurnaceGUIRenderMetal: public FurnaceGUIRender {
int getWindowFlags();
int getMaxTextureWidth();
int getMaxTextureHeight();
unsigned int getTextureFormats();
const char* getBackendName();
const char* getVendorName();
const char* getDeviceName();

View file

@ -84,7 +84,11 @@ bool FurnaceGUIRenderMetal::updateTexture(FurnaceGUITexture* which, void* data,
return true;
}
FurnaceGUITexture* FurnaceGUIRenderMetal::createTexture(bool dynamic, int width, int height, bool interpolate) {
FurnaceGUITexture* FurnaceGUIRenderMetal::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
if (format!=GUI_TEXFORMAT_ABGR32) {
logE("unsupported texture format!");
return NULL;
}
MTLTextureDescriptor* texDesc=[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm width:(NSUInteger)width height:(NSUInteger)height mipmapped:NO];
texDesc.usage=MTLTextureUsageShaderRead;
texDesc.storageMode=MTLStorageModeManaged;
@ -193,6 +197,10 @@ int FurnaceGUIRenderMetal::getMaxTextureHeight() {
return bigTextures?16384:8192;
}
unsigned int FurnaceGUIRenderMetal::getTextureFormats() {
return GUI_TEXFORMAT_ABGR32;
}
const char* FurnaceGUIRenderMetal::getBackendName() {
return "Metal";
}

View file

@ -49,7 +49,11 @@ bool FurnaceGUIRenderSDL::updateTexture(FurnaceGUITexture* which, void* data, in
return SDL_UpdateTexture(t->tex,NULL,data,pitch)==0;
}
FurnaceGUITexture* FurnaceGUIRenderSDL::createTexture(bool dynamic, int width, int height, bool interpolate) {
FurnaceGUITexture* FurnaceGUIRenderSDL::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
if (format!=GUI_TEXFORMAT_ABGR32) {
logE("unsupported texture format!");
return NULL;
}
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,interpolate?"1":"0");
SDL_Texture* t=SDL_CreateTexture(sdlRend,SDL_PIXELFORMAT_ABGR8888,dynamic?SDL_TEXTUREACCESS_STREAMING:SDL_TEXTUREACCESS_STATIC,width,height);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,"1");
@ -156,6 +160,10 @@ int FurnaceGUIRenderSDL::getMaxTextureHeight() {
return renderInfo.max_texture_height;
}
unsigned int FurnaceGUIRenderSDL::getTextureFormats() {
return GUI_TEXFORMAT_ABGR32;
}
const char* FurnaceGUIRenderSDL::getBackendName() {
return "SDL Renderer";
}

View file

@ -29,7 +29,7 @@ class FurnaceGUIRenderSDL: public FurnaceGUIRender {
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
bool unlockTexture(FurnaceGUITexture* which);
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
bool destroyTexture(FurnaceGUITexture* which);
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
void setBlendMode(FurnaceGUIBlendMode mode);
@ -45,6 +45,7 @@ class FurnaceGUIRenderSDL: public FurnaceGUIRender {
int getWindowFlags();
int getMaxTextureWidth();
int getMaxTextureHeight();
unsigned int getTextureFormats();
const char* getBackendName();
const char* getVendorName();
const char* getDeviceName();

View file

@ -52,7 +52,11 @@ bool FurnaceGUIRenderSoftware::updateTexture(FurnaceGUITexture* which, void* dat
return true;
}
FurnaceGUITexture* FurnaceGUIRenderSoftware::createTexture(bool dynamic, int width, int height, bool interpolate) {
FurnaceGUITexture* FurnaceGUIRenderSoftware::createTexture(bool dynamic, int width, int height, bool interpolate, FurnaceGUITextureFormat format) {
if (format!=GUI_TEXFORMAT_ARGB32) {
logE("unsupported texture format!");
return NULL;
}
FurnaceSoftwareTexture* ret=new FurnaceSoftwareTexture;
ret->tex=new SWTexture(width,height);
return ret;
@ -141,6 +145,10 @@ int FurnaceGUIRenderSoftware::getMaxTextureHeight() {
return 16384;
}
unsigned int FurnaceGUIRenderSoftware::getTextureFormats() {
return GUI_TEXFORMAT_ARGB32;
}
const char* FurnaceGUIRenderSoftware::getBackendName() {
return "Software";
}

View file

@ -26,7 +26,7 @@ class FurnaceGUIRenderSoftware: public FurnaceGUIRender {
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
bool unlockTexture(FurnaceGUITexture* which);
bool updateTexture(FurnaceGUITexture* which, void* data, int pitch);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true);
FurnaceGUITexture* createTexture(bool dynamic, int width, int height, bool interpolate=true, FurnaceGUITextureFormat format=GUI_TEXFORMAT_ABGR32);
bool destroyTexture(FurnaceGUITexture* which);
void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode);
void setBlendMode(FurnaceGUIBlendMode mode);
@ -42,6 +42,7 @@ class FurnaceGUIRenderSoftware: public FurnaceGUIRender {
int getWindowFlags();
int getMaxTextureWidth();
int getMaxTextureHeight();
unsigned int getTextureFormats();
const char* getBackendName();
const char* getVendorName();
const char* getDeviceName();

View file

@ -1476,7 +1476,7 @@ void FurnaceGUI::drawSampleEdit() {
}
if (avail.x>=1 && avail.y>=1) {
logD("recreating sample texture.");
sampleTex=rend->createTexture(true,avail.x,avail.y);
sampleTex=rend->createTexture(true,avail.x,avail.y,true,bestTexFormat);
sampleTexW=avail.x;
sampleTexH=avail.y;
if (sampleTex==NULL) {

View file

@ -791,7 +791,7 @@ void FurnaceGUI::drawTutorial() {
cv->hiScore=cvHiScore;
}
if (cvTex==NULL) {
cvTex=rend->createTexture(true,320,224,false);
cvTex=rend->createTexture(true,320,224,false,bestTexFormat);
}
if (cv->pleaseInitSongs) {