Commit 8866a85c by Nicolas Capens Committed by Nicolas Capens

Eliminate large image specialization

Images with dimensions of 65536 texels or more exceed the 16-bit logic used by our 'low' precision sampler code. Thus we were treating them differently and forced them to use our 32-bit code path. However, ordinary images can't have such large dimensions. Only texel buffers must support 65536 or more texels. Those can only be accessed by OpImageFetch, OpImageRead, and OpImageWrite instructions, and the latter two already use custom 32-bit addressing logic. Thus we can simply specify all Fetch operations to use the 32-bit sampler code path instead of differentiating based on resource dimensions. This fixes dEQP robustness tests which are enabled by the shaderStorageImageExtendedFormats feature, because the 16-bit code path does not bounds check fetch coordinates correctly. Note that fetch does not perform filtering, and thus there is no excess from using 32-bit filtering code. Bug: b/152224843 Tests: dEQP-VK.robustness.buffer_access.*.texel_copy.a2b10g10r10_unorm_pack32.oob_uniform_read.* Change-Id: Ie658e0fc9da05cad8efec58bac3238fb498ff10b Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/46131 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAntonio Maiorano <amaiorano@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com>
parent 7bc7120b
...@@ -106,7 +106,6 @@ struct Sampler ...@@ -106,7 +106,6 @@ struct Sampler
VkCompareOp compareOp; VkCompareOp compareOp;
VkBorderColor border; VkBorderColor border;
bool unnormalizedCoordinates; bool unnormalizedCoordinates;
bool largeTexture;
VkSamplerYcbcrModelConversion ycbcrModel; VkSamplerYcbcrModelConversion ycbcrModel;
bool studioSwing; // Narrow range bool studioSwing; // Narrow range
......
...@@ -151,8 +151,8 @@ Vector4f SamplerCore::sampleTexture(Pointer<Byte> &texture, Float4 uvw[4], Float ...@@ -151,8 +151,8 @@ Vector4f SamplerCore::sampleTexture(Pointer<Byte> &texture, Float4 uvw[4], Float
bool force32BitFiltering = state.highPrecisionFiltering && !isYcbcrFormat() && (state.textureFilter != FILTER_POINT); bool force32BitFiltering = state.highPrecisionFiltering && !isYcbcrFormat() && (state.textureFilter != FILTER_POINT);
bool seamlessCube = (state.addressingModeU == ADDRESSING_SEAMLESS); bool seamlessCube = (state.addressingModeU == ADDRESSING_SEAMLESS);
bool use32BitFiltering = hasFloatTexture() || hasUnnormalizedIntegerTexture() || force32BitFiltering || bool use32BitFiltering = hasFloatTexture() || hasUnnormalizedIntegerTexture() || force32BitFiltering ||
seamlessCube || state.unnormalizedCoordinates || state.compareEnable || state.largeTexture || seamlessCube || state.unnormalizedCoordinates || state.compareEnable ||
borderModeActive() || (function == Gather); borderModeActive() || (function == Gather) || (function == Fetch);
if(use32BitFiltering) if(use32BitFiltering)
{ {
...@@ -520,11 +520,9 @@ Vector4s SamplerCore::sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, ...@@ -520,11 +520,9 @@ Vector4s SamplerCore::sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v,
Pointer<Byte> buffer; Pointer<Byte> buffer;
selectMipmap(texture, mipmap, buffer, lod, secondLOD); selectMipmap(texture, mipmap, buffer, lod, secondLOD);
bool texelFetch = (function == Fetch); Short4 uuuu = address(u, state.addressingModeU, mipmap);
Short4 vvvv = address(v, state.addressingModeV, mipmap);
Short4 uuuu = texelFetch ? Short4(As<Int4>(u)) : address(u, state.addressingModeU, mipmap); Short4 wwww = address(w, state.addressingModeW, mipmap);
Short4 vvvv = texelFetch ? Short4(As<Int4>(v)) : address(v, state.addressingModeV, mipmap);
Short4 wwww = texelFetch ? Short4(As<Int4>(w)) : address(w, state.addressingModeW, mipmap);
Short4 cubeArrayId(0); Short4 cubeArrayId(0);
if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
...@@ -532,7 +530,7 @@ Vector4s SamplerCore::sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, ...@@ -532,7 +530,7 @@ Vector4s SamplerCore::sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v,
cubeArrayId = address(cubeArrayCoord, state.addressingModeY, mipmap); cubeArrayId = address(cubeArrayCoord, state.addressingModeY, mipmap);
} }
if(state.textureFilter == FILTER_POINT || texelFetch) if(state.textureFilter == FILTER_POINT)
{ {
c = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, cubeArrayId, sampleId, buffer, function); c = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, cubeArrayId, sampleId, buffer, function);
} }
...@@ -729,11 +727,9 @@ Vector4s SamplerCore::sample3D(Pointer<Byte> &texture, Float4 &u_, Float4 &v_, F ...@@ -729,11 +727,9 @@ Vector4s SamplerCore::sample3D(Pointer<Byte> &texture, Float4 &u_, Float4 &v_, F
Pointer<Byte> buffer; Pointer<Byte> buffer;
selectMipmap(texture, mipmap, buffer, lod, secondLOD); selectMipmap(texture, mipmap, buffer, lod, secondLOD);
bool texelFetch = (function == Fetch); Short4 uuuu = address(u_, state.addressingModeU, mipmap);
Short4 vvvv = address(v_, state.addressingModeV, mipmap);
Short4 uuuu = texelFetch ? Short4(As<Int4>(u_)) : address(u_, state.addressingModeU, mipmap); Short4 wwww = address(w_, state.addressingModeW, mipmap);
Short4 vvvv = texelFetch ? Short4(As<Int4>(v_)) : address(v_, state.addressingModeV, mipmap);
Short4 wwww = texelFetch ? Short4(As<Int4>(w_)) : address(w_, state.addressingModeW, mipmap);
Short4 cubeArrayId(0); Short4 cubeArrayId(0);
if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
...@@ -741,7 +737,7 @@ Vector4s SamplerCore::sample3D(Pointer<Byte> &texture, Float4 &u_, Float4 &v_, F ...@@ -741,7 +737,7 @@ Vector4s SamplerCore::sample3D(Pointer<Byte> &texture, Float4 &u_, Float4 &v_, F
cubeArrayId = address(cubeArrayCoord, state.addressingModeY, mipmap); cubeArrayId = address(cubeArrayCoord, state.addressingModeY, mipmap);
} }
if(state.textureFilter == FILTER_POINT || texelFetch) if(state.textureFilter == FILTER_POINT)
{ {
c_ = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, cubeArrayId, sampleId, buffer, function); c_ = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, cubeArrayId, sampleId, buffer, function);
} }
...@@ -1355,8 +1351,6 @@ Short4 SamplerCore::applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, Ad ...@@ -1355,8 +1351,6 @@ Short4 SamplerCore::applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, Ad
case AddressingMode::ADDRESSING_BORDER: // FIXME: Implement and test ADDRESSING_MIRROR, ADDRESSING_MIRRORONCE, ADDRESSING_BORDER case AddressingMode::ADDRESSING_BORDER: // FIXME: Implement and test ADDRESSING_MIRROR, ADDRESSING_MIRRORONCE, ADDRESSING_BORDER
tmp = Min(Max(tmp, Int4(0)), whd - Int4(1)); tmp = Min(Max(tmp, Int4(0)), whd - Int4(1));
break; break;
case ADDRESSING_TEXELFETCH:
break;
case AddressingMode::ADDRESSING_SEAMLESS: case AddressingMode::ADDRESSING_SEAMLESS:
ASSERT(false); // Cube sampling doesn't support offset. ASSERT(false); // Cube sampling doesn't support offset.
default: default:
...@@ -1368,21 +1362,15 @@ Short4 SamplerCore::applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, Ad ...@@ -1368,21 +1362,15 @@ Short4 SamplerCore::applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, Ad
void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, const Short4 &cubeArrayId, const Int4 &sampleId, SamplerFunction function) void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, const Short4 &cubeArrayId, const Int4 &sampleId, SamplerFunction function)
{ {
bool texelFetch = (function == Fetch);
bool hasOffset = (function.offset != 0); bool hasOffset = (function.offset != 0);
if(!texelFetch)
{
uuuu = MulHigh(As<UShort4>(uuuu), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, width)))); uuuu = MulHigh(As<UShort4>(uuuu), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, width))));
vvvv = MulHigh(As<UShort4>(vvvv), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, height)))); vvvv = MulHigh(As<UShort4>(vvvv), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, height))));
}
if(hasOffset) if(hasOffset)
{ {
uuuu = applyOffset(uuuu, offset.x, *Pointer<Int4>(mipmap + OFFSET(Mipmap, width)), uuuu = applyOffset(uuuu, offset.x, *Pointer<Int4>(mipmap + OFFSET(Mipmap, width)), state.addressingModeU);
texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeU); vvvv = applyOffset(vvvv, offset.y, *Pointer<Int4>(mipmap + OFFSET(Mipmap, height)), state.addressingModeV);
vvvv = applyOffset(vvvv, offset.y, *Pointer<Int4>(mipmap + OFFSET(Mipmap, height)),
texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeV);
} }
Short4 uuu2 = uuuu; Short4 uuu2 = uuuu;
...@@ -1395,15 +1383,11 @@ void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 ...@@ -1395,15 +1383,11 @@ void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4
{ {
if(state.textureType == VK_IMAGE_VIEW_TYPE_3D) if(state.textureType == VK_IMAGE_VIEW_TYPE_3D)
{ {
if(!texelFetch)
{
wwww = MulHigh(As<UShort4>(wwww), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, depth)))); wwww = MulHigh(As<UShort4>(wwww), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, depth))));
}
if(hasOffset) if(hasOffset)
{ {
wwww = applyOffset(wwww, offset.z, *Pointer<Int4>(mipmap + OFFSET(Mipmap, depth)), wwww = applyOffset(wwww, offset.z, *Pointer<Int4>(mipmap + OFFSET(Mipmap, depth)), state.addressingModeW);
texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeW);
} }
} }
...@@ -1423,22 +1407,6 @@ void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 ...@@ -1423,22 +1407,6 @@ void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4
index[3] = Extract(As<Int2>(uuu2), 1); index[3] = Extract(As<Int2>(uuu2), 1);
} }
if(texelFetch)
{
Int size = *Pointer<Int>(mipmap + OFFSET(Mipmap, sliceP));
if(hasThirdCoordinate())
{
size *= *Pointer<Int>(mipmap + OFFSET(Mipmap, depth));
}
UInt min = 0;
UInt max = size - 1;
for(int i = 0; i < 4; i++)
{
index[i] = Min(Max(index[i], min), max);
}
}
if(function.sample) if(function.sample)
{ {
UInt4 sampleOffset = Min(As<UInt4>(sampleId), *Pointer<UInt4>(mipmap + OFFSET(Mipmap, sampleMax), 16)) * UInt4 sampleOffset = Min(As<UInt4>(sampleId), *Pointer<UInt4>(mipmap + OFFSET(Mipmap, sampleMax), 16)) *
......
...@@ -56,9 +56,6 @@ SpirvShader::ImageSampler *SpirvShader::getImageSampler(uint32_t inst, vk::Sampl ...@@ -56,9 +56,6 @@ SpirvShader::ImageSampler *SpirvShader::getImageSampler(uint32_t inst, vk::Sampl
samplerState.mipmapFilter = convertMipmapMode(sampler); samplerState.mipmapFilter = convertMipmapMode(sampler);
samplerState.swizzle = imageDescriptor->swizzle; samplerState.swizzle = imageDescriptor->swizzle;
samplerState.gatherComponent = instruction.gatherComponent; samplerState.gatherComponent = instruction.gatherComponent;
samplerState.largeTexture = (imageDescriptor->extent.width > SHRT_MAX) ||
(imageDescriptor->extent.height > SHRT_MAX) ||
(imageDescriptor->extent.depth > SHRT_MAX);
if(sampler) if(sampler)
{ {
......
...@@ -64,12 +64,6 @@ Identifier::Identifier(const Image *image, VkImageViewType type, VkFormat fmt, V ...@@ -64,12 +64,6 @@ Identifier::Identifier(const Image *image, VkImageViewType type, VkFormat fmt, V
g = mapping.g; g = mapping.g;
b = mapping.b; b = mapping.b;
a = mapping.a; a = mapping.a;
// TODO(b/152224843): eliminate
auto extent = image->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
large = (extent.width > SHRT_MAX) ||
(extent.height > SHRT_MAX) ||
(extent.depth > SHRT_MAX);
} }
Identifier::Identifier(VkFormat fmt) Identifier::Identifier(VkFormat fmt)
......
...@@ -53,7 +53,6 @@ union Identifier ...@@ -53,7 +53,6 @@ union Identifier
uint32_t g : 3; uint32_t g : 3;
uint32_t b : 3; uint32_t b : 3;
uint32_t a : 3; uint32_t a : 3;
uint32_t large : 1; // Has dimension larger than SHRT_MAX (see b/133429305).
}; };
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment