Commit 8a6dcf76 by Alexis Hetu Committed by Alexis Hétu

Support sample image instruction operand

- Added support for the sample operand in SamplerCore, which simply involves offsetting the buffer by the the sampleId * samplePitch. - Also added a check so that sampleId is within the expected range and doesn't cause reading memory out of bounds. Bug: b/135265531 Change-Id: Ie828d07db41d36befb34037156736a6576af0676 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/38728Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 2613cb5e
...@@ -40,6 +40,8 @@ namespace sw ...@@ -40,6 +40,8 @@ namespace sw
short4 onePitchP; short4 onePitchP;
int4 pitchP; int4 pitchP;
int4 sliceP; int4 sliceP;
int4 samplePitchP;
int4 sampleMax;
}; };
struct Texture struct Texture
......
...@@ -53,7 +53,7 @@ namespace sw ...@@ -53,7 +53,7 @@ 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, SamplerFunction function) 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 c; Vector4f c;
...@@ -151,7 +151,7 @@ namespace sw ...@@ -151,7 +151,7 @@ namespace sw
if(use32BitFiltering) if(use32BitFiltering)
{ {
c = sampleFloatFilter(texture, uuuu, vvvv, wwww, qqqq, offset, lod, anisotropy, uDelta, vDelta, function); c = sampleFloatFilter(texture, uuuu, vvvv, wwww, qqqq, offset, sampleId, lod, anisotropy, uDelta, vDelta, function);
if (!hasFloatTexture() && !hasUnnormalizedIntegerTexture() && !state.compareEnable) if (!hasFloatTexture() && !hasUnnormalizedIntegerTexture() && !state.compareEnable)
{ {
...@@ -207,7 +207,7 @@ namespace sw ...@@ -207,7 +207,7 @@ namespace sw
} }
else // 16-bit filtering. else // 16-bit filtering.
{ {
Vector4s cs = sampleFilter(texture, uuuu, vvvv, wwww, offset, lod, anisotropy, uDelta, vDelta, function); Vector4s cs = sampleFilter(texture, uuuu, vvvv, wwww, offset, sampleId, lod, anisotropy, uDelta, vDelta, function);
switch (state.textureFormat) switch (state.textureFormat)
{ {
...@@ -339,9 +339,9 @@ namespace sw ...@@ -339,9 +339,9 @@ namespace sw
return uvw; return uvw;
} }
Vector4s SamplerCore::sampleFilter(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, 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 Int4& sampleId, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, SamplerFunction function)
{ {
Vector4s c = sampleAniso(texture, u, v, w, offset, lod, anisotropy, uDelta, vDelta, false, function); Vector4s c = sampleAniso(texture, u, v, w, offset, sampleId, lod, anisotropy, uDelta, vDelta, false, function);
if(function == Fetch) if(function == Fetch)
{ {
...@@ -350,7 +350,7 @@ namespace sw ...@@ -350,7 +350,7 @@ namespace sw
if(state.mipmapFilter == MIPMAP_LINEAR) if(state.mipmapFilter == MIPMAP_LINEAR)
{ {
Vector4s cc = sampleAniso(texture, u, v, w, offset, lod, anisotropy, uDelta, vDelta, true, function); Vector4s cc = sampleAniso(texture, u, v, w, offset, sampleId, lod, anisotropy, uDelta, vDelta, true, function);
lod *= Float(1 << 16); lod *= Float(1 << 16);
...@@ -384,13 +384,13 @@ namespace sw ...@@ -384,13 +384,13 @@ namespace sw
return c; return c;
} }
Vector4s SamplerCore::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 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 c; Vector4s c;
if(state.textureFilter != FILTER_ANISOTROPIC || function == Lod || function == Fetch) if(state.textureFilter != FILTER_ANISOTROPIC || function == Lod || function == Fetch)
{ {
c = sampleQuad(texture, u, v, w, offset, lod, secondLOD, function); c = sampleQuad(texture, u, v, w, offset, sampleId, lod, secondLOD, function);
} }
else else
{ {
...@@ -421,7 +421,7 @@ namespace sw ...@@ -421,7 +421,7 @@ namespace sw
Do Do
{ {
c = sampleQuad(texture, u0, v0, w, offset, lod, secondLOD, function); c = sampleQuad(texture, u0, v0, w, offset, sampleId, lod, secondLOD, function);
u0 += du; u0 += du;
v0 += dv; v0 += dv;
...@@ -444,19 +444,19 @@ namespace sw ...@@ -444,19 +444,19 @@ namespace sw
return c; return c;
} }
Vector4s SamplerCore::sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function) Vector4s SamplerCore::sampleQuad(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
{ {
if(state.textureType != VK_IMAGE_VIEW_TYPE_3D) if(state.textureType != VK_IMAGE_VIEW_TYPE_3D)
{ {
return sampleQuad2D(texture, u, v, w, offset, lod, secondLOD, function); return sampleQuad2D(texture, u, v, w, offset, sampleId, lod, secondLOD, function);
} }
else else
{ {
return sample3D(texture, u, v, w, offset, lod, secondLOD, function); return sample3D(texture, u, v, w, offset, sampleId, lod, secondLOD, function);
} }
} }
Vector4s SamplerCore::sampleQuad2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction 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 c; Vector4s c;
...@@ -475,7 +475,7 @@ namespace sw ...@@ -475,7 +475,7 @@ namespace sw
if(state.textureFilter == FILTER_POINT || texelFetch) if(state.textureFilter == FILTER_POINT || texelFetch)
{ {
c = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, buffer, function); c = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, sampleId, buffer, function);
} }
else else
{ {
...@@ -484,10 +484,10 @@ namespace sw ...@@ -484,10 +484,10 @@ namespace sw
Short4 uuuu1 = offsetSample(uuuu, mipmap, OFFSET(Mipmap,uHalf), state.addressingModeU == ADDRESSING_WRAP, +1, lod); 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); Short4 vvvv1 = offsetSample(vvvv, mipmap, OFFSET(Mipmap,vHalf), state.addressingModeV == ADDRESSING_WRAP, +1, lod);
Vector4s c00 = sampleTexel(uuuu0, vvvv0, wwww, offset, mipmap, buffer, function); Vector4s c00 = sampleTexel(uuuu0, vvvv0, wwww, offset, mipmap, sampleId, buffer, function);
Vector4s c10 = sampleTexel(uuuu1, vvvv0, wwww, offset, mipmap, buffer, function); Vector4s c10 = sampleTexel(uuuu1, vvvv0, wwww, offset, mipmap, sampleId, buffer, function);
Vector4s c01 = sampleTexel(uuuu0, vvvv1, wwww, offset, mipmap, buffer, function); Vector4s c01 = sampleTexel(uuuu0, vvvv1, wwww, offset, mipmap, sampleId, buffer, function);
Vector4s c11 = sampleTexel(uuuu1, vvvv1, wwww, offset, mipmap, buffer, function); Vector4s c11 = sampleTexel(uuuu1, vvvv1, wwww, offset, mipmap, sampleId, buffer, function);
if(!gather) // Blend if(!gather) // Blend
{ {
...@@ -660,7 +660,7 @@ namespace sw ...@@ -660,7 +660,7 @@ namespace sw
return c; return c;
} }
Vector4s SamplerCore::sample3D(Pointer<Byte> &texture, Float4 &u_, Float4 &v_, Float4 &w_, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function) Vector4s SamplerCore::sample3D(Pointer<Byte> &texture, Float4 &u_, Float4 &v_, Float4 &w_, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
{ {
Vector4s c_; Vector4s c_;
...@@ -678,7 +678,7 @@ namespace sw ...@@ -678,7 +678,7 @@ namespace sw
if(state.textureFilter == FILTER_POINT || texelFetch) if(state.textureFilter == FILTER_POINT || texelFetch)
{ {
c_ = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, buffer, function); c_ = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, sampleId, buffer, function);
} }
else else
{ {
...@@ -750,7 +750,7 @@ namespace sw ...@@ -750,7 +750,7 @@ namespace sw
{ {
for(int k = 0; k < 2; k++) 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, buffer, function); c[i][j][k] = sampleTexel(u[i][j][k], v[i][j][k], s[i][j][k], offset, mipmap, 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 >= 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]); } 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 +783,9 @@ namespace sw ...@@ -783,9 +783,9 @@ namespace sw
return c_; return c_;
} }
Vector4f SamplerCore::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 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 c = sampleFloatAniso(texture, u, v, w, q, offset, lod, anisotropy, uDelta, vDelta, false, function); Vector4f c = sampleFloatAniso(texture, u, v, w, q, offset, sampleId, lod, anisotropy, uDelta, vDelta, false, function);
if(function == Fetch) if(function == Fetch)
{ {
...@@ -794,7 +794,7 @@ namespace sw ...@@ -794,7 +794,7 @@ namespace sw
if(state.mipmapFilter == MIPMAP_LINEAR) if(state.mipmapFilter == MIPMAP_LINEAR)
{ {
Vector4f cc = sampleFloatAniso(texture, u, v, w, q, offset, lod, anisotropy, uDelta, vDelta, true, function); Vector4f cc = sampleFloatAniso(texture, u, v, w, q, offset, sampleId, lod, anisotropy, uDelta, vDelta, true, function);
Float4 lod4 = Float4(Frac(lod)); Float4 lod4 = Float4(Frac(lod));
...@@ -807,13 +807,13 @@ namespace sw ...@@ -807,13 +807,13 @@ namespace sw
return c; return c;
} }
Vector4f SamplerCore::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 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 c; Vector4f c;
if(state.textureFilter != FILTER_ANISOTROPIC || function == Lod || function == Fetch) if(state.textureFilter != FILTER_ANISOTROPIC || function == Lod || function == Fetch)
{ {
c = sampleFloat(texture, u, v, w, q, offset, lod, secondLOD, function); c = sampleFloat(texture, u, v, w, q, offset, sampleId, lod, secondLOD, function);
} }
else else
{ {
...@@ -842,7 +842,7 @@ namespace sw ...@@ -842,7 +842,7 @@ namespace sw
Do Do
{ {
c = sampleFloat(texture, u0, v0, w, q, offset, lod, secondLOD, function); c = sampleFloat(texture, u0, v0, w, q, offset, sampleId, lod, secondLOD, function);
u0 += du; u0 += du;
v0 += dv; v0 += dv;
...@@ -865,19 +865,19 @@ namespace sw ...@@ -865,19 +865,19 @@ namespace sw
return c; return c;
} }
Vector4f SamplerCore::sampleFloat(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function) 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)
{ {
if(state.textureType != VK_IMAGE_VIEW_TYPE_3D) if(state.textureType != VK_IMAGE_VIEW_TYPE_3D)
{ {
return sampleFloat2D(texture, u, v, w, q, offset, lod, secondLOD, function); return sampleFloat2D(texture, u, v, w, q, offset, sampleId, lod, secondLOD, function);
} }
else else
{ {
return sampleFloat3D(texture, u, v, w, offset, lod, secondLOD, function); return sampleFloat3D(texture, u, v, w, offset, sampleId, lod, secondLOD, function);
} }
} }
Vector4f SamplerCore::sampleFloat2D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Float4 &q, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction 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 c; Vector4f c;
...@@ -904,16 +904,16 @@ namespace sw ...@@ -904,16 +904,16 @@ namespace sw
if(state.textureFilter == FILTER_POINT || (function == Fetch)) if(state.textureFilter == FILTER_POINT || (function == Fetch))
{ {
c = sampleTexel(x0, y0, z0, q, mipmap, buffer, function); c = sampleTexel(x0, y0, z0, q, mipmap, sampleId, buffer, function);
} }
else else
{ {
y1 *= pitchP; y1 *= pitchP;
Vector4f c00 = sampleTexel(x0, y0, z0, q, mipmap, buffer, function); Vector4f c00 = sampleTexel(x0, y0, z0, q, mipmap, sampleId, buffer, function);
Vector4f c10 = sampleTexel(x1, y0, z0, q, mipmap, buffer, function); Vector4f c10 = sampleTexel(x1, y0, z0, q, mipmap, sampleId, buffer, function);
Vector4f c01 = sampleTexel(x0, y1, z0, q, mipmap, buffer, function); Vector4f c01 = sampleTexel(x0, y1, z0, q, mipmap, sampleId, buffer, function);
Vector4f c11 = sampleTexel(x1, y1, z0, q, mipmap, buffer, function); Vector4f c11 = sampleTexel(x1, y1, z0, q, mipmap, sampleId, buffer, function);
if(!gather) // Blend if(!gather) // Blend
{ {
...@@ -954,7 +954,7 @@ namespace sw ...@@ -954,7 +954,7 @@ namespace sw
return c; return c;
} }
Vector4f SamplerCore::sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, Float &lod, bool secondLOD, SamplerFunction function) Vector4f SamplerCore::sampleFloat3D(Pointer<Byte> &texture, Float4 &u, Float4 &v, Float4 &w, Vector4f &offset, const Int4& sampleId, Float &lod, bool secondLOD, SamplerFunction function)
{ {
Vector4f c; Vector4f c;
...@@ -978,21 +978,21 @@ namespace sw ...@@ -978,21 +978,21 @@ namespace sw
if(state.textureFilter == FILTER_POINT || (function == Fetch)) if(state.textureFilter == FILTER_POINT || (function == Fetch))
{ {
c = sampleTexel(x0, y0, z0, w, mipmap, buffer, function); c = sampleTexel(x0, y0, z0, w, mipmap, sampleId, buffer, function);
} }
else else
{ {
y1 *= pitchP; y1 *= pitchP;
z1 *= sliceP; z1 *= sliceP;
Vector4f c000 = sampleTexel(x0, y0, z0, w, mipmap, buffer, function); Vector4f c000 = sampleTexel(x0, y0, z0, w, mipmap, sampleId, buffer, function);
Vector4f c100 = sampleTexel(x1, y0, z0, w, mipmap, buffer, function); Vector4f c100 = sampleTexel(x1, y0, z0, w, mipmap, sampleId, buffer, function);
Vector4f c010 = sampleTexel(x0, y1, z0, w, mipmap, buffer, function); Vector4f c010 = sampleTexel(x0, y1, z0, w, mipmap, sampleId, buffer, function);
Vector4f c110 = sampleTexel(x1, y1, z0, w, mipmap, buffer, function); Vector4f c110 = sampleTexel(x1, y1, z0, w, mipmap, sampleId, buffer, function);
Vector4f c001 = sampleTexel(x0, y0, z1, w, mipmap, buffer, function); Vector4f c001 = sampleTexel(x0, y0, z1, w, mipmap, sampleId, buffer, function);
Vector4f c101 = sampleTexel(x1, y0, z1, w, mipmap, buffer, function); Vector4f c101 = sampleTexel(x1, y0, z1, w, mipmap, sampleId, buffer, function);
Vector4f c011 = sampleTexel(x0, y1, z1, w, mipmap, buffer, function); Vector4f c011 = sampleTexel(x0, y1, z1, w, mipmap, sampleId, buffer, function);
Vector4f c111 = sampleTexel(x1, y1, z1, w, mipmap, buffer, function); Vector4f c111 = sampleTexel(x1, y1, z1, w, mipmap, sampleId, buffer, function);
// Blend first slice // Blend first slice
if(componentCount >= 1) c000.x = c000.x + fu * (c100.x - c000.x); if(componentCount >= 1) c000.x = c000.x + fu * (c100.x - c000.x);
...@@ -1261,7 +1261,7 @@ namespace sw ...@@ -1261,7 +1261,7 @@ namespace sw
return As<Short4>(UShort4(tmp)); return As<Short4>(UShort4(tmp));
} }
void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, SamplerFunction function) void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, const Int4& sampleId, SamplerFunction function)
{ {
bool texelFetch = (function == Fetch); bool texelFetch = (function == Fetch);
bool hasOffset = (function.offset != 0); bool hasOffset = (function.offset != 0);
...@@ -1333,9 +1333,19 @@ namespace sw ...@@ -1333,9 +1333,19 @@ namespace sw
index[i] = Min(Max(index[i], min), max); index[i] = Min(Max(index[i], min), max);
} }
} }
if(function.sample)
{
UInt4 sampleOffset = Min(As<UInt4>(sampleId), *Pointer<UInt4>(mipmap + OFFSET(Mipmap, sampleMax), 16)) *
*Pointer<UInt4>(mipmap + OFFSET(Mipmap, samplePitchP), 16);
for(int i = 0; i < 4; i++)
{
index[i] += Extract(sampleOffset, i);
}
}
} }
void SamplerCore::computeIndices(UInt index[4], Int4 uuuu, Int4 vvvv, Int4 wwww, Int4 valid, const Pointer<Byte> &mipmap, SamplerFunction function) void SamplerCore::computeIndices(UInt index[4], Int4 uuuu, Int4 vvvv, Int4 wwww, Int4 valid, const Pointer<Byte> &mipmap, const Int4& sampleId, SamplerFunction function)
{ {
UInt4 indices = uuuu + vvvv; UInt4 indices = uuuu + vvvv;
...@@ -1351,6 +1361,12 @@ namespace sw ...@@ -1351,6 +1361,12 @@ namespace sw
indices &= As<UInt4>(valid); indices &= As<UInt4>(valid);
} }
if(function.sample)
{
indices += Min(As<UInt4>(sampleId), *Pointer<UInt4>(mipmap + OFFSET(Mipmap, sampleMax), 16)) *
*Pointer<UInt4>(mipmap + OFFSET(Mipmap, samplePitchP), 16);
}
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
{ {
index[i] = Extract(As<Int4>(indices), i); index[i] = Extract(As<Int4>(indices), i);
...@@ -1604,12 +1620,12 @@ namespace sw ...@@ -1604,12 +1620,12 @@ namespace sw
return c; return c;
} }
Vector4s SamplerCore::sampleTexel(Short4 &uuuu, Short4 &vvvv, Short4 &wwww, Vector4f &offset, Pointer<Byte> &mipmap, Pointer<Byte> buffer, SamplerFunction function) Vector4s SamplerCore::sampleTexel(Short4 &uuuu, Short4 &vvvv, Short4 &wwww, Vector4f &offset, Pointer<Byte> &mipmap, const Int4& sampleId, Pointer<Byte> buffer, SamplerFunction function)
{ {
Vector4s c; Vector4s c;
UInt index[4]; UInt index[4];
computeIndices(index, uuuu, vvvv, wwww, offset, mipmap, function); computeIndices(index, uuuu, vvvv, wwww, offset, mipmap, sampleId, function);
if(isYcbcrFormat()) if(isYcbcrFormat())
{ {
...@@ -1630,7 +1646,7 @@ namespace sw ...@@ -1630,7 +1646,7 @@ namespace sw
// Chroma // Chroma
{ {
computeIndices(index, uuuu, vvvv, wwww, offset, mipmap + sizeof(Mipmap), function); computeIndices(index, uuuu, vvvv, wwww, offset, mipmap + sizeof(Mipmap), sampleId, function);
UShort4 U, V; UShort4 U, V;
if(state.textureFormat == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) if(state.textureFormat == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM)
...@@ -1752,7 +1768,7 @@ namespace sw ...@@ -1752,7 +1768,7 @@ namespace sw
return c; return c;
} }
Vector4f SamplerCore::sampleTexel(Int4 &uuuu, Int4 &vvvv, Int4 &wwww, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer, SamplerFunction function) Vector4f SamplerCore::sampleTexel(Int4 &uuuu, Int4 &vvvv, Int4 &wwww, Float4 &z, Pointer<Byte> &mipmap, const Int4& sampleId, Pointer<Byte> buffer, SamplerFunction function)
{ {
Int4 valid; Int4 valid;
...@@ -1768,7 +1784,7 @@ namespace sw ...@@ -1768,7 +1784,7 @@ namespace sw
UInt index[4]; UInt index[4];
UInt4 t0, t1, t2, t3; UInt4 t0, t1, t2, t3;
computeIndices(index, uuuu, vvvv, wwww, valid, mipmap, function); computeIndices(index, uuuu, vvvv, wwww, valid, mipmap, sampleId, function);
Vector4f c; Vector4f c;
......
...@@ -60,20 +60,20 @@ namespace sw ...@@ -60,20 +60,20 @@ namespace sw
public: public:
SamplerCore(Pointer<Byte> &constants, const Sampler &state); 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, SamplerFunction function); 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);
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, SamplerFunction function); 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, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, bool secondLOD, 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, Float &lod, 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, 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, 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, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, 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, Float &lod, Float &anisotropy, Float4 &uDelta, Float4 &vDelta, bool secondLOD, 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, Float &lod, 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, 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, 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);
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, Float4 &dsx, Float4 &dsy, SamplerFunction function); 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,11 +81,11 @@ namespace sw ...@@ -81,11 +81,11 @@ namespace sw
void computeLod3D(Pointer<Byte> &texture, Pointer<Byte> &sampler, Float &lod, Float4 &u, Float4 &v, Float4 &w, Float4 &dsx, Float4 &dsy, SamplerFunction function); 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); 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, const Int4& sampleId, 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, const Int4& sampleId, SamplerFunction function);
Vector4s sampleTexel(Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, Pointer<Byte> &mipmap, Pointer<Byte> buffer, SamplerFunction function); Vector4s sampleTexel(Short4 &u, Short4 &v, Short4 &s, Vector4f &offset, Pointer<Byte> &mipmap, const Int4& sampleId, Pointer<Byte> buffer, SamplerFunction function);
Vector4s sampleTexel(UInt index[4], Pointer<Byte> buffer); Vector4s sampleTexel(UInt index[4], Pointer<Byte> buffer);
Vector4f sampleTexel(Int4 &u, Int4 &v, Int4 &s, Float4 &z, Pointer<Byte> &mipmap, Pointer<Byte> buffer, SamplerFunction function); Vector4f sampleTexel(Int4 &u, Int4 &v, Int4 &s, Float4 &z, Pointer<Byte> &mipmap, const Int4& sampleId, Pointer<Byte> buffer, SamplerFunction function);
Vector4f replaceBorderTexel(const Vector4f &c, Int4 valid); Vector4f replaceBorderTexel(const Vector4f &c, Int4 valid);
void selectMipmap(const Pointer<Byte> &texture, Pointer<Byte> &mipmap, Pointer<Byte> &buffer, const Float &lod, 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);
......
...@@ -5169,7 +5169,7 @@ namespace sw ...@@ -5169,7 +5169,7 @@ namespace sw
if(sample) if(sample)
{ {
auto sampleValue = GenericValue(this, state, sampleId); auto sampleValue = GenericValue(this, state, sampleId);
in[i] = sampleValue.Float(0); in[i] = As<SIMD::Float>(sampleValue.Int(0));
} }
auto cacheIt = state->routine->samplerCache.find(resultId); auto cacheIt = state->routine->samplerCache.find(resultId);
......
...@@ -120,6 +120,7 @@ std::shared_ptr<rr::Routine> SpirvShader::emitSamplerRoutine(ImageInstruction in ...@@ -120,6 +120,7 @@ std::shared_ptr<rr::Routine> SpirvShader::emitSamplerRoutine(ImageInstruction in
Vector4f dsx = {0, 0, 0, 0}; Vector4f dsx = {0, 0, 0, 0};
Vector4f dsy = {0, 0, 0, 0}; Vector4f dsy = {0, 0, 0, 0};
Vector4f offset = {0, 0, 0, 0}; Vector4f offset = {0, 0, 0, 0};
SIMD::Int sampleId = 0;
SamplerFunction samplerFunction = instruction.getSamplerFunction(); SamplerFunction samplerFunction = instruction.getSamplerFunction();
uint32_t i = 0; uint32_t i = 0;
...@@ -169,7 +170,10 @@ std::shared_ptr<rr::Routine> SpirvShader::emitSamplerRoutine(ImageInstruction in ...@@ -169,7 +170,10 @@ std::shared_ptr<rr::Routine> SpirvShader::emitSamplerRoutine(ImageInstruction in
offset[j] = in[i]; offset[j] = in[i];
} }
// TODO(b/133868964): Handle 'Sample' operand. if(instruction.sample)
{
sampleId = As<SIMD::Int>(in[i]);
}
SamplerCore s(constants, samplerState); SamplerCore s(constants, samplerState);
...@@ -199,7 +203,7 @@ std::shared_ptr<rr::Routine> SpirvShader::emitSamplerRoutine(ImageInstruction in ...@@ -199,7 +203,7 @@ std::shared_ptr<rr::Routine> SpirvShader::emitSamplerRoutine(ImageInstruction in
dPdy.y = Float(0.0f); dPdy.y = Float(0.0f);
} }
Vector4f sample = s.sampleTexture(texture, sampler, uvw[0], uvw[1], uvw[2], q, lod[i], dPdx, dPdy, offset, samplerFunction); Vector4f sample = s.sampleTexture(texture, sampler, uvw[0], uvw[1], uvw[2], q, lod[i], dPdx, dPdy, offset, sampleId, samplerFunction);
Pointer<Float> rgba = out; Pointer<Float> rgba = out;
rgba[0 * SIMD::Width + i] = Pointer<Float>(&sample.x)[i]; rgba[0 * SIMD::Width + i] = Pointer<Float>(&sample.x)[i];
...@@ -210,7 +214,7 @@ std::shared_ptr<rr::Routine> SpirvShader::emitSamplerRoutine(ImageInstruction in ...@@ -210,7 +214,7 @@ std::shared_ptr<rr::Routine> SpirvShader::emitSamplerRoutine(ImageInstruction in
} }
else else
{ {
Vector4f sample = s.sampleTexture(texture, sampler, uvw[0], uvw[1], uvw[2], q, lodOrBias.x, (dsx.x), (dsy.x), offset, samplerFunction); Vector4f sample = s.sampleTexture(texture, sampler, uvw[0], uvw[1], uvw[2], q, lodOrBias.x, (dsx.x), (dsy.x), offset, sampleId, samplerFunction);
Pointer<SIMD::Float> rgba = out; Pointer<SIMD::Float> rgba = out;
rgba[0] = sample.x; rgba[0] = sample.x;
......
...@@ -384,13 +384,13 @@ void DescriptorSetLayout::WriteDescriptorSet(Device* device, DescriptorSet *dstS ...@@ -384,13 +384,13 @@ void DescriptorSetLayout::WriteDescriptorSet(Device* device, DescriptorSet *dstS
imageView->getFormat(VK_IMAGE_ASPECT_PLANE_0_BIT).bytes(); imageView->getFormat(VK_IMAGE_ASPECT_PLANE_0_BIT).bytes();
// Write plane 0 parameters to mipmap level 0. // Write plane 0 parameters to mipmap level 0.
WriteTextureLevelInfo(texture, 0, width, height, 1, pitchP0, 0); WriteTextureLevelInfo(texture, 0, width, height, 1, pitchP0, 0, 0, 0);
// Plane 2, if present, has equal parameters to plane 1, so we use mipmap level 1 for both. // Plane 2, if present, has equal parameters to plane 1, so we use mipmap level 1 for both.
int pitchP1 = imageView->rowPitchBytes(VK_IMAGE_ASPECT_PLANE_1_BIT, level, ImageView::SAMPLING) / int pitchP1 = imageView->rowPitchBytes(VK_IMAGE_ASPECT_PLANE_1_BIT, level, ImageView::SAMPLING) /
imageView->getFormat(VK_IMAGE_ASPECT_PLANE_1_BIT).bytes(); imageView->getFormat(VK_IMAGE_ASPECT_PLANE_1_BIT).bytes();
WriteTextureLevelInfo(texture, 1, width / 2, height / 2, 1, pitchP1, 0); WriteTextureLevelInfo(texture, 1, width / 2, height / 2, 1, pitchP1, 0, 0, 0);
} }
else else
{ {
...@@ -418,12 +418,15 @@ void DescriptorSetLayout::WriteDescriptorSet(Device* device, DescriptorSet *dstS ...@@ -418,12 +418,15 @@ void DescriptorSetLayout::WriteDescriptorSet(Device* device, DescriptorSet *dstS
int width = extent.width; int width = extent.width;
int height = extent.height; 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; // TODO(b/129523279): Untangle depth vs layers throughout the sampler
int depth = layers > 1 ? layers : extent.depth; int depth = layers > 1 ? layers : extent.depth;
int pitchP = imageView->rowPitchBytes(aspect, level, ImageView::SAMPLING) / 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)) / format.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;
int sampleMax = imageView->getSampleCount() - 1;
WriteTextureLevelInfo(texture, mipmapLevel, width, height, depth, pitchP, sliceP); WriteTextureLevelInfo(texture, mipmapLevel, width, height, depth, pitchP, sliceP, samplePitchP, sampleMax);
} }
} }
} }
...@@ -451,9 +454,9 @@ void DescriptorSetLayout::WriteDescriptorSet(Device* device, DescriptorSet *dstS ...@@ -451,9 +454,9 @@ void DescriptorSetLayout::WriteDescriptorSet(Device* device, DescriptorSet *dstS
{ {
descriptor[i].stencilPtr = imageView->getOffsetPointer({0, 0, 0}, VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0); descriptor[i].stencilPtr = imageView->getOffsetPointer({0, 0, 0}, VK_IMAGE_ASPECT_STENCIL_BIT, 0, 0);
descriptor[i].stencilRowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0); descriptor[i].stencilRowPitchBytes = imageView->rowPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
descriptor[i].stencilSamplePitchBytes = imageView->getSubresourceRange().layerCount > 1 descriptor[i].stencilSamplePitchBytes = (imageView->getSubresourceRange().layerCount > 1)
? imageView->layerPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT) ? imageView->layerPitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT)
: imageView->slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0); : imageView->slicePitchBytes(VK_IMAGE_ASPECT_STENCIL_BIT, 0);
descriptor[i].stencilSlicePitchBytes = descriptor[i].stencilSamplePitchBytes * imageView->getSampleCount(); descriptor[i].stencilSlicePitchBytes = descriptor[i].stencilSamplePitchBytes * imageView->getSampleCount();
} }
} }
...@@ -492,7 +495,7 @@ void DescriptorSetLayout::WriteDescriptorSet(Device* device, DescriptorSet *dstS ...@@ -492,7 +495,7 @@ void DescriptorSetLayout::WriteDescriptorSet(Device* device, DescriptorSet *dstS
} }
} }
void DescriptorSetLayout::WriteTextureLevelInfo(sw::Texture *texture, int level, int width, int height, int depth, int pitchP, int sliceP) void DescriptorSetLayout::WriteTextureLevelInfo(sw::Texture *texture, int level, int width, int height, int depth, int pitchP, int sliceP, int samplePitchP, int sampleMax)
{ {
if(level == 0) if(level == 0)
{ {
...@@ -567,6 +570,16 @@ void DescriptorSetLayout::WriteTextureLevelInfo(sw::Texture *texture, int level, ...@@ -567,6 +570,16 @@ void DescriptorSetLayout::WriteTextureLevelInfo(sw::Texture *texture, int level,
mipmap.sliceP[1] = sliceP; mipmap.sliceP[1] = sliceP;
mipmap.sliceP[2] = sliceP; mipmap.sliceP[2] = sliceP;
mipmap.sliceP[3] = 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;
} }
void DescriptorSetLayout::WriteDescriptorSet(Device* device, const VkWriteDescriptorSet& writeDescriptorSet) void DescriptorSetLayout::WriteDescriptorSet(Device* device, const VkWriteDescriptorSet& writeDescriptorSet)
......
...@@ -90,7 +90,7 @@ public: ...@@ -90,7 +90,7 @@ public:
static void CopyDescriptorSet(const VkCopyDescriptorSet& descriptorCopies); static void CopyDescriptorSet(const VkCopyDescriptorSet& descriptorCopies);
static void WriteDescriptorSet(Device* device, DescriptorSet *dstSet, VkDescriptorUpdateTemplateEntry const &entry, char const *src); static void WriteDescriptorSet(Device* device, DescriptorSet *dstSet, VkDescriptorUpdateTemplateEntry const &entry, char const *src);
static void WriteTextureLevelInfo(sw::Texture *texture, int level, int width, int height, int depth, int pitchP, int sliceP); static void WriteTextureLevelInfo(sw::Texture *texture, int level, int width, int height, int depth, int pitchP, int sliceP, int samplePitchP, int sampleMax);
void initialize(DescriptorSet* descriptorSet); void initialize(DescriptorSet* descriptorSet);
......
...@@ -81,6 +81,7 @@ public: ...@@ -81,6 +81,7 @@ public:
bool is3DSlice() const; bool is3DSlice() const;
uint8_t* end() const; uint8_t* end() const;
VkDeviceSize getLayerSize(VkImageAspectFlagBits aspect) const; VkDeviceSize getLayerSize(VkImageAspectFlagBits aspect) const;
VkDeviceSize getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
bool canBindToMemory(DeviceMemory* pDeviceMemory) const; bool canBindToMemory(DeviceMemory* pDeviceMemory) const;
void prepareForSampling(const VkImageSubresourceRange& subresourceRange); void prepareForSampling(const VkImageSubresourceRange& subresourceRange);
...@@ -95,7 +96,6 @@ public: ...@@ -95,7 +96,6 @@ public:
private: private:
void copy(Buffer* buffer, const VkBufferImageCopy& region, bool bufferIsSource); void copy(Buffer* buffer, const VkBufferImageCopy& region, bool bufferIsSource);
VkDeviceSize getStorageSize(VkImageAspectFlags flags) const; VkDeviceSize getStorageSize(VkImageAspectFlags flags) const;
VkDeviceSize getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
VkDeviceSize getMultiSampledLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; VkDeviceSize getMultiSampledLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
VkDeviceSize getLayerOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; VkDeviceSize getLayerOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const; VkDeviceSize getMemoryOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
......
...@@ -267,6 +267,11 @@ int ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, ...@@ -267,6 +267,11 @@ int ImageView::slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel,
return getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel); return getImage(usage)->slicePitchBytes(aspect, subresourceRange.baseMipLevel + mipLevel);
} }
int ImageView::getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage) const
{
return getImage(usage)->getMipLevelSize(aspect, subresourceRange.baseMipLevel + mipLevel);
}
int ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const int ImageView::layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage) const
{ {
return static_cast<int>(getImage(usage)->getLayerSize(aspect)); return static_cast<int>(getImage(usage)->getLayerSize(aspect));
......
...@@ -51,6 +51,7 @@ public: ...@@ -51,6 +51,7 @@ public:
Format getFormat(VkImageAspectFlagBits aspect) const { return image->getFormat(aspect); } Format getFormat(VkImageAspectFlagBits aspect) const { return image->getFormat(aspect); }
int rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const; int rowPitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const;
int slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const; int slicePitchBytes(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const;
int getMipLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel, Usage usage = RAW) const;
int layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage = RAW) const; int layerPitchBytes(VkImageAspectFlagBits aspect, Usage usage = RAW) const;
VkExtent3D getMipLevelExtent(uint32_t mipLevel) const; VkExtent3D getMipLevelExtent(uint32_t mipLevel) const;
......
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