Support for large textures
Texture dimensions larger than SHRT_MAX (32767)
were not supported by SwiftShader. Used integers
instead of shorts to store texture sizes to
increase the maximum texture size to INT_MAX
(2147483647).
Tests: dEQP-VK.memory.pipeline_barrier.host_write_uniform_texel_buffer.*
Tests: dEQP-VK.memory.pipeline_barrier.transfer_dst_uniform_texel_buffer.*
Bug b/133429305
Change-Id: I7913f5f4c1f933889e74c57851a837ad7982f87a
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31989
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Device/Sampler.hpp b/src/Device/Sampler.hpp
index 8768a19..cbe29d8 100644
--- a/src/Device/Sampler.hpp
+++ b/src/Device/Sampler.hpp
@@ -31,16 +31,12 @@
{
const void *buffer[6];
- float4 fWidth;
- float4 fHeight;
- float4 fDepth;
-
short uHalf[4];
short vHalf[4];
short wHalf[4];
- short width[4];
- short height[4];
- short depth[4];
+ int4 width;
+ int4 height;
+ int4 depth;
short onePitchP[4];
int4 pitchP;
int4 sliceP;
@@ -154,6 +150,7 @@
VkCompareOp compareOp;
VkBorderColor border;
bool unnormalizedCoordinates;
+ bool largeTexture;
#if PERF_PROFILE
bool compressedFormat;
diff --git a/src/Pipeline/SamplerCore.cpp b/src/Pipeline/SamplerCore.cpp
index ef0e75c..f3e4d1b 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -150,7 +150,8 @@
bool force32BitFiltering = state.highPrecisionFiltering && !hasYuvFormat() && (state.textureFilter != FILTER_POINT);
bool seamlessCube = (state.addressingModeU == ADDRESSING_SEAMLESS);
bool use32BitFiltering = hasFloatTexture() || hasUnnormalizedIntegerTexture() || force32BitFiltering ||
- seamlessCube || state.unnormalizedCoordinates || state.compareEnable || borderModeActive();
+ seamlessCube || state.unnormalizedCoordinates || state.compareEnable || state.largeTexture ||
+ borderModeActive();
if(use32BitFiltering)
{
@@ -448,8 +449,8 @@
if(!gather) // Blend
{
// Fractions
- UShort4 f0u = As<UShort4>(uuuu0) * *Pointer<UShort4>(mipmap + OFFSET(Mipmap,width));
- UShort4 f0v = As<UShort4>(vvvv0) * *Pointer<UShort4>(mipmap + OFFSET(Mipmap,height));
+ UShort4 f0u = As<UShort4>(uuuu0) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap,width)));
+ UShort4 f0v = As<UShort4>(vvvv0) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap,height)));
UShort4 f1u = ~f0u;
UShort4 f1v = ~f0v;
@@ -650,9 +651,9 @@
}
// Fractions
- UShort4 f0u = As<UShort4>(u[0][0][0]) * *Pointer<UShort4>(mipmap + OFFSET(Mipmap,width));
- UShort4 f0v = As<UShort4>(v[0][0][0]) * *Pointer<UShort4>(mipmap + OFFSET(Mipmap,height));
- UShort4 f0s = As<UShort4>(s[0][0][0]) * *Pointer<UShort4>(mipmap + OFFSET(Mipmap,depth));
+ UShort4 f0u = As<UShort4>(u[0][0][0]) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap,width)));
+ UShort4 f0v = As<UShort4>(v[0][0][0]) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap,height)));
+ UShort4 f0s = As<UShort4>(s[0][0][0]) * UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap,depth)));
UShort4 f1u = ~f0u;
UShort4 f1v = ~f0v;
@@ -1203,16 +1204,16 @@
if(!texelFetch)
{
- uuuu = MulHigh(As<UShort4>(uuuu), *Pointer<UShort4>(mipmap + OFFSET(Mipmap, width)));
- vvvv = MulHigh(As<UShort4>(vvvv), *Pointer<UShort4>(mipmap + OFFSET(Mipmap, height)));
+ uuuu = MulHigh(As<UShort4>(uuuu), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, width))));
+ vvvv = MulHigh(As<UShort4>(vvvv), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, height))));
}
if(hasOffset)
{
- UShort4 w = *Pointer<UShort4>(mipmap + OFFSET(Mipmap, width));
- uuuu = applyOffset(uuuu, offset.x, Int4(w), texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeU);
- UShort4 h = *Pointer<UShort4>(mipmap + OFFSET(Mipmap, height));
- vvvv = applyOffset(vvvv, offset.y, Int4(h), texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeV);
+ uuuu = applyOffset(uuuu, offset.x, *Pointer<Int4>(mipmap + OFFSET(Mipmap, width)),
+ texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeU);
+ vvvv = applyOffset(vvvv, offset.y, *Pointer<Int4>(mipmap + OFFSET(Mipmap, height)),
+ texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeV);
}
Short4 uuu2 = uuuu;
@@ -1227,13 +1228,13 @@
{
if(!texelFetch)
{
- wwww = MulHigh(As<UShort4>(wwww), *Pointer<UShort4>(mipmap + OFFSET(Mipmap, depth)));
+ wwww = MulHigh(As<UShort4>(wwww), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, depth))));
}
if(hasOffset)
{
- UShort4 d = *Pointer<UShort4>(mipmap + OFFSET(Mipmap, depth));
- wwww = applyOffset(wwww, offset.z, Int4(d), texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeW);
+ wwww = applyOffset(wwww, offset.z, *Pointer<Int4>(mipmap + OFFSET(Mipmap, depth)),
+ texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeW);
}
}
@@ -1255,10 +1256,10 @@
if(texelFetch)
{
- Int size = Int(*Pointer<Int>(mipmap + OFFSET(Mipmap, sliceP)));
+ Int size = *Pointer<Int>(mipmap + OFFSET(Mipmap, sliceP));
if(hasThirdCoordinate())
{
- size *= Int(*Pointer<Short>(mipmap + OFFSET(Mipmap, depth)));
+ size *= *Pointer<Int>(mipmap + OFFSET(Mipmap, depth));
}
UInt min = 0;
UInt max = size - 1;
@@ -1989,7 +1990,7 @@
}
else if(addressingMode == ADDRESSING_LAYER)
{
- return Min(Max(Short4(RoundInt(uw)), Short4(0)), *Pointer<Short4>(mipmap + OFFSET(Mipmap, depth)) - Short4(1));
+ return Short4(Min(Max(RoundInt(uw), Int4(0)), *Pointer<Int4>(mipmap + OFFSET(Mipmap, depth)) - Int4(1)));
}
else if(addressingMode == ADDRESSING_CLAMP || addressingMode == ADDRESSING_BORDER)
{
@@ -2030,7 +2031,7 @@
return;
}
- Int4 dim = Int4(*Pointer<Short4>(mipmap + whd, 16));
+ Int4 dim = *Pointer<Int4>(mipmap + whd, 16);
Int4 maxXYZ = dim - Int4(1);
if(function == Fetch)
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index 9a3ae2a..e7b7848 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -28,6 +28,7 @@
#include <spirv/unified1/spirv.hpp>
#include <spirv/unified1/GLSL.std.450.h>
+#include <climits>
#include <mutex>
namespace sw {
@@ -66,6 +67,9 @@
samplerState.compareEnable = (sampler->compareEnable == VK_TRUE);
samplerState.compareOp = sampler->compareOp;
samplerState.unnormalizedCoordinates = (sampler->unnormalizedCoordinates == VK_TRUE);
+ samplerState.largeTexture = (imageDescriptor->extent.width > SHRT_MAX) ||
+ (imageDescriptor->extent.height > SHRT_MAX) ||
+ (imageDescriptor->extent.depth > SHRT_MAX);
if(sampler->anisotropyEnable != VK_FALSE)
{
diff --git a/src/Vulkan/VkDescriptorSetLayout.cpp b/src/Vulkan/VkDescriptorSetLayout.cpp
index 58985c4..d0b906a 100644
--- a/src/Vulkan/VkDescriptorSetLayout.cpp
+++ b/src/Vulkan/VkDescriptorSetLayout.cpp
@@ -323,7 +323,7 @@
sw::Mipmap &mipmap = imageSampler[i].texture.mipmap[0];
mipmap.buffer[0] = bufferView->getPointer();
- mipmap.width[0] = mipmap.width[1] = mipmap.width[2] = mipmap.width[3] = static_cast<short>(numElements);
+ mipmap.width[0] = mipmap.width[1] = mipmap.width[2] = mipmap.width[3] = numElements;
mipmap.height[0] = mipmap.height[1] = mipmap.height[2] = mipmap.height[3] = 1;
mipmap.depth[0] = mipmap.depth[1] = mipmap.depth[2] = mipmap.depth[3] = 1;
mipmap.pitchP.x = mipmap.pitchP.y = mipmap.pitchP.z = mipmap.pitchP.w = numElements;
@@ -419,24 +419,6 @@
texture->depth[3] = depth;
}
- if(format.isFloatFormat())
- {
- mipmap.fWidth[0] = (float)width / 65536.0f;
- mipmap.fWidth[1] = (float)width / 65536.0f;
- mipmap.fWidth[2] = (float)width / 65536.0f;
- mipmap.fWidth[3] = (float)width / 65536.0f;
-
- mipmap.fHeight[0] = (float)height / 65536.0f;
- mipmap.fHeight[1] = (float)height / 65536.0f;
- mipmap.fHeight[2] = (float)height / 65536.0f;
- mipmap.fHeight[3] = (float)height / 65536.0f;
-
- mipmap.fDepth[0] = (float)depth / 65536.0f;
- mipmap.fDepth[1] = (float)depth / 65536.0f;
- mipmap.fDepth[2] = (float)depth / 65536.0f;
- mipmap.fDepth[3] = (float)depth / 65536.0f;
- }
-
short halfTexelU = 0x8000 / width;
short halfTexelV = 0x8000 / height;
short halfTexelW = 0x8000 / depth;