From 4f658e41195a3c9260b73861c844007ede72b2b6 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 2 May 2024 15:54:01 -0500 Subject: [PATCH 01/36] prepare for DirectX 9 backend... --- CMakeLists.txt | 22 +-- src/gui/render.cpp | 3 + src/gui/render/renderDX9.cpp | 295 +++++++++++++++++++++++++++++++++++ src/gui/render/renderDX9.h | 82 ++++++++++ 4 files changed, 391 insertions(+), 11 deletions(-) create mode 100644 src/gui/render/renderDX9.cpp create mode 100644 src/gui/render/renderDX9.h diff --git a/CMakeLists.txt b/CMakeLists.txt index df850c42b..addd4ed68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -971,17 +971,17 @@ if (WITH_RENDER_DX11) endif() endif() -#if (WITH_RENDER_DX9) -# if (WIN32) -# list(APPEND GUI_SOURCES src/gui/render/renderDX9.cpp) -# list(APPEND GUI_SOURCES extern/imgui_patched/backends/imgui_impl_dx9.cpp) -# list(APPEND DEPENDENCIES_DEFINES HAVE_RENDER_DX9) -# list(APPEND DEPENDENCIES_LIBRARIES d3d9) -# message(STATUS "UI render backend: DirectX 9") -# else() -# message(FATAL_ERROR "DirectX 9 render backend only for Windows!") -# endif() -#endif() +if (WITH_RENDER_DX9) + if (WIN32) + list(APPEND GUI_SOURCES src/gui/render/renderDX9.cpp) + list(APPEND GUI_SOURCES extern/imgui_patched/backends/imgui_impl_dx9.cpp) + list(APPEND DEPENDENCIES_DEFINES HAVE_RENDER_DX9) + list(APPEND DEPENDENCIES_LIBRARIES d3d9) + message(STATUS "UI render backend: DirectX 9") + else() + message(FATAL_ERROR "DirectX 9 render backend only for Windows!") + endif() +endif() if (WITH_RENDER_METAL) if (APPLE) diff --git a/src/gui/render.cpp b/src/gui/render.cpp index 81dcc2dc2..8db99c025 100644 --- a/src/gui/render.cpp +++ b/src/gui/render.cpp @@ -31,6 +31,9 @@ #ifdef HAVE_RENDER_DX11 #include "render/renderDX11.h" #endif +#ifdef HAVE_RENDER_DX9 +#include "render/renderDX9.h" +#endif #ifdef HAVE_RENDER_METAL #include "render/renderMetal.h" #endif diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp new file mode 100644 index 000000000..9fd65bd4d --- /dev/null +++ b/src/gui/render/renderDX9.cpp @@ -0,0 +1,295 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2024 tildearrow and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define INCLUDE_D3D9 +#include "renderDX9.h" +#include +#include "backends/imgui_impl_dx9.h" +#include "../../ta-log.h" +#include "../../utfutils.h" + +class FurnaceDX9Texture: public FurnaceGUITexture { + public: + ID3D11Texture2D* tex; + ID3D11ShaderResourceView* view; + int width, height; + unsigned char* lockedData; + bool dynamic; + FurnaceDX9Texture(): + tex(NULL), + view(NULL), + width(0), + height(0), + lockedData(NULL), + dynamic(false) {} +}; + +bool FurnaceGUIRenderDX9::destroyRenderTarget() { + if (renderTarget!=NULL) { + renderTarget->Release(); + renderTarget=NULL; + return true; + } + return false; +} + +bool FurnaceGUIRenderDX9::createRenderTarget() { + ID3D11Texture2D* screen=NULL; + HRESULT result; + + destroyRenderTarget(); + + if (swapchain==NULL || device==NULL) { + logW("createRenderTarget: swapchain or device are NULL!"); + return false; + } + + DXGI_SWAP_CHAIN_DESC chainDesc; + memset(&chainDesc,0,sizeof(chainDesc)); + if (swapchain->GetDesc(&chainDesc)!=S_OK) { + logW("createRenderTarget: could not get swapchain desc!"); + } else { + outW=chainDesc.BufferDesc.Width; + outH=chainDesc.BufferDesc.Height; + logI("DX9: buffer desc sizes: %d, %d",chainDesc.BufferDesc.Width,chainDesc.BufferDesc.Height); + } + + result=swapchain->GetBuffer(0,IID_PPV_ARGS(&screen)); + if (result!=S_OK) { + logW("createRenderTarget: could not get buffer! %.8x",result); + return false; + } + if (screen==NULL) { + logW("createRenderTarget: screen is null!"); + return false; + } + + result=device->CreateRenderTargetView(screen,NULL,&renderTarget); + if (result!=S_OK) { + logW("createRenderTarget: could not create render target view! %.8x",result); + screen->Release(); + return false; + } + if (renderTarget==NULL) { + logW("createRenderTarget: what the hell the render target is null?"); + screen->Release(); + return false; + } + + screen->Release(); + return true; +} + +ImTextureID FurnaceGUIRenderDX9::getTextureID(FurnaceGUITexture* which) { + FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + return (ImTextureID)t->view; +} + +bool FurnaceGUIRenderDX9::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { + FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + if (t->lockedData!=NULL) return false; + + D3D11_MAPPED_SUBRESOURCE mappedRes; + memset(&mappedRes,0,sizeof(mappedRes)); + + HRESULT result=context->Map(t->tex,D3D11CalcSubresource(0,0,1),D3D11_MAP_WRITE_DISCARD,0,&mappedRes); + if (result!=S_OK) { + logW("could not map texture! %.8x",result); + return false; + } + t->lockedData=(unsigned char*)mappedRes.pData; + *data=mappedRes.pData; + *pitch=mappedRes.RowPitch; + + logV("texture locked... pitch: %d",mappedRes.RowPitch); + return true; +} + +bool FurnaceGUIRenderDX9::unlockTexture(FurnaceGUITexture* which) { + FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + if (t->lockedData==NULL) return false; + context->Unmap(t->tex,D3D11CalcSubresource(0,0,1)); + t->lockedData=NULL; + return true; +} + +bool FurnaceGUIRenderDX9::updateTexture(FurnaceGUITexture* which, void* data, int pitch) { + FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + if (t->dynamic) { + unsigned char* d=NULL; + int p=0; + if (!lockTexture(t,(void**)&d,&p)) return false; + if (p==pitch) { + memcpy(d,data,p*t->height); + } else { + unsigned char* ucData=(unsigned char*)data; + int srcPos=0; + int destPos=0; + for (int i=0; iheight; i++) { + memcpy(&d[destPos],&ucData[srcPos],pitch); + srcPos+=pitch; + destPos+=p; + } + } + unlockTexture(t); + } else { + context->UpdateSubresource(t->tex,D3D11CalcSubresource(0,0,1),NULL,data,pitch,pitch*t->height); + } + return true; +} + +FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, int height, bool interpolate) { + return ret; +} + +bool FurnaceGUIRenderDX9::destroyTexture(FurnaceGUITexture* which) { + FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + delete t; + return true; +} + +void FurnaceGUIRenderDX9::setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode) { +} + +void FurnaceGUIRenderDX9::setBlendMode(FurnaceGUIBlendMode mode) { +} + +void FurnaceGUIRenderDX9::resized(const SDL_Event& ev) { + destroyRenderTarget(); + logI("DX9: resizing buffers"); + HRESULT result=swapchain->ResizeBuffers(0,(unsigned int)ev.window.data1,(unsigned int)ev.window.data2,DXGI_FORMAT_UNKNOWN,DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH); + if (result!=S_OK) { + if (result==DXGI_ERROR_DEVICE_REMOVED || result==DXGI_ERROR_DEVICE_RESET) { + dead=true; + } + logW("error while resizing swapchain buffers! %.8x",result); + } + if (!dead) { + createRenderTarget(); + } +} + +void FurnaceGUIRenderDX9::clear(ImVec4 color) { + float floatColor[4]={ + color.x*color.w, + color.y*color.w, + color.z*color.w, + color.w, + }; + + context->OMSetRenderTargets(1,&renderTarget,NULL); + context->ClearRenderTargetView(renderTarget,floatColor); +} + +bool FurnaceGUIRenderDX9::newFrame() { + return ImGui_ImplDX9_NewFrame(); +} + +bool FurnaceGUIRenderDX9::canVSync() { + // TODO: find out how to retrieve VSync status + return true; +} + +void FurnaceGUIRenderDX9::createFontsTexture() { + ImGui_ImplDX9_CreateDeviceObjects(); +} + +void FurnaceGUIRenderDX9::destroyFontsTexture() { + ImGui_ImplDX9_InvalidateDeviceObjects(); +} + +void FurnaceGUIRenderDX9::renderGUI() { + ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); +} + +void FurnaceGUIRenderDX9::wipe(float alpha) { +} + +bool FurnaceGUIRenderDX9::getOutputSize(int& w, int& h) { + w=outW; + h=outH; + return true; +} + +int FurnaceGUIRenderDX9::getWindowFlags() { + return 0; +} + +int FurnaceGUIRenderDX9::getMaxTextureWidth() { + return maxWidth; +} + +int FurnaceGUIRenderDX9::getMaxTextureHeight() { + return maxHeight; +} + +const char* FurnaceGUIRenderDX9::getBackendName() { + return "DirectX 9"; +} + +const char* FurnaceGUIRenderDX9::getVendorName() { + return vendorName.c_str(); +} + +const char* FurnaceGUIRenderDX9::getDeviceName() { + return deviceName.c_str(); +} + +const char* FurnaceGUIRenderDX9::getAPIVersion() { + return apiVersion.c_str(); +} + +void FurnaceGUIRenderDX9::setSwapInterval(int swapInt) { + swapInterval=swapInt; +} + +void FurnaceGUIRenderDX9::preInit() { +} + +bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { + SDL_SysWMinfo sysWindow; + D3D_FEATURE_LEVEL featureLevel; + + SDL_VERSION(&sysWindow.version); + if (SDL_GetWindowWMInfo(win,&sysWindow)==SDL_FALSE) { + logE("could not get window WM info! %s",SDL_GetError()); + return false; + } + HWND window=(HWND)sysWindow.info.win.window; + + return true; +} + +void FurnaceGUIRenderDX9::initGUI(SDL_Window* win) { + ImGui_ImplSDL2_InitForD3D(win); + ImGui_ImplDX9_Init(device,context); +} + +bool FurnaceGUIRenderDX9::quit() { + dead=false; + return true; +} + +void FurnaceGUIRenderDX9::quitGUI() { + ImGui_ImplDX9_Shutdown(); +} + +bool FurnaceGUIRenderDX9::isDead() { + return dead; +} diff --git a/src/gui/render/renderDX9.h b/src/gui/render/renderDX9.h new file mode 100644 index 000000000..9bdfdf177 --- /dev/null +++ b/src/gui/render/renderDX9.h @@ -0,0 +1,82 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2024 tildearrow and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "../gui.h" +#ifdef INCLUDE_D3D9 +#include +#else + +#endif + +class FurnaceGUIRenderDX9: public FurnaceGUIRender { + IDirect3DDevice9* device; + + int outW, outH, swapInterval; + + bool dead, haveScene; + + // SHADERS // + + int maxWidth, maxHeight; + String vendorName, deviceName, apiVersion; + + public: + ImTextureID getTextureID(FurnaceGUITexture* which); + 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); + bool destroyTexture(FurnaceGUITexture* which); + void setTextureBlendMode(FurnaceGUITexture* which, FurnaceGUIBlendMode mode); + void setBlendMode(FurnaceGUIBlendMode mode); + void resized(const SDL_Event& ev); + void clear(ImVec4 color); + bool newFrame(); + bool canVSync(); + void createFontsTexture(); + void destroyFontsTexture(); + void renderGUI(); + void wipe(float alpha); + void present(); + bool getOutputSize(int& w, int& h); + int getWindowFlags(); + int getMaxTextureWidth(); + int getMaxTextureHeight(); + const char* getBackendName(); + const char* getVendorName(); + const char* getDeviceName(); + const char* getAPIVersion(); + void setSwapInterval(int swapInterval); + void preInit(); + bool init(SDL_Window* win, int swapInterval); + void initGUI(SDL_Window* win); + void quitGUI(); + bool quit(); + bool isDead(); + FurnaceGUIRenderDX9(): + device(NULL), + outW(0), + outH(0), + swapInterval(1), + dead(false), + haveScene(false), + maxWidth(8192), + maxHeight(8192) { + } +}; From 39daeed27aef97c302f72e766dfc2c576a6bb215 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 12 May 2024 17:02:37 -0500 Subject: [PATCH 02/36] DirectX 9 backend, part 1 untested --- src/gui/render/renderDX9.cpp | 181 ++++++++++++----------------------- src/gui/render/renderDX9.h | 14 ++- 2 files changed, 73 insertions(+), 122 deletions(-) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 9fd65bd4d..f7df06617 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -26,136 +26,37 @@ class FurnaceDX9Texture: public FurnaceGUITexture { public: - ID3D11Texture2D* tex; - ID3D11ShaderResourceView* view; + IDirect3DTexture9* tex; int width, height; unsigned char* lockedData; bool dynamic; FurnaceDX9Texture(): tex(NULL), - view(NULL), width(0), height(0), lockedData(NULL), dynamic(false) {} }; -bool FurnaceGUIRenderDX9::destroyRenderTarget() { - if (renderTarget!=NULL) { - renderTarget->Release(); - renderTarget=NULL; - return true; - } - return false; -} - -bool FurnaceGUIRenderDX9::createRenderTarget() { - ID3D11Texture2D* screen=NULL; - HRESULT result; - - destroyRenderTarget(); - - if (swapchain==NULL || device==NULL) { - logW("createRenderTarget: swapchain or device are NULL!"); - return false; - } - - DXGI_SWAP_CHAIN_DESC chainDesc; - memset(&chainDesc,0,sizeof(chainDesc)); - if (swapchain->GetDesc(&chainDesc)!=S_OK) { - logW("createRenderTarget: could not get swapchain desc!"); - } else { - outW=chainDesc.BufferDesc.Width; - outH=chainDesc.BufferDesc.Height; - logI("DX9: buffer desc sizes: %d, %d",chainDesc.BufferDesc.Width,chainDesc.BufferDesc.Height); - } - - result=swapchain->GetBuffer(0,IID_PPV_ARGS(&screen)); - if (result!=S_OK) { - logW("createRenderTarget: could not get buffer! %.8x",result); - return false; - } - if (screen==NULL) { - logW("createRenderTarget: screen is null!"); - return false; - } - - result=device->CreateRenderTargetView(screen,NULL,&renderTarget); - if (result!=S_OK) { - logW("createRenderTarget: could not create render target view! %.8x",result); - screen->Release(); - return false; - } - if (renderTarget==NULL) { - logW("createRenderTarget: what the hell the render target is null?"); - screen->Release(); - return false; - } - - screen->Release(); - return true; -} - ImTextureID FurnaceGUIRenderDX9::getTextureID(FurnaceGUITexture* which) { FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; - return (ImTextureID)t->view; + return (ImTextureID)t->tex; } bool FurnaceGUIRenderDX9::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { - FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; - if (t->lockedData!=NULL) return false; - - D3D11_MAPPED_SUBRESOURCE mappedRes; - memset(&mappedRes,0,sizeof(mappedRes)); - - HRESULT result=context->Map(t->tex,D3D11CalcSubresource(0,0,1),D3D11_MAP_WRITE_DISCARD,0,&mappedRes); - if (result!=S_OK) { - logW("could not map texture! %.8x",result); - return false; - } - t->lockedData=(unsigned char*)mappedRes.pData; - *data=mappedRes.pData; - *pitch=mappedRes.RowPitch; - - logV("texture locked... pitch: %d",mappedRes.RowPitch); - return true; + return false; } bool FurnaceGUIRenderDX9::unlockTexture(FurnaceGUITexture* which) { - FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; - if (t->lockedData==NULL) return false; - context->Unmap(t->tex,D3D11CalcSubresource(0,0,1)); - t->lockedData=NULL; - return true; + return false; } bool FurnaceGUIRenderDX9::updateTexture(FurnaceGUITexture* which, void* data, int pitch) { - FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; - if (t->dynamic) { - unsigned char* d=NULL; - int p=0; - if (!lockTexture(t,(void**)&d,&p)) return false; - if (p==pitch) { - memcpy(d,data,p*t->height); - } else { - unsigned char* ucData=(unsigned char*)data; - int srcPos=0; - int destPos=0; - for (int i=0; iheight; i++) { - memcpy(&d[destPos],&ucData[srcPos],pitch); - srcPos+=pitch; - destPos+=p; - } - } - unlockTexture(t); - } else { - context->UpdateSubresource(t->tex,D3D11CalcSubresource(0,0,1),NULL,data,pitch,pitch*t->height); - } - return true; + return false; } FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, int height, bool interpolate) { - return ret; + return NULL; } bool FurnaceGUIRenderDX9::destroyTexture(FurnaceGUITexture* which) { @@ -171,18 +72,13 @@ void FurnaceGUIRenderDX9::setBlendMode(FurnaceGUIBlendMode mode) { } void FurnaceGUIRenderDX9::resized(const SDL_Event& ev) { - destroyRenderTarget(); logI("DX9: resizing buffers"); - HRESULT result=swapchain->ResizeBuffers(0,(unsigned int)ev.window.data1,(unsigned int)ev.window.data2,DXGI_FORMAT_UNKNOWN,DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH); - if (result!=S_OK) { - if (result==DXGI_ERROR_DEVICE_REMOVED || result==DXGI_ERROR_DEVICE_RESET) { - dead=true; - } - logW("error while resizing swapchain buffers! %.8x",result); - } - if (!dead) { - createRenderTarget(); + ImGui_ImplDX9_InvalidateDeviceObjects(); + HRESULT result=g_pd3dDevice->Reset(&priv->present); + if (result==D3DERR_INVALIDCALL) { + logE("OH NO"); } + ImGui_ImplDX9_CreateDeviceObjects(); } void FurnaceGUIRenderDX9::clear(ImVec4 color) { @@ -193,8 +89,11 @@ void FurnaceGUIRenderDX9::clear(ImVec4 color) { color.w, }; - context->OMSetRenderTargets(1,&renderTarget,NULL); - context->ClearRenderTargetView(renderTarget,floatColor); + device->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,ImGui::ColorConvertFloat4ToU32(floatColor),0,0); +} + +void FurnaceGUIRenderDX9::present() { + device->Present(NULL,NULL,NULL,NULL); } bool FurnaceGUIRenderDX9::newFrame() { @@ -215,7 +114,13 @@ void FurnaceGUIRenderDX9::destroyFontsTexture() { } void FurnaceGUIRenderDX9::renderGUI() { - ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); + HRESULT result=device->BeginScene(); + if (result==D3D_OK) { + ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); + device->EndScene(); + } else { + logW("couldn't render GUI! %.8x",result); + } } void FurnaceGUIRenderDX9::wipe(float alpha) { @@ -259,12 +164,11 @@ void FurnaceGUIRenderDX9::setSwapInterval(int swapInt) { swapInterval=swapInt; } -void FurnaceGUIRenderDX9::preInit() { +void FurnaceGUIRenderDX9::preInit(const DivConfig& conf) { } bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { SDL_SysWMinfo sysWindow; - D3D_FEATURE_LEVEL featureLevel; SDL_VERSION(&sysWindow.version); if (SDL_GetWindowWMInfo(win,&sysWindow)==SDL_FALSE) { @@ -273,6 +177,35 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { } HWND window=(HWND)sysWindow.info.win.window; + iface=Direct3DCreate9(D3D_SDK_VERSION); + if (iface==NULL) { + logE("could not create Direct3D 9!"); + return false; + } + + priv=new FurnaceGUIRenderDX9Private; + + memset(priv->present,0,sizeof(D3DPRESENT_PARAMETERS); + priv->present.Windowed=TRUE; + priv->present.SwapEffect=D3DSWAPEFFECT_DISCARD; + priv->present.BackBufferFormat=D3DFMT_UNKNOWN; + priv->present.EnableAutoDepthStencil=TRUE; + priv->present.AutoDepthStencilFormat=D3DFMT_D16; + if (swapInt>0) { + priv->present.PresentationInterval=D3DPRESENT_INTERVAL_ONE; + } else { + priv->present.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE; + } + + HRESULT result=iface->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,window,D3DCREATE_HARDWARE_VERTEXPROCESSING,&priv->present,&device); + + if (result!=D3D_OK) { + logE("could not create device! %.8x",result); + iface->Release(); + iface=NULL; + return false; + } + return true; } @@ -282,6 +215,14 @@ void FurnaceGUIRenderDX9::initGUI(SDL_Window* win) { } bool FurnaceGUIRenderDX9::quit() { + if (device) { + device->Release(); + device=NULL; + } + if (iface) { + iface->Release(); + iface=NULL; + } dead=false; return true; } diff --git a/src/gui/render/renderDX9.h b/src/gui/render/renderDX9.h index 9bdfdf177..b19eb68ec 100644 --- a/src/gui/render/renderDX9.h +++ b/src/gui/render/renderDX9.h @@ -20,12 +20,20 @@ #include "../gui.h" #ifdef INCLUDE_D3D9 #include -#else +struct FurnaceGUIRenderDX9Private { + D3DPRESENT_PARAMETERS present; +}; +#else +typedef void IDirect3D9; +typedef void IDirect3DDevice9; +typedef void FurnaceGUIRenderDX9Private; #endif class FurnaceGUIRenderDX9: public FurnaceGUIRender { + IDirect3D9* iface; IDirect3DDevice9* device; + FurnaceGUIRenderDX9Private* priv; int outW, outH, swapInterval; @@ -63,14 +71,16 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { const char* getDeviceName(); const char* getAPIVersion(); void setSwapInterval(int swapInterval); - void preInit(); + void preInit(const DivConfig& conf); bool init(SDL_Window* win, int swapInterval); void initGUI(SDL_Window* win); void quitGUI(); bool quit(); bool isDead(); FurnaceGUIRenderDX9(): + iface(NULL), device(NULL), + priv(NULL), outW(0), outH(0), swapInterval(1), From 056545d899cad49d072069694f01247276d52334 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 12 May 2024 17:23:57 -0500 Subject: [PATCH 03/36] DirectX 9 backend, part 2 it compiles --- .../imgui_patched/backends/imgui_impl_dx9.cpp | 4 +--- src/gui/render/renderDX9.cpp | 18 ++++++------------ src/gui/render/renderDX9.h | 1 - 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/extern/imgui_patched/backends/imgui_impl_dx9.cpp b/extern/imgui_patched/backends/imgui_impl_dx9.cpp index 7ee02b5b9..0519bcdef 100644 --- a/extern/imgui_patched/backends/imgui_impl_dx9.cpp +++ b/extern/imgui_patched/backends/imgui_impl_dx9.cpp @@ -506,9 +506,7 @@ static void ImGui_ImplDX9_RenderWindow(ImGuiViewport* viewport, void*) static void ImGui_ImplDX9_SwapBuffers(ImGuiViewport* viewport, void*) { ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData; - HRESULT hr = vd->SwapChain->Present(nullptr, nullptr, vd->d3dpp.hDeviceWindow, nullptr, 0); - // Let main application handle D3DERR_DEVICELOST by resetting the device. - IM_ASSERT(hr == D3D_OK || hr == D3DERR_DEVICELOST); + vd->SwapChain->Present(nullptr, nullptr, vd->d3dpp.hDeviceWindow, nullptr, 0); } static void ImGui_ImplDX9_InitPlatformInterface() diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index f7df06617..a9bf0ff83 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -74,7 +74,7 @@ void FurnaceGUIRenderDX9::setBlendMode(FurnaceGUIBlendMode mode) { void FurnaceGUIRenderDX9::resized(const SDL_Event& ev) { logI("DX9: resizing buffers"); ImGui_ImplDX9_InvalidateDeviceObjects(); - HRESULT result=g_pd3dDevice->Reset(&priv->present); + HRESULT result=device->Reset(&priv->present); if (result==D3DERR_INVALIDCALL) { logE("OH NO"); } @@ -82,14 +82,7 @@ void FurnaceGUIRenderDX9::resized(const SDL_Event& ev) { } void FurnaceGUIRenderDX9::clear(ImVec4 color) { - float floatColor[4]={ - color.x*color.w, - color.y*color.w, - color.z*color.w, - color.w, - }; - - device->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,ImGui::ColorConvertFloat4ToU32(floatColor),0,0); + device->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,ImGui::ColorConvertFloat4ToU32(color),0,0); } void FurnaceGUIRenderDX9::present() { @@ -97,7 +90,8 @@ void FurnaceGUIRenderDX9::present() { } bool FurnaceGUIRenderDX9::newFrame() { - return ImGui_ImplDX9_NewFrame(); + ImGui_ImplDX9_NewFrame(); + return true; } bool FurnaceGUIRenderDX9::canVSync() { @@ -185,7 +179,7 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { priv=new FurnaceGUIRenderDX9Private; - memset(priv->present,0,sizeof(D3DPRESENT_PARAMETERS); + memset(&priv->present,0,sizeof(D3DPRESENT_PARAMETERS)); priv->present.Windowed=TRUE; priv->present.SwapEffect=D3DSWAPEFFECT_DISCARD; priv->present.BackBufferFormat=D3DFMT_UNKNOWN; @@ -211,7 +205,7 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { void FurnaceGUIRenderDX9::initGUI(SDL_Window* win) { ImGui_ImplSDL2_InitForD3D(win); - ImGui_ImplDX9_Init(device,context); + ImGui_ImplDX9_Init(device); } bool FurnaceGUIRenderDX9::quit() { diff --git a/src/gui/render/renderDX9.h b/src/gui/render/renderDX9.h index b19eb68ec..7ac8fb071 100644 --- a/src/gui/render/renderDX9.h +++ b/src/gui/render/renderDX9.h @@ -26,7 +26,6 @@ struct FurnaceGUIRenderDX9Private { }; #else typedef void IDirect3D9; -typedef void IDirect3DDevice9; typedef void FurnaceGUIRenderDX9Private; #endif From 5a0ddbc2126667d8b2e2d02a7e1821a2c5f5a346 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 13 May 2024 16:38:09 -0500 Subject: [PATCH 04/36] DirectX 9 backend, part 3 --- .../imgui_patched/backends/imgui_impl_dx9.cpp | 6 +- .../imgui_patched/backends/imgui_impl_dx9.h | 2 +- src/gui/render/renderDX9.cpp | 79 ++++++++++++++++--- src/gui/render/renderDX9.h | 4 +- 4 files changed, 78 insertions(+), 13 deletions(-) diff --git a/extern/imgui_patched/backends/imgui_impl_dx9.cpp b/extern/imgui_patched/backends/imgui_impl_dx9.cpp index 0519bcdef..d39f2a22e 100644 --- a/extern/imgui_patched/backends/imgui_impl_dx9.cpp +++ b/extern/imgui_patched/backends/imgui_impl_dx9.cpp @@ -391,13 +391,15 @@ void ImGui_ImplDX9_InvalidateDeviceObjects() ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows(); } -void ImGui_ImplDX9_NewFrame() +bool ImGui_ImplDX9_NewFrame() { ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX9_Init()?"); if (!bd->FontTexture) - ImGui_ImplDX9_CreateDeviceObjects(); + return ImGui_ImplDX9_CreateDeviceObjects(); + + return true; } //-------------------------------------------------------------------------------------------------------- diff --git a/extern/imgui_patched/backends/imgui_impl_dx9.h b/extern/imgui_patched/backends/imgui_impl_dx9.h index ffcd46826..716de6488 100644 --- a/extern/imgui_patched/backends/imgui_impl_dx9.h +++ b/extern/imgui_patched/backends/imgui_impl_dx9.h @@ -19,7 +19,7 @@ struct IDirect3DDevice9; IMGUI_IMPL_API bool ImGui_ImplDX9_Init(IDirect3DDevice9* device); IMGUI_IMPL_API void ImGui_ImplDX9_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame(); +IMGUI_IMPL_API bool ImGui_ImplDX9_NewFrame(); IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data); // Use if you want to reset your rendering device without losing Dear ImGui state. diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index a9bf0ff83..7e0ca620f 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -27,13 +27,15 @@ class FurnaceDX9Texture: public FurnaceGUITexture { public: IDirect3DTexture9* tex; - int width, height; + int width, height, widthReal, heightReal; unsigned char* lockedData; bool dynamic; FurnaceDX9Texture(): tex(NULL), width(0), height(0), + widthReal(0), + heightReal(0), lockedData(NULL), dynamic(false) {} }; @@ -44,23 +46,72 @@ ImTextureID FurnaceGUIRenderDX9::getTextureID(FurnaceGUITexture* which) { } bool FurnaceGUIRenderDX9::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { - return false; + FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + D3DLOCKED_RECT lockedRect; + + HRESULT result=t->tex->LockRect(0,&lockedRect,NULL,D3DLOCK_DISCARD); + + if (result!=D3D_OK) { + logW("could not lock texture!"); + return false; + } + + *data=lockedRect.pBits; + *pitch=lockedRect.Pitch; + return true; } bool FurnaceGUIRenderDX9::unlockTexture(FurnaceGUITexture* which) { - return false; + FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + HRESULT result=t->tex->UnlockRect(0); + + if (result!=D3D_OK) { + logW("could not unlock texture!"); + return false; + } + + return true; } bool FurnaceGUIRenderDX9::updateTexture(FurnaceGUITexture* which, void* data, int pitch) { + // TODO return false; } -FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, int height, bool interpolate) { - return NULL; +FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, int height, bool interpolate) { + IDirect3DTexture9* tex=NULL; + int widthReal=width; + int heightReal=height; + + if ((widthReal&(widthReal-1))!=0) { + widthReal=1<CreateTexture(widthReal,heightReal,1,dynamic?D3DUSAGE_DYNAMIC:0,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&tex,NULL); + + if (result!=D3D_OK) { + logW("could not create texture! %.8x",result); + return NULL; + } + + FurnaceDXTexture* ret=new FurnaceDXTexture; + ret->width=width; + ret->height=height; + ret->widthReal=widthReal; + ret->heightReal=heightReal; + ret->tex=tex; + ret->dynamic=dynamic; + return ret; } bool FurnaceGUIRenderDX9::destroyTexture(FurnaceGUITexture* which) { FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + t->tex->Release(); delete t; return true; } @@ -90,13 +141,11 @@ void FurnaceGUIRenderDX9::present() { } bool FurnaceGUIRenderDX9::newFrame() { - ImGui_ImplDX9_NewFrame(); - return true; + return ImGui_ImplDX9_NewFrame(); } bool FurnaceGUIRenderDX9::canVSync() { - // TODO: find out how to retrieve VSync status - return true; + return supportsVSync; } void FurnaceGUIRenderDX9::createFontsTexture() { @@ -190,6 +239,7 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { } else { priv->present.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE; } + priv->present.hDeviceWindow=window; HRESULT result=iface->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,window,D3DCREATE_HARDWARE_VERTEXPROCESSING,&priv->present,&device); @@ -200,6 +250,17 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { return false; } + D3DCAPS9 caps; + + result=device->GetDeviceCaps(&caps); + + if (result==D3D_OK) { + supportsDynamicTex=(caps.Caps2&D3DCAPS2_DYNAMICTEXTURES); + supportsVSync=(caps.PresentationIntervals&D3DPRESENT_INTERVAL_ONE); + maxWidth=caps.MaxTextureWidth; + maxHeight=caps.MaxTextureHeight; + } + return true; } diff --git a/src/gui/render/renderDX9.h b/src/gui/render/renderDX9.h index 7ac8fb071..f3076686b 100644 --- a/src/gui/render/renderDX9.h +++ b/src/gui/render/renderDX9.h @@ -36,7 +36,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { int outW, outH, swapInterval; - bool dead, haveScene; + bool dead, haveScene, supportsDynamicTex, supportsVSync; // SHADERS // @@ -85,6 +85,8 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { swapInterval(1), dead(false), haveScene(false), + supportsDynamicTex(false), + supportsVSync(false), maxWidth(8192), maxHeight(8192) { } From ba15db42920d42adba926ea5847dc4bb66e648f7 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 13 May 2024 16:39:55 -0500 Subject: [PATCH 05/36] DirectX 9 backend, part 4 --- src/gui/render/renderDX9.cpp | 2 +- src/gui/settings.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 7e0ca620f..06d5a644e 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -99,7 +99,7 @@ FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, i return NULL; } - FurnaceDXTexture* ret=new FurnaceDXTexture; + FurnaceDX9Texture* ret=new FurnaceDX9Texture; ret->width=width; ret->height=height; ret->widthReal=widthReal; diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index d3a64033e..f24d12799 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -411,6 +411,12 @@ void FurnaceGUI::drawSettings() { settingsChanged=true; } #endif +#ifdef HAVE_RENDER_DX9 + if (ImGui::Selectable("DirectX 9",curRenderBackend=="DirectX 9")) { + settings.renderBackend="DirectX 9"; + settingsChanged=true; + } +#endif #ifdef HAVE_RENDER_METAL if (ImGui::Selectable("Metal",curRenderBackend=="Metal")) { settings.renderBackend="Metal"; From d0083b71244d66980586eb36d37c05572730fa03 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 13 May 2024 16:42:03 -0500 Subject: [PATCH 06/36] DirectX 9 backend, part 5 --- src/gui/render/renderDX9.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 06d5a644e..ba061d498 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -23,6 +23,7 @@ #include "backends/imgui_impl_dx9.h" #include "../../ta-log.h" #include "../../utfutils.h" +#include "../engine/bsr.h" class FurnaceDX9Texture: public FurnaceGUITexture { public: From 106d12962287e7c703ac53d77ff33d2ff1576c51 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 13 May 2024 17:00:25 -0500 Subject: [PATCH 07/36] DirectX 9 backend, part 6 mouse input works --- src/gui/render/renderDX9.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index ba061d498..29708d1fe 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -131,6 +131,9 @@ void FurnaceGUIRenderDX9::resized(const SDL_Event& ev) { logE("OH NO"); } ImGui_ImplDX9_CreateDeviceObjects(); + + outW=ev.window.data1; + outH=ev.window.data2; } void FurnaceGUIRenderDX9::clear(ImVec4 color) { @@ -262,6 +265,8 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { maxHeight=caps.MaxTextureHeight; } + SDL_GetWindowSize(win,&outW,&outH); + return true; } From cbf9e96067de0ca16c21bce02cf0145ccc1dc7b9 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 13 May 2024 23:53:25 -0500 Subject: [PATCH 08/36] DirectX 9 backend, part 7 resizing works --- src/gui/render/renderDX9.cpp | 24 ++++++++++++++++-------- src/gui/render/renderDX9.h | 3 ++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 29708d1fe..02199fecf 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -93,6 +93,8 @@ FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, i logV("width: %d (requested)... %d (actual)",width,widthReal); logV("height: %d (requested)... %d (actual)",height,heightReal); + if (!supportsDynamicTex) dynamic=false; + HRESULT result=device->CreateTexture(widthReal,heightReal,1,dynamic?D3DUSAGE_DYNAMIC:0,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&tex,NULL); if (result!=D3D_OK) { @@ -124,14 +126,7 @@ void FurnaceGUIRenderDX9::setBlendMode(FurnaceGUIBlendMode mode) { } void FurnaceGUIRenderDX9::resized(const SDL_Event& ev) { - logI("DX9: resizing buffers"); - ImGui_ImplDX9_InvalidateDeviceObjects(); - HRESULT result=device->Reset(&priv->present); - if (result==D3DERR_INVALIDCALL) { - logE("OH NO"); - } - ImGui_ImplDX9_CreateDeviceObjects(); - + mustResize=true; outW=ev.window.data1; outH=ev.window.data2; } @@ -145,6 +140,19 @@ void FurnaceGUIRenderDX9::present() { } bool FurnaceGUIRenderDX9::newFrame() { + if (mustResize) { + logI("DX9: resizing buffers"); + ImGui_ImplDX9_InvalidateDeviceObjects(); + priv->present.BackBufferWidth=outW; + priv->present.BackBufferHeight=outH; + HRESULT result=device->Reset(&priv->present); + if (result==D3DERR_INVALIDCALL) { + logE("OH NO"); + } + ImGui_ImplDX9_CreateDeviceObjects(); + mustResize=false; + } + return ImGui_ImplDX9_NewFrame(); } diff --git a/src/gui/render/renderDX9.h b/src/gui/render/renderDX9.h index f3076686b..e53eddb89 100644 --- a/src/gui/render/renderDX9.h +++ b/src/gui/render/renderDX9.h @@ -36,7 +36,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { int outW, outH, swapInterval; - bool dead, haveScene, supportsDynamicTex, supportsVSync; + bool dead, haveScene, supportsDynamicTex, supportsVSync, mustResize; // SHADERS // @@ -87,6 +87,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { haveScene(false), supportsDynamicTex(false), supportsVSync(false), + mustResize(false), maxWidth(8192), maxHeight(8192) { } From d86d248ef34747c94937225d072b10ca8ee523ce Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 14 May 2024 02:40:16 -0500 Subject: [PATCH 09/36] DirectX 9 backend, part 8 --- src/gui/render/renderDX9.cpp | 13 ++++++++++++- src/gui/render/renderDX9.h | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 02199fecf..03f7920f5 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -46,6 +46,16 @@ ImTextureID FurnaceGUIRenderDX9::getTextureID(FurnaceGUITexture* which) { return (ImTextureID)t->tex; } +float FurnaceGUIRenderDX9::getTextureU(FurnaceGUITexture* which) { + FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + return (float)t->width/(float)t->widthReal; +} + +float FurnaceGUIRenderDX9::getTextureV(FurnaceGUITexture* which) { + FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + return (float)t->height/(float)t->heightReal; +} + bool FurnaceGUIRenderDX9::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; D3DLOCKED_RECT lockedRect; @@ -76,6 +86,7 @@ bool FurnaceGUIRenderDX9::unlockTexture(FurnaceGUITexture* which) { bool FurnaceGUIRenderDX9::updateTexture(FurnaceGUITexture* which, void* data, int pitch) { // TODO + return false; } @@ -95,7 +106,7 @@ FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, i if (!supportsDynamicTex) dynamic=false; - HRESULT result=device->CreateTexture(widthReal,heightReal,1,dynamic?D3DUSAGE_DYNAMIC:0,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&tex,NULL); + HRESULT result=device->CreateTexture(widthReal,heightReal,1,dynamic?D3DUSAGE_DYNAMIC:0,D3DFMT_A8B8G8R8,D3DPOOL_DEFAULT,&tex,NULL); if (result!=D3D_OK) { logW("could not create texture! %.8x",result); diff --git a/src/gui/render/renderDX9.h b/src/gui/render/renderDX9.h index e53eddb89..829a17519 100644 --- a/src/gui/render/renderDX9.h +++ b/src/gui/render/renderDX9.h @@ -45,6 +45,8 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { public: ImTextureID getTextureID(FurnaceGUITexture* which); + float getTextureU(FurnaceGUITexture* which); + float getTextureV(FurnaceGUITexture* which); bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); bool unlockTexture(FurnaceGUITexture* which); bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); From 0ef5b84234043d516f6b080e10b74e62c88dd63a Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 14 May 2024 12:22:14 -0500 Subject: [PATCH 10/36] DirectX backend, part 9 finish textures and (hopefully) wipe --- src/gui/render/renderDX9.cpp | 130 ++++++++++++++++++++++++++++++++++- src/gui/render/renderDX9.h | 3 + 2 files changed, 131 insertions(+), 2 deletions(-) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 03f7920f5..492aa23ca 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -28,11 +28,13 @@ class FurnaceDX9Texture: public FurnaceGUITexture { public: IDirect3DTexture9* tex; + IDirect3DTexture9* texPre; int width, height, widthReal, heightReal; unsigned char* lockedData; bool dynamic; FurnaceDX9Texture(): tex(NULL), + texPre(NULL), width(0), height(0), widthReal(0), @@ -85,13 +87,62 @@ bool FurnaceGUIRenderDX9::unlockTexture(FurnaceGUITexture* which) { } bool FurnaceGUIRenderDX9::updateTexture(FurnaceGUITexture* which, void* data, int pitch) { - // TODO + FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + IDirect3DTexture9* which=NULL; - return false; + if (t->texPre==NULL) { + // update by locking + if (!t->dynamic) { + logW("updating static texture but texPre does not exist!"); + return false; + } + which=t->tex; + } else { + // update by calling UpdateTexture + which=t->texPre; + } + + D3DLOCKED_RECT lockedRect; + HRESULT result=which->LockRect(0,&lockedRect,NULL,D3DLOCK_DISCARD); + if (result!=D3D_OK) { + logW("could not update texture (lock)! %.8x",result); + return false; + } + + if (lockedRect.Pitch==pitch) { + memcpy(lockedRect.pBits,data,pitch*t->height); + } else { + unsigned char* ucData=(unsigned char*)data; + unsigned char* d=(unsigned char*)lockedRect.pBits; + int srcPos=0; + int destPos=0; + for (int i=0; iheight; i++) { + memcpy(&d[destPos],&ucData[srcPos],pitch); + srcPos+=pitch; + destPos+=lockedRect.Pitch; + } + } + + which->UnlockRect(0); + + if (t->texPre!=NULL) { + result=t->tex->AddDirtyRect(NULL); + if (result!=D3D_OK) { + logW("could not taint texture! %.8x",result); + } + result=device->UpdateTexture(t->texPre,t->tex); + if (result!=D3D_OK) { + logW("could not update texture! %.8x",result); + return false; + } + } + + return true; } FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, int height, bool interpolate) { IDirect3DTexture9* tex=NULL; + IDirect3DTexture9* texPre=NULL; int widthReal=width; int heightReal=height; @@ -113,12 +164,23 @@ FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, i return NULL; } + if (!dynamic) { + HRESULT result=device->CreateTexture(widthReal,heightReal,1,0,D3DFMT_A8B8G8R8,D3DPOOL_SYSTEMMEM,&texPre,NULL); + + if (result!=D3D_OK) { + logW("could not create pre-texture! %.8x",result); + tex->Release(); + return NULL; + } + } + FurnaceDX9Texture* ret=new FurnaceDX9Texture; ret->width=width; ret->height=height; ret->widthReal=widthReal; ret->heightReal=heightReal; ret->tex=tex; + ret->texPre=texPre; ret->dynamic=dynamic; return ret; } @@ -189,7 +251,57 @@ void FurnaceGUIRenderDX9::renderGUI() { } } +struct WipeVertex { + float x, y, z; + unsigned int color; + + WipeVertex(float _x, float _y, float _z, unsigned int c): + x(_x), + y(_y), + z(_z), + color(c) {} + WipeVertex(): + x(0), + y(0), + z(0), + color(0) {} +}; + void FurnaceGUIRenderDX9::wipe(float alpha) { + if (wipeBuf==NULL) return; + + HRESULT result=device->BeginScene(); + if (result==D3D_OK) { + D3DVIEWPORT9 view; + view.X=0; + view.Y=0; + view.Width=outW; + view.Height=outH; + view.MinZ=0.0f; + view.MaxZ=1.0f; + device->SetViewport(view); + + unsigned int color=alpha*255; + + void* lockedData; + WipeVertex vertex[4]; + vertex[0]=WipeVertex(0,0,0,color); + vertex[1]=WipeVertex(outW,0,0,color); + vertex[2]=WipeVertex(outW,outH,0,color); + vertex[3]=WipeVertex(0,outH,0,color); + + result=wipeBuf->Lock(0,0,&lockedData,D3DLOCK_DISCARD); + if (result==D3D_OK) { + memcpy(lockedData,vertex,sizeof(WipeVertex)*4); + wipeBuf->Unlock(); + + device->SetStreamSource(0,wipeBuf,0,sizeof(WipeVertex)); + device->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE); + device->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,1); + } + + device->EndScene(); + } } bool FurnaceGUIRenderDX9::getOutputSize(int& w, int& h) { @@ -282,6 +394,16 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { supportsVSync=(caps.PresentationIntervals&D3DPRESENT_INTERVAL_ONE); maxWidth=caps.MaxTextureWidth; maxHeight=caps.MaxTextureHeight; + + if (!supportsDynamicTex) { + logI("no support for dynamic textures"); + } + } + + result=device->CreateVertexBuffer(sizeof(WipeVertex)*4,0,D3DFVF_XYZ|D3DFVF_DIFFUSE,D3DPOOL_DEFAULT,&wipeBuf,NULL); + + if (result!=D3D_OK) { + logE("could not create wipe buffer! %.8x",result); } SDL_GetWindowSize(win,&outW,&outH); @@ -295,6 +417,10 @@ void FurnaceGUIRenderDX9::initGUI(SDL_Window* win) { } bool FurnaceGUIRenderDX9::quit() { + if (wipeBuf) { + wipeBuf->Release(); + wipeBuf=NULL; + } if (device) { device->Release(); device=NULL; diff --git a/src/gui/render/renderDX9.h b/src/gui/render/renderDX9.h index 829a17519..c64db3e84 100644 --- a/src/gui/render/renderDX9.h +++ b/src/gui/render/renderDX9.h @@ -26,6 +26,7 @@ struct FurnaceGUIRenderDX9Private { }; #else typedef void IDirect3D9; +typedef void IDirect3DVertexBuffer9; typedef void FurnaceGUIRenderDX9Private; #endif @@ -33,6 +34,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { IDirect3D9* iface; IDirect3DDevice9* device; FurnaceGUIRenderDX9Private* priv; + IDirect3DVertexBuffer9* wipeBuf; int outW, outH, swapInterval; @@ -82,6 +84,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { iface(NULL), device(NULL), priv(NULL), + wipeBuf(NULL), outW(0), outH(0), swapInterval(1), From 850e00059adf13a93a1408da60976fa4b9163cb3 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 14 May 2024 13:05:25 -0500 Subject: [PATCH 11/36] DirectX 9 backend, part 10 KAD BGKBY EA HEATK SBEKE S KH --- src/gui/render/renderDX9.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 492aa23ca..6ecf3c39e 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -88,7 +88,7 @@ bool FurnaceGUIRenderDX9::unlockTexture(FurnaceGUITexture* which) { bool FurnaceGUIRenderDX9::updateTexture(FurnaceGUITexture* which, void* data, int pitch) { FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; - IDirect3DTexture9* which=NULL; + IDirect3DTexture9* crap=NULL; if (t->texPre==NULL) { // update by locking @@ -96,14 +96,14 @@ bool FurnaceGUIRenderDX9::updateTexture(FurnaceGUITexture* which, void* data, in logW("updating static texture but texPre does not exist!"); return false; } - which=t->tex; + crap=t->tex; } else { // update by calling UpdateTexture - which=t->texPre; + crap=t->texPre; } D3DLOCKED_RECT lockedRect; - HRESULT result=which->LockRect(0,&lockedRect,NULL,D3DLOCK_DISCARD); + HRESULT result=crap->LockRect(0,&lockedRect,NULL,D3DLOCK_DISCARD); if (result!=D3D_OK) { logW("could not update texture (lock)! %.8x",result); return false; @@ -123,7 +123,7 @@ bool FurnaceGUIRenderDX9::updateTexture(FurnaceGUITexture* which, void* data, in } } - which->UnlockRect(0); + crap->UnlockRect(0); if (t->texPre!=NULL) { result=t->tex->AddDirtyRect(NULL); @@ -279,7 +279,10 @@ void FurnaceGUIRenderDX9::wipe(float alpha) { view.Height=outH; view.MinZ=0.0f; view.MaxZ=1.0f; - device->SetViewport(view); + result=device->SetViewport(&view); + if (result!=D3D_OK) { + logW("could not set viewport! %.8x",result); + } unsigned int color=alpha*255; From 3420cae9a2bdc170cef4975d34757b662c2bbcea Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 14 May 2024 13:32:11 -0500 Subject: [PATCH 12/36] test build 1 --- src/engine/engine.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index ace57ec76..157532b64 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -52,10 +52,10 @@ class DivWorkPool; #define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock(); #define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false; -//#define DIV_UNSTABLE +#define DIV_UNSTABLE -#define DIV_VERSION "0.6.3" -#define DIV_ENGINE_VERSION 201 +#define DIV_VERSION "DX9 Test I" +#define DIV_ENGINE_VERSION 202 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 From 8cfd37b6f51d373d1f48dd742de56ca07edb9c25 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 14 May 2024 14:11:39 -0500 Subject: [PATCH 13/36] test build 2 --- src/engine/engine.h | 4 ++-- src/gui/render/renderDX9.cpp | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 157532b64..80bdadb9f 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "DX9 Test I" -#define DIV_ENGINE_VERSION 202 +#define DIV_VERSION "DX9 Test II" +#define DIV_ENGINE_VERSION 203 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 6ecf3c39e..66efdf0e6 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -382,10 +382,14 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { HRESULT result=iface->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,window,D3DCREATE_HARDWARE_VERTEXPROCESSING,&priv->present,&device); if (result!=D3D_OK) { - logE("could not create device! %.8x",result); - iface->Release(); - iface=NULL; - return false; + logW("no hardware vertex processing!"); + result=iface->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,window,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&priv->present,&device); + if (result!=D3D_OK) { + logE("could not create device! %.8x",result); + iface->Release(); + iface=NULL; + return false; + } } D3DCAPS9 caps; From 4247faa97c4daad1ebef16bbb52bc49eb194b667 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 14 May 2024 15:06:06 -0500 Subject: [PATCH 14/36] fix possible crash when texture size is 0 --- src/gui/intro.cpp | 2 ++ src/gui/render/renderDX9.cpp | 4 ++++ src/gui/render/renderGL1.cpp | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/gui/intro.cpp b/src/gui/intro.cpp index cbb4ff042..f191d4b34 100644 --- a/src/gui/intro.cpp +++ b/src/gui/intro.cpp @@ -27,6 +27,8 @@ void FurnaceGUI::drawImage(ImDrawList* dl, FurnaceGUIImages image, const ImVec2& FurnaceGUIImage* imgI=getImage(image); FurnaceGUITexture* img=getTexture(image); + if (img==NULL) return; + float squareSize=MAX(introMax.x-introMin.x,introMax.y-introMin.y); float uDiff=uvMax.x-uvMin.x; float vDiff=uvMax.y-uvMin.y; diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 66efdf0e6..a2bba061c 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -50,11 +50,15 @@ ImTextureID FurnaceGUIRenderDX9::getTextureID(FurnaceGUITexture* which) { float FurnaceGUIRenderDX9::getTextureU(FurnaceGUITexture* which) { FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + if (which==NULL) return 0.0; + if (t->widthReal<1) return 0.0f; return (float)t->width/(float)t->widthReal; } float FurnaceGUIRenderDX9::getTextureV(FurnaceGUITexture* which) { FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + if (which==NULL) return 0.0; + if (t->heightReal<1) return 0.0f; return (float)t->height/(float)t->heightReal; } diff --git a/src/gui/render/renderGL1.cpp b/src/gui/render/renderGL1.cpp index 9fb4485b5..66aa35cdc 100644 --- a/src/gui/render/renderGL1.cpp +++ b/src/gui/render/renderGL1.cpp @@ -46,11 +46,13 @@ ImTextureID FurnaceGUIRenderGL1::getTextureID(FurnaceGUITexture* which) { float FurnaceGUIRenderGL1::getTextureU(FurnaceGUITexture* which) { FurnaceGL1Texture* t=(FurnaceGL1Texture*)which; + if (t->widthReal<1) return 0.0f; return (float)t->width/(float)t->widthReal; } float FurnaceGUIRenderGL1::getTextureV(FurnaceGUITexture* which) { FurnaceGL1Texture* t=(FurnaceGL1Texture*)which; + if (t->heightReal<1) return 0.0f; return (float)t->height/(float)t->heightReal; } From a34f768e5a11faf2ec6d277c74c8c69e03c9e20f Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 14 May 2024 15:32:39 -0500 Subject: [PATCH 15/36] test build 3 --- src/engine/engine.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 80bdadb9f..f69eb512c 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "DX9 Test II" -#define DIV_ENGINE_VERSION 203 +#define DIV_VERSION "DX9 Test III" +#define DIV_ENGINE_VERSION 204 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 From 11157825b277add5344d2d2d9d355e878a758656 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 14 May 2024 16:09:24 -0500 Subject: [PATCH 16/36] test build 4 --- src/engine/engine.h | 4 ++-- src/gui/render/renderDX9.cpp | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index f69eb512c..230b8daee 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "DX9 Test III" -#define DIV_ENGINE_VERSION 204 +#define DIV_VERSION "DX9 Test IV" +#define DIV_ENGINE_VERSION 205 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index a2bba061c..81bb57859 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -370,12 +370,17 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { priv=new FurnaceGUIRenderDX9Private; + SDL_GetWindowSize(win,&outW,&outH); + memset(&priv->present,0,sizeof(D3DPRESENT_PARAMETERS)); priv->present.Windowed=TRUE; priv->present.SwapEffect=D3DSWAPEFFECT_DISCARD; + priv->present.BackBufferWidth=outW; + priv->present.BackBufferHeight=outH; + priv->present.BackBufferCount=1; priv->present.BackBufferFormat=D3DFMT_UNKNOWN; - priv->present.EnableAutoDepthStencil=TRUE; - priv->present.AutoDepthStencilFormat=D3DFMT_D16; + //priv->present.EnableAutoDepthStencil=TRUE; + //priv->present.AutoDepthStencilFormat=D3DFMT_D16; if (swapInt>0) { priv->present.PresentationInterval=D3DPRESENT_INTERVAL_ONE; } else { @@ -417,8 +422,6 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { logE("could not create wipe buffer! %.8x",result); } - SDL_GetWindowSize(win,&outW,&outH); - return true; } From 60181c33040d6538a180d59536840628454d5e84 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 14 May 2024 16:37:56 -0500 Subject: [PATCH 17/36] test build 5 square only handling --- src/engine/engine.h | 4 ++-- src/gui/render/renderDX9.cpp | 11 +++++++++++ src/gui/render/renderDX9.h | 3 ++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 230b8daee..b808e26e9 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "DX9 Test IV" -#define DIV_ENGINE_VERSION 205 +#define DIV_VERSION "DX9 Test V" +#define DIV_ENGINE_VERSION 206 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 81bb57859..2e81a2a2b 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -156,6 +156,13 @@ FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, i if ((heightReal&(heightReal-1))!=0) { heightReal=1<heightReal) { + heightReal=widthReal; + } else { + widthReal=heightReal; + } + } logV("width: %d (requested)... %d (actual)",width,widthReal); logV("height: %d (requested)... %d (actual)",height,heightReal); @@ -407,6 +414,7 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { if (result==D3D_OK) { supportsDynamicTex=(caps.Caps2&D3DCAPS2_DYNAMICTEXTURES); + squareTex=(caps.TextureCaps&D3DPTEXTURECAPS_SQUAREONLY); supportsVSync=(caps.PresentationIntervals&D3DPRESENT_INTERVAL_ONE); maxWidth=caps.MaxTextureWidth; maxHeight=caps.MaxTextureHeight; @@ -414,6 +422,9 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { if (!supportsDynamicTex) { logI("no support for dynamic textures"); } + if (squareTex) { + logI("square textures only"); + } } result=device->CreateVertexBuffer(sizeof(WipeVertex)*4,0,D3DFVF_XYZ|D3DFVF_DIFFUSE,D3DPOOL_DEFAULT,&wipeBuf,NULL); diff --git a/src/gui/render/renderDX9.h b/src/gui/render/renderDX9.h index c64db3e84..f412d1943 100644 --- a/src/gui/render/renderDX9.h +++ b/src/gui/render/renderDX9.h @@ -38,7 +38,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { int outW, outH, swapInterval; - bool dead, haveScene, supportsDynamicTex, supportsVSync, mustResize; + bool dead, haveScene, supportsDynamicTex, supportsVSync, mustResize, squareTex; // SHADERS // @@ -93,6 +93,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { supportsDynamicTex(false), supportsVSync(false), mustResize(false), + squareTex(false), maxWidth(8192), maxHeight(8192) { } From 71786d0f7cf2994a5af8dfc43436f40ccbaad9f9 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 14 May 2024 20:51:15 -0500 Subject: [PATCH 18/36] comment --- src/gui/render/renderDX9.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 2e81a2a2b..e91e43e07 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -281,6 +281,8 @@ struct WipeVertex { void FurnaceGUIRenderDX9::wipe(float alpha) { if (wipeBuf==NULL) return; + /* + HRESULT result=device->BeginScene(); if (result==D3D_OK) { D3DVIEWPORT9 view; @@ -316,6 +318,7 @@ void FurnaceGUIRenderDX9::wipe(float alpha) { device->EndScene(); } + */ } bool FurnaceGUIRenderDX9::getOutputSize(int& w, int& h) { From 540cbbd12914a7e38b57e9987080cb1d68f25671 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 15 May 2024 00:02:22 -0500 Subject: [PATCH 19/36] no way --- src/gui/render/renderDX9.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index e91e43e07..ea16a9af3 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -168,7 +168,7 @@ FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, i if (!supportsDynamicTex) dynamic=false; - HRESULT result=device->CreateTexture(widthReal,heightReal,1,dynamic?D3DUSAGE_DYNAMIC:0,D3DFMT_A8B8G8R8,D3DPOOL_DEFAULT,&tex,NULL); + HRESULT result=device->CreateTexture(widthReal,heightReal,1,dynamic?D3DUSAGE_DYNAMIC:0,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&tex,NULL); if (result!=D3D_OK) { logW("could not create texture! %.8x",result); @@ -176,7 +176,7 @@ FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, i } if (!dynamic) { - HRESULT result=device->CreateTexture(widthReal,heightReal,1,0,D3DFMT_A8B8G8R8,D3DPOOL_SYSTEMMEM,&texPre,NULL); + HRESULT result=device->CreateTexture(widthReal,heightReal,1,0,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM,&texPre,NULL); if (result!=D3D_OK) { logW("could not create pre-texture! %.8x",result); From 394d5d6583271e8c5dae36477c93e61f3023ea67 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 15 May 2024 02:48:18 -0500 Subject: [PATCH 20/36] prepare to handle other texture formats required for DirectX 9... --- src/gui/chanOsc.cpp | 2 +- src/gui/debugWindow.cpp | 6 +++--- src/gui/gui.cpp | 12 ++++++++++++ src/gui/gui.h | 13 ++++++++++++- src/gui/image.cpp | 2 +- src/gui/render/abstract.cpp | 10 +++++++++- src/gui/render/renderDX11.cpp | 24 ++++++++++++++++++++++-- src/gui/render/renderDX11.h | 3 ++- src/gui/render/renderDX9.cpp | 11 ++++++++++- src/gui/render/renderDX9.h | 3 ++- src/gui/render/renderGL.cpp | 10 +++++++++- src/gui/render/renderGL.h | 3 ++- src/gui/render/renderGL1.cpp | 10 +++++++++- src/gui/render/renderGL1.h | 3 ++- src/gui/render/renderMetal.h | 3 ++- src/gui/render/renderMetal.mm | 10 +++++++++- src/gui/render/renderSDL.cpp | 10 +++++++++- src/gui/render/renderSDL.h | 3 ++- src/gui/render/renderSoftware.cpp | 10 +++++++++- src/gui/render/renderSoftware.h | 3 ++- src/gui/sampleEdit.cpp | 2 +- src/gui/tutorial.cpp | 2 +- 22 files changed, 131 insertions(+), 24 deletions(-) diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index bb7e345be..111c59b65 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -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!"); diff --git a/src/gui/debugWindow.cpp b/src/gui/debugWindow.cpp index fdaf3b066..53b8aa9ae 100644 --- a/src/gui/debugWindow.cpp +++ b/src/gui/debugWindow.cpp @@ -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; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 4cfc563ce..efb4b3a6d 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -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!"); diff --git a/src/gui/gui.h b/src/gui/gui.h index e29c7e3b6..dcdceaf0d 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -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; diff --git a/src/gui/image.cpp b/src/gui/image.cpp index a31c1dd9f..d8cfa149b 100644 --- a/src/gui/image.cpp +++ b/src/gui/image.cpp @@ -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; diff --git a/src/gui/render/abstract.cpp b/src/gui/render/abstract.cpp index 48710cb2f..05ec3358c 100644 --- a/src/gui/render/abstract.cpp +++ b/src/gui/render/abstract.cpp @@ -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"; } diff --git a/src/gui/render/renderDX11.cpp b/src/gui/render/renderDX11.cpp index 75ff58fc9..31d9654ff 100644 --- a/src/gui/render/renderDX11.cpp +++ b/src/gui/render/renderDX11.cpp @@ -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"; } diff --git a/src/gui/render/renderDX11.h b/src/gui/render/renderDX11.h index 1fd015122..4b24a525d 100644 --- a/src/gui/render/renderDX11.h +++ b/src/gui/render/renderDX11.h @@ -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(); diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index ea16a9af3..8e1fefe83 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -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<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(); } diff --git a/src/gui/render/renderGL.h b/src/gui/render/renderGL.h index 4664bec34..7970158b3 100644 --- a/src/gui/render/renderGL.h +++ b/src/gui/render/renderGL.h @@ -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(); diff --git a/src/gui/render/renderGL1.cpp b/src/gui/render/renderGL1.cpp index 66aa35cdc..bc6be7301 100644 --- a/src/gui/render/renderGL1.cpp +++ b/src/gui/render/renderGL1.cpp @@ -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"; } diff --git a/src/gui/render/renderGL1.h b/src/gui/render/renderGL1.h index f6081be6a..ee545fde8 100644 --- a/src/gui/render/renderGL1.h +++ b/src/gui/render/renderGL1.h @@ -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(); diff --git a/src/gui/render/renderMetal.h b/src/gui/render/renderMetal.h index 8aaa88d89..e77ebc002 100644 --- a/src/gui/render/renderMetal.h +++ b/src/gui/render/renderMetal.h @@ -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(); diff --git a/src/gui/render/renderMetal.mm b/src/gui/render/renderMetal.mm index 8649b66a0..dde706810 100644 --- a/src/gui/render/renderMetal.mm +++ b/src/gui/render/renderMetal.mm @@ -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"; } diff --git a/src/gui/render/renderSDL.cpp b/src/gui/render/renderSDL.cpp index a5f95ead9..49f1a1956 100644 --- a/src/gui/render/renderSDL.cpp +++ b/src/gui/render/renderSDL.cpp @@ -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"; } diff --git a/src/gui/render/renderSDL.h b/src/gui/render/renderSDL.h index 46a47559a..de14f8731 100644 --- a/src/gui/render/renderSDL.h +++ b/src/gui/render/renderSDL.h @@ -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(); diff --git a/src/gui/render/renderSoftware.cpp b/src/gui/render/renderSoftware.cpp index 8ca812661..d18569c15 100644 --- a/src/gui/render/renderSoftware.cpp +++ b/src/gui/render/renderSoftware.cpp @@ -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"; } diff --git a/src/gui/render/renderSoftware.h b/src/gui/render/renderSoftware.h index 05315dab8..cc03bc256 100644 --- a/src/gui/render/renderSoftware.h +++ b/src/gui/render/renderSoftware.h @@ -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(); diff --git a/src/gui/sampleEdit.cpp b/src/gui/sampleEdit.cpp index b5bf8f736..e646323db 100644 --- a/src/gui/sampleEdit.cpp +++ b/src/gui/sampleEdit.cpp @@ -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) { diff --git a/src/gui/tutorial.cpp b/src/gui/tutorial.cpp index 690cff7bd..f9232e6b7 100644 --- a/src/gui/tutorial.cpp +++ b/src/gui/tutorial.cpp @@ -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) { From f51ad1cf1f08b0997c5389b332667726dcee25ed Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 15 May 2024 02:48:54 -0500 Subject: [PATCH 21/36] test build 6 --- src/engine/engine.h | 4 ++-- src/gui/render/renderDX11.cpp | 8 +------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index b808e26e9..630914e4f 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "DX9 Test V" -#define DIV_ENGINE_VERSION 206 +#define DIV_VERSION "DX9 Test VI" +#define DIV_ENGINE_VERSION 207 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/gui/render/renderDX11.cpp b/src/gui/render/renderDX11.cpp index 31d9654ff..71b9a6df0 100644 --- a/src/gui/render/renderDX11.cpp +++ b/src/gui/render/renderDX11.cpp @@ -221,12 +221,6 @@ FurnaceGUITexture* FurnaceGUIRenderDX11::createTexture(bool dynamic, int width, 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; @@ -394,7 +388,7 @@ int FurnaceGUIRenderDX11::getMaxTextureHeight() { } unsigned int FurnaceGUIRenderDX11::getTextureFormats() { - return GUI_TEXFORMAT_ABGR32|GUI_TEXFORMAT_ARGB32|GUI_TEXFORMAT_BGRA32|GUI_TEXFORMAT_RGBA32; + return GUI_TEXFORMAT_ABGR32|GUI_TEXFORMAT_ARGB32; } const char* FurnaceGUIRenderDX11::getBackendName() { From a4cba0f05cc9b4aa76224fb24d7bc0caec78fa0f Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 15 May 2024 04:08:50 -0500 Subject: [PATCH 22/36] handle other texture formats --- src/gui/image.cpp | 38 +++++++++++++++++++++++++++++++ src/gui/render/renderDX11.cpp | 8 +++++++ src/gui/render/renderDX11.h | 1 + src/gui/render/renderDX9.cpp | 8 +++++++ src/gui/render/renderDX9.h | 1 + src/gui/render/renderGL.cpp | 8 +++++++ src/gui/render/renderGL.h | 1 + src/gui/render/renderGL1.cpp | 8 +++++++ src/gui/render/renderGL1.h | 1 + src/gui/render/renderMetal.h | 1 + src/gui/render/renderMetal.mm | 7 ++++++ src/gui/render/renderSDL.cpp | 10 +++++++- src/gui/render/renderSDL.h | 1 + src/gui/render/renderSoftware.cpp | 10 +++++++- src/gui/render/renderSoftware.h | 1 + src/gui/sampleEdit.cpp | 33 +++++++++++++++++++++++++++ 16 files changed, 135 insertions(+), 2 deletions(-) diff --git a/src/gui/image.cpp b/src/gui/image.cpp index d8cfa149b..980929e77 100644 --- a/src/gui/image.cpp +++ b/src/gui/image.cpp @@ -101,6 +101,44 @@ FurnaceGUIImage* FurnaceGUI::getImage(FurnaceGUIImages image) { } #endif + if (ret->ch==4) { + size_t total=ret->width*ret->height*ret->ch; + switch (bestTexFormat) { + case GUI_TEXFORMAT_ARGB32: + for (size_t i=0; idata[i]^=ret->data[i|2]; + ret->data[i|2]^=ret->data[i]; + ret->data[i]^=ret->data[i|2]; + } + break; + case GUI_TEXFORMAT_BGRA32: + for (size_t i=0; idata[i]^=ret->data[i|3]; + ret->data[i|3]^=ret->data[i]; + ret->data[i]^=ret->data[i|3]; + ret->data[i|1]^=ret->data[i|2]; + ret->data[i|2]^=ret->data[i|1]; + ret->data[i|1]^=ret->data[i|2]; + ret->data[i|1]^=ret->data[i|3]; + ret->data[i|3]^=ret->data[i|1]; + ret->data[i|1]^=ret->data[i|3]; + } + break; + case GUI_TEXFORMAT_RGBA32: + for (size_t i=0; idata[i]^=ret->data[i|3]; + ret->data[i|3]^=ret->data[i]; + ret->data[i]^=ret->data[i|3]; + ret->data[i|1]^=ret->data[i|2]; + ret->data[i|2]^=ret->data[i|1]; + ret->data[i|1]^=ret->data[i|2]; + } + break; + default: + break; + } + } + images[image]=ret; } diff --git a/src/gui/render/renderDX11.cpp b/src/gui/render/renderDX11.cpp index 71b9a6df0..a05220124 100644 --- a/src/gui/render/renderDX11.cpp +++ b/src/gui/render/renderDX11.cpp @@ -75,6 +75,7 @@ class FurnaceDXTexture: public FurnaceGUITexture { ID3D11Texture2D* tex; ID3D11ShaderResourceView* view; int width, height; + FurnaceGUITextureFormat format; unsigned char* lockedData; bool dynamic; FurnaceDXTexture(): @@ -82,6 +83,7 @@ class FurnaceDXTexture: public FurnaceGUITexture { view(NULL), width(0), height(0), + format(GUI_TEXFORMAT_UNKNOWN), lockedData(NULL), dynamic(false) {} }; @@ -147,6 +149,11 @@ ImTextureID FurnaceGUIRenderDX11::getTextureID(FurnaceGUITexture* which) { return (ImTextureID)t->view; } +FurnaceGUITextureFormat FurnaceGUIRenderDX11::getTextureFormat(FurnaceGUITexture* which) { + FurnaceDXTexture* t=(FurnaceDXTexture*)which; + return t->format; +} + bool FurnaceGUIRenderDX11::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { FurnaceDXTexture* t=(FurnaceDXTexture*)which; if (t->lockedData!=NULL) return false; @@ -256,6 +263,7 @@ FurnaceGUITexture* FurnaceGUIRenderDX11::createTexture(bool dynamic, int width, ret->tex=tex; ret->view=view; ret->dynamic=dynamic; + ret->format=format; return ret; } diff --git a/src/gui/render/renderDX11.h b/src/gui/render/renderDX11.h index 4b24a525d..3243999f1 100644 --- a/src/gui/render/renderDX11.h +++ b/src/gui/render/renderDX11.h @@ -64,6 +64,7 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender { public: ImTextureID getTextureID(FurnaceGUITexture* which); + FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which); bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); bool unlockTexture(FurnaceGUITexture* which); bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 8e1fefe83..68f1dd760 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -30,6 +30,7 @@ class FurnaceDX9Texture: public FurnaceGUITexture { IDirect3DTexture9* tex; IDirect3DTexture9* texPre; int width, height, widthReal, heightReal; + FurnaceGUITextureFormat format; unsigned char* lockedData; bool dynamic; FurnaceDX9Texture(): @@ -39,6 +40,7 @@ class FurnaceDX9Texture: public FurnaceGUITexture { height(0), widthReal(0), heightReal(0), + format(GUI_TEXFORMAT_UNKNOWN), lockedData(NULL), dynamic(false) {} }; @@ -62,6 +64,11 @@ float FurnaceGUIRenderDX9::getTextureV(FurnaceGUITexture* which) { return (float)t->height/(float)t->heightReal; } +FurnaceGUITextureFormat FurnaceGUIRenderDX9::getTextureFormat(FurnaceGUITexture* which) { + FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + return t->format; +} + bool FurnaceGUIRenderDX9::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; D3DLOCKED_RECT lockedRect; @@ -198,6 +205,7 @@ FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, i ret->tex=tex; ret->texPre=texPre; ret->dynamic=dynamic; + ret->format=format; return ret; } diff --git a/src/gui/render/renderDX9.h b/src/gui/render/renderDX9.h index ad215ef60..36d5c08e2 100644 --- a/src/gui/render/renderDX9.h +++ b/src/gui/render/renderDX9.h @@ -49,6 +49,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { ImTextureID getTextureID(FurnaceGUITexture* which); float getTextureU(FurnaceGUITexture* which); float getTextureV(FurnaceGUITexture* which); + FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which); bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); bool unlockTexture(FurnaceGUITexture* which); bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); diff --git a/src/gui/render/renderGL.cpp b/src/gui/render/renderGL.cpp index e5ac9afa3..161b36b2e 100644 --- a/src/gui/render/renderGL.cpp +++ b/src/gui/render/renderGL.cpp @@ -65,11 +65,13 @@ class FurnaceGLTexture: public FurnaceGUITexture { public: GLuint id; int width, height; + FurnaceGUITextureFormat format; unsigned char* lockedData; FurnaceGLTexture(): id(0), width(0), height(0), + format(GUI_TEXFORMAT_UNKNOWN), lockedData(NULL) {} }; @@ -281,6 +283,11 @@ ImTextureID FurnaceGUIRenderGL::getTextureID(FurnaceGUITexture* which) { return (ImTextureID)ret; } +FurnaceGUITextureFormat FurnaceGUIRenderGL::getTextureFormat(FurnaceGUITexture* which) { + FurnaceGLTexture* t=(FurnaceGLTexture*)which; + return t->format; +} + bool FurnaceGUIRenderGL::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { FurnaceGLTexture* t=(FurnaceGLTexture*)which; if (t->lockedData!=NULL) return false; @@ -334,6 +341,7 @@ FurnaceGUITexture* FurnaceGUIRenderGL::createTexture(bool dynamic, int width, in C(furActiveTexture(GL_TEXTURE0)); t->width=width; t->height=height; + t->format=format; return t; } diff --git a/src/gui/render/renderGL.h b/src/gui/render/renderGL.h index 7970158b3..0cf861596 100644 --- a/src/gui/render/renderGL.h +++ b/src/gui/render/renderGL.h @@ -56,6 +56,7 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender { public: ImTextureID getTextureID(FurnaceGUITexture* which); + FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which); bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); bool unlockTexture(FurnaceGUITexture* which); bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); diff --git a/src/gui/render/renderGL1.cpp b/src/gui/render/renderGL1.cpp index bc6be7301..0ebf8b391 100644 --- a/src/gui/render/renderGL1.cpp +++ b/src/gui/render/renderGL1.cpp @@ -29,6 +29,7 @@ class FurnaceGL1Texture: public FurnaceGUITexture { public: GLuint id; int width, height, widthReal, heightReal; + FurnaceGUITextureFormat format; unsigned char* lockedData; FurnaceGL1Texture(): id(0), @@ -36,6 +37,7 @@ class FurnaceGL1Texture: public FurnaceGUITexture { height(0), widthReal(0), heightReal(0), + format(GUI_TEXFORMAT_UNKNOWN), lockedData(NULL) {} }; @@ -56,6 +58,11 @@ float FurnaceGUIRenderGL1::getTextureV(FurnaceGUITexture* which) { return (float)t->height/(float)t->heightReal; } +FurnaceGUITextureFormat FurnaceGUIRenderGL1::getTextureFormat(FurnaceGUITexture* which) { + FurnaceGL1Texture* t=(FurnaceGL1Texture*)which; + return t->format; +} + bool FurnaceGUIRenderGL1::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { FurnaceGL1Texture* t=(FurnaceGL1Texture*)which; if (t->lockedData!=NULL) return false; @@ -125,6 +132,7 @@ FurnaceGUITexture* FurnaceGUIRenderGL1::createTexture(bool dynamic, int width, i t->height=height; t->widthReal=widthReal; t->heightReal=heightReal; + t->format=format; return t; } diff --git a/src/gui/render/renderGL1.h b/src/gui/render/renderGL1.h index ee545fde8..9b3b6d2d3 100644 --- a/src/gui/render/renderGL1.h +++ b/src/gui/render/renderGL1.h @@ -32,6 +32,7 @@ class FurnaceGUIRenderGL1: public FurnaceGUIRender { ImTextureID getTextureID(FurnaceGUITexture* which); float getTextureU(FurnaceGUITexture* which); float getTextureV(FurnaceGUITexture* which); + FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which); bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); bool unlockTexture(FurnaceGUITexture* which); bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); diff --git a/src/gui/render/renderMetal.h b/src/gui/render/renderMetal.h index e77ebc002..a0a249416 100644 --- a/src/gui/render/renderMetal.h +++ b/src/gui/render/renderMetal.h @@ -28,6 +28,7 @@ class FurnaceGUIRenderMetal: public FurnaceGUIRender { String vendorName, deviceName, apiVersion; public: ImTextureID getTextureID(FurnaceGUITexture* which); + FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which); bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); bool unlockTexture(FurnaceGUITexture* which); bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); diff --git a/src/gui/render/renderMetal.mm b/src/gui/render/renderMetal.mm index dde706810..ae27b3b89 100644 --- a/src/gui/render/renderMetal.mm +++ b/src/gui/render/renderMetal.mm @@ -44,11 +44,13 @@ class FurnaceMetalTexture: public FurnaceGUITexture { public: id tex; int width, height; + FurnaceGUITextureFormat format; unsigned char* lockedData; FurnaceMetalTexture(): tex(NULL), width(0), height(0), + format(GUI_TEXFORMAT_UNKNOWN), lockedData(NULL) {} }; @@ -57,6 +59,11 @@ ImTextureID FurnaceGUIRenderMetal::getTextureID(FurnaceGUITexture* which) { return t->tex; } +FurnaceGUITextureFormat FurnaceGUIRenderMetal::getTextureFormat(FurnaceGUITexture* which) { + FurnaceMetalTexture* t=(FurnaceMetalTexture*)which; + return t->format; +} + bool FurnaceGUIRenderMetal::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { FurnaceMetalTexture* t=(FurnaceMetalTexture*)which; if (t->lockedData!=NULL) return false; diff --git a/src/gui/render/renderSDL.cpp b/src/gui/render/renderSDL.cpp index 49f1a1956..cb0a6a402 100644 --- a/src/gui/render/renderSDL.cpp +++ b/src/gui/render/renderSDL.cpp @@ -24,8 +24,10 @@ class FurnaceSDLTexture: public FurnaceGUITexture { public: SDL_Texture* tex; + FurnaceGUITextureFormat format; FurnaceSDLTexture(): - tex(NULL) {} + tex(NULL), + format(GUI_TEXFORMAT_UNKNOWN) {} }; ImTextureID FurnaceGUIRenderSDL::getTextureID(FurnaceGUITexture* which) { @@ -33,6 +35,11 @@ ImTextureID FurnaceGUIRenderSDL::getTextureID(FurnaceGUITexture* which) { return t->tex; } +FurnaceGUITextureFormat FurnaceGUIRenderSDL::getTextureFormat(FurnaceGUITexture* which) { + FurnaceSDLTexture* t=(FurnaceSDLTexture*)which; + return t->format; +} + bool FurnaceGUIRenderSDL::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { FurnaceSDLTexture* t=(FurnaceSDLTexture*)which; return SDL_LockTexture(t->tex,NULL,data,pitch)==0; @@ -61,6 +68,7 @@ FurnaceGUITexture* FurnaceGUIRenderSDL::createTexture(bool dynamic, int width, i if (t==NULL) return NULL; FurnaceSDLTexture* ret=new FurnaceSDLTexture; ret->tex=t; + ret->format=format; return ret; } diff --git a/src/gui/render/renderSDL.h b/src/gui/render/renderSDL.h index de14f8731..fa394dcac 100644 --- a/src/gui/render/renderSDL.h +++ b/src/gui/render/renderSDL.h @@ -26,6 +26,7 @@ class FurnaceGUIRenderSDL: public FurnaceGUIRender { bool swapIntervalSet; public: ImTextureID getTextureID(FurnaceGUITexture* which); + FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which); bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); bool unlockTexture(FurnaceGUITexture* which); bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); diff --git a/src/gui/render/renderSoftware.cpp b/src/gui/render/renderSoftware.cpp index d18569c15..d18c11aa2 100644 --- a/src/gui/render/renderSoftware.cpp +++ b/src/gui/render/renderSoftware.cpp @@ -24,8 +24,10 @@ class FurnaceSoftwareTexture: public FurnaceGUITexture { public: SWTexture* tex; + FurnaceGUITextureFormat format; FurnaceSoftwareTexture(): - tex(NULL) {} + tex(NULL), + format(GUI_TEXFORMAT_UNKNOWN) {} }; ImTextureID FurnaceGUIRenderSoftware::getTextureID(FurnaceGUITexture* which) { @@ -33,6 +35,11 @@ ImTextureID FurnaceGUIRenderSoftware::getTextureID(FurnaceGUITexture* which) { return t->tex; } +FurnaceGUITextureFormat FurnaceGUIRenderSoftware::getTextureFormat(FurnaceGUITexture* which) { + FurnaceSoftwareTexture* t=(FurnaceSoftwareTexture*)which; + return t->format; +} + bool FurnaceGUIRenderSoftware::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { FurnaceSoftwareTexture* t=(FurnaceSoftwareTexture*)which; if (!t->tex->managed) return false; @@ -59,6 +66,7 @@ FurnaceGUITexture* FurnaceGUIRenderSoftware::createTexture(bool dynamic, int wid } FurnaceSoftwareTexture* ret=new FurnaceSoftwareTexture; ret->tex=new SWTexture(width,height); + ret->format=format; return ret; } diff --git a/src/gui/render/renderSoftware.h b/src/gui/render/renderSoftware.h index cc03bc256..eef580aff 100644 --- a/src/gui/render/renderSoftware.h +++ b/src/gui/render/renderSoftware.h @@ -23,6 +23,7 @@ class FurnaceGUIRenderSoftware: public FurnaceGUIRender { SDL_Window* sdlWin; public: ImTextureID getTextureID(FurnaceGUITexture* which); + FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which); bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); bool unlockTexture(FurnaceGUITexture* which); bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); diff --git a/src/gui/sampleEdit.cpp b/src/gui/sampleEdit.cpp index e646323db..8f97d6beb 100644 --- a/src/gui/sampleEdit.cpp +++ b/src/gui/sampleEdit.cpp @@ -31,6 +31,15 @@ #include "sampleUtil.h" #include "util.h" +#define SWAP_COLOR_ARGB(x) \ + x=(x&0xff00ff00)|((x&0xff)<<16)|((x&0xff0000)>>16); + +#define SWAP_COLOR_BGRA(x) \ + x=((x&0xff0000000)>>24)|((x&0xffffff)<<8); + +#define SWAP_COLOR_RGBA(x) \ + x=((x&0xff)<<24)|((x&0xff00)<<8)|((x&0xff0000)>>8)|((x&0xff000000)>>24); + const double timeDivisors[10]={ 1000.0, 500.0, 200.0, 100.0, 50.0, 20.0, 10.0, 5.0, 2.0, 1.0 }; @@ -1501,6 +1510,30 @@ void FurnaceGUI::drawSampleEdit() { ImU32 bgColorLoop=ImGui::GetColorU32(uiColors[GUI_COLOR_SAMPLE_LOOP]); ImU32 lineColor=ImGui::GetColorU32(uiColors[GUI_COLOR_SAMPLE_FG]); ImU32 centerLineColor=ImGui::GetColorU32(uiColors[GUI_COLOR_SAMPLE_CENTER]); + + switch (rend->getTextureFormat(sampleTex)) { + case GUI_TEXFORMAT_ARGB32: + SWAP_COLOR_ARGB(bgColor); + SWAP_COLOR_ARGB(bgColorLoop); + SWAP_COLOR_ARGB(lineColor); + SWAP_COLOR_ARGB(centerLineColor); + break; + case GUI_TEXFORMAT_BGRA32: + SWAP_COLOR_BGRA(bgColor); + SWAP_COLOR_BGRA(bgColorLoop); + SWAP_COLOR_BGRA(lineColor); + SWAP_COLOR_BGRA(centerLineColor); + break; + case GUI_TEXFORMAT_RGBA32: + SWAP_COLOR_RGBA(bgColor); + SWAP_COLOR_RGBA(bgColorLoop); + SWAP_COLOR_RGBA(lineColor); + SWAP_COLOR_RGBA(centerLineColor); + break; + default: + break; + } + int ij=0; for (int i=0; i Date: Wed, 15 May 2024 14:35:35 -0500 Subject: [PATCH 23/36] possibly fix resize... --- src/gui/render/renderDX9.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 68f1dd760..8cc7412e6 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -229,6 +229,23 @@ void FurnaceGUIRenderDX9::resized(const SDL_Event& ev) { } void FurnaceGUIRenderDX9::clear(ImVec4 color) { + if (mustResize) { + logI("DX9: resizing buffers"); + ImGui_ImplDX9_InvalidateDeviceObjects(); + priv->present.BackBufferWidth=outW; + priv->present.BackBufferHeight=outH; + priv->present.BackBufferCount=1; + HRESULT result=device->Reset(&priv->present); + priv->present.BackBufferWidth=outW; + priv->present.BackBufferHeight=outH; + priv->present.BackBufferCount=1; + if (result==D3DERR_INVALIDCALL) { + logE("OH NO"); + } + ImGui_ImplDX9_CreateDeviceObjects(); + mustResize=false; + } + device->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,ImGui::ColorConvertFloat4ToU32(color),0,0); } @@ -237,19 +254,6 @@ void FurnaceGUIRenderDX9::present() { } bool FurnaceGUIRenderDX9::newFrame() { - if (mustResize) { - logI("DX9: resizing buffers"); - ImGui_ImplDX9_InvalidateDeviceObjects(); - priv->present.BackBufferWidth=outW; - priv->present.BackBufferHeight=outH; - HRESULT result=device->Reset(&priv->present); - if (result==D3DERR_INVALIDCALL) { - logE("OH NO"); - } - ImGui_ImplDX9_CreateDeviceObjects(); - mustResize=false; - } - return ImGui_ImplDX9_NewFrame(); } From 5ece0067280e22e27a22bee1049ce14eaa1adfca Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 15 May 2024 14:42:22 -0500 Subject: [PATCH 24/36] test build 7 --- src/engine/engine.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 630914e4f..3631331a2 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "DX9 Test VI" -#define DIV_ENGINE_VERSION 207 +#define DIV_VERSION "DX9 Test VII" +#define DIV_ENGINE_VERSION 208 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 From 8905a483610b320e3ec2fc1829fe9411070a6c0b Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 15 May 2024 17:22:48 -0500 Subject: [PATCH 25/36] test build 8 is this the fix --- src/engine/engine.h | 4 +-- src/gui/render/renderDX9.cpp | 47 ++++++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 3631331a2..62d4cbf7e 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "DX9 Test VII" -#define DIV_ENGINE_VERSION 208 +#define DIV_VERSION "DX9 Test VIII" +#define DIV_ENGINE_VERSION 209 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 8cc7412e6..a4afe7e54 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -45,6 +45,23 @@ class FurnaceDX9Texture: public FurnaceGUITexture { dynamic(false) {} }; +struct WipeVertex { + float x, y, z; + unsigned int color; + + WipeVertex(float _x, float _y, float _z, unsigned int c): + x(_x), + y(_y), + z(_z), + color(c) {} + WipeVertex(): + x(0), + y(0), + z(0), + color(0) {} +}; + + ImTextureID FurnaceGUIRenderDX9::getTextureID(FurnaceGUITexture* which) { FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; return (ImTextureID)t->tex; @@ -232,6 +249,12 @@ void FurnaceGUIRenderDX9::clear(ImVec4 color) { if (mustResize) { logI("DX9: resizing buffers"); ImGui_ImplDX9_InvalidateDeviceObjects(); + + if (wipeBuf!=NULL) { + wipeBuf->Release(); + wipeBuf=NULL; + } + priv->present.BackBufferWidth=outW; priv->present.BackBufferHeight=outH; priv->present.BackBufferCount=1; @@ -242,7 +265,15 @@ void FurnaceGUIRenderDX9::clear(ImVec4 color) { if (result==D3DERR_INVALIDCALL) { logE("OH NO"); } + ImGui_ImplDX9_CreateDeviceObjects(); + + result=device->CreateVertexBuffer(sizeof(WipeVertex)*4,0,D3DFVF_XYZ|D3DFVF_DIFFUSE,D3DPOOL_DEFAULT,&wipeBuf,NULL); + + if (result!=D3D_OK) { + logE("could not create wipe buffer! %.8x",result); + } + mustResize=false; } @@ -279,22 +310,6 @@ void FurnaceGUIRenderDX9::renderGUI() { } } -struct WipeVertex { - float x, y, z; - unsigned int color; - - WipeVertex(float _x, float _y, float _z, unsigned int c): - x(_x), - y(_y), - z(_z), - color(c) {} - WipeVertex(): - x(0), - y(0), - z(0), - color(0) {} -}; - void FurnaceGUIRenderDX9::wipe(float alpha) { if (wipeBuf==NULL) return; From d00cdabe6e4f7a1dcc7c5f1ea8f3fb11c3f4202b Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 15 May 2024 18:36:23 -0500 Subject: [PATCH 26/36] so we need to destroy textures --- src/gui/render/renderDX9.cpp | 42 +++++++++++++++++++++++++++++------- src/gui/render/renderDX9.h | 5 +---- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index a4afe7e54..720fc15c4 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -45,6 +45,11 @@ class FurnaceDX9Texture: public FurnaceGUITexture { dynamic(false) {} }; +struct FurnaceGUIRenderDX9Private { + D3DPRESENT_PARAMETERS present; + std::vector texPool; +}; + struct WipeVertex { float x, y, z; unsigned int color; @@ -223,13 +228,23 @@ FurnaceGUITexture* FurnaceGUIRenderDX9::createTexture(bool dynamic, int width, i ret->texPre=texPre; ret->dynamic=dynamic; ret->format=format; + + priv->texPool.push_back(ret); return ret; } bool FurnaceGUIRenderDX9::destroyTexture(FurnaceGUITexture* which) { FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; - t->tex->Release(); + if (t->texPre!=NULL) t->texPre->Release(); + if (t->tex!=NULL) t->tex->Release(); delete t; + + for (size_t i=0; itexPool.size(); i++) { + if (priv->texPool[i]==t) { + priv->texPool.erase(priv->texPool.begin()+i); + break; + } + } return true; } @@ -246,15 +261,32 @@ void FurnaceGUIRenderDX9::resized(const SDL_Event& ev) { } void FurnaceGUIRenderDX9::clear(ImVec4 color) { + device->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,ImGui::ColorConvertFloat4ToU32(color),0,0); +} + +void FurnaceGUIRenderDX9::present() { + device->Present(NULL,NULL,NULL,NULL); + if (mustResize) { logI("DX9: resizing buffers"); ImGui_ImplDX9_InvalidateDeviceObjects(); - if (wipeBuf!=NULL) { + if (wipeBuf) { wipeBuf->Release(); wipeBuf=NULL; } + for (FurnaceDX9Texture* i: priv->texPool) { + if (i->tex) { + i->tex->Release(); + i->tex=NULL; + } + if (i->texPre) { + i->texPre->Release(); + i->texPre=NULL; + } + } + priv->present.BackBufferWidth=outW; priv->present.BackBufferHeight=outH; priv->present.BackBufferCount=1; @@ -276,12 +308,6 @@ void FurnaceGUIRenderDX9::clear(ImVec4 color) { mustResize=false; } - - device->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,ImGui::ColorConvertFloat4ToU32(color),0,0); -} - -void FurnaceGUIRenderDX9::present() { - device->Present(NULL,NULL,NULL,NULL); } bool FurnaceGUIRenderDX9::newFrame() { diff --git a/src/gui/render/renderDX9.h b/src/gui/render/renderDX9.h index 36d5c08e2..c7cd4e1e5 100644 --- a/src/gui/render/renderDX9.h +++ b/src/gui/render/renderDX9.h @@ -20,10 +20,7 @@ #include "../gui.h" #ifdef INCLUDE_D3D9 #include - -struct FurnaceGUIRenderDX9Private { - D3DPRESENT_PARAMETERS present; -}; +struct FurnaceGUIRenderDX9Private; #else typedef void IDirect3D9; typedef void IDirect3DVertexBuffer9; From f66d723251c2ecaabb224aa4681569edac3dc404 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 15 May 2024 19:52:05 -0500 Subject: [PATCH 27/36] handle texture death finally fixes resize --- src/gui/gui.h | 1 + src/gui/image.cpp | 12 ++++++++++++ src/gui/render/abstract.cpp | 4 ++++ src/gui/render/renderDX9.cpp | 7 +++++++ src/gui/sampleEdit.cpp | 2 +- src/gui/tutorial.cpp | 3 +++ 6 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/gui/gui.h b/src/gui/gui.h index dcdceaf0d..b7a09e3b9 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1491,6 +1491,7 @@ class FurnaceGUIRender { virtual float getTextureU(FurnaceGUITexture* which); virtual float getTextureV(FurnaceGUITexture* which); virtual FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which); + virtual bool isTextureValid(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); diff --git a/src/gui/image.cpp b/src/gui/image.cpp index 980929e77..e526b43ed 100644 --- a/src/gui/image.cpp +++ b/src/gui/image.cpp @@ -53,7 +53,19 @@ FurnaceGUITexture* FurnaceGUI::getTexture(FurnaceGUIImages image, FurnaceGUIBlen if (img->data==NULL) return NULL; if (img->width<=0 || img->height<=0) return NULL; + bool createTex=false; + if (img->tex==NULL) { + createTex=true; + } else { + if (!rend->isTextureValid(img->tex)) { + rend->destroyTexture(img->tex); + img->tex=NULL; + createTex=true; + } + } + + if (createTex) { 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()); diff --git a/src/gui/render/abstract.cpp b/src/gui/render/abstract.cpp index 05ec3358c..90fc67a01 100644 --- a/src/gui/render/abstract.cpp +++ b/src/gui/render/abstract.cpp @@ -35,6 +35,10 @@ FurnaceGUITextureFormat FurnaceGUIRender::getTextureFormat(FurnaceGUITexture* wh return GUI_TEXFORMAT_UNKNOWN; } +bool FurnaceGUIRender::isTextureValid(FurnaceGUITexture* which) { + return (which!=NULL); +} + bool FurnaceGUIRender::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { return false; } diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 720fc15c4..5799d3e4b 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -91,6 +91,12 @@ FurnaceGUITextureFormat FurnaceGUIRenderDX9::getTextureFormat(FurnaceGUITexture* return t->format; } +bool FurnaceGUIRenderDX9::isTextureValid(FurnaceGUITexture* which) { + if (which==NULL) return false; + FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; + return (t->tex!=NULL); +} + bool FurnaceGUIRenderDX9::lockTexture(FurnaceGUITexture* which, void** data, int* pitch) { FurnaceDX9Texture* t=(FurnaceDX9Texture*)which; D3DLOCKED_RECT lockedRect; @@ -519,6 +525,7 @@ bool FurnaceGUIRenderDX9::quit() { iface->Release(); iface=NULL; } + priv->texPool.clear(); dead=false; return true; } diff --git a/src/gui/sampleEdit.cpp b/src/gui/sampleEdit.cpp index 8f97d6beb..4a85cdd06 100644 --- a/src/gui/sampleEdit.cpp +++ b/src/gui/sampleEdit.cpp @@ -1478,7 +1478,7 @@ void FurnaceGUI::drawSampleEdit() { } } - if (sampleTex==NULL || sampleTexW!=avail.x || sampleTexH!=avail.y) { + if (sampleTex==NULL || sampleTexW!=avail.x || sampleTexH!=avail.y || !rend->isTextureValid(sampleTex)) { if (sampleTex!=NULL) { rend->destroyTexture(sampleTex); sampleTex=NULL; diff --git a/src/gui/tutorial.cpp b/src/gui/tutorial.cpp index f9232e6b7..43ed2248d 100644 --- a/src/gui/tutorial.cpp +++ b/src/gui/tutorial.cpp @@ -792,6 +792,9 @@ void FurnaceGUI::drawTutorial() { } if (cvTex==NULL) { cvTex=rend->createTexture(true,320,224,false,bestTexFormat); + } else if (!rend->isTextureValid(cvTex)) { + rend->destroyTexture(cvTex); + cvTex=rend->createTexture(true,320,224,false,bestTexFormat); } if (cv->pleaseInitSongs) { From aea11233893a33787cd6597b22ff9a81437b4d99 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 15 May 2024 23:18:10 -0500 Subject: [PATCH 28/36] fix build --- src/gui/render/renderDX9.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/render/renderDX9.h b/src/gui/render/renderDX9.h index c7cd4e1e5..e9a8bef25 100644 --- a/src/gui/render/renderDX9.h +++ b/src/gui/render/renderDX9.h @@ -47,6 +47,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { float getTextureU(FurnaceGUITexture* which); float getTextureV(FurnaceGUITexture* which); FurnaceGUITextureFormat getTextureFormat(FurnaceGUITexture* which); + bool isTextureValid(FurnaceGUITexture* which); bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch); bool unlockTexture(FurnaceGUITexture* which); bool updateTexture(FurnaceGUITexture* which, void* data, int pitch); From 02fd841f676ff84556af275ddab036e620b80966 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 16 May 2024 02:28:49 -0500 Subject: [PATCH 29/36] handle device death --- src/gui/render/renderDX9.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 5799d3e4b..8642f15d4 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -271,7 +271,11 @@ void FurnaceGUIRenderDX9::clear(ImVec4 color) { } void FurnaceGUIRenderDX9::present() { - device->Present(NULL,NULL,NULL,NULL); + if (device->Present(NULL,NULL,NULL,NULL)==D3DERR_DEVICEREMOVED) { + logI("device is gone"); + dead=true; + return false; + } if (mustResize) { logI("DX9: resizing buffers"); @@ -302,6 +306,9 @@ void FurnaceGUIRenderDX9::present() { priv->present.BackBufferCount=1; if (result==D3DERR_INVALIDCALL) { logE("OH NO"); + dead=true; + mustResize=false; + return; } ImGui_ImplDX9_CreateDeviceObjects(); From 7413a1536934b24a7232b33171999f439a8033c9 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 16 May 2024 03:02:45 -0500 Subject: [PATCH 30/36] WIPE! --- .../imgui_patched/backends/imgui_impl_dx9.cpp | 14 ++- src/gui/render/renderDX9.cpp | 117 ++++++++++++------ src/gui/render/renderDX9.h | 3 +- 3 files changed, 89 insertions(+), 45 deletions(-) diff --git a/extern/imgui_patched/backends/imgui_impl_dx9.cpp b/extern/imgui_patched/backends/imgui_impl_dx9.cpp index d39f2a22e..90dbd168a 100644 --- a/extern/imgui_patched/backends/imgui_impl_dx9.cpp +++ b/extern/imgui_patched/backends/imgui_impl_dx9.cpp @@ -175,6 +175,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) } // Backup the DX9 state + /* IDirect3DStateBlock9* d3d9_state_block = nullptr; if (bd->pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0) return; @@ -182,26 +183,28 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) { d3d9_state_block->Release(); return; - } + }*/ // Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to) + /* D3DMATRIX last_world, last_view, last_projection; bd->pd3dDevice->GetTransform(D3DTS_WORLD, &last_world); bd->pd3dDevice->GetTransform(D3DTS_VIEW, &last_view); bd->pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection); + */ // Allocate buffers CUSTOMVERTEX* vtx_dst; ImDrawIdx* idx_dst; if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0) { - d3d9_state_block->Release(); + //d3d9_state_block->Release(); return; } if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0) { bd->pVB->Unlock(); - d3d9_state_block->Release(); + //d3d9_state_block->Release(); return; } @@ -282,13 +285,18 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, 0); // Restore the DX9 transform + // don't. I like this transform. + /* bd->pd3dDevice->SetTransform(D3DTS_WORLD, &last_world); bd->pd3dDevice->SetTransform(D3DTS_VIEW, &last_view); bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection); + */ // Restore the DX9 state + /* d3d9_state_block->Apply(); d3d9_state_block->Release(); + */ } bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index 8642f15d4..cd09562ac 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -271,10 +271,15 @@ void FurnaceGUIRenderDX9::clear(ImVec4 color) { } void FurnaceGUIRenderDX9::present() { + if (inScene) { + device->EndScene(); + inScene=false; + } + if (device->Present(NULL,NULL,NULL,NULL)==D3DERR_DEVICEREMOVED) { logI("device is gone"); dead=true; - return false; + return; } if (mustResize) { @@ -340,56 +345,86 @@ void FurnaceGUIRenderDX9::destroyFontsTexture() { } void FurnaceGUIRenderDX9::renderGUI() { - HRESULT result=device->BeginScene(); - if (result==D3D_OK) { - ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); - device->EndScene(); - } else { - logW("couldn't render GUI! %.8x",result); + if (!inScene) { + HRESULT result=device->BeginScene(); + if (result!=D3D_OK) { + logW("couldn't render GUI! %.8x",result); + return; + } + inScene=true; } + + ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); } void FurnaceGUIRenderDX9::wipe(float alpha) { if (wipeBuf==NULL) return; - /* + logV("WIPE..."); - HRESULT result=device->BeginScene(); - if (result==D3D_OK) { - D3DVIEWPORT9 view; - view.X=0; - view.Y=0; - view.Width=outW; - view.Height=outH; - view.MinZ=0.0f; - view.MaxZ=1.0f; - result=device->SetViewport(&view); + if (!inScene) { + HRESULT result=device->BeginScene(); if (result!=D3D_OK) { - logW("could not set viewport! %.8x",result); + logW("couldn't render GUI! %.8x",result); + return; } - - unsigned int color=alpha*255; - - void* lockedData; - WipeVertex vertex[4]; - vertex[0]=WipeVertex(0,0,0,color); - vertex[1]=WipeVertex(outW,0,0,color); - vertex[2]=WipeVertex(outW,outH,0,color); - vertex[3]=WipeVertex(0,outH,0,color); - - result=wipeBuf->Lock(0,0,&lockedData,D3DLOCK_DISCARD); - if (result==D3D_OK) { - memcpy(lockedData,vertex,sizeof(WipeVertex)*4); - wipeBuf->Unlock(); - - device->SetStreamSource(0,wipeBuf,0,sizeof(WipeVertex)); - device->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE); - device->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,1); - } - - device->EndScene(); + inScene=true; + } + + D3DVIEWPORT9 view; + view.X=0; + view.Y=0; + view.Width=outW; + view.Height=outH; + view.MinZ=0.0f; + view.MaxZ=1.0f; + HRESULT result=device->SetViewport(&view); + if (result!=D3D_OK) { + logW("could not set viewport! %.8x",result); + } + + unsigned char alphaU=alpha*255.0f; + unsigned int color=alphaU<<24; + + void* lockedData; + WipeVertex vertex[4]; + vertex[0]=WipeVertex(0,0,0,color); + vertex[1]=WipeVertex(outW,0,0,color); + vertex[2]=WipeVertex(outW,outH,0,color); + vertex[3]=WipeVertex(0,outH,0,color); + + result=wipeBuf->Lock(0,0,&lockedData,D3DLOCK_DISCARD); + if (result==D3D_OK) { + memcpy(lockedData,vertex,sizeof(WipeVertex)*4); + wipeBuf->Unlock(); + + result=device->SetRenderState(D3DRS_SCISSORTESTENABLE,FALSE); + if (result!=D3D_OK) { + logE("SHIT! scissor, %.8x",result); + } + result=device->SetTexture(0,NULL); + if (result!=D3D_OK) { + logE("SHIT! set texture, %.8x",result); + } + result=device->SetStreamSource(0,wipeBuf,0,sizeof(WipeVertex)); + if (result!=D3D_OK) { + logE("SHIT! set stream source, %.8x",result); + } + result=device->SetTexture(0,NULL); + if (result!=D3D_OK) { + logE("SHIT! set texture, %.8x",result); + } + result=device->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE); + if (result!=D3D_OK) { + logE("SHIT! set FVF, %.8x",result); + } + result=device->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2); + if (result!=D3D_OK) { + logE("SHIT! draw primitive, %.8x",result); + } + } else { + logE("SHIT! lock, %.8x",result); } - */ } bool FurnaceGUIRenderDX9::getOutputSize(int& w, int& h) { diff --git a/src/gui/render/renderDX9.h b/src/gui/render/renderDX9.h index e9a8bef25..3d46326e8 100644 --- a/src/gui/render/renderDX9.h +++ b/src/gui/render/renderDX9.h @@ -35,7 +35,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { int outW, outH, swapInterval; - bool dead, haveScene, supportsDynamicTex, supportsVSync, mustResize, squareTex; + bool dead, haveScene, supportsDynamicTex, supportsVSync, mustResize, squareTex, inScene; // SHADERS // @@ -94,6 +94,7 @@ class FurnaceGUIRenderDX9: public FurnaceGUIRender { supportsVSync(false), mustResize(false), squareTex(false), + inScene(false), maxWidth(8192), maxHeight(8192) { } From 580780bc66e3952db6da731b8f0457132e3450ee Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 16 May 2024 03:09:25 -0500 Subject: [PATCH 31/36] test build 9 --- src/engine/engine.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 62d4cbf7e..7f79ac189 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "DX9 Test VIII" -#define DIV_ENGINE_VERSION 209 +#define DIV_VERSION "DX9 Test IX" +#define DIV_ENGINE_VERSION 210 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 From 9d6d7a82fe44262b918c66cbebf3cd907dd5e793 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 16 May 2024 12:47:39 -0500 Subject: [PATCH 32/36] finally, finally fix VIA dumb drivers that claim to support 32-bit index but does not thanks wbcbz7 for diagnosis --- extern/imgui_patched/backends/imgui_impl_dx9.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/extern/imgui_patched/backends/imgui_impl_dx9.cpp b/extern/imgui_patched/backends/imgui_impl_dx9.cpp index 90dbd168a..8e6c75943 100644 --- a/extern/imgui_patched/backends/imgui_impl_dx9.cpp +++ b/extern/imgui_patched/backends/imgui_impl_dx9.cpp @@ -170,7 +170,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) { if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; } bd->IndexBufferSize = draw_data->TotalIdxCount + 10000; - if (bd->pd3dDevice->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0) + if (bd->pd3dDevice->CreateIndexBuffer(bd->IndexBufferSize * sizeof(unsigned short), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0) return; } @@ -195,13 +195,13 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) // Allocate buffers CUSTOMVERTEX* vtx_dst; - ImDrawIdx* idx_dst; + unsigned short* idx_dst; if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0) { //d3d9_state_block->Release(); return; } - if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0) + if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(unsigned short)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0) { bd->pVB->Unlock(); //d3d9_state_block->Release(); @@ -227,7 +227,14 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) vtx_dst++; vtx_src++; } - memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + if (sizeof(ImDrawIdx) == sizeof(unsigned short) { + memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); + } else { + // slower, but works on VIA + for (int i=0; iIdxBuffer.Size; i++) { + idx_dst[i]=cmd_list->IdxBuffer.Data[i]; + } + } idx_dst += cmd_list->IdxBuffer.Size; } bd->pVB->Unlock(); From b6ed27f394421ec79de4c34e34e69762e20279c2 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 16 May 2024 12:57:47 -0500 Subject: [PATCH 33/36] blind coding moment --- extern/imgui_patched/backends/imgui_impl_dx9.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/imgui_patched/backends/imgui_impl_dx9.cpp b/extern/imgui_patched/backends/imgui_impl_dx9.cpp index 8e6c75943..27fc73793 100644 --- a/extern/imgui_patched/backends/imgui_impl_dx9.cpp +++ b/extern/imgui_patched/backends/imgui_impl_dx9.cpp @@ -227,7 +227,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) vtx_dst++; vtx_src++; } - if (sizeof(ImDrawIdx) == sizeof(unsigned short) { + if (sizeof(ImDrawIdx) == sizeof(unsigned short)) { memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); } else { // slower, but works on VIA From 5a1f35b878e28f02866ffee11b2976b76c1ca377 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 16 May 2024 16:31:53 -0500 Subject: [PATCH 34/36] test build 10 --- scripts/release-winxp.sh | 2 +- src/engine/engine.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/release-winxp.sh b/scripts/release-winxp.sh index 134fc9f17..ec8e5d8d1 100755 --- a/scripts/release-winxp.sh +++ b/scripts/release-winxp.sh @@ -15,7 +15,7 @@ fi cd xpbuild # TODO: potential Arch-ism? -i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=ON -DWITH_RENDER_DX11=OFF -DSDL_SSE2=OFF -DSDL_SSE3=OFF -DENABLE_SSE=OFF -DENABLE_SSE2=OFF -DENABLE_AVX=OFF -DENABLE_AVX2=OFF -DUSE_BACKWARD=ON .. || exit 1 +i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=ON -DWITH_RENDER_DX11=OFF -DSDL_SSE2=OFF -DSDL_SSE3=OFF -DENABLE_SSE=OFF -DENABLE_SSE2=OFF -DENABLE_AVX=OFF -DENABLE_AVX2=OFF -DUSE_BACKWARD=ON -DCONSOLE_SUBSYSTEM=OFF .. || exit 1 make -j8 || exit 1 cd .. diff --git a/src/engine/engine.h b/src/engine/engine.h index 7f79ac189..acca36570 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "DX9 Test IX" -#define DIV_ENGINE_VERSION 210 +#define DIV_VERSION "DX9 Test X" +#define DIV_ENGINE_VERSION 211 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 From fa41c4982d423afe446e00135e0913899cf0ace3 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 16 May 2024 17:05:20 -0500 Subject: [PATCH 35/36] disable SSE on 32-bit Windows builds oh crap... --- scripts/release-win32.sh | 2 +- scripts/release-winxp.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/release-win32.sh b/scripts/release-win32.sh index 388ceb5aa..0126d213e 100755 --- a/scripts/release-win32.sh +++ b/scripts/release-win32.sh @@ -15,7 +15,7 @@ fi cd win32build # TODO: potential Arch-ism? -i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2 -march=i586" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type -march=i586" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=OFF -DWITH_RENDER_DX11=ON -DUSE_BACKWARD=ON -DSDL_SSE2=OFF -DSDL_SSE3=OFF -DENABLE_SSE=OFF -DENABLE_SSE2=OFF -DENABLE_AVX=OFF -DENABLE_AVX2=OFF .. || exit 1 +i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2 -march=i586" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type -march=i586" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=OFF -DWITH_RENDER_DX11=ON -DUSE_BACKWARD=ON -DSDL_SSE=OFF -DSDL_SSE2=OFF -DSDL_SSE3=OFF -DENABLE_SSE=OFF -DENABLE_SSE2=OFF -DENABLE_AVX=OFF -DENABLE_AVX2=OFF .. || exit 1 make -j8 || exit 1 cd .. diff --git a/scripts/release-winxp.sh b/scripts/release-winxp.sh index ec8e5d8d1..bbe751c65 100755 --- a/scripts/release-winxp.sh +++ b/scripts/release-winxp.sh @@ -15,7 +15,7 @@ fi cd xpbuild # TODO: potential Arch-ism? -i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=ON -DWITH_RENDER_DX11=OFF -DSDL_SSE2=OFF -DSDL_SSE3=OFF -DENABLE_SSE=OFF -DENABLE_SSE2=OFF -DENABLE_AVX=OFF -DENABLE_AVX2=OFF -DUSE_BACKWARD=ON -DCONSOLE_SUBSYSTEM=OFF .. || exit 1 +i686-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type" -DBUILD_SHARED_LIBS=OFF -DSUPPORT_XP=ON -DWITH_RENDER_DX11=OFF -DSDL_SSE=OFF -DSDL_SSE2=OFF -DSDL_SSE3=OFF -DENABLE_SSE=OFF -DENABLE_SSE2=OFF -DENABLE_AVX=OFF -DENABLE_AVX2=OFF -DUSE_BACKWARD=ON -DCONSOLE_SUBSYSTEM=OFF .. || exit 1 make -j8 || exit 1 cd .. From 5c3ff727039c9f751d97ec87259d5daae98466f0 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 16 May 2024 17:41:40 -0500 Subject: [PATCH 36/36] driver info --- src/gui/render/renderDX9.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/gui/render/renderDX9.cpp b/src/gui/render/renderDX9.cpp index cd09562ac..353208114 100644 --- a/src/gui/render/renderDX9.cpp +++ b/src/gui/render/renderDX9.cpp @@ -473,6 +473,7 @@ void FurnaceGUIRenderDX9::preInit(const DivConfig& conf) { } bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { + D3DADAPTER_IDENTIFIER9 adapterInfo; SDL_SysWMinfo sysWindow; SDL_VERSION(&sysWindow.version); @@ -507,8 +508,18 @@ bool FurnaceGUIRenderDX9::init(SDL_Window* win, int swapInt) { priv->present.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE; } priv->present.hDeviceWindow=window; + + HRESULT result=iface->GetAdapterIdentifier(D3DADAPTER_DEFAULT,0,&adapterInfo); + + if (result==D3D_OK) { + vendorName=fmt::sprintf("0x%.4X",adapterInfo.VendorId); + deviceName=fmt::sprintf("%s (%s)",adapterInfo.Description,adapterInfo.DeviceName); + apiVersion=fmt::sprintf("%.8X %.8X %s",adapterInfo.DriverVersion.HighPart,adapterInfo.DriverVersion.LowPart,adapterInfo.Driver); + } else { + logW("could not get adapter info! %.8x",result); + } - HRESULT result=iface->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,window,D3DCREATE_HARDWARE_VERTEXPROCESSING,&priv->present,&device); + result=iface->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,window,D3DCREATE_HARDWARE_VERTEXPROCESSING,&priv->present,&device); if (result!=D3D_OK) { logW("no hardware vertex processing!");