GE debugger improvements

This commit is contained in:
Henrik Rydgård
2024-12-18 18:35:55 +01:00
parent bff2498a3f
commit 58adb379ea
7 changed files with 75 additions and 4 deletions
+1
View File
@@ -74,6 +74,7 @@ bool DataFormatIsDepthStencil(DataFormat fmt);
inline bool DataFormatIsColor(DataFormat fmt) {
return !DataFormatIsDepthStencil(fmt);
}
int DataFormatNumChannels(DataFormat fmt);
bool DataFormatIsBlockCompressed(DataFormat fmt, int *blockSize);
// Limited format support for now.
+7 -1
View File
@@ -803,9 +803,15 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanBarrierBatch *postBarriers, Vu
}
VkComponentMapping r8AsAlpha[4] = { VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_R };
VkComponentMapping r8AsColor[4] = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ONE };
VkComponentMapping *swizzle = nullptr;
switch (desc.swizzle) {
case TextureSwizzle::R8_AS_ALPHA: swizzle = r8AsAlpha; break;
case TextureSwizzle::R8_AS_GRAYSCALE: swizzle = r8AsColor; break;
}
VulkanBarrierBatch barrier;
if (!vkTex_->CreateDirect(width_, height_, 1, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits, &barrier, desc.swizzle == TextureSwizzle::R8_AS_ALPHA ? r8AsAlpha : nullptr)) {
if (!vkTex_->CreateDirect(width_, height_, 1, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits, &barrier, swizzle)) {
ERROR_LOG(Log::G3D, "Failed to create VulkanTexture: %dx%dx%d fmt %d, %d levels", width_, height_, depth_, (int)vulkanFormat, mipLevels_);
return false;
}
+19
View File
@@ -118,6 +118,25 @@ bool DataFormatIsBlockCompressed(DataFormat fmt, int *blockSize) {
}
}
int DataFormatNumChannels(DataFormat fmt) {
switch (fmt) {
case DataFormat::D16:
case DataFormat::D32F:
case DataFormat::R8_UNORM:
case DataFormat::R16_UNORM:
case DataFormat::R16_FLOAT:
case DataFormat::R32_FLOAT:
return 1;
case DataFormat::R8G8B8A8_UNORM:
case DataFormat::R8G8B8A8_UNORM_SRGB:
case DataFormat::B8G8R8A8_UNORM:
case DataFormat::B8G8R8A8_UNORM_SRGB:
return 4;
default:
return 0;
}
}
RefCountedObject::~RefCountedObject() {
const int rc = refcount_.load();
_dbg_assert_msg_(rc == 0xDEDEDE, "Unexpected refcount %d in object of type '%s'", rc, name_);
+1
View File
@@ -643,6 +643,7 @@ typedef std::function<bool(uint8_t *data, const uint8_t *initData, uint32_t w, u
enum class TextureSwizzle {
DEFAULT,
R8_AS_ALPHA,
R8_AS_GRAYSCALE,
};
struct TextureDesc {
+2
View File
@@ -170,12 +170,14 @@ enum class ImCmd {
SHOW_IN_CPU_DISASM,
SHOW_IN_GE_DISASM,
SHOW_IN_MEMORY_VIEWER, // param is address, param2 is viewer index
SHOW_IN_PIXEL_VIEWER, // param is address, param2 is stride, |0x80000000 if depth, param3 is w/h
};
struct ImCommand {
ImCmd cmd;
uint32_t param;
uint32_t param2;
uint32_t param3;
};
struct ImControl {
+41 -3
View File
@@ -149,12 +149,39 @@ void ImGePixelViewerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInte
if (ImGui::Button("Refresh")) {
viewer_.Snapshot();
}
if (ImGui::Button("Show cur depth")) {
viewer_.addr = gstate.getDepthBufRawAddress() | 0x04000000;
viewer_.format = GE_FORMAT_DEPTH16;
viewer_.stride = gstate.DepthBufStride();
viewer_.width = viewer_.stride;
viewer_.Snapshot();
}
if (ImGui::Button("Show cur color")) {
viewer_.addr = gstate.getFrameBufAddress();
viewer_.format = gstate.FrameBufFormat();
viewer_.stride = gstate.FrameBufStride();
viewer_.width = viewer_.stride;
viewer_.Snapshot();
}
}
ImGui::EndChild();
ImGui::SameLine();
if (ImGui::BeginChild("right")) {
ImVec2 p0 = ImGui::GetCursorScreenPos();
viewer_.Draw(gpuDebug, draw);
if (ImGui::IsItemHovered()) {
int x = (int)(ImGui::GetMousePos().x - p0.x);
int y = (int)(ImGui::GetMousePos().y - p0.y);
char temp[128];
if (viewer_.FormatValueAt(temp, sizeof(temp), x, y)) {
ImGui::Text("(%d, %d): %s", x, y, temp);
} else {
ImGui::Text("%d, %d: N/A", x, y);
}
} else {
ImGui::TextUnformatted("(no pixel hovered)");
}
}
ImGui::EndChild();
ImGui::End();
@@ -211,6 +238,12 @@ bool ImGePixelViewer::FormatValueAt(char *buf, size_t bufSize, int x, int y) con
snprintf(buf, bufSize, "%08x (raw: %04x)", RGBA5551ToRGBA8888(raw), raw);
break;
}
case GE_FORMAT_DEPTH16:
{
u16 raw = Memory::Read_U16(pixelAddr);
snprintf(buf, bufSize, "%0.4f (raw: %04x / %d)", (float)raw / 65535.0f, raw, raw);
break;
}
default:
snprintf(buf, bufSize, "N/A");
return false;
@@ -356,6 +389,7 @@ bool ImGeReadbackViewer::Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *dr
readbackFmt_ = Draw::DataFormat::R8G8B8A8_UNORM;
break;
case Draw::Aspect::DEPTH_BIT:
// TODO: Add fallback
readbackFmt_ = Draw::DataFormat::D32F;
break;
case Draw::Aspect::STENCIL_BIT:
@@ -385,14 +419,15 @@ bool ImGeReadbackViewer::Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *dr
}
}
Draw::DataFormat fmt = rbBpp == 1 ? Draw::DataFormat::R8_UNORM : Draw::DataFormat::R32_FLOAT;
Draw::TextureDesc desc{ Draw::TextureType::LINEAR2D,
rbBpp == 1 ? Draw::DataFormat::R8_UNORM : Draw::DataFormat::R32_FLOAT,
fmt,
(int)w,
(int)h,
1,
1,
false,
rbBpp == 1 ? Draw::TextureSwizzle::R8_AS_ALPHA : Draw::TextureSwizzle::DEFAULT,
Draw::DataFormatNumChannels(fmt) == 1 ? Draw::TextureSwizzle::R8_AS_GRAYSCALE: Draw::TextureSwizzle::DEFAULT,
"PixelViewer temp",
{ texData },
nullptr,
@@ -432,7 +467,9 @@ bool ImGeReadbackViewer::FormatValueAt(char *buf, size_t bufSize, int x, int y)
case Draw::DataFormat::D32F:
{
const float *read = (const float *)(data_ + offset);
snprintf(buf, bufSize, "%0.4f", *read);
float value = *read;
int ivalue = *read * 65535.0f;
snprintf(buf, bufSize, "%0.4f (raw: %04x / %d)", *read, ivalue, ivalue);
return true;
}
case Draw::DataFormat::S8:
@@ -1060,6 +1097,7 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterfa
DrawPreviewPrimitive(drawList, p0, previewPrim_, previewIndices_, previewVertices_, previewCount_, true, texW, texH);
drawList->PopClipRect();
} else {
ImGui::Text("(no valid texture bound)");
// In software mode, we should just decode the texture here.
+4
View File
@@ -114,6 +114,10 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d
boundSampler = bd->fontSampler;
} else {
size_t index = (size_t)pcmd->TextureId - TEX_ID_OFFSET;
if (index >= bd->tempTextures.size()) {
WARN_LOG(Log::System, "Missing temp texture %d (out of %d)", index, (int)bd->tempTextures.size());
continue;
}
_dbg_assert_(index < bd->tempTextures.size());
switch (bd->tempTextures[index].type) {
case RegisteredTextureType::Framebuffer: