Commit 1245f078 by Anders Leino Committed by Commit Bot

Use D3D11 GetDimensions driver workaround for dynamic images

Some NVIDIA D3D11 drivers are buggy and interprets the level passed to GetDimensions as being relative to 0, rather than the SRV's MostDetailedMip. This affects the implementation of the imageSize function in the D3D11 backend. Bug: angleproject:3100 Change-Id: I1e48f5df5e40caf49a4d07662aec587e98cf8388 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1677206Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 615ae1a7
......@@ -592,7 +592,8 @@ void ResourcesHLSL::imageMetadataUniforms(TInfoSinkBase &out, unsigned int regIn
out << " struct ImageMetadata\n"
" {\n"
" int layer;\n"
" int3 padding;\n"
" uint level;\n"
" int2 padding;\n"
" };\n";
if (mReadonlyImageCount > 0)
......
......@@ -325,7 +325,7 @@ std::string getImage2DGroupReturnType(Image2DHLSLGroup group, Image2DMethod meth
}
}
std::string getImageMetadataLayer(Image2DHLSLGroup group)
std::string getImageMetadata(Image2DHLSLGroup group)
{
switch (group)
{
......@@ -334,13 +334,13 @@ std::string getImageMetadataLayer(Image2DHLSLGroup group)
case IMAGE2D_R_SNORM:
case IMAGE2D_R_UINT4:
case IMAGE2D_R_INT4:
return "readonlyImageMetadata[imageIndex - readonlyImageIndexStart].layer";
return "readonlyImageMetadata[imageIndex - readonlyImageIndexStart]";
case IMAGE2D_W_FLOAT4:
case IMAGE2D_W_UNORM:
case IMAGE2D_W_SNORM:
case IMAGE2D_W_UINT4:
case IMAGE2D_W_INT4:
return "imageMetadata[imageIndex - imageIndexStart].layer";
return "imageMetadata[imageIndex - imageIndexStart]";
default:
UNREACHABLE();
return "unknown image method";
......@@ -390,7 +390,8 @@ void OutputImage2DSizeFunction(std::ostringstream &out,
unsigned int texture3DCount,
unsigned int texture2DArrayCount,
const std::string &offsetStr,
const std::string &declarationStr)
const std::string &declarationStr,
bool getDimensionsIgnoresBaseLevel)
{
out << getImage2DGroupReturnType(textureGroup, IMAGE2DSIZE) << " "
<< Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DSIZE) << "(";
......@@ -404,7 +405,17 @@ void OutputImage2DSizeFunction(std::ostringstream &out,
if (texture2DCount == totalCount)
{
out << " const uint index = imageIndex - " << offsetStr << "2D;\n";
out << " " << declarationStr << "2D[index].GetDimensions(width, height);\n";
if (getDimensionsIgnoresBaseLevel)
{
out << " uint levelCount;\n";
out << " const uint level = " << getImageMetadata(textureGroup) << ".level;\n";
out << " " << declarationStr
<< "2D[index].GetDimensions(level, width, height, levelCount);\n";
}
else
{
out << " " << declarationStr << "2D[index].GetDimensions(width, height);\n";
}
}
else
{
......@@ -519,7 +530,7 @@ void OutputImage2DLoadFunction(std::ostringstream &out,
{
out << " const uint index = imageIndex - " << offsetStr << "3D;\n";
out << " result = " << declarationStr << "3D[index][uint3(p.x, p.y, "
<< getImageMetadataLayer(textureGroup) << ")];\n";
<< getImageMetadata(textureGroup) << ".layer)];\n";
}
else
{
......@@ -543,7 +554,7 @@ void OutputImage2DLoadFunction(std::ostringstream &out,
out << " {\n";
out << " const uint index = imageIndex - " << offsetStr << "3D;\n";
out << " result = " << declarationStr << "3D[index][uint3(p.x, p.y, "
<< getImageMetadataLayer(textureGroup) << ")];\n";
<< getImageMetadata(textureGroup) << ".layer)];\n";
out << " }\n";
}
}
......@@ -554,7 +565,7 @@ void OutputImage2DLoadFunction(std::ostringstream &out,
{
out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n";
out << " result = " << declarationStr << "2DArray[index][uint3(p.x, p.y, "
<< getImageMetadataLayer(textureGroup) << ")];\n";
<< getImageMetadata(textureGroup) << ".layer)];\n";
}
else
{
......@@ -562,7 +573,7 @@ void OutputImage2DLoadFunction(std::ostringstream &out,
out << " {\n";
out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n";
out << " result = " << declarationStr << "2DArray[index][uint3(p.x, p.y, "
<< getImageMetadataLayer(textureGroup) << ")];\n";
<< getImageMetadata(textureGroup) << ".layer)];\n";
out << " }\n";
}
}
......@@ -610,7 +621,7 @@ void OutputImage2DStoreFunction(std::ostringstream &out,
{
out << " const uint index = imageIndex - " << offsetStr << "3D;\n";
out << " " << declarationStr << "3D[index][uint3(p.x, p.y, "
<< getImageMetadataLayer(textureGroup) << ")] = data;\n";
<< getImageMetadata(textureGroup) << ".layer)] = data;\n";
}
else
{
......@@ -634,7 +645,7 @@ void OutputImage2DStoreFunction(std::ostringstream &out,
out << " {\n";
out << " const uint index = imageIndex - " << offsetStr << "3D;\n";
out << " " << declarationStr << "3D[index][uint3(p.x, p.y, "
<< getImageMetadataLayer(textureGroup) << ")] = data;\n";
<< getImageMetadata(textureGroup) << ".layer)] = data;\n";
out << " }\n";
}
}
......@@ -645,7 +656,7 @@ void OutputImage2DStoreFunction(std::ostringstream &out,
{
out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n";
out << " " << declarationStr << "2DArray[index][uint3(p.x, p.y, "
<< getImageMetadataLayer(textureGroup) << ")] = data;\n";
<< getImageMetadata(textureGroup) << ".layer)] = data;\n";
}
else
{
......@@ -653,7 +664,7 @@ void OutputImage2DStoreFunction(std::ostringstream &out,
out << " {\n";
out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n";
out << " " << declarationStr << "2DArray[index][uint3(p.x, p.y, "
<< getImageMetadataLayer(textureGroup) << ")] = data;\n";
<< getImageMetadata(textureGroup) << ".layer)] = data;\n";
out << " }\n";
}
}
......@@ -816,11 +827,13 @@ void OutputHLSLImage2DUniformGroup(ProgramD3D &programD3D,
gl::Shader *shaderGL = programData.getAttachedShader(shaderType);
const ShaderD3D *shaderD3D = GetImplAs<ShaderD3D>(shaderGL);
const bool getDimensionsIgnoresBaseLevel = programD3D.usesGetDimensionsIgnoresBaseLevel();
if (shaderD3D->useImage2DFunction(Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DSIZE)))
{
OutputImage2DSizeFunction(out, textureGroup, totalCount, texture2DCount, texture3DCount,
texture2DArrayCount, offsetStr, declarationStr);
texture2DArrayCount, offsetStr, declarationStr,
getDimensionsIgnoresBaseLevel);
}
if (shaderD3D->useImage2DFunction(Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DLOAD)))
{
......
......@@ -677,6 +677,11 @@ bool ProgramD3D::usesGeometryShaderForPointSpriteEmulation() const
return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation();
}
bool ProgramD3D::usesGetDimensionsIgnoresBaseLevel() const
{
return mRenderer->getFeatures().getDimensionsIgnoresBaseLevel.enabled;
}
bool ProgramD3D::usesGeometryShader(const gl::State &state, const gl::PrimitiveMode drawMode) const
{
if (mHasANGLEMultiviewEnabled && !mRenderer->canSelectViewInVertexShader())
......
......@@ -183,6 +183,7 @@ class ProgramD3D : public ProgramImpl
bool usesPointSpriteEmulation() const;
bool usesGeometryShader(const gl::State &state, gl::PrimitiveMode drawMode) const;
bool usesGeometryShaderForPointSpriteEmulation() const;
bool usesGetDimensionsIgnoresBaseLevel() const;
bool usesInstancedPointSpriteEmulation() const;
std::unique_ptr<LinkEvent> load(const gl::Context *context,
......
......@@ -447,12 +447,19 @@ bool ShaderConstants11::updateSamplerMetadata(SamplerMetadata *data,
bool ShaderConstants11::updateImageMetadata(ImageMetadata *data, const gl::ImageUnit &imageUnit)
{
bool dirty = false;
if (data->layer != static_cast<int>(imageUnit.layer))
{
data->layer = static_cast<int>(imageUnit.layer);
dirty = true;
}
if (data->level != static_cast<unsigned int>(imageUnit.level))
{
data->level = static_cast<unsigned int>(imageUnit.level);
dirty = true;
}
return dirty;
}
......
......@@ -133,10 +133,11 @@ class ShaderConstants11 : angle::NonCopyable
struct ImageMetadata
{
ImageMetadata() : layer(0), padding{0} {}
ImageMetadata() : layer(0), level(0), padding{0} {}
int layer;
int padding[3]; // This just pads the struct to 16 bytes
unsigned int level;
int padding[2]; // This just pads the struct to 16 bytes
};
static_assert(sizeof(ImageMetadata) == 16u,
"Image metadata struct must be one 4-vec --> 16 bytes.");
......
......@@ -2786,9 +2786,6 @@ void main()
// Test imageSize to access mipmap slice.
TEST_P(ComputeShaderTest, ImageSizeMipmapSlice)
{
// TODO(xinghua.cao@intel.com): http://anglebug.com/3100
ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsD3D11());
// TODO(xinghua.cao@intel.com): http://anglebug.com/3101
ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
......
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