Commit 3087370e by Nicolas Capens Committed by Nicolas Capens

Treat the array coordinate separately

The array layer coordinate isn't subject to addressing modes like the other coordinates. There's just one selection computation: https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#textures-unnormalized-to-integer This change eliminates the internally used ADDRESSING_LAYER mode, and avoids using the 'w' coordinate as the array layer coordinate for 2D array images (instead exclusively using it for 3D images). Also, the cube face index is combined with the array layer in case of cube array images. The division by 6 was eliminated by adjusting the descriptor 'depth' field instead. Bug: b/162315264 Change-Id: I4a541697ea265b3ad5b7d7c3a2420c045f46cbbe Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/47388 Presubmit-Ready: Nicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com>
parent 2e40a573
......@@ -83,7 +83,6 @@ enum AddressingMode ENUM_UNDERLYING_TYPE_UNSIGNED_INT
ADDRESSING_BORDER, // Single color
ADDRESSING_SEAMLESS, // Border of pixels
ADDRESSING_CUBEFACE, // Cube face layer
ADDRESSING_LAYER, // Array layer
ADDRESSING_TEXELFETCH,
ADDRESSING_LAST = ADDRESSING_TEXELFETCH
......@@ -97,7 +96,6 @@ struct Sampler
AddressingMode addressingModeU;
AddressingMode addressingModeV;
AddressingMode addressingModeW;
AddressingMode addressingModeA;
MipmapType mipmapFilter;
VkComponentMapping swizzle;
int gatherComponent;
......@@ -115,6 +113,26 @@ struct Sampler
float maxAnisotropy = 0.0f;
float minLod = 0.0f;
float maxLod = 0.0f;
bool isArrayed() const
{
switch(textureType)
{
case VK_IMAGE_VIEW_TYPE_1D:
case VK_IMAGE_VIEW_TYPE_2D:
case VK_IMAGE_VIEW_TYPE_3D:
case VK_IMAGE_VIEW_TYPE_CUBE:
return false;
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
return true;
default:
UNSUPPORTED("VkImageViewType %d", (int)textureType);
}
return false;
}
};
} // namespace sw
......
......@@ -61,16 +61,17 @@ public:
Vector4f sampleTexture(Pointer<Byte> &texture, Float4 uvwa[4], Float4 &q, Float &&lodOrBias, Float4 &dsx, Float4 &dsy, Vector4i &offset, Int4 &sample, SamplerFunction function);
private:
Float4 applySwizzle(const Vector4f &c, VkComponentSwizzle swizzle, bool integer);
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, const Float4 &cubeArrayCoord, Vector4i &offset, const Int4 &sample, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, SamplerFunction function);
Vector4s sampleAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &cubeArrayCoord, Vector4i &offset, const Int4 &sample, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, bool secondLOD, SamplerFunction function);
Vector4s sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &cubeArrayCoord, Vector4i &offset, const Int4 &sample, Float &lod, bool secondLOD, SamplerFunction function);
Vector4s sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &cubeArrayCoord, Vector4i &offset, const Int4 &sample, Float &lod, bool secondLOD, SamplerFunction function);
Vector4s sampleFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &a, Vector4i &offset, const Int4 &sample, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, SamplerFunction function);
Vector4s sampleAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &a, Vector4i &offset, const Int4 &sample, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, bool secondLOD, SamplerFunction function);
Vector4s sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &a, Vector4i &offset, const Int4 &sample, Float &lod, bool secondLOD, SamplerFunction function);
Vector4s sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &a, Vector4i &offset, const Int4 &sample, Float &lod, bool secondLOD, SamplerFunction function);
Vector4s sample3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4i &offset, const Int4 &sample, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &cubeArrayCoord, Float4 &dRef, Vector4i &offset, const Int4 &sample, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, SamplerFunction function);
Vector4f sampleFloatAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &cubeArrayCoord, Float4 &dRef, Vector4i &offset, const Int4 &sample, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, bool secondLOD, SamplerFunction function);
Vector4f sampleFloat(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &cubeArrayCoord, Float4 &dRef, Vector4i &offset, const Int4 &sample, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &cubeArrayCoord, Float4 &dRef, Vector4i &offset, const Int4 &sample, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &a, Float4 &dRef, Vector4i &offset, const Int4 &sample, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, SamplerFunction function);
Vector4f sampleFloatAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &a, Float4 &dRef, Vector4i &offset, const Int4 &sample, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, bool secondLOD, SamplerFunction function);
Vector4f sampleFloat(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &a, Float4 &dRef, Vector4i &offset, const Int4 &sample, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, const Float4 &a, Float4 &dRef, Vector4i &offset, const Int4 &sample, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &dRef, Vector4i &offset, const Int4 &sample, Float &lod, bool secondLOD, SamplerFunction function);
Float log2sqrt(Float lod);
Float log2(Float lod);
......@@ -80,14 +81,16 @@ private:
Int4 cubeFace(Float4 &U, Float4 &V, Float4 &x, Float4 &y, Float4 &z, Float4 &M);
Short4 applyOffset(Short4 &uvw, Int4 &offset, const Int4 &whd, AddressingMode mode);
void computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, const Short4 &cubeArrayLayer, Vector4i &offset, const Int4 &sample, const Pointer<Byte> &mipmap, SamplerFunction function);
void computeIndices(UInt index[4], Int4 uuuu, Int4 vvvv, Int4 wwww, const Int4 &cubeArrayLayer, const Int4 &sample, Int4 valid, const Pointer<Byte> &mipmap, SamplerFunction function);
void computeIndices(UInt index[4], Int4 uuuu, Int4 vvvv, Int4 wwww, const Int4 &sample, Int4 valid, const Pointer<Byte> &mipmap, SamplerFunction function);
Vector4s sampleTexel(Short4 &u, Short4 &v, Short4 &w, const Short4 &cubeArrayLayer, Vector4i &offset, const Int4 &sample, Pointer<Byte> &mipmap, Pointer<Byte> buffer, SamplerFunction function);
Vector4s sampleTexel(UInt index[4], Pointer<Byte> buffer);
Vector4f sampleTexel(Int4 &u, Int4 &v, Int4 &w, const Int4 &cubeArrayLayer, Float4 &dRef, const Int4 &sample, Pointer<Byte> &mipmap, Pointer<Byte> buffer, SamplerFunction function);
Vector4f sampleTexel(Int4 &u, Int4 &v, Int4 &w, Float4 &dRef, const Int4 &sample, Pointer<Byte> &mipmap, Pointer<Byte> buffer, SamplerFunction function);
Vector4f replaceBorderTexel(const Vector4f &c, Int4 valid);
void selectMipmap(const Pointer<Byte> &texture, Pointer<Byte> &mipmap, Pointer<Byte> &buffer, const Float &lod, bool secondLOD);
Short4 address(const Float4 &uw, AddressingMode addressingMode, Pointer<Byte> &mipmap);
void address(const Float4 &uw, Int4 &xyz0, Int4 &xyz1, Float4 &f, Pointer<Byte> &mipmap, Int4 &offset, Int4 &filter, int whd, AddressingMode addressingMode, SamplerFunction function);
Short4 address(const Float4 &uvw, AddressingMode addressingMode, Pointer<Byte> &mipmap);
Short4 computeLayerIndex(const Float4 &a, Pointer<Byte> &mipmap);
void address(const Float4 &uvw, Int4 &xyz0, Int4 &xyz1, Float4 &f, Pointer<Byte> &mipmap, Int4 &offset, Int4 &filter, int whd, AddressingMode addressingMode, SamplerFunction function);
Int4 computeLayerIndex(const Float4 &a, Pointer<Byte> &mipmap, SamplerFunction function);
Int4 computeFilterOffset(Float &lod);
void convertSigned15(Float4 &cf, Short4 &ci);
......
......@@ -51,7 +51,6 @@ SpirvShader::ImageSampler *SpirvShader::getImageSampler(uint32_t inst, vk::Sampl
samplerState.addressingModeU = convertAddressingMode(0, sampler, type);
samplerState.addressingModeV = convertAddressingMode(1, sampler, type);
samplerState.addressingModeW = convertAddressingMode(2, sampler, type);
samplerState.addressingModeA = convertAddressingMode(3, sampler, type);
samplerState.mipmapFilter = convertMipmapMode(sampler);
samplerState.swizzle = imageDescriptor->swizzle;
......@@ -281,71 +280,39 @@ sw::AddressingMode SpirvShader::convertAddressingMode(int coordinateIndex, const
{
switch(imageViewType)
{
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
if(coordinateIndex == 3)
{
return ADDRESSING_LAYER;
}
// Fall through to CUBE case:
case VK_IMAGE_VIEW_TYPE_CUBE:
if(coordinateIndex <= 1) // Cube faces themselves are addressed as 2D images.
{
// Vulkan 1.1 spec:
// "Cube images ignore the wrap modes specified in the sampler. Instead, if VK_FILTER_NEAREST is used within a mip level then
// VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE is used, and if VK_FILTER_LINEAR is used within a mip level then sampling at the edges
// is performed as described earlier in the Cube map edge handling section."
// This corresponds with our 'SEAMLESS' addressing mode.
return ADDRESSING_SEAMLESS;
}
else if(coordinateIndex == 2)
{
// The cube face is an index into array layers.
return ADDRESSING_CUBEFACE;
}
else
{
return ADDRESSING_UNUSED;
}
break;
case VK_IMAGE_VIEW_TYPE_1D: // Treated as 2D texture with second coordinate 0. TODO(b/134669567)
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
if(coordinateIndex == 1)
{
return ADDRESSING_WRAP;
}
else if(coordinateIndex >= 2)
// Fall through to 2D case:
case VK_IMAGE_VIEW_TYPE_2D:
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
if(coordinateIndex == 2)
{
return ADDRESSING_UNUSED;
}
break;
case VK_IMAGE_VIEW_TYPE_3D:
if(coordinateIndex >= 3)
{
return ADDRESSING_UNUSED;
}
break;
case VK_IMAGE_VIEW_TYPE_1D_ARRAY: // Treated as 2D texture with second coordinate 0. TODO(b/134669567)
if(coordinateIndex == 1)
{
return ADDRESSING_WRAP;
}
// Fall through to 2D_ARRAY case:
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
if(coordinateIndex == 2)
{
return ADDRESSING_LAYER;
}
else if(coordinateIndex >= 3)
case VK_IMAGE_VIEW_TYPE_CUBE:
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
if(coordinateIndex <= 1) // Cube faces themselves are addressed as 2D images.
{
return ADDRESSING_UNUSED;
// Vulkan 1.1 spec:
// "Cube images ignore the wrap modes specified in the sampler. Instead, if VK_FILTER_NEAREST is used within a mip level then
// VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE is used, and if VK_FILTER_LINEAR is used within a mip level then sampling at the edges
// is performed as described earlier in the Cube map edge handling section."
// This corresponds with our 'SEAMLESS' addressing mode.
return ADDRESSING_SEAMLESS;
}
// Fall through to 2D case:
case VK_IMAGE_VIEW_TYPE_2D:
if(coordinateIndex >= 2)
else // coordinateIndex == 2
{
return ADDRESSING_UNUSED;
// The cube face is an index into 2D array layers.
return ADDRESSING_CUBEFACE;
}
break;
......
......@@ -410,9 +410,10 @@ void DescriptorSetLayout::WriteDescriptorSet(Device *device, DescriptorSet *dstS
int width = extent.width;
int height = extent.height;
int bytes = format.bytes();
int layers = imageView->getSubresourceRange().layerCount; // TODO(b/129523279): Untangle depth vs layers throughout the sampler
int layers = imageView->getSubresourceRange().layerCount;
int depth = layers > 1 ? layers : extent.depth;
if(imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) depth /= 6;
int bytes = format.bytes();
int pitchP = imageView->rowPitchBytes(aspect, level, ImageView::SAMPLING) / bytes;
int sliceP = (layers > 1 ? imageView->layerPitchBytes(aspect, ImageView::SAMPLING) : imageView->slicePitchBytes(aspect, level, ImageView::SAMPLING)) / bytes;
int samplePitchP = imageView->getMipLevelSize(aspect, level, ImageView::SAMPLING) / bytes;
......@@ -492,25 +493,14 @@ void DescriptorSetLayout::WriteTextureLevelInfo(sw::Texture *texture, int level,
{
if(level == 0)
{
texture->widthWidthHeightHeight[0] =
texture->widthWidthHeightHeight[1] = static_cast<float>(width);
texture->widthWidthHeightHeight[2] =
texture->widthWidthHeightHeight[3] = static_cast<float>(height);
texture->width[0] =
texture->width[1] =
texture->width[2] =
texture->width[3] = static_cast<float>(width);
texture->height[0] =
texture->height[1] =
texture->height[2] =
texture->height[3] = static_cast<float>(height);
texture->depth[0] =
texture->depth[1] =
texture->depth[2] =
texture->depth[3] = static_cast<float>(depth);
texture->widthWidthHeightHeight[0] = static_cast<float>(width);
texture->widthWidthHeightHeight[1] = static_cast<float>(width);
texture->widthWidthHeightHeight[2] = static_cast<float>(height);
texture->widthWidthHeightHeight[3] = static_cast<float>(height);
texture->width = sw::float4(static_cast<float>(width));
texture->height = sw::float4(static_cast<float>(height));
texture->depth = sw::float4(static_cast<float>(depth));
}
sw::Mipmap &mipmap = texture->mipmap[level];
......@@ -519,60 +509,23 @@ void DescriptorSetLayout::WriteTextureLevelInfo(sw::Texture *texture, int level,
short halfTexelV = 0x8000 / height;
short halfTexelW = 0x8000 / depth;
mipmap.uHalf[0] =
mipmap.uHalf[1] =
mipmap.uHalf[2] =
mipmap.uHalf[3] = halfTexelU;
mipmap.vHalf[0] =
mipmap.vHalf[1] =
mipmap.vHalf[2] =
mipmap.vHalf[3] = halfTexelV;
mipmap.wHalf[0] =
mipmap.wHalf[1] =
mipmap.wHalf[2] =
mipmap.wHalf[3] = halfTexelW;
mipmap.width[0] =
mipmap.width[1] =
mipmap.width[2] =
mipmap.width[3] = width;
mipmap.height[0] =
mipmap.height[1] =
mipmap.height[2] =
mipmap.height[3] = height;
mipmap.uHalf = sw::short4(halfTexelU);
mipmap.vHalf = sw::short4(halfTexelV);
mipmap.wHalf = sw::short4(halfTexelW);
mipmap.depth[0] =
mipmap.depth[1] =
mipmap.depth[2] =
mipmap.depth[3] = depth;
mipmap.width = sw::int4(width);
mipmap.height = sw::int4(height);
mipmap.depth = sw::int4(depth);
mipmap.onePitchP[0] = 1;
mipmap.onePitchP[1] = static_cast<short>(pitchP);
mipmap.onePitchP[2] = 1;
mipmap.onePitchP[3] = static_cast<short>(pitchP);
mipmap.pitchP[0] = pitchP;
mipmap.pitchP[1] = pitchP;
mipmap.pitchP[2] = pitchP;
mipmap.pitchP[3] = pitchP;
mipmap.sliceP[0] = sliceP;
mipmap.sliceP[1] = sliceP;
mipmap.sliceP[2] = sliceP;
mipmap.sliceP[3] = sliceP;
mipmap.samplePitchP[0] = samplePitchP;
mipmap.samplePitchP[1] = samplePitchP;
mipmap.samplePitchP[2] = samplePitchP;
mipmap.samplePitchP[3] = samplePitchP;
mipmap.sampleMax[0] = sampleMax;
mipmap.sampleMax[1] = sampleMax;
mipmap.sampleMax[2] = sampleMax;
mipmap.sampleMax[3] = sampleMax;
mipmap.pitchP = sw::int4(pitchP);
mipmap.sliceP = sw::int4(sliceP);
mipmap.samplePitchP = sw::int4(samplePitchP);
mipmap.sampleMax = sw::int4(sampleMax);
}
void DescriptorSetLayout::WriteDescriptorSet(Device *device, const VkWriteDescriptorSet &writeDescriptorSet)
......
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