mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-20 22:41:36 +00:00
Implement a rather hacky PickPixel implementation
This commit is contained in:
@@ -14,6 +14,16 @@ CustomPaintWidget::~CustomPaintWidget()
|
||||
|
||||
}
|
||||
|
||||
void CustomPaintWidget::mousePressEvent(QMouseEvent *e)
|
||||
{
|
||||
emit clicked(e);
|
||||
}
|
||||
|
||||
void CustomPaintWidget::mouseMoveEvent(QMouseEvent *e)
|
||||
{
|
||||
emit mouseMove(e);
|
||||
}
|
||||
|
||||
void CustomPaintWidget::paintEvent(QPaintEvent *e)
|
||||
{
|
||||
if(m_Output)
|
||||
|
||||
@@ -14,7 +14,13 @@ class CustomPaintWidget : public QWidget
|
||||
|
||||
void SetOutput(IReplayOutput *out) { m_Output = out; }
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void clicked(QMouseEvent *e);
|
||||
void mouseMove(QMouseEvent *e);
|
||||
|
||||
private slots:
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
|
||||
public slots:
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@ m_Core(core)
|
||||
|
||||
QWidget *renderContainer = ui->renderContainer;
|
||||
|
||||
QObject::connect(ui->render, &CustomPaintWidget::clicked, this, &TextureViewer::on_render_clicked);
|
||||
QObject::connect(ui->render, &CustomPaintWidget::mouseMove, this, &TextureViewer::on_render_clicked);
|
||||
|
||||
ui->dockarea->addToolWindow(ui->renderContainer, ToolWindowManager::EmptySpace);
|
||||
ui->dockarea->setToolWindowProperties(renderContainer, ToolWindowManager::DisallowUserDocking |
|
||||
ToolWindowManager::HideCloseButton |
|
||||
@@ -113,6 +116,39 @@ TextureViewer::~TextureViewer()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void TextureViewer::on_render_clicked(QMouseEvent *e)
|
||||
{
|
||||
uint32_t x = (uint32_t)e->x();
|
||||
uint32_t y = (uint32_t)e->y();
|
||||
|
||||
if(e->buttons() & Qt::RightButton)
|
||||
{
|
||||
m_Core->Renderer()->AsyncInvoke([this,x,y](IReplayRenderer *) {
|
||||
|
||||
ResourceId id;
|
||||
if(m_Core->APIProps().pipelineType == ePipelineState_D3D11)
|
||||
id = m_Core->CurD3D11PipelineState.m_OM.RenderTargets[0].Resource;
|
||||
else
|
||||
id = m_Core->CurGLPipelineState.m_FB.m_DrawFBO.Color[0].Obj;
|
||||
|
||||
PixelValue val;
|
||||
ReplayOutput_PickPixel(m_Output, id, false, x, y, 0, 0, 0, &val);
|
||||
|
||||
QString str = QString("Pixel %1 %2 %3 %4").arg(val.value_f[0]).arg(val.value_f[1]).arg(val.value_f[2]).arg(val.value_f[3]);
|
||||
|
||||
GUIInvoke::call([this,str,val]() {
|
||||
ui->statusText->setText(str);
|
||||
QPalette Pal(palette());
|
||||
|
||||
// set black background
|
||||
Pal.setColor(QPalette::Background, QColor(int(val.value_f[0]*255), int(val.value_f[1]*255), int(val.value_f[2]*255)));
|
||||
ui->pickSwatch->setAutoFillBackground(true);
|
||||
ui->pickSwatch->setPalette(Pal);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void TextureViewer::OnLogfileLoaded()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define TEXTUREVIEWER_H
|
||||
|
||||
#include <QFrame>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "Code/Core.h"
|
||||
|
||||
@@ -22,6 +23,9 @@ class TextureViewer : public QFrame, public ILogViewerForm
|
||||
void OnLogfileClosed();
|
||||
void OnEventSelected(uint32_t frameID, uint32_t eventID);
|
||||
|
||||
private slots:
|
||||
void on_render_clicked(QMouseEvent *e);
|
||||
|
||||
private:
|
||||
Ui::TextureViewer *ui;
|
||||
Core *m_Core;
|
||||
|
||||
@@ -842,7 +842,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<widget class="QWidget" name="pickSwatch" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -864,7 +864,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="s">
|
||||
<widget class="QLabel" name="statusText">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "vk_core.h"
|
||||
#include "serialise/string_utils.h"
|
||||
|
||||
// VKTODOHIGH need to call vkResetCommandBuffer() before calling vkBeginCommandBuffer()
|
||||
|
||||
// VKTODOLOW dirty buffers should propagate through to their memory somehow
|
||||
// images can be separately dirty since we can't just copy their memory
|
||||
// (tiling could be different)
|
||||
|
||||
@@ -265,7 +265,96 @@ vector<ResourceId> VulkanReplay::GetBuffers()
|
||||
|
||||
void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4])
|
||||
{
|
||||
RDCUNIMPLEMENTED("PickPixel");
|
||||
//VULKANNOTIMP("PickPixel");
|
||||
|
||||
ResourceId resid;
|
||||
VkImage fakeBBIm = VK_NULL_HANDLE;
|
||||
VkDeviceMemory fakeBBMem = VK_NULL_HANDLE;
|
||||
m_pDriver->GetFakeBB(resid, fakeBBIm, fakeBBMem);
|
||||
|
||||
VkDevice dev = m_pDriver->GetDev();
|
||||
VkCmdBuffer cmd = m_pDriver->GetCmd();
|
||||
VkQueue q = m_pDriver->GetQ();
|
||||
const VulkanFunctions &vk = m_pDriver->m_Real;
|
||||
|
||||
VkDeviceMemory readbackmem = VK_NULL_HANDLE;
|
||||
|
||||
{
|
||||
VkMemoryAllocInfo allocInfo = {
|
||||
/*.sType =*/ VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
|
||||
/*.pNext =*/ NULL,
|
||||
/*.allocationSize =*/ 128,
|
||||
/*.memoryTypeIndex =*/ 0, // VKTODOHIGH find appropriate memory type index
|
||||
};
|
||||
|
||||
VkResult res = vk.vkAllocMemory(dev, &allocInfo, &readbackmem);
|
||||
RDCASSERT(res == VK_SUCCESS);
|
||||
|
||||
VkBufferCreateInfo bufInfo = {
|
||||
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL,
|
||||
128, VK_BUFFER_USAGE_GENERAL, 0,
|
||||
VK_SHARING_MODE_EXCLUSIVE, 0, NULL,
|
||||
};
|
||||
|
||||
VkBuffer destbuf;
|
||||
|
||||
res = vk.vkCreateBuffer(dev, &bufInfo, &destbuf);
|
||||
RDCASSERT(res == VK_SUCCESS);
|
||||
|
||||
res = vk.vkBindBufferMemory(dev, destbuf, readbackmem, 0);
|
||||
RDCASSERT(res == VK_SUCCESS);
|
||||
|
||||
// VKTODOHIGH find out the actual current image state
|
||||
VkImageMemoryBarrier fakeTrans = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL,
|
||||
0, 0, VK_IMAGE_LAYOUT_PRESENT_SOURCE_WSI, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL,
|
||||
0, 0, fakeBBIm,
|
||||
{ VK_IMAGE_ASPECT_COLOR, 0, 1, 0, 1 } };
|
||||
|
||||
VkCmdBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, NULL, VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT };
|
||||
|
||||
res = vk.vkBeginCommandBuffer(cmd, &beginInfo);
|
||||
RDCASSERT(res == VK_SUCCESS);
|
||||
|
||||
void *barrier = (void *)&fakeTrans;
|
||||
vk.vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
|
||||
fakeTrans.oldLayout = fakeTrans.newLayout;
|
||||
|
||||
VkBufferImageCopy region = {
|
||||
0, 128, 1,
|
||||
{ VK_IMAGE_ASPECT_COLOR, 0, 0}, { (int)x, (int)y, 0 },
|
||||
{ 1, 1, 1 },
|
||||
};
|
||||
vk.vkCmdCopyImageToBuffer(cmd, fakeBBIm, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, destbuf, 1, ®ion);
|
||||
|
||||
fakeTrans.newLayout = VK_IMAGE_LAYOUT_PRESENT_SOURCE_WSI;
|
||||
vk.vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, 1, &barrier);
|
||||
|
||||
vk.vkEndCommandBuffer(cmd);
|
||||
|
||||
vk.vkQueueSubmit(q, 1, &cmd, VK_NULL_HANDLE);
|
||||
|
||||
vk.vkQueueWaitIdle(q);
|
||||
}
|
||||
|
||||
// VKTODOHIGH ultra cheeky - map memory directly without copying
|
||||
// to host-visible memory
|
||||
byte *pData = NULL;
|
||||
vk.vkMapMemory(dev, readbackmem, 0, 0, 0, (void **)&pData);
|
||||
|
||||
RDCASSERT(pData != NULL);
|
||||
|
||||
// VKTODOHIGH assuming BGRA
|
||||
pixel[2] = float(pData[0])/255.0f;
|
||||
pixel[1] = float(pData[1])/255.0f;
|
||||
pixel[0] = float(pData[2])/255.0f;
|
||||
pixel[3] = float(pData[3])/255.0f;
|
||||
|
||||
vk.vkUnmapMemory(dev, readbackmem);
|
||||
|
||||
vk.vkDeviceWaitIdle(dev);
|
||||
|
||||
vk.vkFreeMemory(dev, readbackmem);
|
||||
}
|
||||
|
||||
uint32_t VulkanReplay::PickVertex(uint32_t frameID, uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y)
|
||||
@@ -428,6 +517,7 @@ void VulkanReplay::FlipOutputWindow(uint64_t id)
|
||||
VkDeviceMemory fakeBBMem = VK_NULL_HANDLE;
|
||||
m_pDriver->GetFakeBB(resid, fakeBBIm, fakeBBMem);
|
||||
|
||||
// VKTODOHIGH find out the actual current image state
|
||||
VkImageMemoryBarrier fakeTrans = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL,
|
||||
0, 0, VK_IMAGE_LAYOUT_PRESENT_SOURCE_WSI, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL,
|
||||
|
||||
Reference in New Issue
Block a user