Skip to content

Commit

Permalink
Merge pull request #19657 from hrydgard/debugger-framebuffer-viewer
Browse files Browse the repository at this point in the history
ImDebugger: Basic framebuffer viewer
  • Loading branch information
hrydgard authored Nov 26, 2024
2 parents a265119 + eaff38f commit c2f5387
Show file tree
Hide file tree
Showing 13 changed files with 190 additions and 102 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
10 changes: 8 additions & 2 deletions Common/GPU/Vulkan/thin3d_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1583,10 +1583,16 @@ void VKContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, co

BindCurrentPipeline();
ApplyDynamicState();
int descSetIndex;
PackedDescriptor *descriptors = renderManager_.PushDescriptorSet(4, &descSetIndex);

for (auto &draw : draws) {
// TODO: Dirty-check these.
if (draw.bindTexture) {
BindTexture(0, draw.bindTexture);
} else if (draw.bindFramebufferAsTex) {
BindFramebufferAsTexture(draw.bindFramebufferAsTex, 0, FBChannel::FB_COLOR_BIT, 0);
}
int descSetIndex;
PackedDescriptor *descriptors = renderManager_.PushDescriptorSet(4, &descSetIndex);
BindDescriptors(vulkanUBObuf, descriptors);
renderManager_.SetScissor(draw.clipx, draw.clipy, draw.clipw, draw.cliph);
renderManager_.DrawIndexed(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset, vulkanIbuf,
Expand Down
2 changes: 2 additions & 0 deletions Common/GPU/thin3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,8 @@ struct ClippedDraw {
s16 clipy;
s16 clipw;
s16 cliph;
Draw::Texture *bindTexture;
Draw::Framebuffer *bindFramebufferAsTex;
};

class DrawContext {
Expand Down
3 changes: 2 additions & 1 deletion Core/Debugger/DebugInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct MemMap;

class DebugInterface {
public:
virtual int getInstructionSize(int instruction) {return 1;}
virtual int getInstructionSize(int instruction) = 0;

virtual bool isAlive() = 0;
virtual bool isBreakpoint(unsigned int address) = 0;
Expand All @@ -47,6 +47,7 @@ class DebugInterface {
virtual u32 GetHi() = 0;
virtual u32 GetLo() = 0;
virtual u32 GetLLBit() = 0;
virtual u32 GetFPCond() = 0;

virtual void SetHi(u32 val) { };
virtual void SetLo(u32 val) { };
Expand Down
3 changes: 1 addition & 2 deletions Core/HLE/sceKernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,7 @@ u32 sceKernelIcacheClearAll()
return 0;
}

void KernelObject::GetQuickInfo(char *ptr, int size)
{
void KernelObject::GetQuickInfo(char *ptr, int size) {
strcpy(ptr, "-");
}

Expand Down
1 change: 1 addition & 0 deletions Core/MIPS/MIPSDebugInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class MIPSDebugInterface : public DebugInterface

u32 GetPC() override { return cpu->pc; }
u32 GetLR() override { return cpu->r[MIPS_REG_RA]; }
u32 GetFPCond() override { return cpu->fpcond; }
void DisAsm(u32 pc, char *out, size_t outSize) override;
void SetPC(u32 _pc) override { cpu->pc = _pc; }

Expand Down
8 changes: 7 additions & 1 deletion GPU/Common/FramebufferManagerCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <cmath>

#include "ext/imgui/imgui.h"
#include "ext/imgui/imgui_impl_thin3d.h"

#include "Common/GPU/thin3d.h"
#include "Common/GPU/OpenGL/GLFeatures.h"
Expand Down Expand Up @@ -3704,5 +3705,10 @@ void FramebufferManagerCommon::DrawImGuiDebug(int &selected) const {
}
ImGui::EndTable();

// Now, draw the actual framebuffer image. This could be refined a lot.
if (selected != -1) {
// Now, draw the image of the selected framebuffer.
Draw::Framebuffer *fb = vfbs_[selected]->fbo;
ImTextureID texId = ImGui_ImplThin3d_AddFBAsTextureTemp(fb);
ImGui::Image(texId, ImVec2(fb->Width(), fb->Height()));
}
}
25 changes: 16 additions & 9 deletions UI/ImDebugger/ImDebugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,17 @@ void DrawRegisterView(MIPSDebugInterface *mipsDebug, bool *open) {
ImGui::TableSetupColumn("regname", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("value_i", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();

auto gprLine = [&](const char *regname, int value) {
ImGui::TableSetColumnIndex(0);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(regname);
ImGui::TableSetColumnIndex(1);
ImGui::TableNextColumn();
ImGui::Text("%08x", value);
if (value >= -1000000 && value <= 1000000) {
ImGui::TableSetColumnIndex(2);
ImGui::Text("%d", value);
}
ImGui::TableNextRow();
};
for (int i = 0; i < 32; i++) {
gprLine(mipsDebug->GetRegName(0, i).c_str(), mipsDebug->GetGPR32Value(i));
Expand All @@ -78,19 +77,27 @@ void DrawRegisterView(MIPSDebugInterface *mipsDebug, bool *open) {
ImGui::TableSetupColumn("regname", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("value_i", ImGuiTableColumnFlags_WidthStretch);

// fpcond
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted("fpcond");
ImGui::TableNextColumn();
ImGui::Text("%08x", mipsDebug->GetFPCond());

for (int i = 0; i < 32; i++) {
float fvalue = mipsDebug->GetFPR32Value(i);
u32 fivalue;
memcpy(&fivalue, &fvalue, sizeof(fivalue));
ImGui::TableSetColumnIndex(0);
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(mipsDebug->GetRegName(1, i).c_str());
ImGui::TableSetColumnIndex(1);
ImGui::TableNextColumn();
ImGui::Text("%0.7f", fvalue);
ImGui::TableSetColumnIndex(2);
ImGui::TableNextColumn();
ImGui::Text("%08x", fivalue);
ImGui::TableNextRow();
}

ImGui::EndTable();
}
ImGui::EndTabItem();
Expand Down Expand Up @@ -227,7 +234,7 @@ static void DrawKernelObjects(ImConfig &cfg) {
ImGui::End();
return;
}
if (ImGui::BeginTable("kos", 5, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH)) {
if (ImGui::BeginTable("kos", 4, ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersH | ImGuiTableFlags_Resizable)) {
ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed);
Expand Down
Loading

0 comments on commit c2f5387

Please sign in to comment.