Commit 60a6a2e7 by Nicolas Capens Committed by Nicolas Capens

Fix clamp-to-border addressing mode

Previously we would check for out-of-range coordinates after filtering to replace the sampled color with the border color. This is incorrect as according to Vulkan 1.1 spec section 15.3.3. Texel Replacement the replacement happens per texel, before filtering. This is achieved by replacing out-of-range coordinates with -1, which will get multiplied by pitch and slice for the second and third coordinate respectively, but will remain negative. These negative coordinates are then detected during sample fetch to look up the texel at 0 instead, and then replace it with the border color. Bug: b/129523279 Test: dEQP-VK.pipeline.image.* Test: dEQP-VK.pipeline.sampler.* Change-Id: I0949e6a4701285f7511bf2b1579bd8a303f2ddb6 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/30710 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com>
parent 8b7597e6
...@@ -63,8 +63,6 @@ namespace sw ...@@ -63,8 +63,6 @@ namespace sw
Vector4f sampleTexture(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &lodOrBias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function); Vector4f sampleTexture(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float4 &lodOrBias, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function);
private: private:
void border(Short4 &mask, Float4 &coordinates);
void border(Int4 &mask, Float4 &coordinates);
Short4 offsetSample(Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod); Short4 offsetSample(Short4 &uvw, Pointer<Byte> &mipmap, int halfOffset, bool wrap, int count, Float &lod);
Vector4s sampleFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function); Vector4s sampleFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function);
Vector4s sampleAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function); Vector4s sampleAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function);
...@@ -84,10 +82,11 @@ namespace sw ...@@ -84,10 +82,11 @@ namespace sw
void cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &x, Float4 &y, Float4 &z, Float4 &M); void cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &x, Float4 &y, Float4 &z, Float4 &M);
Short4 applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, AddressingMode mode); Short4 applyOffset(Short4 &uvw, Float4 &offset, const Int4 &whd, AddressingMode mode);
void computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, SamplerFunction function); void computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, SamplerFunction function);
void computeIndices(UInt index[4], Int4& uuuu, Int4& vvvv, Int4& wwww, const Pointer<Byte> &mipmap, SamplerFunction function); void computeIndices(UInt index[4], Int4 uuuu, Int4 vvvv, Int4 wwww, Int4 valid, const Pointer<Byte> &mipmap, SamplerFunction function);
Vector4s sampleTexel(Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], SamplerFunction function); Vector4s sampleTexel(Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], SamplerFunction function);
Vector4s sampleTexel(UInt index[4], Pointer<Byte> buffer[4]); Vector4s sampleTexel(UInt index[4], Pointer<Byte> buffer[4]);
Vector4f sampleTexel(Int4 &u, Int4 &v, Int4 &s, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], SamplerFunction function); Vector4f sampleTexel(Int4 &u, Int4 &v, Int4 &s, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer[4], SamplerFunction function);
Vector4f replaceBorderTexel(const Vector4f &c, Int4 valid);
void selectMipmap(Pointer<Byte> &texture, Pointer<Byte> buffer[4], Pointer<Byte> &mipmap, Float &lod, Int face[4], bool secondLOD); void selectMipmap(Pointer<Byte> &texture, Pointer<Byte> buffer[4], Pointer<Byte> &mipmap, Float &lod, Int face[4], bool secondLOD);
Short4 address(Float4 &uw, AddressingMode addressingMode, Pointer<Byte>& mipmap); Short4 address(Float4 &uw, AddressingMode addressingMode, Pointer<Byte>& mipmap);
void address(Float4 &uw, Int4& xyz0, Int4& xyz1, Float4& f, Pointer<Byte>& mipmap, Float4 &texOffset, Int4 &filter, int whd, AddressingMode addressingMode, SamplerFunction function); void address(Float4 &uw, Int4& xyz0, Int4& xyz1, Float4& f, Pointer<Byte>& mipmap, Float4 &texOffset, Int4 &filter, int whd, AddressingMode addressingMode, SamplerFunction function);
...@@ -108,6 +107,7 @@ namespace sw ...@@ -108,6 +107,7 @@ namespace sw
bool has32bitIntegerTextureComponents() const; bool has32bitIntegerTextureComponents() const;
bool hasYuvFormat() const; bool hasYuvFormat() const;
bool isRGBComponent(int component) const; bool isRGBComponent(int component) const;
bool borderModeActive() const;
Pointer<Byte> &constants; Pointer<Byte> &constants;
const Sampler &state; const Sampler &state;
......
...@@ -238,10 +238,25 @@ sw::AddressingMode SpirvShader::convertAddressingMode(int coordinateIndex, VkSam ...@@ -238,10 +238,25 @@ sw::AddressingMode SpirvShader::convertAddressingMode(int coordinateIndex, VkSam
} }
break; break;
case VK_IMAGE_VIEW_TYPE_1D: case VK_IMAGE_VIEW_TYPE_1D:
if(coordinateIndex >= 1)
{
return ADDRESSING_WRAP; // Unused, but must avoid BORDER mode.
}
break;
case VK_IMAGE_VIEW_TYPE_2D: case VK_IMAGE_VIEW_TYPE_2D:
if(coordinateIndex == 2)
{
return ADDRESSING_WRAP; // Unused, but must avoid BORDER mode.
}
break;
case VK_IMAGE_VIEW_TYPE_3D: case VK_IMAGE_VIEW_TYPE_3D:
break; break;
case VK_IMAGE_VIEW_TYPE_1D_ARRAY: // Treated as 2D texture with second coordinate 0. case VK_IMAGE_VIEW_TYPE_1D_ARRAY: // Treated as 2D texture with second coordinate 0.
if(coordinateIndex == 1)
{
return ADDRESSING_WRAP; // Unused, but must avoid BORDER mode.
}
// Fall through to 2D array case
case VK_IMAGE_VIEW_TYPE_2D_ARRAY: case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
if(coordinateIndex == 2) if(coordinateIndex == 2)
{ {
......
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