Commit bb575d48 by Nicolas Capens Committed by Nicolas Capens

Address cubemap faces as consecutive layers

Vulkan cubemaps use six consecutive layers for the faces, so we can reuse the same addressing logic as for 2D array textures. Hence the 3D lookup vector becomes a 2D coordinate plus layer coordinate after projection. The only difference is we don't have to clamp to the range of layers. This simplifies the sampled image descriptor since we only have to store a single pointer per mipmap level. We also avoid the per-lane lookup (gather) operation. YCbCr sampling was adjusted to not use the same array of buffer pointers. Also eliminate the unused lodOrBias parameter from computeLod*(). It's added afterwards. Bug: b/134164485 Bug: b/129523279 Change-Id: I5c349ff458aabb1d77e32104429b635d96237292 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31088Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 95b1db96
...@@ -1855,7 +1855,7 @@ namespace sw ...@@ -1855,7 +1855,7 @@ namespace sw
// Low Border, Low Pixel, High Border, High Pixel // Low Border, Low Pixel, High Border, High Pixel
Int LB(-1), LP(0), HB(dim), HP(dim-1); Int LB(-1), LP(0), HB(dim), HP(dim-1);
for(int i = 0; i < 6; ++i) for(int face = 0; face < 6; face++)
{ {
computeCubeCorner(layers, LB, LP, LB, LP, pitchB, state); computeCubeCorner(layers, LB, LP, LB, LP, pitchB, state);
computeCubeCorner(layers, LB, LP, HB, HP, pitchB, state); computeCubeCorner(layers, LB, LP, HB, HP, pitchB, state);
......
...@@ -29,7 +29,7 @@ namespace sw ...@@ -29,7 +29,7 @@ namespace sw
{ {
struct Mipmap struct Mipmap
{ {
const void *buffer[6]; const void *buffer;
short4 uHalf; short4 uHalf;
short4 vHalf; short4 vHalf;
...@@ -102,7 +102,8 @@ namespace sw ...@@ -102,7 +102,8 @@ namespace sw
ADDRESSING_MIRRORONCE, ADDRESSING_MIRRORONCE,
ADDRESSING_BORDER, // Single color ADDRESSING_BORDER, // Single color
ADDRESSING_SEAMLESS, // Border of pixels ADDRESSING_SEAMLESS, // Border of pixels
ADDRESSING_LAYER, ADDRESSING_CUBEFACE, // Cube face layer
ADDRESSING_LAYER, // Array layer
ADDRESSING_TEXELFETCH, ADDRESSING_TEXELFETCH,
ADDRESSING_LAST = ADDRESSING_TEXELFETCH ADDRESSING_LAST = ADDRESSING_TEXELFETCH
......
...@@ -66,30 +66,30 @@ namespace sw ...@@ -66,30 +66,30 @@ namespace sw
private: private:
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, 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, bool secondLOD, SamplerFunction function);
Vector4s sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function); Vector4s sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
Vector4s sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function); Vector4s sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
Vector4s sample3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function); Vector4s sample3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], SamplerFunction function); Vector4f sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, SamplerFunction function);
Vector4f sampleFloatAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Int face[4], bool secondLOD, SamplerFunction function); Vector4f sampleFloatAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, bool secondLOD, SamplerFunction function);
Vector4f sampleFloat(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function); Vector4f sampleFloat(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, Int face[4], bool secondLOD, SamplerFunction function); Vector4f sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function); Vector4f sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function);
Float log2sqrt(Float lod); Float log2sqrt(Float lod);
Float log2(Float lod); Float log2(Float lod);
void computeLod(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &u, Float4 &v, const Float &lodOrBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function); void computeLod(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, Float4 &u, Float4 &v, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
void computeLodCube(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodOrBias, Vector4f &dsx, Vector4f &dsy, Float4 &M, SamplerFunction function); void computeLodCube(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float &lod, Float4 &u, Float4 &v, Float4 &w, Vector4f &dsx, Vector4f &dsy, Float4 &M, SamplerFunction function);
void computeLod3D(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float &lod, Float4 &u, Float4 &v, Float4 &w, const Float &lodOrBias, Vector4f &dsx, Vector4f &dsy, SamplerFunction function); void computeLod3D(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float &lod, Float4 &u, Float4 &v, Float4 &w, Vector4f &dsx, Vector4f &dsy, SamplerFunction function);
void cubeFace(Int face[4], Float4 &U, Float4 &V, Float4 &x, Float4 &y, Float4 &z, Float4 &M); Int4 cubeFace(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, Int4 valid, 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, SamplerFunction function);
Vector4s sampleTexel(UInt index[4], Pointer<Byte> buffer[4]); Vector4s sampleTexel(UInt index[4], Pointer<Byte> buffer);
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, SamplerFunction function);
Vector4f replaceBorderTexel(const Vector4f &c, Int4 valid); 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(const Pointer<Byte> &texture, Pointer<Byte> &mipmap, Pointer<Byte> &buffer, const Float &lod, 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);
Int4 computeFilterOffset(Float &lod); Int4 computeFilterOffset(Float &lod);
......
...@@ -272,12 +272,7 @@ sw::AddressingMode SpirvShader::convertAddressingMode(int coordinateIndex, VkSam ...@@ -272,12 +272,7 @@ sw::AddressingMode SpirvShader::convertAddressingMode(int coordinateIndex, VkSam
} }
// Fall through to CUBE case: // Fall through to CUBE case:
case VK_IMAGE_VIEW_TYPE_CUBE: case VK_IMAGE_VIEW_TYPE_CUBE:
if(coordinateIndex >= 2) if(coordinateIndex <= 1) // Cube faces themselves are addressed as 2D images.
{
// Cube faces are addressed as 2D images.
return ADDRESSING_UNUSED;
}
else
{ {
// Vulkan 1.1 spec: // 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 // "Cube images ignore the wrap modes specified in the sampler. Instead, if VK_FILTER_NEAREST is used within a mip level then
...@@ -286,6 +281,15 @@ sw::AddressingMode SpirvShader::convertAddressingMode(int coordinateIndex, VkSam ...@@ -286,6 +281,15 @@ sw::AddressingMode SpirvShader::convertAddressingMode(int coordinateIndex, VkSam
// This corresponds with our 'SEAMLESS' addressing mode. // This corresponds with our 'SEAMLESS' addressing mode.
return ADDRESSING_SEAMLESS; return ADDRESSING_SEAMLESS;
} }
else if(coordinateIndex == 2)
{
// The cube face is an index into array layers.
return ADDRESSING_CUBEFACE;
}
else
{
return ADDRESSING_UNUSED;
}
break; break;
case VK_IMAGE_VIEW_TYPE_1D: // Treated as 2D texture with second coordinate 0. case VK_IMAGE_VIEW_TYPE_1D: // Treated as 2D texture with second coordinate 0.
......
...@@ -1475,7 +1475,7 @@ namespace rr ...@@ -1475,7 +1475,7 @@ namespace rr
RValue<Vector4> operator=(RValue<typename Scalar<Vector4>::Type> rhs); RValue<Vector4> operator=(RValue<typename Scalar<Vector4>::Type> rhs);
private: private:
Float4 *parent; Vector4 *parent;
}; };
template<class Vector4, int T> template<class Vector4, int T>
......
...@@ -322,7 +322,7 @@ void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptor ...@@ -322,7 +322,7 @@ void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptor
imageSampler[i].texture.depth = sw::replicate(1); imageSampler[i].texture.depth = sw::replicate(1);
sw::Mipmap &mipmap = imageSampler[i].texture.mipmap[0]; sw::Mipmap &mipmap = imageSampler[i].texture.mipmap[0];
mipmap.buffer[0] = bufferView->getPointer(); mipmap.buffer = bufferView->getPointer();
mipmap.width[0] = mipmap.width[1] = mipmap.width[2] = mipmap.width[3] = 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.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.depth[0] = mipmap.depth[1] = mipmap.depth[2] = mipmap.depth[3] = 1;
...@@ -373,11 +373,11 @@ void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptor ...@@ -373,11 +373,11 @@ void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptor
const int level = 0; const int level = 0;
VkOffset3D offset = {0, 0, 0}; VkOffset3D offset = {0, 0, 0};
texture->mipmap[0].buffer[0] = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_0_BIT, level, 0, ImageView::SAMPLING); texture->mipmap[0].buffer = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_0_BIT, level, 0, ImageView::SAMPLING);
texture->mipmap[1].buffer[0] = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_1_BIT, level, 0, ImageView::SAMPLING); texture->mipmap[1].buffer = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_1_BIT, level, 0, ImageView::SAMPLING);
if(format.getAspects() & VK_IMAGE_ASPECT_PLANE_2_BIT) if(format.getAspects() & VK_IMAGE_ASPECT_PLANE_2_BIT)
{ {
texture->mipmap[2].buffer[0] = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_2_BIT, level, 0, ImageView::SAMPLING); texture->mipmap[2].buffer = imageView->getOffsetPointer(offset, VK_IMAGE_ASPECT_PLANE_2_BIT, level, 0, ImageView::SAMPLING);
} }
VkExtent3D extent = imageView->getMipLevelExtent(0); VkExtent3D extent = imageView->getMipLevelExtent(0);
...@@ -407,20 +407,15 @@ void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptor ...@@ -407,20 +407,15 @@ void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptor
if(imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE) if(imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE)
{ {
for(int face = 0; face < 6; face++) // Obtain the pointer to the corner of the level including the border, for seamless sampling.
{ // This is taken into account in the sampling routine, which can't handle negative texel coordinates.
// Obtain the pointer to the corner of the level including the border, for seamless sampling. VkOffset3D offset = {-1, -1, 0};
// This is taken into account in the sampling routine, which can't handle negative texel coordinates. mipmap.buffer = imageView->getOffsetPointer(offset, aspect, level, 0, ImageView::SAMPLING);
VkOffset3D offset = {-1, -1, 0};
// TODO(b/129523279): Implement as 6 consecutive layers instead of separate pointers.
mipmap.buffer[face] = imageView->getOffsetPointer(offset, aspect, level, face, ImageView::SAMPLING);
}
} }
else else
{ {
VkOffset3D offset = {0, 0, 0}; VkOffset3D offset = {0, 0, 0};
mipmap.buffer[0] = imageView->getOffsetPointer(offset, aspect, level, 0, ImageView::SAMPLING); mipmap.buffer = imageView->getOffsetPointer(offset, aspect, level, 0, ImageView::SAMPLING);
} }
VkExtent3D extent = imageView->getMipLevelExtent(level); VkExtent3D extent = imageView->getMipLevelExtent(level);
...@@ -438,7 +433,7 @@ void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptor ...@@ -438,7 +433,7 @@ void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptor
} }
} }
else if (entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || else if (entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
entry.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) entry.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)
{ {
auto descriptor = reinterpret_cast<StorageImageDescriptor *>(memToWrite); auto descriptor = reinterpret_cast<StorageImageDescriptor *>(memToWrite);
for(uint32_t i = 0; i < entry.descriptorCount; i++) for(uint32_t i = 0; i < entry.descriptorCount; i++)
...@@ -485,9 +480,9 @@ void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptor ...@@ -485,9 +480,9 @@ void DescriptorSetLayout::WriteDescriptorSet(DescriptorSet *dstSet, VkDescriptor
} }
} }
else if (entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || else if (entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || entry.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) entry.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)
{ {
auto descriptor = reinterpret_cast<BufferDescriptor *>(memToWrite); auto descriptor = reinterpret_cast<BufferDescriptor *>(memToWrite);
for (uint32_t i = 0; i < entry.descriptorCount; i++) for (uint32_t i = 0; i < entry.descriptorCount; i++)
......
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