mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-21 05:56:37 +00:00
Fix calculation of small mip co-ordinates for NPOT textures
This commit is contained in:
@@ -736,8 +736,8 @@ void TextureViewer::RT_FetchCurrentPixel(IReplayController *r, uint32_t x, uint3
|
||||
if(m_TexDisplay.flipY)
|
||||
y = (texptr->height - 1) - y;
|
||||
|
||||
x = qMax(0U, x >> m_TexDisplay.subresource.mip);
|
||||
y = qMax(0U, y >> m_TexDisplay.subresource.mip);
|
||||
x = qMax(0U, MipCoordFromBase(x, texptr->width));
|
||||
y = qMax(0U, MipCoordFromBase(y, texptr->height));
|
||||
|
||||
ResourceId id = m_TexDisplay.resourceId;
|
||||
Subresource sub = m_TexDisplay.subresource;
|
||||
@@ -965,11 +965,12 @@ void TextureViewer::UI_UpdateStatusText()
|
||||
ui->pickSwatch->setPalette(Pal);
|
||||
}
|
||||
|
||||
int y = m_CurHoverPixel.y() >> (int)m_TexDisplay.subresource.mip;
|
||||
|
||||
uint32_t mipWidth = qMax(1U, tex.width >> (int)m_TexDisplay.subresource.mip);
|
||||
uint32_t mipHeight = qMax(1U, tex.height >> (int)m_TexDisplay.subresource.mip);
|
||||
|
||||
int x = MipCoordFromBase(m_CurHoverPixel.x(), tex.width);
|
||||
int y = MipCoordFromBase(m_CurHoverPixel.y(), tex.height);
|
||||
|
||||
if(ShouldFlipForGL())
|
||||
y = (int)(mipHeight - 1) - y;
|
||||
if(m_TexDisplay.flipY)
|
||||
@@ -977,7 +978,6 @@ void TextureViewer::UI_UpdateStatusText()
|
||||
|
||||
y = qMax(0, y);
|
||||
|
||||
int x = m_CurHoverPixel.x() >> (int)m_TexDisplay.subresource.mip;
|
||||
float invWidth = 1.0f / mipWidth;
|
||||
float invHeight = 1.0f / mipHeight;
|
||||
|
||||
@@ -1004,8 +1004,8 @@ void TextureViewer::UI_UpdateStatusText()
|
||||
|
||||
if(m_PickedPoint.x() >= 0)
|
||||
{
|
||||
x = m_PickedPoint.x() >> (int)m_TexDisplay.subresource.mip;
|
||||
y = m_PickedPoint.y() >> (int)m_TexDisplay.subresource.mip;
|
||||
x = MipCoordFromBase(m_PickedPoint.x(), tex.width);
|
||||
y = MipCoordFromBase(m_PickedPoint.y(), tex.height);
|
||||
if(ShouldFlipForGL())
|
||||
y = (int)(mipHeight - 1) - y;
|
||||
if(m_TexDisplay.flipY)
|
||||
@@ -2151,8 +2151,8 @@ void TextureViewer::GotoLocation(uint32_t x, uint32_t y)
|
||||
if(tex == NULL)
|
||||
return;
|
||||
|
||||
x = qMin(x << m_TexDisplay.subresource.mip, uint32_t(tex->width - 1));
|
||||
y = qMin(y << m_TexDisplay.subresource.mip, uint32_t(tex->height - 1));
|
||||
x = qMin(BaseCoordFromMip(x, tex->width), uint32_t(tex->width - 1));
|
||||
y = qMin(BaseCoordFromMip(y, tex->height), uint32_t(tex->height - 1));
|
||||
|
||||
m_PickedPoint = QPoint(x, y);
|
||||
|
||||
@@ -3796,8 +3796,8 @@ rdcpair<int32_t, int32_t> TextureViewer::GetPickedLocation()
|
||||
{
|
||||
QPoint p = m_PickedPoint;
|
||||
|
||||
p.setX(p.x() >> (int)m_TexDisplay.subresource.mip);
|
||||
p.setY(p.y() >> (int)m_TexDisplay.subresource.mip);
|
||||
p.setX(MipCoordFromBase(p.x(), texptr->width));
|
||||
p.setY(MipCoordFromBase(p.y(), texptr->height));
|
||||
|
||||
uint32_t mipHeight = qMax(1U, texptr->height >> (int)m_TexDisplay.subresource.mip);
|
||||
|
||||
@@ -3820,8 +3820,8 @@ void TextureViewer::ShowGotoPopup()
|
||||
{
|
||||
QPoint p = m_PickedPoint;
|
||||
|
||||
p.setX(p.x() >> (int)m_TexDisplay.subresource.mip);
|
||||
p.setY(p.y() >> (int)m_TexDisplay.subresource.mip);
|
||||
p.setX(MipCoordFromBase(p.x(), texptr->width));
|
||||
p.setY(MipCoordFromBase(p.y(), texptr->height));
|
||||
|
||||
uint32_t mipHeight = qMax(1U, texptr->height >> (int)m_TexDisplay.subresource.mip);
|
||||
|
||||
@@ -3969,11 +3969,11 @@ void TextureViewer::on_debugPixelContext_clicked()
|
||||
if(m_PickedPoint.x() < 0 || m_PickedPoint.y() < 0)
|
||||
return;
|
||||
|
||||
int x = m_PickedPoint.x() >> (int)m_TexDisplay.subresource.mip;
|
||||
int y = m_PickedPoint.y() >> (int)m_TexDisplay.subresource.mip;
|
||||
|
||||
TextureDescription *texptr = GetCurrentTexture();
|
||||
|
||||
int x = MipCoordFromBase(m_PickedPoint.x(), texptr->width);
|
||||
int y = MipCoordFromBase(m_PickedPoint.y(), texptr->height);
|
||||
|
||||
uint32_t mipHeight = qMax(1U, texptr->height >> (int)m_TexDisplay.subresource.mip);
|
||||
|
||||
if(m_TexDisplay.flipY)
|
||||
@@ -4035,8 +4035,8 @@ void TextureViewer::on_pixelHistory_clicked()
|
||||
|
||||
ANALYTIC_SET(UIFeatures.PixelHistory, true);
|
||||
|
||||
int x = m_PickedPoint.x() >> (int)m_TexDisplay.subresource.mip;
|
||||
int y = m_PickedPoint.y() >> (int)m_TexDisplay.subresource.mip;
|
||||
int x = MipCoordFromBase(m_PickedPoint.x(), texptr->width);
|
||||
int y = MipCoordFromBase(m_PickedPoint.y(), texptr->height);
|
||||
|
||||
uint32_t mipHeight = qMax(1U, texptr->height >> (int)m_TexDisplay.subresource.mip);
|
||||
|
||||
@@ -4417,6 +4417,34 @@ QString TextureViewer::getShaderPath(const QString &filename) const
|
||||
return path;
|
||||
}
|
||||
|
||||
uint32_t TextureViewer::MipCoordFromBase(int coord, uint32_t dim)
|
||||
{
|
||||
const uint32_t mip = m_TexDisplay.subresource.mip;
|
||||
const uint32_t mipDim = qMax(1U, dim >> mip);
|
||||
|
||||
// for mip levels where we more than half (e.g. 15x15 to 7x7) the coord can't be shifted by the
|
||||
// mip.
|
||||
// e.g. if the top level is 960x540 an x coordinate of 950 would be shifted by 7 down to 7, but
|
||||
// mip 7 is 7x4 so the max x co-ordinate is 6. Instead we need to get the float value on the top
|
||||
// mip, multiply by the mip dimension, and floor it
|
||||
|
||||
float coordf = float(coord) / float(dim);
|
||||
|
||||
return uint32_t(mipDim * coordf);
|
||||
}
|
||||
|
||||
uint32_t TextureViewer::BaseCoordFromMip(int coord, uint32_t dim)
|
||||
{
|
||||
const uint32_t mip = m_TexDisplay.subresource.mip;
|
||||
uint32_t mipDim = qMax(1U, dim >> mip);
|
||||
|
||||
// reverse of the above conversion
|
||||
|
||||
float coordf = float(coord) / float(mipDim);
|
||||
|
||||
return uint32_t(dim * coordf);
|
||||
}
|
||||
|
||||
void TextureViewer::on_customCreate_clicked()
|
||||
{
|
||||
QString filename = ui->customShader->currentText();
|
||||
|
||||
@@ -307,6 +307,8 @@ private:
|
||||
void ShowGotoPopup();
|
||||
|
||||
bool ShouldFlipForGL();
|
||||
uint32_t MipCoordFromBase(int coord, uint32_t dim);
|
||||
uint32_t BaseCoordFromMip(int coord, uint32_t dim);
|
||||
|
||||
void UI_UpdateFittedScale();
|
||||
void UI_SetScale(float s);
|
||||
|
||||
@@ -61,8 +61,8 @@ RWBuffer<int4> MinMaxDestInt : register(u2);
|
||||
{
|
||||
for(uint x = topleft.x; x < min(texDim.x, topleft.x + HGRAM_PIXELS_PER_TILE); x++)
|
||||
{
|
||||
uint4 data = SampleTextureUInt4(texType, float2(x, y) / float2(texDim.xy), HistogramSlice,
|
||||
HistogramMip, HistogramSample, texDim);
|
||||
uint4 data = SampleTextureUInt4(texType, float2(x + 0.1f, y + 0.1f) / float2(texDim.xy),
|
||||
HistogramSlice, HistogramMip, HistogramSample, texDim);
|
||||
|
||||
if(i == 0)
|
||||
{
|
||||
@@ -91,8 +91,8 @@ RWBuffer<int4> MinMaxDestInt : register(u2);
|
||||
{
|
||||
for(uint x = topleft.x; x < min(texDim.x, topleft.x + HGRAM_PIXELS_PER_TILE); x++)
|
||||
{
|
||||
int4 data = SampleTextureInt4(texType, float2(x, y) / float2(texDim.xy), HistogramSlice,
|
||||
HistogramMip, HistogramSample, texDim);
|
||||
int4 data = SampleTextureInt4(texType, float2(x + 0.1f, y + 0.1f) / float2(texDim.xy),
|
||||
HistogramSlice, HistogramMip, HistogramSample, texDim);
|
||||
|
||||
if(i == 0)
|
||||
{
|
||||
@@ -121,9 +121,10 @@ RWBuffer<int4> MinMaxDestInt : register(u2);
|
||||
{
|
||||
for(uint x = topleft.x; x < min(texDim.x, topleft.x + HGRAM_PIXELS_PER_TILE); x++)
|
||||
{
|
||||
float4 data = SampleTextureFloat4(texType, false, float2(x, y) / float2(texDim.xy),
|
||||
HistogramSlice, HistogramMip, HistogramSample, texDim,
|
||||
HistogramYUVDownsampleRate, HistogramYUVAChannels);
|
||||
float4 data =
|
||||
SampleTextureFloat4(texType, false, float2(x + 0.1f, y + 0.1f) / float2(texDim.xy),
|
||||
HistogramSlice, HistogramMip, HistogramSample, texDim,
|
||||
HistogramYUVDownsampleRate, HistogramYUVAChannels);
|
||||
|
||||
if(i == 0)
|
||||
{
|
||||
@@ -238,8 +239,8 @@ RWBuffer<uint> HistogramDest : register(u0);
|
||||
|
||||
#if UINT_TEX
|
||||
{
|
||||
uint4 data = SampleTextureUInt4(texType, float2(x, y) / float2(texDim.xy), HistogramSlice,
|
||||
HistogramMip, HistogramSample, texDim);
|
||||
uint4 data = SampleTextureUInt4(texType, float2(x + 0.1f, y + 0.1f) / float2(texDim.xy),
|
||||
HistogramSlice, HistogramMip, HistogramSample, texDim);
|
||||
|
||||
if((HistogramChannels & 0x1) == 0)
|
||||
data.x = uint(HistogramMax + 1);
|
||||
@@ -268,8 +269,8 @@ RWBuffer<uint> HistogramDest : register(u0);
|
||||
}
|
||||
#elif SINT_TEX
|
||||
{
|
||||
int4 data = SampleTextureInt4(texType, float2(x, y) / float2(texDim.xy), HistogramSlice,
|
||||
HistogramMip, HistogramSample, texDim);
|
||||
int4 data = SampleTextureInt4(texType, float2(x + 0.1f, y + 0.1f) / float2(texDim.xy),
|
||||
HistogramSlice, HistogramMip, HistogramSample, texDim);
|
||||
|
||||
if((HistogramChannels & 0x1) == 0)
|
||||
data.x = int(HistogramMax + 1);
|
||||
@@ -298,9 +299,10 @@ RWBuffer<uint> HistogramDest : register(u0);
|
||||
}
|
||||
#else
|
||||
{
|
||||
float4 data = SampleTextureFloat4(texType, false, float2(x, y) / float2(texDim.xy),
|
||||
HistogramSlice, HistogramMip, HistogramSample, texDim,
|
||||
HistogramYUVDownsampleRate, HistogramYUVAChannels);
|
||||
float4 data =
|
||||
SampleTextureFloat4(texType, false, float2(x + 0.1f, y + 0.1f) / float2(texDim.xy),
|
||||
HistogramSlice, HistogramMip, HistogramSample, texDim,
|
||||
HistogramYUVDownsampleRate, HistogramYUVAChannels);
|
||||
|
||||
if((HistogramChannels & 0x1) == 0)
|
||||
data.x = float(HistogramMax + 1);
|
||||
|
||||
@@ -1704,8 +1704,47 @@ void D3D11Replay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, const Su
|
||||
texDisplay.resourceId = texture;
|
||||
texDisplay.typeCast = typeCast;
|
||||
texDisplay.rawOutput = true;
|
||||
texDisplay.xOffset = -float(x << sub.mip);
|
||||
texDisplay.yOffset = -float(y << sub.mip);
|
||||
|
||||
uint32_t texWidth = 1, texHeight = 1;
|
||||
|
||||
auto it1 = WrappedID3D11Texture1D::m_TextureList.find(texture);
|
||||
auto it2 = WrappedID3D11Texture2D1::m_TextureList.find(texture);
|
||||
auto it3 = WrappedID3D11Texture3D1::m_TextureList.find(texture);
|
||||
if(it1 != WrappedID3D11Texture1D::m_TextureList.end())
|
||||
{
|
||||
WrappedID3D11Texture1D *wrapTex1D = (WrappedID3D11Texture1D *)it1->second.m_Texture;
|
||||
|
||||
D3D11_TEXTURE1D_DESC desc1d = {0};
|
||||
wrapTex1D->GetDesc(&desc1d);
|
||||
|
||||
texWidth = desc1d.Width;
|
||||
}
|
||||
else if(it2 != WrappedID3D11Texture2D1::m_TextureList.end())
|
||||
{
|
||||
WrappedID3D11Texture2D1 *wrapTex2D = (WrappedID3D11Texture2D1 *)it2->second.m_Texture;
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc2d = {0};
|
||||
wrapTex2D->GetDesc(&desc2d);
|
||||
|
||||
texWidth = desc2d.Width;
|
||||
texHeight = desc2d.Height;
|
||||
}
|
||||
else if(it3 != WrappedID3D11Texture3D1::m_TextureList.end())
|
||||
{
|
||||
WrappedID3D11Texture3D1 *wrapTex3D = (WrappedID3D11Texture3D1 *)it3->second.m_Texture;
|
||||
|
||||
D3D11_TEXTURE3D_DESC desc3d = {0};
|
||||
wrapTex3D->GetDesc(&desc3d);
|
||||
|
||||
texWidth = desc3d.Width;
|
||||
texHeight = desc3d.Height;
|
||||
}
|
||||
|
||||
uint32_t mipWidth = RDCMAX(1U, texWidth >> sub.mip);
|
||||
uint32_t mipHeight = RDCMAX(1U, texHeight >> sub.mip);
|
||||
|
||||
texDisplay.xOffset = -(float(x) / float(mipWidth)) * texWidth;
|
||||
texDisplay.yOffset = -(float(y) / float(mipHeight)) * texHeight;
|
||||
|
||||
RenderTextureInternal(texDisplay, eTexDisplay_None);
|
||||
}
|
||||
|
||||
@@ -2580,8 +2580,19 @@ void D3D12Replay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, const Su
|
||||
texDisplay.resourceId = texture;
|
||||
texDisplay.typeCast = typeCast;
|
||||
texDisplay.rawOutput = true;
|
||||
texDisplay.xOffset = -float(x << sub.mip);
|
||||
texDisplay.yOffset = -float(y << sub.mip);
|
||||
|
||||
ID3D12Resource *resource = m_pDevice->GetResourceList()[texture];
|
||||
|
||||
if(resource)
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc = resource->GetDesc();
|
||||
|
||||
uint32_t mipWidth = RDCMAX(1U, UINT(desc.Width >> sub.mip));
|
||||
uint32_t mipHeight = RDCMAX(1U, desc.Height >> sub.mip);
|
||||
|
||||
texDisplay.xOffset = -(float(x) / float(mipWidth)) * desc.Width;
|
||||
texDisplay.yOffset = -(float(y) / float(mipHeight)) * desc.Height;
|
||||
}
|
||||
|
||||
m_OutputViewport = {0, 0, 1, 1, 0.0f, 1.0f};
|
||||
RenderTextureInternal(GetDebugManager()->GetCPUHandle(PICK_PIXEL_RTV), texDisplay,
|
||||
|
||||
@@ -1620,14 +1620,20 @@ void GLReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, const Subre
|
||||
texDisplay.xOffset = -float(x << sub.mip);
|
||||
texDisplay.yOffset = -float(y << sub.mip);
|
||||
|
||||
auto &texDetails = m_pDriver->m_Textures[texDisplay.resourceId];
|
||||
|
||||
uint32_t mipWidth = RDCMAX(1U, (uint32_t)texDetails.width >> sub.mip);
|
||||
uint32_t mipHeight = RDCMAX(1U, (uint32_t)texDetails.height >> sub.mip);
|
||||
|
||||
texDisplay.xOffset = -(float(x) / float(mipWidth)) * texDetails.width;
|
||||
texDisplay.yOffset = -(float(y) / float(mipHeight)) * texDetails.height;
|
||||
|
||||
RenderTextureInternal(texDisplay, eTexDisplay_MipShift);
|
||||
|
||||
drv.glReadPixels(0, 0, 1, 1, eGL_RGBA, eGL_FLOAT, (void *)pixel);
|
||||
|
||||
if(!HasExt[ARB_gpu_shader5])
|
||||
{
|
||||
auto &texDetails = m_pDriver->m_Textures[texDisplay.resourceId];
|
||||
|
||||
if(IsSIntFormat(texDetails.internalFormat))
|
||||
{
|
||||
int32_t casted[4] = {
|
||||
@@ -1647,8 +1653,6 @@ void GLReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, const Subre
|
||||
}
|
||||
|
||||
{
|
||||
auto &texDetails = m_pDriver->m_Textures[texture];
|
||||
|
||||
// need to read stencil separately as GL can't read both depth and stencil
|
||||
// at the same time.
|
||||
if(texDetails.internalFormat == eGL_DEPTH24_STENCIL8 ||
|
||||
|
||||
@@ -2406,8 +2406,12 @@ void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, const S
|
||||
texDisplay.resourceId = texture;
|
||||
texDisplay.typeCast = typeCast;
|
||||
texDisplay.rawOutput = true;
|
||||
texDisplay.xOffset = -float(x << sub.mip);
|
||||
texDisplay.yOffset = -float(y << sub.mip);
|
||||
|
||||
uint32_t mipWidth = RDCMAX(1U, iminfo.extent.width >> sub.mip);
|
||||
uint32_t mipHeight = RDCMAX(1U, iminfo.extent.height >> sub.mip);
|
||||
|
||||
texDisplay.xOffset = -(float(x) / float(mipWidth)) * iminfo.extent.width;
|
||||
texDisplay.yOffset = -(float(y) / float(mipHeight)) * iminfo.extent.height;
|
||||
|
||||
// only render green (stencil) in second pass
|
||||
if(pass == 1)
|
||||
|
||||
@@ -97,6 +97,8 @@ private:
|
||||
bool dirty;
|
||||
} m_MainOutput;
|
||||
|
||||
rdcpair<uint32_t, uint32_t> m_TextureDim = {0, 0};
|
||||
|
||||
ResourceId m_OverlayResourceId;
|
||||
ResourceId m_CustomShaderResourceId;
|
||||
|
||||
|
||||
@@ -202,6 +202,15 @@ void ReplayOutput::SetTextureDisplay(const TextureDisplay &o)
|
||||
m_CustomDirty = true;
|
||||
m_RenderData.texDisplay = o;
|
||||
m_MainOutput.dirty = true;
|
||||
|
||||
m_TextureDim = {0, 0};
|
||||
for(size_t t = 0; t < m_pController->m_Textures.size(); t++)
|
||||
{
|
||||
if(m_pController->m_Textures[t].resourceId == m_RenderData.texDisplay.resourceId)
|
||||
{
|
||||
m_TextureDim = {m_pController->m_Textures[t].width, m_pController->m_Textures[t].height};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReplayOutput::SetMeshDisplay(const MeshDisplay &o)
|
||||
@@ -593,11 +602,25 @@ void ReplayOutput::DisplayContext()
|
||||
int x = (int)m_ContextX;
|
||||
int y = (int)m_ContextY;
|
||||
|
||||
x >>= disp.subresource.mip;
|
||||
x <<= disp.subresource.mip;
|
||||
if(m_TextureDim.first > 0 && m_TextureDim.second > 0)
|
||||
{
|
||||
rdcpair<uint32_t, uint32_t> mipDim = {RDCMAX(1U, m_TextureDim.first >> disp.subresource.mip),
|
||||
RDCMAX(1U, m_TextureDim.second >> disp.subresource.mip)};
|
||||
|
||||
y >>= disp.subresource.mip;
|
||||
y <<= disp.subresource.mip;
|
||||
x = int((float(x) / float(m_TextureDim.first)) * mipDim.first);
|
||||
x = int((float(x) / float(mipDim.first)) * m_TextureDim.first);
|
||||
|
||||
y = int((float(y) / float(m_TextureDim.second)) * mipDim.second);
|
||||
y = int((float(y) / float(mipDim.second)) * m_TextureDim.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
x >>= disp.subresource.mip;
|
||||
x <<= disp.subresource.mip;
|
||||
|
||||
y >>= disp.subresource.mip;
|
||||
y <<= disp.subresource.mip;
|
||||
}
|
||||
|
||||
disp.xOffset = -(float)x * disp.scale;
|
||||
disp.yOffset = -(float)y * disp.scale;
|
||||
|
||||
Reference in New Issue
Block a user