ES31: support compute shader sampling on D3D backend
BUG=angleproject:2756
TEST=angle_end2end_tests.ComputeShaderTest.SamplingAndImageReadWrite/ES3_1_D3D11
Change-Id: I8f112227c5703fcaafffbd2262e6a039f869c483
Reviewed-on: https://chromium-review.googlesource.com/1161754
Commit-Queue: Xinghua Cao <xinghua.cao@intel.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 25104e6..5c96d7b 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -560,8 +560,8 @@
mUsesFlatInterpolation(false),
mUsedShaderSamplerRanges({}),
mDirtySamplerMapping(true),
- mUsedComputeImageRange(0),
- mUsedComputeReadonlyImageRange(0),
+ mUsedComputeImageRange(0, 0),
+ mUsedComputeReadonlyImageRange(0, 0),
mSerial(issueSerial())
{
mDynamicHLSL = new DynamicHLSL(renderer);
@@ -640,7 +640,7 @@
return samplers[samplerIndex].textureType;
}
-GLuint ProgramD3D::getUsedSamplerRange(gl::ShaderType type) const
+gl::RangeUI ProgramD3D::getUsedSamplerRange(gl::ShaderType type) const
{
ASSERT(type != gl::ShaderType::InvalidEnum);
return mUsedShaderSamplerRanges[type];
@@ -722,7 +722,7 @@
return -1;
}
-GLuint ProgramD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const
+gl::RangeUI ProgramD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const
{
switch (type)
{
@@ -731,7 +731,7 @@
// TODO(xinghua.cao@intel.com): add image range of vertex shader and pixel shader.
default:
UNREACHABLE();
- return 0u;
+ return {0, 0};
}
}
@@ -778,7 +778,10 @@
mShaderSamplers[shaderType].push_back(sampler);
}
- stream->readInt(&mUsedShaderSamplerRanges[shaderType]);
+ unsigned int samplerRangeLow, samplerRangeHigh;
+ stream->readInt(&samplerRangeLow);
+ stream->readInt(&samplerRangeHigh);
+ mUsedShaderSamplerRanges[shaderType] = gl::RangeUI(samplerRangeLow, samplerRangeHigh);
}
const unsigned int csImageCount = stream->readInt<unsigned int>();
@@ -799,8 +802,15 @@
mReadonlyImagesCS.push_back(image);
}
- stream->readInt(&mUsedComputeImageRange);
- stream->readInt(&mUsedComputeReadonlyImageRange);
+ unsigned int computeImageRangeLow, computeImageRangeHigh, computeReadonlyImageRangeLow,
+ computeReadonlyImageRangeHigh;
+ stream->readInt(&computeImageRangeLow);
+ stream->readInt(&computeImageRangeHigh);
+ stream->readInt(&computeReadonlyImageRangeLow);
+ stream->readInt(&computeReadonlyImageRangeHigh);
+ mUsedComputeImageRange = gl::RangeUI(computeImageRangeLow, computeImageRangeHigh);
+ mUsedComputeReadonlyImageRange =
+ gl::RangeUI(computeReadonlyImageRangeLow, computeReadonlyImageRangeHigh);
const unsigned int uniformCount = stream->readInt<unsigned int>();
if (stream->error())
@@ -1036,7 +1046,8 @@
stream->writeEnum(mShaderSamplers[shaderType][i].textureType);
}
- stream->writeInt(mUsedShaderSamplerRanges[shaderType]);
+ stream->writeInt(mUsedShaderSamplerRanges[shaderType].low());
+ stream->writeInt(mUsedShaderSamplerRanges[shaderType].high());
}
stream->writeInt(mImagesCS.size());
@@ -1053,8 +1064,10 @@
stream->writeInt(mReadonlyImagesCS[i].logicalImageUnit);
}
- stream->writeInt(mUsedComputeImageRange);
- stream->writeInt(mUsedComputeReadonlyImageRange);
+ stream->writeInt(mUsedComputeImageRange.low());
+ stream->writeInt(mUsedComputeImageRange.high());
+ stream->writeInt(mUsedComputeReadonlyImageRange.low());
+ stream->writeInt(mUsedComputeReadonlyImageRange.high());
stream->writeInt(mD3DUniforms.size());
for (const D3DUniform *uniform : mD3DUniforms)
@@ -2028,6 +2041,11 @@
}
assignAllSamplerRegisters();
+ // Samplers and readonly images share shader input resource slot, adjust low value of
+ // readonly image range.
+ mUsedComputeReadonlyImageRange =
+ gl::RangeUI(mUsedShaderSamplerRanges[gl::ShaderType::Compute].high(),
+ mUsedShaderSamplerRanges[gl::ShaderType::Compute].high());
assignAllImageRegisters();
initializeUniformStorage(attachedShaders);
}
@@ -2315,7 +2333,7 @@
GLboolean transpose,
const GLfloat *value)
{
- D3DUniform *targetUniform = getD3DUniformFromLocation(location);
+ D3DUniform *targetUniform = getD3DUniformFromLocation(location);
const gl::VariableLocation &uniformLocation = mState.getUniformLocations()[location];
unsigned int arrayElementOffset = uniformLocation.arrayIndex;
unsigned int elementCount = targetUniform->getArraySizeProduct();
@@ -2390,9 +2408,11 @@
const gl::UniformTypeInfo &typeInfo,
unsigned int samplerCount,
std::vector<Sampler> &outSamplers,
- GLuint *outUsedRange)
+ gl::RangeUI *outUsedRange)
{
unsigned int samplerIndex = startSamplerIndex;
+ unsigned int low = outUsedRange->low();
+ unsigned int high = outUsedRange->high();
do
{
@@ -2401,9 +2421,13 @@
sampler->active = true;
sampler->textureType = gl::FromGLenum<gl::TextureType>(typeInfo.textureType);
sampler->logicalTextureUnit = 0;
- *outUsedRange = std::max(samplerIndex + 1, *outUsedRange);
+ low = std::min(samplerIndex, low);
+ high = std::max(samplerIndex + 1, high);
samplerIndex++;
} while (samplerIndex < startSamplerIndex + samplerCount);
+
+ ASSERT(low < high);
+ *outUsedRange = gl::RangeUI(low, high);
}
void ProgramD3D::assignAllImageRegisters()
@@ -2469,9 +2493,12 @@
int startLogicalImageUnit,
unsigned int imageCount,
std::vector<Image> &outImages,
- GLuint *outUsedRange)
+ gl::RangeUI *outUsedRange)
{
unsigned int imageIndex = startImageIndex;
+ unsigned int low = outUsedRange->low();
+ unsigned int high = outUsedRange->high();
+
// If declare without a binding qualifier, any uniform image variable (include all elements of
// unbound image array) shoud be bound to unit zero.
if (startLogicalImageUnit == -1)
@@ -2480,7 +2507,10 @@
Image *image = &outImages[imageIndex];
image->active = true;
image->logicalImageUnit = 0;
- *outUsedRange = std::max(imageIndex + 1, *outUsedRange);
+ low = std::min(imageIndex, low);
+ high = std::max(imageIndex + 1, high);
+ ASSERT(low < high);
+ *outUsedRange = gl::RangeUI(low, high);
return;
}
@@ -2491,10 +2521,14 @@
Image *image = &outImages[imageIndex];
image->active = true;
image->logicalImageUnit = logcalImageUnit;
- *outUsedRange = std::max(imageIndex + 1, *outUsedRange);
+ low = std::min(imageIndex, low);
+ high = std::max(imageIndex + 1, high);
imageIndex++;
logcalImageUnit++;
} while (imageIndex < startImageIndex + imageCount);
+
+ ASSERT(low < high);
+ *outUsedRange = gl::RangeUI(low, high);
}
void ProgramD3D::reset()
@@ -2534,10 +2568,10 @@
mImagesCS.clear();
mReadonlyImagesCS.clear();
- mUsedShaderSamplerRanges.fill(0);
+ mUsedShaderSamplerRanges.fill({0, 0});
mDirtySamplerMapping = true;
- mUsedComputeImageRange = 0;
- mUsedComputeReadonlyImageRange = 0;
+ mUsedComputeImageRange = {0, 0};
+ mUsedComputeReadonlyImageRange = {0, 0};
mAttribLocationToD3DSemantic.fill(-1);
@@ -2684,9 +2718,9 @@
for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex)
{
const auto ®isterInfo = registerInfos[registerIndex];
- const auto &varying = *registerInfo.packedVarying->varying;
- GLenum transposedType = gl::TransposeMatrixType(varying.type);
- int componentCount = gl::VariableColumnCount(transposedType);
+ const auto &varying = *registerInfo.packedVarying->varying;
+ GLenum transposedType = gl::TransposeMatrixType(varying.type);
+ int componentCount = gl::VariableColumnCount(transposedType);
ASSERT(!varying.isBuiltIn() && !varying.isStruct());
// There can be more than one register assigned to a particular varying, and each