Commit 6dfdca83 by Xinghua Cao Committed by Commit Bot

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: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 24507bc7
...@@ -560,8 +560,8 @@ ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer) ...@@ -560,8 +560,8 @@ ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer)
mUsesFlatInterpolation(false), mUsesFlatInterpolation(false),
mUsedShaderSamplerRanges({}), mUsedShaderSamplerRanges({}),
mDirtySamplerMapping(true), mDirtySamplerMapping(true),
mUsedComputeImageRange(0), mUsedComputeImageRange(0, 0),
mUsedComputeReadonlyImageRange(0), mUsedComputeReadonlyImageRange(0, 0),
mSerial(issueSerial()) mSerial(issueSerial())
{ {
mDynamicHLSL = new DynamicHLSL(renderer); mDynamicHLSL = new DynamicHLSL(renderer);
...@@ -640,7 +640,7 @@ gl::TextureType ProgramD3D::getSamplerTextureType(gl::ShaderType type, ...@@ -640,7 +640,7 @@ gl::TextureType ProgramD3D::getSamplerTextureType(gl::ShaderType type,
return samplers[samplerIndex].textureType; return samplers[samplerIndex].textureType;
} }
GLuint ProgramD3D::getUsedSamplerRange(gl::ShaderType type) const gl::RangeUI ProgramD3D::getUsedSamplerRange(gl::ShaderType type) const
{ {
ASSERT(type != gl::ShaderType::InvalidEnum); ASSERT(type != gl::ShaderType::InvalidEnum);
return mUsedShaderSamplerRanges[type]; return mUsedShaderSamplerRanges[type];
...@@ -722,7 +722,7 @@ GLint ProgramD3D::getImageMapping(gl::ShaderType type, ...@@ -722,7 +722,7 @@ GLint ProgramD3D::getImageMapping(gl::ShaderType type,
return -1; return -1;
} }
GLuint ProgramD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const gl::RangeUI ProgramD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const
{ {
switch (type) switch (type)
{ {
...@@ -731,7 +731,7 @@ GLuint ProgramD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const ...@@ -731,7 +731,7 @@ GLuint ProgramD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const
// TODO(xinghua.cao@intel.com): add image range of vertex shader and pixel shader. // TODO(xinghua.cao@intel.com): add image range of vertex shader and pixel shader.
default: default:
UNREACHABLE(); UNREACHABLE();
return 0u; return {0, 0};
} }
} }
...@@ -778,7 +778,10 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context, ...@@ -778,7 +778,10 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
mShaderSamplers[shaderType].push_back(sampler); 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>(); const unsigned int csImageCount = stream->readInt<unsigned int>();
...@@ -799,8 +802,15 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context, ...@@ -799,8 +802,15 @@ gl::LinkResult ProgramD3D::load(const gl::Context *context,
mReadonlyImagesCS.push_back(image); mReadonlyImagesCS.push_back(image);
} }
stream->readInt(&mUsedComputeImageRange); unsigned int computeImageRangeLow, computeImageRangeHigh, computeReadonlyImageRangeLow,
stream->readInt(&mUsedComputeReadonlyImageRange); 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>(); const unsigned int uniformCount = stream->readInt<unsigned int>();
if (stream->error()) if (stream->error())
...@@ -1036,7 +1046,8 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream ...@@ -1036,7 +1046,8 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream
stream->writeEnum(mShaderSamplers[shaderType][i].textureType); stream->writeEnum(mShaderSamplers[shaderType][i].textureType);
} }
stream->writeInt(mUsedShaderSamplerRanges[shaderType]); stream->writeInt(mUsedShaderSamplerRanges[shaderType].low());
stream->writeInt(mUsedShaderSamplerRanges[shaderType].high());
} }
stream->writeInt(mImagesCS.size()); stream->writeInt(mImagesCS.size());
...@@ -1053,8 +1064,10 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream ...@@ -1053,8 +1064,10 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream
stream->writeInt(mReadonlyImagesCS[i].logicalImageUnit); stream->writeInt(mReadonlyImagesCS[i].logicalImageUnit);
} }
stream->writeInt(mUsedComputeImageRange); stream->writeInt(mUsedComputeImageRange.low());
stream->writeInt(mUsedComputeReadonlyImageRange); stream->writeInt(mUsedComputeImageRange.high());
stream->writeInt(mUsedComputeReadonlyImageRange.low());
stream->writeInt(mUsedComputeReadonlyImageRange.high());
stream->writeInt(mD3DUniforms.size()); stream->writeInt(mD3DUniforms.size());
for (const D3DUniform *uniform : mD3DUniforms) for (const D3DUniform *uniform : mD3DUniforms)
...@@ -2028,6 +2041,11 @@ void ProgramD3D::defineUniformsAndAssignRegisters() ...@@ -2028,6 +2041,11 @@ void ProgramD3D::defineUniformsAndAssignRegisters()
} }
assignAllSamplerRegisters(); 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(); assignAllImageRegisters();
initializeUniformStorage(attachedShaders); initializeUniformStorage(attachedShaders);
} }
...@@ -2315,7 +2333,7 @@ void ProgramD3D::setUniformMatrixfvInternal(GLint location, ...@@ -2315,7 +2333,7 @@ void ProgramD3D::setUniformMatrixfvInternal(GLint location,
GLboolean transpose, GLboolean transpose,
const GLfloat *value) const GLfloat *value)
{ {
D3DUniform *targetUniform = getD3DUniformFromLocation(location); D3DUniform *targetUniform = getD3DUniformFromLocation(location);
const gl::VariableLocation &uniformLocation = mState.getUniformLocations()[location]; const gl::VariableLocation &uniformLocation = mState.getUniformLocations()[location];
unsigned int arrayElementOffset = uniformLocation.arrayIndex; unsigned int arrayElementOffset = uniformLocation.arrayIndex;
unsigned int elementCount = targetUniform->getArraySizeProduct(); unsigned int elementCount = targetUniform->getArraySizeProduct();
...@@ -2390,9 +2408,11 @@ void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex, ...@@ -2390,9 +2408,11 @@ void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex,
const gl::UniformTypeInfo &typeInfo, const gl::UniformTypeInfo &typeInfo,
unsigned int samplerCount, unsigned int samplerCount,
std::vector<Sampler> &outSamplers, std::vector<Sampler> &outSamplers,
GLuint *outUsedRange) gl::RangeUI *outUsedRange)
{ {
unsigned int samplerIndex = startSamplerIndex; unsigned int samplerIndex = startSamplerIndex;
unsigned int low = outUsedRange->low();
unsigned int high = outUsedRange->high();
do do
{ {
...@@ -2401,9 +2421,13 @@ void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex, ...@@ -2401,9 +2421,13 @@ void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex,
sampler->active = true; sampler->active = true;
sampler->textureType = gl::FromGLenum<gl::TextureType>(typeInfo.textureType); sampler->textureType = gl::FromGLenum<gl::TextureType>(typeInfo.textureType);
sampler->logicalTextureUnit = 0; sampler->logicalTextureUnit = 0;
*outUsedRange = std::max(samplerIndex + 1, *outUsedRange); low = std::min(samplerIndex, low);
high = std::max(samplerIndex + 1, high);
samplerIndex++; samplerIndex++;
} while (samplerIndex < startSamplerIndex + samplerCount); } while (samplerIndex < startSamplerIndex + samplerCount);
ASSERT(low < high);
*outUsedRange = gl::RangeUI(low, high);
} }
void ProgramD3D::assignAllImageRegisters() void ProgramD3D::assignAllImageRegisters()
...@@ -2469,9 +2493,12 @@ void ProgramD3D::AssignImages(unsigned int startImageIndex, ...@@ -2469,9 +2493,12 @@ void ProgramD3D::AssignImages(unsigned int startImageIndex,
int startLogicalImageUnit, int startLogicalImageUnit,
unsigned int imageCount, unsigned int imageCount,
std::vector<Image> &outImages, std::vector<Image> &outImages,
GLuint *outUsedRange) gl::RangeUI *outUsedRange)
{ {
unsigned int imageIndex = startImageIndex; 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 // If declare without a binding qualifier, any uniform image variable (include all elements of
// unbound image array) shoud be bound to unit zero. // unbound image array) shoud be bound to unit zero.
if (startLogicalImageUnit == -1) if (startLogicalImageUnit == -1)
...@@ -2480,7 +2507,10 @@ void ProgramD3D::AssignImages(unsigned int startImageIndex, ...@@ -2480,7 +2507,10 @@ void ProgramD3D::AssignImages(unsigned int startImageIndex,
Image *image = &outImages[imageIndex]; Image *image = &outImages[imageIndex];
image->active = true; image->active = true;
image->logicalImageUnit = 0; 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; return;
} }
...@@ -2491,10 +2521,14 @@ void ProgramD3D::AssignImages(unsigned int startImageIndex, ...@@ -2491,10 +2521,14 @@ void ProgramD3D::AssignImages(unsigned int startImageIndex,
Image *image = &outImages[imageIndex]; Image *image = &outImages[imageIndex];
image->active = true; image->active = true;
image->logicalImageUnit = logcalImageUnit; image->logicalImageUnit = logcalImageUnit;
*outUsedRange = std::max(imageIndex + 1, *outUsedRange); low = std::min(imageIndex, low);
high = std::max(imageIndex + 1, high);
imageIndex++; imageIndex++;
logcalImageUnit++; logcalImageUnit++;
} while (imageIndex < startImageIndex + imageCount); } while (imageIndex < startImageIndex + imageCount);
ASSERT(low < high);
*outUsedRange = gl::RangeUI(low, high);
} }
void ProgramD3D::reset() void ProgramD3D::reset()
...@@ -2534,10 +2568,10 @@ void ProgramD3D::reset() ...@@ -2534,10 +2568,10 @@ void ProgramD3D::reset()
mImagesCS.clear(); mImagesCS.clear();
mReadonlyImagesCS.clear(); mReadonlyImagesCS.clear();
mUsedShaderSamplerRanges.fill(0); mUsedShaderSamplerRanges.fill({0, 0});
mDirtySamplerMapping = true; mDirtySamplerMapping = true;
mUsedComputeImageRange = 0; mUsedComputeImageRange = {0, 0};
mUsedComputeReadonlyImageRange = 0; mUsedComputeReadonlyImageRange = {0, 0};
mAttribLocationToD3DSemantic.fill(-1); mAttribLocationToD3DSemantic.fill(-1);
...@@ -2684,9 +2718,9 @@ void ProgramD3D::gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyi ...@@ -2684,9 +2718,9 @@ void ProgramD3D::gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyi
for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex) for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex)
{ {
const auto &registerInfo = registerInfos[registerIndex]; const auto &registerInfo = registerInfos[registerIndex];
const auto &varying = *registerInfo.packedVarying->varying; const auto &varying = *registerInfo.packedVarying->varying;
GLenum transposedType = gl::TransposeMatrixType(varying.type); GLenum transposedType = gl::TransposeMatrixType(varying.type);
int componentCount = gl::VariableColumnCount(transposedType); int componentCount = gl::VariableColumnCount(transposedType);
ASSERT(!varying.isBuiltIn() && !varying.isStruct()); ASSERT(!varying.isBuiltIn() && !varying.isStruct());
// There can be more than one register assigned to a particular varying, and each // There can be more than one register assigned to a particular varying, and each
......
...@@ -156,7 +156,7 @@ class ProgramD3D : public ProgramImpl ...@@ -156,7 +156,7 @@ class ProgramD3D : public ProgramImpl
unsigned int samplerIndex, unsigned int samplerIndex,
const gl::Caps &caps) const; const gl::Caps &caps) const;
gl::TextureType getSamplerTextureType(gl::ShaderType type, unsigned int samplerIndex) const; gl::TextureType getSamplerTextureType(gl::ShaderType type, unsigned int samplerIndex) const;
GLuint getUsedSamplerRange(gl::ShaderType type) const; gl::RangeUI getUsedSamplerRange(gl::ShaderType type) const;
enum SamplerMapping enum SamplerMapping
{ {
...@@ -170,7 +170,7 @@ class ProgramD3D : public ProgramImpl ...@@ -170,7 +170,7 @@ class ProgramD3D : public ProgramImpl
unsigned int imageIndex, unsigned int imageIndex,
bool readonly, bool readonly,
const gl::Caps &caps) const; const gl::Caps &caps) const;
GLuint getUsedImageRange(gl::ShaderType type, bool readonly) const; gl::RangeUI getUsedImageRange(gl::ShaderType type, bool readonly) const;
bool usesPointSize() const { return mUsesPointSize; } bool usesPointSize() const { return mUsesPointSize; }
bool usesPointSpriteEmulation() const; bool usesPointSpriteEmulation() const;
...@@ -421,7 +421,7 @@ class ProgramD3D : public ProgramImpl ...@@ -421,7 +421,7 @@ class ProgramD3D : public ProgramImpl
const gl::UniformTypeInfo &typeInfo, const gl::UniformTypeInfo &typeInfo,
unsigned int samplerCount, unsigned int samplerCount,
std::vector<Sampler> &outSamplers, std::vector<Sampler> &outSamplers,
GLuint *outUsedRange); gl::RangeUI *outUsedRange);
void assignAllImageRegisters(); void assignAllImageRegisters();
void assignImageRegisters(size_t uniformIndex); void assignImageRegisters(size_t uniformIndex);
...@@ -429,7 +429,7 @@ class ProgramD3D : public ProgramImpl ...@@ -429,7 +429,7 @@ class ProgramD3D : public ProgramImpl
int startLogicalImageUnit, int startLogicalImageUnit,
unsigned int imageCount, unsigned int imageCount,
std::vector<Image> &outImages, std::vector<Image> &outImages,
GLuint *outUsedRange); gl::RangeUI *outUsedRange);
template <typename DestT> template <typename DestT>
void getUniformInternal(GLint location, DestT *dataOut) const; void getUniformInternal(GLint location, DestT *dataOut) const;
...@@ -500,13 +500,13 @@ class ProgramD3D : public ProgramImpl ...@@ -500,13 +500,13 @@ class ProgramD3D : public ProgramImpl
gl::ShaderMap<std::unique_ptr<UniformStorageD3D>> mShaderUniformStorages; gl::ShaderMap<std::unique_ptr<UniformStorageD3D>> mShaderUniformStorages;
gl::ShaderMap<std::vector<Sampler>> mShaderSamplers; gl::ShaderMap<std::vector<Sampler>> mShaderSamplers;
gl::ShaderMap<GLuint> mUsedShaderSamplerRanges; gl::ShaderMap<gl::RangeUI> mUsedShaderSamplerRanges;
bool mDirtySamplerMapping; bool mDirtySamplerMapping;
std::vector<Image> mImagesCS; std::vector<Image> mImagesCS;
std::vector<Image> mReadonlyImagesCS; std::vector<Image> mReadonlyImagesCS;
GLuint mUsedComputeImageRange; gl::RangeUI mUsedComputeImageRange;
GLuint mUsedComputeReadonlyImageRange; gl::RangeUI mUsedComputeReadonlyImageRange;
// Cache for pixel shader output layout to save reallocations. // Cache for pixel shader output layout to save reallocations.
std::vector<GLenum> mPixelShaderOutputLayoutCache; std::vector<GLenum> mPixelShaderOutputLayoutCache;
......
...@@ -289,7 +289,8 @@ class StateManager11 final : angle::NonCopyable ...@@ -289,7 +289,8 @@ class StateManager11 final : angle::NonCopyable
angle::Result syncProgram(const gl::Context *context, gl::PrimitiveMode drawMode); angle::Result syncProgram(const gl::Context *context, gl::PrimitiveMode drawMode);
angle::Result syncTextures(const gl::Context *context); angle::Result syncTextures(const gl::Context *context);
angle::Result applyTextures(const gl::Context *context, gl::ShaderType shaderType); angle::Result applyTexturesForSamplers(const gl::Context *context, gl::ShaderType shaderType);
angle::Result applyTexturesForImages(const gl::Context *context, gl::ShaderType shaderType);
angle::Result syncTexturesForCompute(const gl::Context *context); angle::Result syncTexturesForCompute(const gl::Context *context);
angle::Result setSamplerState(const gl::Context *context, angle::Result setSamplerState(const gl::Context *context,
...@@ -297,11 +298,11 @@ class StateManager11 final : angle::NonCopyable ...@@ -297,11 +298,11 @@ class StateManager11 final : angle::NonCopyable
int index, int index,
gl::Texture *texture, gl::Texture *texture,
const gl::SamplerState &sampler); const gl::SamplerState &sampler);
angle::Result setTexture(const gl::Context *context, angle::Result setTextureForSampler(const gl::Context *context,
gl::ShaderType type, gl::ShaderType type,
int index, int index,
gl::Texture *texture, gl::Texture *texture,
const gl::SamplerState &sampler); const gl::SamplerState &sampler);
angle::Result setTextureForImage(const gl::Context *context, angle::Result setTextureForImage(const gl::Context *context,
gl::ShaderType type, gl::ShaderType type,
int index, int index,
......
...@@ -3098,8 +3098,9 @@ angle::Result Renderer9::applyTextures(const gl::Context *context, gl::ShaderTyp ...@@ -3098,8 +3098,9 @@ angle::Result Renderer9::applyTextures(const gl::Context *context, gl::ShaderTyp
// TODO(jmadill): Use the Program's sampler bindings. // TODO(jmadill): Use the Program's sampler bindings.
const gl::ActiveTexturePointerArray &activeTextures = glState.getActiveTexturesCache(); const gl::ActiveTexturePointerArray &activeTextures = glState.getActiveTexturesCache();
unsigned int samplerRange = programD3D->getUsedSamplerRange(shaderType); const gl::RangeUI samplerRange = programD3D->getUsedSamplerRange(shaderType);
for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) for (unsigned int samplerIndex = samplerRange.low(); samplerIndex < samplerRange.high();
samplerIndex++)
{ {
GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, caps); GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, caps);
ASSERT(textureUnit != -1); ASSERT(textureUnit != -1);
...@@ -3137,7 +3138,7 @@ angle::Result Renderer9::applyTextures(const gl::Context *context, gl::ShaderTyp ...@@ -3137,7 +3138,7 @@ angle::Result Renderer9::applyTextures(const gl::Context *context, gl::ShaderTyp
: caps.maxShaderTextureImageUnits[gl::ShaderType::Vertex]; : caps.maxShaderTextureImageUnits[gl::ShaderType::Vertex];
// TODO(jmadill): faster way? // TODO(jmadill): faster way?
for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++) for (size_t samplerIndex = samplerRange.high(); samplerIndex < samplerCount; samplerIndex++)
{ {
ANGLE_TRY(setTexture(context, shaderType, static_cast<int>(samplerIndex), nullptr)); ANGLE_TRY(setTexture(context, shaderType, static_cast<int>(samplerIndex), nullptr));
} }
......
...@@ -654,6 +654,76 @@ TEST_P(ComputeShaderTest, TextureSampling) ...@@ -654,6 +654,76 @@ TEST_P(ComputeShaderTest, TextureSampling)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
// Test mixed use of sampler and image.
TEST_P(ComputeShaderTest, SamplingAndImageReadWrite)
{
GLTexture texture[3];
GLFramebuffer framebuffer;
const std::string csSource =
R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
precision highp usampler2D;
uniform usampler2D tex;
void main()
{
uvec4 value_1 = texelFetch(tex, ivec2(gl_LocalInvocationID.xy), 0);
uvec4 value_2 = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value_1 + value_2);
})";
constexpr int kWidth = 1, kHeight = 1;
constexpr GLuint kInputValues[3][1] = {{50}, {100}, {20}};
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
kInputValues[0]);
glBindTexture(GL_TEXTURE_2D, texture[2]);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
kInputValues[2]);
EXPECT_GL_NO_ERROR();
glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
kInputValues[1]);
EXPECT_GL_NO_ERROR();
ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
glUseProgram(program.get());
glBindImageTexture(0, texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
glBindImageTexture(1, texture[2], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
EXPECT_GL_NO_ERROR();
glDispatchCompute(1, 1, 1);
EXPECT_GL_NO_ERROR();
glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
GLuint outputValues[kWidth * kHeight];
constexpr GLuint expectedValue = 150;
glUseProgram(0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture[2], 0);
EXPECT_GL_NO_ERROR();
glReadPixels(0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT, outputValues);
EXPECT_GL_NO_ERROR();
for (int i = 0; i < kWidth * kHeight; i++)
{
EXPECT_EQ(expectedValue, outputValues[i]);
}
}
// Use image uniform to read and write Texture2D in compute shader, and verify the contents. // Use image uniform to read and write Texture2D in compute shader, and verify the contents.
TEST_P(ComputeShaderTest, BindImageTextureWithTexture2D) TEST_P(ComputeShaderTest, BindImageTextureWithTexture2D)
{ {
......
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