Fix calculation of small mip co-ordinates for NPOT textures

This commit is contained in:
baldurk
2022-07-15 18:07:08 +01:00
parent 123509166e
commit 234262649f
9 changed files with 161 additions and 46 deletions
+46 -18
View File
@@ -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();
+2
View File
@@ -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);
+16 -14
View File
@@ -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);
+41 -2
View File
@@ -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);
}
+13 -2
View File
@@ -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,
+8 -4
View File
@@ -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 ||
+6 -2
View File
@@ -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)
+2
View File
@@ -97,6 +97,8 @@ private:
bool dirty;
} m_MainOutput;
rdcpair<uint32_t, uint32_t> m_TextureDim = {0, 0};
ResourceId m_OverlayResourceId;
ResourceId m_CustomShaderResourceId;
+27 -4
View File
@@ -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;