Commit 06a22620 by Xinghua Cao Committed by Commit Bot

ES31: Use indices to access image variables in built-in image functions

In order to implement glBindImageTexture to bind a layer of 3D/2DArray/Cube texture, use indices to access image variables when translating built-in image functions. There is a conflict when transferring image2D/iimage2D/uimage2D variables to an user defined function. For example, layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1; layout(r32ui, binding = 1) readonly uniform highp uimage2D uImage_2; uvec4 lod_fun(uimage2D img, ivec2 p) { return imageLoad(img, p); } void main() { uvec4 value_1 = lod_fun(uImage_1, ivec2(gl_LocalInvocationID.xy)); uvec4 value_2 = lod_fun(uImage_2, ivec2(gl_LocalInvocationID.xy)); } If uImage_1 binds to a 2D texture, and uImage_2 binds to a layer of 3D texture, uImage_1 will be translated to Texture2D type, and uImage_2 will be translated to Texture3D type, "img" type of lod_fun will be translated Texture2D, so uImage_2 cannot be transferred to lod_fun as a parameter. Indices without Texture/RWTexture information could handle this situation easily. BUG=angleproject:1987 TEST=angle_end2end_tests.ComputeShaderTest.* Change-Id: I7647395f0042f613c5d6e9eeb49392ab6252e21e Reviewed-on: https://chromium-review.googlesource.com/1065797 Commit-Queue: Xinghua Cao <xinghua.cao@intel.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent 9491e5eb
......@@ -7,24 +7,48 @@
//
#include "compiler/translator/ImageFunctionHLSL.h"
#include "compiler/translator/ImmutableStringBuilder.h"
#include "compiler/translator/UtilsHLSL.h"
namespace sh
{
// static
void ImageFunctionHLSL::OutputImageFunctionArgumentList(
ImmutableString ImageFunctionHLSL::GetImageReference(
TInfoSinkBase &out,
const ImageFunctionHLSL::ImageFunction &imageFunction)
{
static const ImmutableString kImageIndexStr("[index]");
if (imageFunction.readonly)
{
out << TextureString(imageFunction.image, imageFunction.imageInternalFormat) << " tex";
static const ImmutableString kReadonlyImagesStr("readonlyImages");
ImmutableString suffix(
TextureGroupSuffix(imageFunction.image, imageFunction.imageInternalFormat));
out << " const uint index = imageIndex - readonlyImageIndexOffset" << suffix.data()
<< ";\n";
ImmutableStringBuilder imageRefBuilder(kReadonlyImagesStr.length() + suffix.length() +
kImageIndexStr.length());
imageRefBuilder << kReadonlyImagesStr << suffix << kImageIndexStr;
return imageRefBuilder;
}
else
{
out << RWTextureString(imageFunction.image, imageFunction.imageInternalFormat) << " tex";
static const ImmutableString kImagesStr("images");
ImmutableString suffix(
RWTextureGroupSuffix(imageFunction.image, imageFunction.imageInternalFormat));
out << " const uint index = imageIndex - imageIndexOffset" << suffix.data() << ";\n";
ImmutableStringBuilder imageRefBuilder(kImagesStr.length() + suffix.length() +
kImageIndexStr.length());
imageRefBuilder << kImagesStr << suffix << kImageIndexStr;
return imageRefBuilder;
}
}
void ImageFunctionHLSL::OutputImageFunctionArgumentList(
TInfoSinkBase &out,
const ImageFunctionHLSL::ImageFunction &imageFunction)
{
out << "uint imageIndex";
if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::LOAD ||
imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE)
......@@ -84,7 +108,7 @@ void ImageFunctionHLSL::OutputImageFunctionArgumentList(
void ImageFunctionHLSL::OutputImageSizeFunctionBody(
TInfoSinkBase &out,
const ImageFunctionHLSL::ImageFunction &imageFunction,
const TString &imageReference)
const ImmutableString &imageReference)
{
if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
IsImageCube(imageFunction.image))
......@@ -115,7 +139,7 @@ void ImageFunctionHLSL::OutputImageSizeFunctionBody(
void ImageFunctionHLSL::OutputImageLoadFunctionBody(
TInfoSinkBase &out,
const ImageFunctionHLSL::ImageFunction &imageFunction,
const TString &imageReference)
const ImmutableString &imageReference)
{
if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
IsImageCube(imageFunction.image))
......@@ -134,7 +158,7 @@ void ImageFunctionHLSL::OutputImageLoadFunctionBody(
void ImageFunctionHLSL::OutputImageStoreFunctionBody(
TInfoSinkBase &out,
const ImageFunctionHLSL::ImageFunction &imageFunction,
const TString &imageReference)
const ImmutableString &imageReference)
{
if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
IsImage2D(imageFunction.image) || IsImageCube(imageFunction.image))
......@@ -175,6 +199,36 @@ TString ImageFunctionHLSL::ImageFunction::name() const
return name;
}
ImageFunctionHLSL::ImageFunction::DataType ImageFunctionHLSL::ImageFunction::getDataType(
TLayoutImageInternalFormat format) const
{
switch (format)
{
case EiifRGBA32F:
case EiifRGBA16F:
case EiifR32F:
return ImageFunction::DataType::FLOAT4;
case EiifRGBA32UI:
case EiifRGBA16UI:
case EiifRGBA8UI:
case EiifR32UI:
return ImageFunction::DataType::UINT4;
case EiifRGBA32I:
case EiifRGBA16I:
case EiifRGBA8I:
case EiifR32I:
return ImageFunction::DataType::INT4;
case EiifRGBA8:
return ImageFunction::DataType::UNORM_FLOAT4;
case EiifRGBA8_SNORM:
return ImageFunction::DataType::SNORM_FLOAT4;
default:
UNREACHABLE();
}
return ImageFunction::DataType::NONE;
}
const char *ImageFunctionHLSL::ImageFunction::getReturnType() const
{
if (method == ImageFunction::Method::SIZE)
......@@ -235,8 +289,8 @@ const char *ImageFunctionHLSL::ImageFunction::getReturnType() const
bool ImageFunctionHLSL::ImageFunction::operator<(const ImageFunction &rhs) const
{
return std::tie(image, imageInternalFormat, readonly, method) <
std::tie(rhs.image, rhs.imageInternalFormat, rhs.readonly, rhs.method);
return std::tie(image, type, method, readonly) <
std::tie(rhs.image, rhs.type, rhs.method, rhs.readonly);
}
TString ImageFunctionHLSL::useImageFunction(const ImmutableString &name,
......@@ -249,6 +303,7 @@ TString ImageFunctionHLSL::useImageFunction(const ImmutableString &name,
imageFunction.image = type;
imageFunction.imageInternalFormat = imageInternalFormat;
imageFunction.readonly = readonly;
imageFunction.type = imageFunction.getDataType(imageInternalFormat);
if (name == "imageSize")
{
......@@ -281,8 +336,7 @@ void ImageFunctionHLSL::imageFunctionHeader(TInfoSinkBase &out)
out << ")\n"
"{\n";
TString imageReference("tex");
ImmutableString imageReference = GetImageReference(out, imageFunction);
if (imageFunction.method == ImageFunction::Method::SIZE)
{
OutputImageSizeFunctionBody(out, imageFunction, imageReference);
......
......@@ -43,30 +43,45 @@ class ImageFunctionHLSL final : angle::NonCopyable
STORE
};
enum class DataType
{
NONE,
FLOAT4,
UINT4,
INT4,
UNORM_FLOAT4,
SNORM_FLOAT4
};
TString name() const;
bool operator<(const ImageFunction &rhs) const;
DataType getDataType(TLayoutImageInternalFormat format) const;
const char *getReturnType() const;
TBasicType image;
TLayoutImageInternalFormat imageInternalFormat;
bool readonly;
Method method;
DataType type;
};
static ImmutableString GetImageReference(TInfoSinkBase &out,
const ImageFunctionHLSL::ImageFunction &imageFunction);
static void OutputImageFunctionArgumentList(
TInfoSinkBase &out,
const ImageFunctionHLSL::ImageFunction &imageFunction);
static void OutputImageSizeFunctionBody(TInfoSinkBase &out,
const ImageFunctionHLSL::ImageFunction &imageFunction,
const TString &imageReference);
const ImmutableString &imageReference);
static void OutputImageLoadFunctionBody(TInfoSinkBase &out,
const ImageFunctionHLSL::ImageFunction &imageFunction,
const TString &imageReference);
const ImmutableString &imageReference);
static void OutputImageStoreFunctionBody(TInfoSinkBase &out,
const ImageFunctionHLSL::ImageFunction &imageFunction,
const TString &imageReference);
const ImmutableString &imageReference);
using ImageFunctionSet = std::set<ImageFunction>;
ImageFunctionSet mUsesImage;
};
......
......@@ -202,8 +202,7 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType,
unsigned int firstUniformRegister =
((compileOptions & SH_SKIP_D3D_CONSTANT_REGISTER_ZERO) != 0) ? 1u : 0u;
mUniformHLSL =
new UniformHLSL(shaderType, mStructureHLSL, outputType, uniforms, firstUniformRegister);
mUniformHLSL = new UniformHLSL(mStructureHLSL, outputType, uniforms, firstUniformRegister);
if (mOutputType == SH_HLSL_3_0_OUTPUT)
{
......
......@@ -22,8 +22,7 @@ class TSymbolTable;
class UniformHLSL : angle::NonCopyable
{
public:
UniformHLSL(sh::GLenum shaderType,
StructureHLSL *structureHLSL,
UniformHLSL(StructureHLSL *structureHLSL,
ShShaderOutput outputType,
const std::vector<Uniform> &uniforms,
unsigned int firstUniformRegister);
......@@ -67,14 +66,6 @@ class UniformHLSL : angle::NonCopyable
const TType &type,
const TVariable &variable,
const unsigned int registerIndex);
void outputHLSL4_1_FL11Texture(TInfoSinkBase &out,
const TType &type,
const TVariable &variable,
const unsigned int registerIndex);
void outputHLSL4_1_FL11RWTexture(TInfoSinkBase &out,
const TType &type,
const TVariable &variable,
const unsigned int registerIndex);
void outputUniform(TInfoSinkBase &out,
const TType &type,
const TVariable &variable,
......@@ -95,12 +86,26 @@ class UniformHLSL : angle::NonCopyable
const TMap<const TVariable *, TString> &samplerInStructSymbolsToAPINames,
unsigned int *groupTextureRegisterIndex);
void outputHLSLImageUniformIndices(TInfoSinkBase &out,
const TVector<const TVariable *> &group,
unsigned int imageArrayIndex,
unsigned int *groupRegisterCount);
void outputHLSLReadonlyImageUniformGroup(TInfoSinkBase &out,
const HLSLTextureGroup textureGroup,
const TVector<const TVariable *> &group,
unsigned int *groupTextureRegisterIndex,
unsigned int *imageUniformGroupIndex);
void outputHLSLImageUniformGroup(TInfoSinkBase &out,
const HLSLRWTextureGroup textureGroup,
const TVector<const TVariable *> &group,
unsigned int *groupTextureRegisterIndex,
unsigned int *imageUniformGroupIndex);
unsigned int mUniformRegister;
unsigned int mUniformBlockRegister;
unsigned int mTextureRegister;
unsigned int mRWTextureRegister;
unsigned int mSamplerCount;
sh::GLenum mShaderType;
StructureHLSL *mStructureHLSL;
ShShaderOutput mOutputType;
......
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