Emulate integer cube texture sampling as an array of six 2D textures.
BUG=angle:525
Change-Id: I3c3ec2cecebf9e745f0c02a132433e3076a6fdea
Reviewed-on: https://chromium-review.googlesource.com/187534
Tested-by: Nicolas Capens <nicolascapens@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 278135e..1b0dce1 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -988,11 +988,11 @@
case EbtSampler2DArray: out << "Texture2DArray x, SamplerState s"; hlslCoords = 3; break;
case EbtISampler2D: out << "Texture2D<int4> x, SamplerState s"; hlslCoords = 2; break;
case EbtISampler3D: out << "Texture3D<int4> x, SamplerState s"; hlslCoords = 3; break;
- case EbtISamplerCube: out << "TextureCube<int4> x, SamplerState s"; hlslCoords = 3; break;
+ case EbtISamplerCube: out << "Texture2DArray<int4> x, SamplerState s"; hlslCoords = 3; break;
case EbtISampler2DArray: out << "Texture2DArray<int4> x, SamplerState s"; hlslCoords = 3; break;
case EbtUSampler2D: out << "Texture2D<uint4> x, SamplerState s"; hlslCoords = 2; break;
case EbtUSampler3D: out << "Texture3D<uint4> x, SamplerState s"; hlslCoords = 3; break;
- case EbtUSamplerCube: out << "TextureCube<uint4> x, SamplerState s"; hlslCoords = 3; break;
+ case EbtUSamplerCube: out << "Texture2DArray<uint4> x, SamplerState s"; hlslCoords = 3; break;
case EbtUSampler2DArray: out << "Texture2DArray<uint4> x, SamplerState s"; hlslCoords = 3; break;
case EbtSampler2DShadow: out << "Texture2D x, SamplerComparisonState s"; hlslCoords = 2; break;
case EbtSamplerCubeShadow: out << "TextureCube x, SamplerComparisonState s"; hlslCoords = 3; break;
@@ -1131,24 +1131,38 @@
default: UNREACHABLE();
}
}
- else if (IsIntegerSampler(textureFunction->sampler) && IsSamplerCube(textureFunction->sampler))
- {
- // Currently unsupported because TextureCube does not support Load
- // This will require emulation using a Texture2DArray with 6 faces
- if (textureFunction->sampler == EbtISamplerCube)
- {
- out << " return int4(0, 0, 0, 0);";
- }
- else if (textureFunction->sampler == EbtUSamplerCube)
- {
- out << " return uint4(0, 0, 0, 0);";
- }
- else UNREACHABLE();
- }
else
{
- if (IsIntegerSampler(textureFunction->sampler) &&
- textureFunction->method != TextureFunction::FETCH)
+ if (IsIntegerSampler(textureFunction->sampler) && IsSamplerCube(textureFunction->sampler))
+ {
+ out << " float width; float height; float layers; float levels;\n";
+
+ out << " uint mip = 0;\n";
+
+ out << " x.GetDimensions(mip, width, height, layers, levels);\n";
+
+ out << " bool xMajor = abs(t.x) > abs(t.y) && abs(t.x) > abs(t.z);\n";
+ out << " bool yMajor = abs(t.y) > abs(t.z) && abs(t.y) > abs(t.x);\n";
+ out << " bool zMajor = abs(t.z) > abs(t.x) && abs(t.z) > abs(t.y);\n";
+ out << " bool negative = (xMajor && t.x < 0.0f) || (yMajor && t.y < 0.0f) || (zMajor && t.z < 0.0f);\n";
+
+ // FACE_POSITIVE_X = 000b
+ // FACE_NEGATIVE_X = 001b
+ // FACE_POSITIVE_Y = 010b
+ // FACE_NEGATIVE_Y = 011b
+ // FACE_POSITIVE_Z = 100b
+ // FACE_NEGATIVE_Z = 101b
+ out << " int face = (int)negative + (int)yMajor * 2 + (int)zMajor * 4;\n";
+
+ out << " float u = xMajor ? -t.z : (yMajor && t.y < 0.0f ? -t.x : t.x);\n";
+ out << " float v = yMajor ? t.z : (negative ? t.y : -t.y);\n";
+ out << " float m = xMajor ? t.x : (yMajor ? t.y : t.z);\n";
+
+ out << " t.x = (u * 0.5f / m) + 0.5f;\n";
+ out << " t.y = (v * 0.5f / m) + 0.5f;\n";
+ }
+ else if (IsIntegerSampler(textureFunction->sampler) &&
+ textureFunction->method != TextureFunction::FETCH)
{
if (IsSampler2D(textureFunction->sampler))
{
@@ -1352,6 +1366,10 @@
{
addressz = "int(max(0, min(layers - 1, floor(0.5 + ";
}
+ else if (IsSamplerCube(textureFunction->sampler))
+ {
+ addressz = "((((";
+ }
else
{
addressz = "int(floor(depth * frac((";
@@ -1416,18 +1434,25 @@
{
if (hlslCoords >= 3)
{
- out << ", " + addressz + ("t.z" + proj) + close;
+ if (IsIntegerSampler(textureFunction->sampler) && IsSamplerCube(textureFunction->sampler))
+ {
+ out << ", face";
+ }
+ else
+ {
+ out << ", " + addressz + ("t.z" + proj) + close;
+ }
}
if (textureFunction->method == TextureFunction::GRAD)
{
if (IsIntegerSampler(textureFunction->sampler))
{
- out << ", mip)";
+ out << ", mip)";
}
else if (IsShadowSampler(textureFunction->sampler))
{
- // Compare value
+ // Compare value
switch(textureFunction->coords)
{
case 3: out << "), t.z"; break;
@@ -3329,11 +3354,11 @@
case EbtSampler3D: return "Texture3D";
case EbtISampler2D: return "Texture2D<int4>";
case EbtISampler3D: return "Texture3D<int4>";
- case EbtISamplerCube: return "TextureCube<int4>";
+ case EbtISamplerCube: return "Texture2DArray<int4>";
case EbtISampler2DArray: return "Texture2DArray<int4>";
case EbtUSampler2D: return "Texture2D<uint4>";
case EbtUSampler3D: return "Texture3D<uint4>";
- case EbtUSamplerCube: return "TextureCube<uint4>";
+ case EbtUSamplerCube: return "Texture2DArray<uint4>";
case EbtUSampler2DArray: return "Texture2DArray<uint4>";
case EbtSampler2DShadow: return "Texture2D";
case EbtSamplerCubeShadow: return "TextureCube";
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 7e3942b..714c6c3 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -1808,8 +1808,6 @@
return TEXTURE_CUBE;
case GL_INT_SAMPLER_CUBE:
case GL_UNSIGNED_INT_SAMPLER_CUBE:
- //UNIMPLEMENTED();
- infoLog.append("Integer cube texture sampling is currently not supported by ANGLE and returns a black color.");
return TEXTURE_CUBE;
case GL_SAMPLER_2D_ARRAY:
case GL_INT_SAMPLER_2D_ARRAY:
diff --git a/src/libGLESv2/formatutils.cpp b/src/libGLESv2/formatutils.cpp
index 9683a98..bc303fe 100644
--- a/src/libGLESv2/formatutils.cpp
+++ b/src/libGLESv2/formatutils.cpp
@@ -1353,7 +1353,7 @@
}
}
-GLuint GetComponentType(GLenum internalFormat, GLuint clientVersion)
+GLenum GetComponentType(GLenum internalFormat, GLuint clientVersion)
{
InternalFormatInfo internalFormatInfo;
if (GetInternalFormatInfo(internalFormat, clientVersion, &internalFormatInfo))
@@ -1363,7 +1363,7 @@
else
{
UNREACHABLE();
- return false;
+ return GL_NONE;
}
}
diff --git a/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp b/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
index df57efd..3a69bc7 100644
--- a/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
+++ b/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
@@ -846,9 +846,23 @@
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat);
- srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
- srvDesc.TextureCube.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
- srvDesc.TextureCube.MostDetailedMip = 0;
+
+ // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six 2D textures
+ if (d3d11::GetComponentType(mTextureFormat) == GL_INT ||
+ d3d11::GetComponentType(mTextureFormat) == GL_UNSIGNED_INT)
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ srvDesc.Texture2DArray.MostDetailedMip = 0;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = 0;
+ srvDesc.Texture2DArray.ArraySize = 6;
+ }
+ else
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+ srvDesc.TextureCube.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
+ srvDesc.TextureCube.MostDetailedMip = 0;
+ }
ID3D11Texture2D *sourceTexture = swizzleRequired ? getSwizzleTexture() : mTexture;
HRESULT result = device->CreateShaderResourceView(sourceTexture, &srvDesc, resultSRV);
@@ -975,7 +989,6 @@
return 6;
}
-
TextureStorage11_3D::TextureStorage11_3D(Renderer *renderer, int baseLevel, int maxLevel, GLenum internalformat, bool renderTarget,
GLsizei width, GLsizei height, GLsizei depth)
: TextureStorage11(renderer, baseLevel, GetTextureBindFlags(internalformat, renderer->getCurrentClientVersion(), renderTarget))