Skip to content

Commit

Permalink
Implement ImGui clipped batch texturing support in the other backends…
Browse files Browse the repository at this point in the history
… too
  • Loading branch information
hrydgard committed Nov 26, 2024
1 parent e82b7f7 commit eaff38f
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 66 deletions.
74 changes: 40 additions & 34 deletions Common/GPU/D3D11/thin3d_d3d11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ class D3D11DepthStencilState;
class D3D11SamplerState;
class D3D11Buffer;
class D3D11RasterState;
class D3D11Framebuffer;

// This must stay POD for the memcmp to work reliably.
struct D3D11DepthStencilKey {
Expand All @@ -60,6 +59,39 @@ class D3D11DepthStencilState : public DepthStencilState {
DepthStencilStateDesc desc;
};

// A D3D11Framebuffer is a D3D11Framebuffer plus all the textures it owns.
class D3D11Framebuffer : public Framebuffer {
public:
D3D11Framebuffer(int width, int height) {
width_ = width;
height_ = height;
}
~D3D11Framebuffer() {
if (colorTex)
colorTex->Release();
if (colorRTView)
colorRTView->Release();
if (colorSRView)
colorSRView->Release();
if (depthSRView)
depthSRView->Release();
if (depthStencilTex)
depthStencilTex->Release();
if (depthStencilRTView)
depthStencilRTView->Release();
}

ID3D11Texture2D *colorTex = nullptr;
ID3D11RenderTargetView *colorRTView = nullptr;
ID3D11ShaderResourceView *colorSRView = nullptr;
ID3D11ShaderResourceView *depthSRView = nullptr;
DXGI_FORMAT colorFormat = DXGI_FORMAT_UNKNOWN;

ID3D11Texture2D *depthStencilTex = nullptr;
ID3D11DepthStencilView *depthStencilRTView = nullptr;
DXGI_FORMAT depthStencilFormat = DXGI_FORMAT_UNKNOWN;
};

class D3D11DrawContext : public DrawContext {
public:
D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *deviceContext, ID3D11Device1 *device1, ID3D11DeviceContext1 *deviceContext1, IDXGISwapChain *swapChain, D3D_FEATURE_LEVEL featureLevel, HWND hWnd, std::vector<std::string> deviceList, int maxInflightFrames);
Expand Down Expand Up @@ -1388,6 +1420,13 @@ void D3D11DrawContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCo
ApplyCurrentState();

for (int i = 0; i < draws.size(); i++) {
if (draws[i].bindTexture) {
ID3D11ShaderResourceView *view = ((D3D11Texture *)draws[i].bindTexture)->View();
context_->PSSetShaderResources(0, 1, &view);
} else {
ID3D11ShaderResourceView *view = ((D3D11Framebuffer *)draws[i].bindFramebufferAsTex)->colorSRView;
context_->PSSetShaderResources(0, 1, &view);
}
D3D11_RECT rc;
rc.left = draws[i].clipx;
rc.top = draws[i].clipy;
Expand Down Expand Up @@ -1420,39 +1459,6 @@ uint32_t D3D11DrawContext::GetDataFormatSupport(DataFormat fmt) const {
return support;
}

// A D3D11Framebuffer is a D3D11Framebuffer plus all the textures it owns.
class D3D11Framebuffer : public Framebuffer {
public:
D3D11Framebuffer(int width, int height) {
width_ = width;
height_ = height;
}
~D3D11Framebuffer() {
if (colorTex)
colorTex->Release();
if (colorRTView)
colorRTView->Release();
if (colorSRView)
colorSRView->Release();
if (depthSRView)
depthSRView->Release();
if (depthStencilTex)
depthStencilTex->Release();
if (depthStencilRTView)
depthStencilRTView->Release();
}

ID3D11Texture2D *colorTex = nullptr;
ID3D11RenderTargetView *colorRTView = nullptr;
ID3D11ShaderResourceView *colorSRView = nullptr;
ID3D11ShaderResourceView *depthSRView = nullptr;
DXGI_FORMAT colorFormat = DXGI_FORMAT_UNKNOWN;

ID3D11Texture2D *depthStencilTex = nullptr;
ID3D11DepthStencilView *depthStencilRTView = nullptr;
DXGI_FORMAT depthStencilFormat = DXGI_FORMAT_UNKNOWN;
};

Framebuffer *D3D11DrawContext::CreateFramebuffer(const FramebufferDesc &desc) {
HRESULT hr;
D3D11Framebuffer *fb = new D3D11Framebuffer(desc.width, desc.height);
Expand Down
36 changes: 21 additions & 15 deletions Common/GPU/D3D9/thin3d_d3d9.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,21 @@ static void SemanticToD3D9UsageAndIndex(int semantic, BYTE *usage, BYTE *index)
}
}

class D3D9Framebuffer : public Framebuffer {
public:
D3D9Framebuffer(int width, int height) {
width_ = width;
height_ = height;
}
~D3D9Framebuffer();

uint32_t id = 0;
ComPtr<IDirect3DSurface9> surf;
ComPtr<IDirect3DSurface9> depthstencil;
ComPtr<IDirect3DTexture9> tex;
ComPtr<IDirect3DTexture9> depthstenciltex;
};

D3D9InputLayout::D3D9InputLayout(LPDIRECT3DDEVICE9 device, const InputLayoutDesc &desc) : decl_(NULL) {
D3DVERTEXELEMENT9 *elements = new D3DVERTEXELEMENT9[desc.attributes.size() + 1];
size_t i;
Expand Down Expand Up @@ -1195,6 +1210,12 @@ void D3D9Context::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount,

// Suboptimal!
for (int i = 0; i < draws.size(); i++) {
if (draws[i].bindTexture) {
device_->SetTexture(0, ((D3D9Texture *)draws[i].bindTexture)->TexturePtr());
} else if (draws[i].bindFramebufferAsTex) {
device_->SetTexture(0, ((D3D9Framebuffer *)draws[i].bindFramebufferAsTex)->tex.Get());
}

RECT rc;
rc.left = draws[i].clipx;
rc.top = draws[i].clipy;
Expand Down Expand Up @@ -1286,21 +1307,6 @@ bool D3D9ShaderModule::Compile(LPDIRECT3DDEVICE9 device, const uint8_t *data, si
return true;
}

class D3D9Framebuffer : public Framebuffer {
public:
D3D9Framebuffer(int width, int height) {
width_ = width;
height_ = height;
}
~D3D9Framebuffer();

uint32_t id = 0;
ComPtr<IDirect3DSurface9> surf;
ComPtr<IDirect3DSurface9> depthstencil;
ComPtr<IDirect3DTexture9> tex;
ComPtr<IDirect3DTexture9> depthstenciltex;
};

Framebuffer *D3D9Context::CreateFramebuffer(const FramebufferDesc &desc) {
// Don't think D3D9 does array layers.
_dbg_assert_(desc.numLayers == 1);
Expand Down
1 change: 1 addition & 0 deletions Common/GPU/OpenGL/GLRenderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ void GLRenderManager::BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRende
}
}

// aspectBit: GL_COLOR_BUFFER_BIT etc
void GLRenderManager::BindFramebufferAsTexture(GLRFramebuffer *fb, int binding, int aspectBit) {
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER);
_dbg_assert_(binding < MAX_GL_TEXTURE_SLOTS);
Expand Down
7 changes: 6 additions & 1 deletion Common/GPU/OpenGL/thin3d_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ class OpenGLTexture : public Texture {
int NumMipmaps() const {
return mipLevels_;
}
const GLRTexture *GetTex() const {
GLRTexture *GetTex() const {
return tex_;
}

Expand Down Expand Up @@ -1463,6 +1463,11 @@ void OpenGLContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount

ApplySamplers();
for (auto &draw : draws) {
if (draw.bindTexture) {
renderManager_.BindTexture(0, ((OpenGLTexture *)draw.bindTexture)->GetTex());
} else if (draw.bindFramebufferAsTex) {
renderManager_.BindFramebufferAsTexture(((OpenGLFramebuffer*)draw.bindFramebufferAsTex)->framebuffer_, 0, GL_COLOR_BUFFER_BIT);
}
GLRect2D scissor;
scissor.x = draw.clipx;
scissor.y = draw.clipy;
Expand Down
1 change: 1 addition & 0 deletions Common/GPU/Vulkan/thin3d_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1585,6 +1585,7 @@ void VKContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, co
ApplyDynamicState();

for (auto &draw : draws) {
// TODO: Dirty-check these.
if (draw.bindTexture) {
BindTexture(0, draw.bindTexture);
} else if (draw.bindFramebufferAsTex) {
Expand Down
29 changes: 13 additions & 16 deletions ext/imgui/imgui_impl_thin3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d
ImTextureID prevTexId = (ImTextureID)-1;

std::vector<Draw::ClippedDraw> draws;
Draw::Texture *boundTexture = nullptr;
Draw::Framebuffer *boundFBAsTexture = nullptr;
Draw::Texture *boundTexture;
Draw::Framebuffer *boundFBAsTexture;

// Render command lists
for (int n = 0; n < draw_data->CmdListsCount; n++) {
Expand All @@ -111,23 +111,20 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d
}
} else {
// Update the texture pointers.
if (pcmd->TextureId != prevTexId) {
if (!pcmd->TextureId) {
draw->BindTexture(0, bd->fontImage);
if (!pcmd->TextureId) {
boundTexture = bd->fontImage;
boundFBAsTexture = nullptr;
} else {
size_t index = (size_t)pcmd->TextureId - TEX_ID_OFFSET;
_dbg_assert_(index < bd->tempTextures.size());
if (bd->tempTextures[index].framebuffer) {
boundFBAsTexture = bd->tempTextures[index].framebuffer;
boundTexture = nullptr;
} else {
size_t index = (size_t)pcmd->TextureId - TEX_ID_OFFSET;
_dbg_assert_(index < bd->tempTextures.size());
if (bd->tempTextures[index].framebuffer) {
boundFBAsTexture = bd->tempTextures[index].framebuffer;
boundTexture = nullptr;
} else {
boundTexture = bd->tempTextures[index].texture;
boundFBAsTexture = nullptr;
}
boundTexture = bd->tempTextures[index].texture;
boundFBAsTexture = nullptr;
}
prevTexId = pcmd->TextureId;
}

// Project scissor/clipping rectangles into framebuffer space
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
Expand Down

0 comments on commit eaff38f

Please sign in to comment.