Commit 7a15cef2 by Alexis Hetu Committed by Alexis Hétu

Cubemap array support

This cl adds logic to propagate the 4th texture coordinate, which is only used for cubemap arrays, and use it as the cubemap array id. Tests: dEQP-VK.glsl.texture_functions*cubearray* Bug: b/144988970 Change-Id: I241b9a50a87424461647f00d442774ead8aaa0f7 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/38876 Presubmit-Ready: Alexis Hétu <sugoi@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarBen Clayton <bclayton@google.com>
parent 84d0f7cb
......@@ -99,6 +99,7 @@ namespace sw
AddressingMode addressingModeU;
AddressingMode addressingModeV;
AddressingMode addressingModeW;
AddressingMode addressingModeY;
MipmapType mipmapFilter;
VkComponentMapping swizzle;
int gatherComponent;
......
......@@ -53,13 +53,14 @@ namespace sw
{
}
Vector4f SamplerCore::sampleTexture(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float &&lodOrBias, Float4 &dsx, Float4 &dsy, Vector4f &offset, Int4& sampleId, SamplerFunction function)
Vector4f SamplerCore::sampleTexture(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float4 uvw[4], Float4 &q, Float &&lodOrBias, Float4 &dsx, Float4 &dsy, Vector4f &offset, Int4& sampleId, SamplerFunction function)
{
Vector4f c;
Float4 uuuu = u;
Float4 vvvv = v;
Float4 wwww = w;
Float4 uuuu = uvw[0];
Float4 vvvv = uvw[1];
Float4 wwww = uvw[2];
Float4 cubeArrayCoord = uvw[3];
Float4 qqqq = q;
Float lod;
......@@ -68,9 +69,9 @@ namespace sw
Float4 vDelta;
Float4 M; // Major axis
if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE)
if(isCube())
{
Int4 face = cubeFace(uuuu, vvvv, u, v, w, M);
Int4 face = cubeFace(uuuu, vvvv, uvw[0], uvw[1], uvw[2], M);
wwww = As<Float4>(face);
}
......@@ -78,13 +79,13 @@ namespace sw
{
if(state.textureType != VK_IMAGE_VIEW_TYPE_3D)
{
if(state.textureType != VK_IMAGE_VIEW_TYPE_CUBE)
if(!isCube())
{
computeLod(texture, sampler, lod, anisotropy, uDelta, vDelta, uuuu, vvvv, dsx, dsy, function);
}
else
{
computeLodCube(texture, sampler, lod, u, v, w, dsx, dsy, M, function);
computeLodCube(texture, sampler, lod, uvw[0], uvw[1], uvw[2], dsx, dsy, M, function);
}
}
else
......@@ -151,7 +152,7 @@ namespace sw
if(use32BitFiltering)
{
c = sampleFloatFilter(texture, uuuu, vvvv, wwww, qqqq, offset, sampleId, lod, anisotropy, uDelta, vDelta, function);
c = sampleFloatFilter(texture, uuuu, vvvv, wwww, qqqq, offset, cubeArrayCoord, sampleId, lod, anisotropy, uDelta, vDelta, function);
if (!hasFloatTexture() && !hasUnnormalizedIntegerTexture() && !state.compareEnable)
{
......@@ -207,7 +208,7 @@ namespace sw
}
else // 16-bit filtering.
{
Vector4s cs = sampleFilter(texture, uuuu, vvvv, wwww, offset, sampleId, lod, anisotropy, uDelta, vDelta, function);
Vector4s cs = sampleFilter(texture, uuuu, vvvv, wwww, offset, cubeArrayCoord, sampleId, lod, anisotropy, uDelta, vDelta, function);
switch (state.textureFormat)
{
......@@ -339,9 +340,9 @@ namespace sw
return uvw;
}
Vector4s SamplerCore::sampleFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Int4& sampleId, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, SamplerFunction function)
Vector4s SamplerCore::sampleFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, SamplerFunction function)
{
Vector4s c = sampleAniso(texture, u, v, w, offset, sampleId, lod, anisotropy, uDelta, vDelta, false, function);
Vector4s c = sampleAniso(texture, u, v, w, offset, cubeArrayCoord, sampleId, lod, anisotropy, uDelta, vDelta, false, function);
if(function == Fetch)
{
......@@ -350,7 +351,7 @@ namespace sw
if(state.mipmapFilter == MIPMAP_LINEAR)
{
Vector4s cc = sampleAniso(texture, u, v, w, offset, sampleId, lod, anisotropy, uDelta, vDelta, true, function);
Vector4s cc = sampleAniso(texture, u, v, w, offset, cubeArrayCoord, sampleId, lod, anisotropy, uDelta, vDelta, true, function);
lod *= Float(1 << 16);
......@@ -384,13 +385,13 @@ namespace sw
return c;
}
Vector4s SamplerCore::sampleAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Int4& sampleId, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, bool secondLOD, SamplerFunction function)
Vector4s SamplerCore::sampleAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, bool secondLOD, SamplerFunction function)
{
Vector4s c;
if(state.textureFilter != FILTER_ANISOTROPIC || function == Lod || function == Fetch)
{
c = sampleQuad(texture, u, v, w, offset, sampleId, lod, secondLOD, function);
c = sampleQuad(texture, u, v, w, offset, cubeArrayCoord, sampleId, lod, secondLOD, function);
}
else
{
......@@ -421,7 +422,7 @@ namespace sw
Do
{
c = sampleQuad(texture, u0, v0, w, offset, sampleId, lod, secondLOD, function);
c = sampleQuad(texture, u0, v0, w, offset, cubeArrayCoord, sampleId, lod, secondLOD, function);
u0 += du;
v0 += dv;
......@@ -444,19 +445,19 @@ namespace sw
return c;
}
Vector4s SamplerCore::sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
Vector4s SamplerCore::sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
{
if(state.textureType != VK_IMAGE_VIEW_TYPE_3D)
{
return sampleQuad2D(texture, u, v, w, offset, sampleId, lod, secondLOD, function);
return sampleQuad2D(texture, u, v, w, offset, cubeArrayCoord, sampleId, lod, secondLOD, function);
}
else
{
return sample3D(texture, u, v, w, offset, sampleId, lod, secondLOD, function);
return sample3D(texture, u, v, w, offset, cubeArrayCoord, sampleId, lod, secondLOD, function);
}
}
Vector4s SamplerCore::sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
Vector4s SamplerCore::sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
{
Vector4s c;
......@@ -473,9 +474,15 @@ namespace sw
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);
if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
{
cubeArrayId = address(cubeArrayCoord, state.addressingModeY, mipmap);
}
if(state.textureFilter == FILTER_POINT || texelFetch)
{
c = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, sampleId, buffer, function);
c = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, cubeArrayId, sampleId, buffer, function);
}
else
{
......@@ -484,10 +491,10 @@ namespace sw
Short4 uuuu1 = offsetSample(uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, +1, lod);
Short4 vvvv1 = offsetSample(vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, +1, lod);
Vector4s c00 = sampleTexel(uuuu0, vvvv0, wwww, offset, mipmap, sampleId, buffer, function);
Vector4s c10 = sampleTexel(uuuu1, vvvv0, wwww, offset, mipmap, sampleId, buffer, function);
Vector4s c01 = sampleTexel(uuuu0, vvvv1, wwww, offset, mipmap, sampleId, buffer, function);
Vector4s c11 = sampleTexel(uuuu1, vvvv1, wwww, offset, mipmap, sampleId, buffer, function);
Vector4s c00 = sampleTexel(uuuu0, vvvv0, wwww, offset, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4s c10 = sampleTexel(uuuu1, vvvv0, wwww, offset, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4s c01 = sampleTexel(uuuu0, vvvv1, wwww, offset, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4s c11 = sampleTexel(uuuu1, vvvv1, wwww, offset, mipmap, cubeArrayId, sampleId, buffer, function);
if(!gather) // Blend
{
......@@ -660,7 +667,7 @@ namespace sw
return c;
}
Vector4s SamplerCore::sample3D(Pointer<Byte> &texture, Float4 &u_, Float4 &v_, Float4 &w_, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
Vector4s SamplerCore::sample3D(Pointer<Byte> &texture, Float4 &u_, Float4 &v_, Float4 &w_, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
{
Vector4s c_;
......@@ -676,9 +683,15 @@ namespace sw
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);
if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
{
cubeArrayId = address(cubeArrayCoord, state.addressingModeY, mipmap);
}
if(state.textureFilter == FILTER_POINT || texelFetch)
{
c_ = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, sampleId, buffer, function);
c_ = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, cubeArrayId, sampleId, buffer, function);
}
else
{
......@@ -750,7 +763,7 @@ namespace sw
{
for(int k = 0; k < 2; k++)
{
c[i][j][k] = sampleTexel(u[i][j][k], v[i][j][k], s[i][j][k], offset, mipmap, sampleId, buffer, function);
c[i][j][k] = sampleTexel(u[i][j][k], v[i][j][k], s[i][j][k], offset, mipmap, cubeArrayId, sampleId, buffer, function);
if(componentCount >= 1) { if(hasUnsignedTextureComponent(0)) c[i][j][k].x = MulHigh(As<UShort4>(c[i][j][k].x), f[1 - i][1 - j][1 - k]); else c[i][j][k].x = MulHigh(c[i][j][k].x, fs[1 - i][1 - j][1 - k]); }
if(componentCount >= 2) { if(hasUnsignedTextureComponent(1)) c[i][j][k].y = MulHigh(As<UShort4>(c[i][j][k].y), f[1 - i][1 - j][1 - k]); else c[i][j][k].y = MulHigh(c[i][j][k].y, fs[1 - i][1 - j][1 - k]); }
......@@ -783,9 +796,9 @@ namespace sw
return c_;
}
Vector4f SamplerCore::sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, const Int4& sampleId, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, SamplerFunction function)
Vector4f SamplerCore::sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, SamplerFunction function)
{
Vector4f c = sampleFloatAniso(texture, u, v, w, q, offset, sampleId, lod, anisotropy, uDelta, vDelta, false, function);
Vector4f c = sampleFloatAniso(texture, u, v, w, q, offset, cubeArrayCoord, sampleId, lod, anisotropy, uDelta, vDelta, false, function);
if(function == Fetch)
{
......@@ -794,7 +807,7 @@ namespace sw
if(state.mipmapFilter == MIPMAP_LINEAR)
{
Vector4f cc = sampleFloatAniso(texture, u, v, w, q, offset, sampleId, lod, anisotropy, uDelta, vDelta, true, function);
Vector4f cc = sampleFloatAniso(texture, u, v, w, q, offset, cubeArrayCoord, sampleId, lod, anisotropy, uDelta, vDelta, true, function);
Float4 lod4 = Float4(Frac(lod));
......@@ -807,13 +820,13 @@ namespace sw
return c;
}
Vector4f SamplerCore::sampleFloatAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, const Int4& sampleId, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, bool secondLOD, SamplerFunction function)
Vector4f SamplerCore::sampleFloatAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, bool secondLOD, SamplerFunction function)
{
Vector4f c;
if(state.textureFilter != FILTER_ANISOTROPIC || function == Lod || function == Fetch)
{
c = sampleFloat(texture, u, v, w, q, offset, sampleId, lod, secondLOD, function);
c = sampleFloat(texture, u, v, w, q, offset, cubeArrayCoord, sampleId, lod, secondLOD, function);
}
else
{
......@@ -842,7 +855,7 @@ namespace sw
Do
{
c = sampleFloat(texture, u0, v0, w, q, offset, sampleId, lod, secondLOD, function);
c = sampleFloat(texture, u0, v0, w, q, offset, cubeArrayCoord, sampleId, lod, secondLOD, function);
u0 += du;
v0 += dv;
......@@ -865,19 +878,19 @@ namespace sw
return c;
}
Vector4f SamplerCore::sampleFloat(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
Vector4f SamplerCore::sampleFloat(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
{
if(state.textureType != VK_IMAGE_VIEW_TYPE_3D)
{
return sampleFloat2D(texture, u, v, w, q, offset, sampleId, lod, secondLOD, function);
return sampleFloat2D(texture, u, v, w, q, offset, cubeArrayCoord, sampleId, lod, secondLOD, function);
}
else
{
return sampleFloat3D(texture, u, v, w, offset, sampleId, lod, secondLOD, function);
return sampleFloat3D(texture, u, v, w, offset, cubeArrayCoord, sampleId, lod, secondLOD, function);
}
}
Vector4f SamplerCore::sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
Vector4f SamplerCore::sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
{
Vector4f c;
......@@ -895,6 +908,12 @@ namespace sw
address(v, y0, y1, fv, mipmap, offset.y, filter, OFFSET(Mipmap, height), state.addressingModeV, function);
address(w, z0, z0, fw, mipmap, offset.z, filter, OFFSET(Mipmap, depth), state.addressingModeW, function);
Int4 cubeArrayId(0);
if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
{
address(cubeArrayCoord, cubeArrayId, cubeArrayId, fw, mipmap, offset.w, filter, OFFSET(Mipmap, depth), state.addressingModeY, function);
}
Int4 pitchP = *Pointer<Int4>(mipmap + OFFSET(Mipmap, pitchP), 16);
y0 *= pitchP;
if(state.addressingModeW != ADDRESSING_UNUSED)
......@@ -904,16 +923,16 @@ namespace sw
if(state.textureFilter == FILTER_POINT || (function == Fetch))
{
c = sampleTexel(x0, y0, z0, q, mipmap, sampleId, buffer, function);
c = sampleTexel(x0, y0, z0, q, mipmap, cubeArrayId, sampleId, buffer, function);
}
else
{
y1 *= pitchP;
Vector4f c00 = sampleTexel(x0, y0, z0, q, mipmap, sampleId, buffer, function);
Vector4f c10 = sampleTexel(x1, y0, z0, q, mipmap, sampleId, buffer, function);
Vector4f c01 = sampleTexel(x0, y1, z0, q, mipmap, sampleId, buffer, function);
Vector4f c11 = sampleTexel(x1, y1, z0, q, mipmap, sampleId, buffer, function);
Vector4f c00 = sampleTexel(x0, y0, z0, q, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4f c10 = sampleTexel(x1, y0, z0, q, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4f c01 = sampleTexel(x0, y1, z0, q, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4f c11 = sampleTexel(x1, y1, z0, q, mipmap, cubeArrayId, sampleId, buffer, function);
if(!gather) // Blend
{
......@@ -954,7 +973,7 @@ namespace sw
return c;
}
Vector4f SamplerCore::sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
Vector4f SamplerCore::sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
{
Vector4f c;
......@@ -971,6 +990,12 @@ namespace sw
address(v, y0, y1, fv, mipmap, offset.y, filter, OFFSET(Mipmap, height), state.addressingModeV, function);
address(w, z0, z1, fw, mipmap, offset.z, filter, OFFSET(Mipmap, depth), state.addressingModeW, function);
Int4 cubeArrayId(0);
if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
{
address(cubeArrayCoord, cubeArrayId, cubeArrayId, fw, mipmap, offset.w, filter, OFFSET(Mipmap, depth), state.addressingModeY, function);
}
Int4 pitchP = *Pointer<Int4>(mipmap + OFFSET(Mipmap, pitchP), 16);
Int4 sliceP = *Pointer<Int4>(mipmap + OFFSET(Mipmap, sliceP), 16);
y0 *= pitchP;
......@@ -978,21 +1003,21 @@ namespace sw
if(state.textureFilter == FILTER_POINT || (function == Fetch))
{
c = sampleTexel(x0, y0, z0, w, mipmap, sampleId, buffer, function);
c = sampleTexel(x0, y0, z0, w, mipmap, cubeArrayId, sampleId, buffer, function);
}
else
{
y1 *= pitchP;
z1 *= sliceP;
Vector4f c000 = sampleTexel(x0, y0, z0, w, mipmap, sampleId, buffer, function);
Vector4f c100 = sampleTexel(x1, y0, z0, w, mipmap, sampleId, buffer, function);
Vector4f c010 = sampleTexel(x0, y1, z0, w, mipmap, sampleId, buffer, function);
Vector4f c110 = sampleTexel(x1, y1, z0, w, mipmap, sampleId, buffer, function);
Vector4f c001 = sampleTexel(x0, y0, z1, w, mipmap, sampleId, buffer, function);
Vector4f c101 = sampleTexel(x1, y0, z1, w, mipmap, sampleId, buffer, function);
Vector4f c011 = sampleTexel(x0, y1, z1, w, mipmap, sampleId, buffer, function);
Vector4f c111 = sampleTexel(x1, y1, z1, w, mipmap, sampleId, buffer, function);
Vector4f c000 = sampleTexel(x0, y0, z0, w, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4f c100 = sampleTexel(x1, y0, z0, w, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4f c010 = sampleTexel(x0, y1, z0, w, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4f c110 = sampleTexel(x1, y1, z0, w, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4f c001 = sampleTexel(x0, y0, z1, w, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4f c101 = sampleTexel(x1, y0, z1, w, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4f c011 = sampleTexel(x0, y1, z1, w, mipmap, cubeArrayId, sampleId, buffer, function);
Vector4f c111 = sampleTexel(x1, y1, z1, w, mipmap, cubeArrayId, sampleId, buffer, function);
// Blend first slice
if(componentCount >= 1) c000.x = c000.x + fu * (c100.x - c000.x);
......@@ -1261,7 +1286,7 @@ namespace sw
return As<Short4>(UShort4(tmp));
}
void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, 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);
......@@ -1343,9 +1368,18 @@ namespace sw
index[i] += Extract(sampleOffset, i);
}
}
if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
{
UInt4 cubeLayerOffset = As<UInt4>(cubeArrayId) * *Pointer<UInt4>(mipmap + OFFSET(Mipmap, sliceP)) * UInt4(6);
for(int i = 0; i < 4; i++)
{
index[i] += Extract(cubeLayerOffset, i);
}
}
}
void SamplerCore::computeIndices(UInt index[4], Int4 uuuu, Int4 vvvv, Int4 wwww, Int4 valid, const Pointer<Byte> &mipmap, const Int4& sampleId, SamplerFunction function)
void SamplerCore::computeIndices(UInt index[4], Int4 uuuu, Int4 vvvv, Int4 wwww, Int4 valid, const Pointer<Byte> &mipmap, const Int4& cubeArrayId, const Int4& sampleId, SamplerFunction function)
{
UInt4 indices = uuuu + vvvv;
......@@ -1367,6 +1401,11 @@ namespace sw
*Pointer<UInt4>(mipmap + OFFSET(Mipmap, samplePitchP), 16);
}
if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
{
indices += As<UInt4>(cubeArrayId) * *Pointer<UInt4>(mipmap + OFFSET(Mipmap, sliceP)) * UInt4(6);
}
for(int i = 0; i < 4; i++)
{
index[i] = Extract(As<Int4>(indices), i);
......@@ -1620,12 +1659,12 @@ namespace sw
return c;
}
Vector4s SamplerCore::sampleTexel(Short4 &uuuu, Short4 &vvvv, Short4 &wwww, Vector4f &offset, Pointer<Byte> &mipmap, const Int4& sampleId, Pointer<Byte> buffer, SamplerFunction function)
Vector4s SamplerCore::sampleTexel(Short4 &uuuu, Short4 &vvvv, Short4 &wwww, Vector4f &offset, Pointer<Byte> &mipmap, const Short4& cubeArrayId, const Int4& sampleId, Pointer<Byte> buffer, SamplerFunction function)
{
Vector4s c;
UInt index[4];
computeIndices(index, uuuu, vvvv, wwww, offset, mipmap, sampleId, function);
computeIndices(index, uuuu, vvvv, wwww, offset, mipmap, cubeArrayId, sampleId, function);
if(isYcbcrFormat())
{
......@@ -1646,7 +1685,7 @@ namespace sw
// Chroma
{
computeIndices(index, uuuu, vvvv, wwww, offset, mipmap + sizeof(Mipmap), sampleId, function);
computeIndices(index, uuuu, vvvv, wwww, offset, mipmap + sizeof(Mipmap), cubeArrayId, sampleId, function);
UShort4 U, V;
if(state.textureFormat == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM)
......@@ -1768,7 +1807,7 @@ namespace sw
return c;
}
Vector4f SamplerCore::sampleTexel(Int4 &uuuu, Int4 &vvvv, Int4 &wwww, Float4 &z, Pointer<Byte> &mipmap, const Int4& sampleId, Pointer<Byte> buffer, SamplerFunction function)
Vector4f SamplerCore::sampleTexel(Int4 &uuuu, Int4 &vvvv, Int4 &wwww, Float4 &z, Pointer<Byte> &mipmap, const Int4& cubeArrayId, const Int4& sampleId, Pointer<Byte> buffer, SamplerFunction function)
{
Int4 valid;
......@@ -1784,7 +1823,7 @@ namespace sw
UInt index[4];
UInt4 t0, t1, t2, t3;
computeIndices(index, uuuu, vvvv, wwww, valid, mipmap, sampleId, function);
computeIndices(index, uuuu, vvvv, wwww, valid, mipmap, cubeArrayId, sampleId, function);
Vector4f c;
......@@ -2065,7 +2104,7 @@ namespace sw
return Int4(~0);
}
Short4 SamplerCore::address(Float4 &uw, AddressingMode addressingMode, Pointer<Byte> &mipmap)
Short4 SamplerCore::address(const Float4 &uw, AddressingMode addressingMode, Pointer<Byte> &mipmap)
{
if(addressingMode == ADDRESSING_UNUSED)
{
......@@ -2073,7 +2112,14 @@ namespace sw
}
else if(addressingMode == ADDRESSING_LAYER)
{
return Short4(Min(Max(RoundInt(uw), Int4(0)), *Pointer<Int4>(mipmap + OFFSET(Mipmap, depth)) - Int4(1)));
Int4 dim = *Pointer<Int4>(mipmap + OFFSET(Mipmap, depth));
// For cube maps, the layer argument is per cube, each of which has 6 layers
if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
{
dim = dim / Int4(6);
}
return Short4(Min(Max(RoundInt(uw), Int4(0)), dim - Int4(1)));
}
else if(addressingMode == ADDRESSING_CLAMP || addressingMode == ADDRESSING_BORDER)
{
......@@ -2121,7 +2167,7 @@ namespace sw
return (positive & x) | (~positive & (x + d));
}
void SamplerCore::address(Float4 &uvw, Int4 &xyz0, Int4 &xyz1, Float4 &f, Pointer<Byte> &mipmap, Float4 &texOffset, Int4 &filter, int whd, AddressingMode addressingMode, SamplerFunction function)
void SamplerCore::address(const Float4 &uvw, Int4 &xyz0, Int4 &xyz1, Float4 &f, Pointer<Byte> &mipmap, Float4 &texOffset, Int4 &filter, int whd, AddressingMode addressingMode, SamplerFunction function)
{
if(addressingMode == ADDRESSING_UNUSED)
{
......@@ -2137,7 +2183,13 @@ namespace sw
}
else if(addressingMode == ADDRESSING_LAYER) // Note: Offset does not apply to array layers
{
xyz0 = Min(Max(RoundInt(uvw), Int4(0)), maxXYZ);
// For cube maps, the layer argument is per cube, each of which has 6 layers
if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
{
dim = dim / Int4(6);
}
xyz0 = Min(Max(RoundInt(uvw), Int4(0)), dim - Int4(1));
}
else if(addressingMode == ADDRESSING_CUBEFACE)
{
......@@ -2420,6 +2472,12 @@ namespace sw
state.addressingModeW == ADDRESSING_BORDER;
}
bool SamplerCore::isCube() const
{
return state.textureType == VK_IMAGE_VIEW_TYPE_CUBE ||
state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
}
VkComponentSwizzle SamplerCore::gatherSwizzle() const
{
switch(state.gatherComponent)
......
......@@ -60,20 +60,20 @@ namespace sw
public:
SamplerCore(Pointer<Byte> &constants, const Sampler &state);
Vector4f sampleTexture(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Float &&lodOrBias, Float4 &dsx, Float4 &dsy, Vector4f &offset, Int4& sampleId, SamplerFunction function);
Vector4f sampleTexture(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float4 uvw[4], Float4 &q, Float &&lodOrBias, Float4 &dsx, Float4 &dsy, Vector4f &offset, Int4& sampleId, SamplerFunction function);
private:
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, const Int4& sampleId, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, SamplerFunction function);
Vector4s sampleAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Int4& sampleId, 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, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function);
Vector4s sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function);
Vector4s sample3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, const Int4& sampleId, 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, const Int4& sampleId, 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, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function);
Vector4s sampleFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, SamplerFunction function);
Vector4s sampleAniso(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, 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, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function);
Vector4s sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function);
Vector4s sample3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloatFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, 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, const Float4& cubeArrayCoord, const Int4& sampleId, 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, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function);
Vector4f sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Float4& cubeArrayCoord, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function);
Float log2sqrt(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, Float4 &dsx, Float4 &dsy, SamplerFunction function);
......@@ -81,15 +81,15 @@ namespace sw
void computeLod3D(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float &lod, Float4 &u, Float4 &v, Float4 &w, Float4 &dsx, Float4 &dsy, SamplerFunction function);
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);
void computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, const Int4& sampleId, SamplerFunction function);
void computeIndices(UInt index[4], Int4 uuuu, Int4 vvvv, Int4 wwww, Int4 valid, const Pointer<Byte> &mipmap, const Int4& sampleId, SamplerFunction function);
Vector4s sampleTexel(Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, Pointer<Byte> &mipmap, const Int4& sampleId, Pointer<Byte> buffer, SamplerFunction function);
void 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 computeIndices(UInt index[4], Int4 uuuu, Int4 vvvv, Int4 wwww, Int4 valid, const Pointer<Byte> &mipmap, const Int4& cubeArrayId, const Int4& sampleId, SamplerFunction function);
Vector4s sampleTexel(Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, Pointer<Byte> &mipmap, const Short4& cubeArrayId, const Int4& sampleId, Pointer<Byte> buffer, SamplerFunction function);
Vector4s sampleTexel(UInt index[4], Pointer<Byte> buffer);
Vector4f sampleTexel(Int4 &u, Int4 &v, Int4 &s, Float4 &z, Pointer<Byte> &mipmap, const Int4& sampleId, Pointer<Byte> buffer, SamplerFunction function);
Vector4f sampleTexel(Int4 &u, Int4 &v, Int4 &s, Float4 &z, Pointer<Byte> &mipmap, const Int4& cubeArrayId, const Int4& sampleId, 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(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);
Short4 address(const Float4 &uw, AddressingMode addressingMode, Pointer<Byte>& mipmap);
void address(const 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);
void convertSigned15(Float4 &cf, Short4 &ci);
......@@ -108,6 +108,7 @@ namespace sw
bool isYcbcrFormat() const;
bool isRGBComponent(int component) const;
bool borderModeActive() const;
bool isCube() const;
VkComponentSwizzle gatherSwizzle() const;
Pointer<Byte> &constants;
......
......@@ -357,6 +357,7 @@ namespace sw
case spv::CapabilitySampled1D: capabilities.Sampled1D = true; break;
case spv::CapabilityImage1D: capabilities.Image1D = true; break;
case spv::CapabilitySampledBuffer: capabilities.SampledBuffer = true; break;
case spv::CapabilitySampledCubeArray: capabilities.SampledCubeArray = true; break;
case spv::CapabilityImageBuffer: capabilities.ImageBuffer = true; break;
case spv::CapabilityStorageImageExtendedFormats: capabilities.StorageImageExtendedFormats = true; break;
case spv::CapabilityImageQuery: capabilities.ImageQuery = true; break;
......
......@@ -490,6 +490,7 @@ namespace sw
bool Sampled1D : 1;
bool Image1D : 1;
bool SampledBuffer : 1;
bool SampledCubeArray : 1;
bool ImageBuffer : 1;
bool StorageImageExtendedFormats : 1;
bool ImageQuery : 1;
......
......@@ -63,6 +63,7 @@ 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.addressingModeY = convertAddressingMode(3, sampler, type);
samplerState.mipmapFilter = convertMipmapMode(sampler);
samplerState.swizzle = imageDescriptor->swizzle;
......@@ -202,7 +203,7 @@ std::shared_ptr<rr::Routine> SpirvShader::emitSamplerRoutine(ImageInstruction in
dPdy.y = Float(0.0f);
}
Vector4f sample = s.sampleTexture(texture, sampler, uvw[0], uvw[1], uvw[2], q, lod[i], dPdx, dPdy, offset, sampleId, samplerFunction);
Vector4f sample = s.sampleTexture(texture, sampler, uvw, q, lod[i], dPdx, dPdy, offset, sampleId, samplerFunction);
Pointer<Float> rgba = out;
rgba[0 * SIMD::Width + i] = Pointer<Float>(&sample.x)[i];
......@@ -213,7 +214,7 @@ std::shared_ptr<rr::Routine> SpirvShader::emitSamplerRoutine(ImageInstruction in
}
else
{
Vector4f sample = s.sampleTexture(texture, sampler, uvw[0], uvw[1], uvw[2], q, lodOrBias.x, (dsx.x), (dsy.x), offset, sampleId, samplerFunction);
Vector4f sample = s.sampleTexture(texture, sampler, uvw, q, lodOrBias.x, (dsx.x), (dsy.x), offset, sampleId, samplerFunction);
Pointer<SIMD::Float> rgba = out;
rgba[0] = sample.x;
......@@ -285,7 +286,6 @@ sw::AddressingMode SpirvShader::convertAddressingMode(int coordinateIndex, const
switch(imageViewType)
{
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
UNSUPPORTED("SPIR-V ImageCubeArray Capability (imageViewType: %d)", int(imageViewType));
if(coordinateIndex == 3)
{
return ADDRESSING_LAYER;
......
......@@ -401,7 +401,8 @@ void DescriptorSetLayout::WriteDescriptorSet(Device* device, DescriptorSet *dstS
VkImageAspectFlagBits aspect = static_cast<VkImageAspectFlagBits>(imageView->getSubresourceRange().aspectMask);
sw::Mipmap &mipmap = texture->mipmap[mipmapLevel];
if(imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE)
if((imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE) ||
(imageView->getType() == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY))
{
// 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.
......
......@@ -49,7 +49,7 @@ const VkPhysicalDeviceFeatures& PhysicalDevice::getFeatures() const
{
VK_TRUE, // robustBufferAccess
VK_TRUE, // fullDrawIndexUint32
VK_FALSE, // imageCubeArray
VK_TRUE, // imageCubeArray
VK_TRUE, // independentBlend
VK_FALSE, // geometryShader
VK_FALSE, // tessellationShader
......
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