Commit 982f6e01 by Jamie Madill Committed by Commit Bot

Improvements to the gl::Range class.

Make this a proper class, fix the extends method (previously did not work as expected), add a contains method, and add tests. Also add an iterator helper class so we can iterate over the range with range-for loops. This also fixes the shader resource unsetting code, which was not actually unsetting all the possible applied textures. BUG=angleproject:2052 Change-Id: I2a6fa97f96ccb612ad01a5e3f24dc869c54c967b Reviewed-on: https://chromium-review.googlesource.com/527318Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 165361ca
...@@ -557,38 +557,65 @@ inline unsigned int averageFloat10(unsigned int a, unsigned int b) ...@@ -557,38 +557,65 @@ inline unsigned int averageFloat10(unsigned int a, unsigned int b)
} }
template <typename T> template <typename T>
struct Range class Range
{ {
public:
Range() {} Range() {}
Range(T lo, T hi) : start(lo), end(hi) { ASSERT(lo <= hi); } Range(T lo, T hi) : mLow(lo), mHigh(hi) {}
T start; T length() const { return (empty() ? 0 : (mHigh - mLow)); }
T end;
T length() const { return end - start; }
bool intersects(Range<T> other) bool intersects(Range<T> other)
{ {
if (start <= other.start) if (mLow <= other.mLow)
{ {
return other.start < end; return other.mLow < mHigh;
} }
else else
{ {
return start < other.end; return mLow < other.mHigh;
} }
} }
// Assumes that end is non-inclusive.. for example, extending to 5 will make "end" 6.
void extend(T value) void extend(T value)
{ {
start = value > start ? value : start; mLow = value < mLow ? value : mLow;
end = value < end ? value : end; mHigh = value >= mHigh ? (value + 1) : mHigh;
} }
bool empty() const bool empty() const { return mHigh <= mLow; }
bool contains(T value) const { return value >= mLow && value < mHigh; }
class Iterator final
{ {
return end <= start; public:
} Iterator(T value) : mCurrent(value) {}
Iterator &operator++()
{
mCurrent++;
return *this;
}
bool operator==(const Iterator &other) const { return mCurrent == other.mCurrent; }
bool operator!=(const Iterator &other) const { return mCurrent != other.mCurrent; }
T operator*() const { return mCurrent; }
private:
T mCurrent;
};
Iterator begin() const { return Iterator(mLow); }
Iterator end() const { return Iterator(mHigh); }
T low() const { return mLow; }
T high() const { return mHigh; }
private:
T mLow;
T mHigh;
}; };
typedef Range<int> RangeI; typedef Range<int> RangeI;
......
...@@ -331,4 +331,38 @@ TEST(MathUtilTest, Ldexp) ...@@ -331,4 +331,38 @@ TEST(MathUtilTest, Ldexp)
EXPECT_EQ(0.0f, Ldexp(1.0f, -129)); EXPECT_EQ(0.0f, Ldexp(1.0f, -129));
} }
// Test that Range::extend works as expected.
TEST(MathUtilTest, RangeExtend)
{
RangeI range(0, 0);
range.extend(5);
EXPECT_EQ(0, range.low());
EXPECT_EQ(6, range.high());
EXPECT_EQ(6, range.length());
range.extend(-1);
EXPECT_EQ(-1, range.low());
EXPECT_EQ(6, range.high());
EXPECT_EQ(7, range.length());
range.extend(10);
EXPECT_EQ(-1, range.low());
EXPECT_EQ(11, range.high());
EXPECT_EQ(12, range.length());
}
// Test that Range iteration works as expected.
TEST(MathUtilTest, RangeIteration)
{
RangeI range(0, 10);
int expected = 0;
for (int value : range)
{
EXPECT_EQ(expected, value);
expected++;
}
EXPECT_EQ(range.length(), expected);
}
} // anonymous namespace } // anonymous namespace
...@@ -139,14 +139,16 @@ ImageIndexIterator ImageIndexIterator::Make2DMultisample() ...@@ -139,14 +139,16 @@ ImageIndexIterator ImageIndexIterator::Make2DMultisample()
nullptr); nullptr);
} }
ImageIndexIterator::ImageIndexIterator(GLenum type, const Range<GLint> &mipRange, ImageIndexIterator::ImageIndexIterator(GLenum type,
const Range<GLint> &layerRange, const GLsizei *layerCounts) const Range<GLint> &mipRange,
const Range<GLint> &layerRange,
const GLsizei *layerCounts)
: mType(type), : mType(type),
mMipRange(mipRange), mMipRange(mipRange),
mLayerRange(layerRange), mLayerRange(layerRange),
mLayerCounts(layerCounts), mLayerCounts(layerCounts),
mCurrentMip(mipRange.start), mCurrentMip(mipRange.low()),
mCurrentLayer(layerRange.start) mCurrentLayer(layerRange.low())
{} {}
GLint ImageIndexIterator::maxLayer() const GLint ImageIndexIterator::maxLayer() const
...@@ -154,9 +156,9 @@ GLint ImageIndexIterator::maxLayer() const ...@@ -154,9 +156,9 @@ GLint ImageIndexIterator::maxLayer() const
if (mLayerCounts) if (mLayerCounts)
{ {
ASSERT(mCurrentMip >= 0); ASSERT(mCurrentMip >= 0);
return (mCurrentMip < mMipRange.end) ? mLayerCounts[mCurrentMip] : 0; return (mCurrentMip < mMipRange.high()) ? mLayerCounts[mCurrentMip] : 0;
} }
return mLayerRange.end; return mLayerRange.high();
} }
ImageIndex ImageIndexIterator::next() ImageIndex ImageIndexIterator::next()
...@@ -174,20 +176,20 @@ ImageIndex ImageIndexIterator::next() ...@@ -174,20 +176,20 @@ ImageIndex ImageIndexIterator::next()
{ {
mCurrentLayer++; mCurrentLayer++;
} }
else if (mCurrentMip < mMipRange.end - 1) else if (mCurrentMip < mMipRange.high() - 1)
{ {
mCurrentMip++; mCurrentMip++;
mCurrentLayer = mLayerRange.start; mCurrentLayer = mLayerRange.low();
} }
else else
{ {
done(); done();
} }
} }
else if (mCurrentMip < mMipRange.end - 1) else if (mCurrentMip < mMipRange.high() - 1)
{ {
mCurrentMip++; mCurrentMip++;
mCurrentLayer = mLayerRange.start; mCurrentLayer = mLayerRange.low();
} }
else else
{ {
...@@ -211,12 +213,12 @@ ImageIndex ImageIndexIterator::current() const ...@@ -211,12 +213,12 @@ ImageIndex ImageIndexIterator::current() const
bool ImageIndexIterator::hasNext() const bool ImageIndexIterator::hasNext() const
{ {
return (mCurrentMip < mMipRange.end || mCurrentLayer < maxLayer()); return (mCurrentMip < mMipRange.high() || mCurrentLayer < maxLayer());
} }
void ImageIndexIterator::done() void ImageIndexIterator::done()
{ {
mCurrentMip = mMipRange.end; mCurrentMip = mMipRange.high();
mCurrentLayer = maxLayer(); mCurrentLayer = maxLayer();
} }
......
...@@ -396,13 +396,13 @@ Optional<GLuint> ProgramState::getSamplerIndex(GLint location) const ...@@ -396,13 +396,13 @@ Optional<GLuint> ProgramState::getSamplerIndex(GLint location) const
bool ProgramState::isSamplerUniformIndex(GLuint index) const bool ProgramState::isSamplerUniformIndex(GLuint index) const
{ {
return index >= mSamplerUniformRange.start && index < mSamplerUniformRange.end; return mSamplerUniformRange.contains(index);
} }
GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const
{ {
ASSERT(isSamplerUniformIndex(uniformIndex)); ASSERT(isSamplerUniformIndex(uniformIndex));
return uniformIndex - mSamplerUniformRange.start; return uniformIndex - mSamplerUniformRange.low();
} }
Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle) Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle)
...@@ -949,8 +949,11 @@ Error Program::loadBinary(const Context *context, ...@@ -949,8 +949,11 @@ Error Program::loadBinary(const Context *context,
"All bits of DrawBufferMask can be contained in an uint32_t"); "All bits of DrawBufferMask can be contained in an uint32_t");
mState.mActiveOutputVariables = stream.readInt<uint32_t>(); mState.mActiveOutputVariables = stream.readInt<uint32_t>();
stream.readInt(&mState.mSamplerUniformRange.start); unsigned int start = 0;
stream.readInt(&mState.mSamplerUniformRange.end); unsigned int end = 0;
stream.readInt(&start);
stream.readInt(&end);
mState.mSamplerUniformRange = RangeUI(start, end);
unsigned int samplerCount = stream.readInt<unsigned int>(); unsigned int samplerCount = stream.readInt<unsigned int>();
for (unsigned int samplerIndex = 0; samplerIndex < samplerCount; ++samplerIndex) for (unsigned int samplerIndex = 0; samplerIndex < samplerCount; ++samplerIndex)
...@@ -1091,8 +1094,8 @@ Error Program::saveBinary(const Context *context, ...@@ -1091,8 +1094,8 @@ Error Program::saveBinary(const Context *context,
"All bits of DrawBufferMask can be contained in an uint32_t"); "All bits of DrawBufferMask can be contained in an uint32_t");
stream.writeInt(static_cast<uint32_t>(mState.mActiveOutputVariables.to_ulong())); stream.writeInt(static_cast<uint32_t>(mState.mActiveOutputVariables.to_ulong()));
stream.writeInt(mState.mSamplerUniformRange.start); stream.writeInt(mState.mSamplerUniformRange.low());
stream.writeInt(mState.mSamplerUniformRange.end); stream.writeInt(mState.mSamplerUniformRange.high());
stream.writeInt(mState.mSamplerBindings.size()); stream.writeInt(mState.mSamplerBindings.size());
for (const auto &samplerBinding : mState.mSamplerBindings) for (const auto &samplerBinding : mState.mSamplerBindings)
...@@ -2048,17 +2051,19 @@ bool Program::linkUniforms(const Context *context, ...@@ -2048,17 +2051,19 @@ bool Program::linkUniforms(const Context *context,
void Program::linkSamplerBindings() void Program::linkSamplerBindings()
{ {
mState.mSamplerUniformRange.end = static_cast<unsigned int>(mState.mUniforms.size()); unsigned int high = static_cast<unsigned int>(mState.mUniforms.size());
mState.mSamplerUniformRange.start = mState.mSamplerUniformRange.end; unsigned int low = high;
auto samplerIter = mState.mUniforms.rbegin();
while (samplerIter != mState.mUniforms.rend() && samplerIter->isSampler()) for (auto samplerIter = mState.mUniforms.rbegin();
samplerIter != mState.mUniforms.rend() && samplerIter->isSampler(); ++samplerIter)
{ {
--mState.mSamplerUniformRange.start; --low;
++samplerIter;
} }
mState.mSamplerUniformRange = RangeUI(low, high);
// If uniform is a sampler type, insert it into the mSamplerBindings array. // If uniform is a sampler type, insert it into the mSamplerBindings array.
for (unsigned int samplerIndex = mState.mSamplerUniformRange.start; for (unsigned int samplerIndex : mState.mSamplerUniformRange)
samplerIndex < mState.mUniforms.size(); ++samplerIndex)
{ {
const auto &samplerUniform = mState.mUniforms[samplerIndex]; const auto &samplerUniform = mState.mUniforms[samplerIndex];
GLenum textureType = SamplerTypeToTextureType(samplerUniform.type); GLenum textureType = SamplerTypeToTextureType(samplerUniform.type);
...@@ -2763,8 +2768,7 @@ void Program::linkOutputVariables(const Context *context) ...@@ -2763,8 +2768,7 @@ void Program::linkOutputVariables(const Context *context)
void Program::setUniformValuesFromBindingQualifiers() void Program::setUniformValuesFromBindingQualifiers()
{ {
for (unsigned int samplerIndex = mState.mSamplerUniformRange.start; for (unsigned int samplerIndex : mState.mSamplerUniformRange)
samplerIndex < mState.mSamplerUniformRange.end; ++samplerIndex)
{ {
const auto &samplerUniform = mState.mUniforms[samplerIndex]; const auto &samplerUniform = mState.mUniforms[samplerIndex];
if (samplerUniform.binding != -1) if (samplerUniform.binding != -1)
......
...@@ -910,9 +910,7 @@ gl::Error StateManager11::clearTextures(gl::SamplerType samplerType, ...@@ -910,9 +910,7 @@ gl::Error StateManager11::clearTextures(gl::SamplerType samplerType,
auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
gl::Range<size_t> clearRange(rangeStart, rangeStart); gl::Range<size_t> clearRange(rangeStart, std::min(rangeEnd, currentSRVs.highestUsed()));
clearRange.extend(std::min(rangeEnd, currentSRVs.highestUsed()));
if (clearRange.empty()) if (clearRange.empty())
{ {
return gl::NoError(); return gl::NoError();
...@@ -921,18 +919,18 @@ gl::Error StateManager11::clearTextures(gl::SamplerType samplerType, ...@@ -921,18 +919,18 @@ gl::Error StateManager11::clearTextures(gl::SamplerType samplerType,
auto deviceContext = mRenderer->getDeviceContext(); auto deviceContext = mRenderer->getDeviceContext();
if (samplerType == gl::SAMPLER_VERTEX) if (samplerType == gl::SAMPLER_VERTEX)
{ {
deviceContext->VSSetShaderResources(static_cast<unsigned int>(rangeStart), deviceContext->VSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
static_cast<unsigned int>(rangeEnd - rangeStart), static_cast<unsigned int>(clearRange.length()),
&mNullSRVs[0]); &mNullSRVs[0]);
} }
else else
{ {
deviceContext->PSSetShaderResources(static_cast<unsigned int>(rangeStart), deviceContext->PSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
static_cast<unsigned int>(rangeEnd - rangeStart), static_cast<unsigned int>(clearRange.length()),
&mNullSRVs[0]); &mNullSRVs[0]);
} }
for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; ++samplerIndex) for (size_t samplerIndex : clearRange)
{ {
currentSRVs.update(samplerIndex, nullptr); currentSRVs.update(samplerIndex, nullptr);
} }
......
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