mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
GE debugger improvements
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user