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)
}
template <typename T>
struct Range
class Range
{
public:
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 end;
T length() const { return end - start; }
T length() const { return (empty() ? 0 : (mHigh - mLow)); }
bool intersects(Range<T> other)
{
if (start <= other.start)
if (mLow <= other.mLow)
{
return other.start < end;
return other.mLow < mHigh;
}
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)
{
start = value > start ? value : start;
end = value < end ? value : end;
mLow = value < mLow ? value : mLow;
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;
......
......@@ -331,4 +331,38 @@ TEST(MathUtilTest, Ldexp)
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
......@@ -139,14 +139,16 @@ ImageIndexIterator ImageIndexIterator::Make2DMultisample()
nullptr);
}
ImageIndexIterator::ImageIndexIterator(GLenum type, const Range<GLint> &mipRange,
const Range<GLint> &layerRange, const GLsizei *layerCounts)
ImageIndexIterator::ImageIndexIterator(GLenum type,
const Range<GLint> &mipRange,
const Range<GLint> &layerRange,
const GLsizei *layerCounts)
: mType(type),
mMipRange(mipRange),
mLayerRange(layerRange),
mLayerCounts(layerCounts),
mCurrentMip(mipRange.start),
mCurrentLayer(layerRange.start)
mCurrentMip(mipRange.low()),
mCurrentLayer(layerRange.low())
{}
GLint ImageIndexIterator::maxLayer() const
......@@ -154,9 +156,9 @@ GLint ImageIndexIterator::maxLayer() const
if (mLayerCounts)
{
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()
......@@ -174,20 +176,20 @@ ImageIndex ImageIndexIterator::next()
{
mCurrentLayer++;
}
else if (mCurrentMip < mMipRange.end - 1)
else if (mCurrentMip < mMipRange.high() - 1)
{
mCurrentMip++;
mCurrentLayer = mLayerRange.start;
mCurrentLayer = mLayerRange.low();
}
else
{
done();
}
}
else if (mCurrentMip < mMipRange.end - 1)
else if (mCurrentMip < mMipRange.high() - 1)
{
mCurrentMip++;
mCurrentLayer = mLayerRange.start;
mCurrentLayer = mLayerRange.low();
}
else
{
......@@ -211,12 +213,12 @@ ImageIndex ImageIndexIterator::current() const
bool ImageIndexIterator::hasNext() const
{
return (mCurrentMip < mMipRange.end || mCurrentLayer < maxLayer());
return (mCurrentMip < mMipRange.high() || mCurrentLayer < maxLayer());
}
void ImageIndexIterator::done()
{
mCurrentMip = mMipRange.end;
mCurrentMip = mMipRange.high();
mCurrentLayer = maxLayer();
}
......
......@@ -396,13 +396,13 @@ Optional<GLuint> ProgramState::getSamplerIndex(GLint location) const
bool ProgramState::isSamplerUniformIndex(GLuint index) const
{
return index >= mSamplerUniformRange.start && index < mSamplerUniformRange.end;
return mSamplerUniformRange.contains(index);
}
GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const
{
ASSERT(isSamplerUniformIndex(uniformIndex));
return uniformIndex - mSamplerUniformRange.start;
return uniformIndex - mSamplerUniformRange.low();
}
Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle)
......@@ -949,8 +949,11 @@ Error Program::loadBinary(const Context *context,
"All bits of DrawBufferMask can be contained in an uint32_t");
mState.mActiveOutputVariables = stream.readInt<uint32_t>();
stream.readInt(&mState.mSamplerUniformRange.start);
stream.readInt(&mState.mSamplerUniformRange.end);
unsigned int start = 0;
unsigned int end = 0;
stream.readInt(&start);
stream.readInt(&end);
mState.mSamplerUniformRange = RangeUI(start, end);
unsigned int samplerCount = stream.readInt<unsigned int>();
for (unsigned int samplerIndex = 0; samplerIndex < samplerCount; ++samplerIndex)
......@@ -1091,8 +1094,8 @@ Error Program::saveBinary(const Context *context,
"All bits of DrawBufferMask can be contained in an uint32_t");
stream.writeInt(static_cast<uint32_t>(mState.mActiveOutputVariables.to_ulong()));
stream.writeInt(mState.mSamplerUniformRange.start);
stream.writeInt(mState.mSamplerUniformRange.end);
stream.writeInt(mState.mSamplerUniformRange.low());
stream.writeInt(mState.mSamplerUniformRange.high());
stream.writeInt(mState.mSamplerBindings.size());
for (const auto &samplerBinding : mState.mSamplerBindings)
......@@ -2048,17 +2051,19 @@ bool Program::linkUniforms(const Context *context,
void Program::linkSamplerBindings()
{
mState.mSamplerUniformRange.end = static_cast<unsigned int>(mState.mUniforms.size());
mState.mSamplerUniformRange.start = mState.mSamplerUniformRange.end;
auto samplerIter = mState.mUniforms.rbegin();
while (samplerIter != mState.mUniforms.rend() && samplerIter->isSampler())
unsigned int high = static_cast<unsigned int>(mState.mUniforms.size());
unsigned int low = high;
for (auto samplerIter = mState.mUniforms.rbegin();
samplerIter != mState.mUniforms.rend() && samplerIter->isSampler(); ++samplerIter)
{
--mState.mSamplerUniformRange.start;
++samplerIter;
--low;
}
mState.mSamplerUniformRange = RangeUI(low, high);
// If uniform is a sampler type, insert it into the mSamplerBindings array.
for (unsigned int samplerIndex = mState.mSamplerUniformRange.start;
samplerIndex < mState.mUniforms.size(); ++samplerIndex)
for (unsigned int samplerIndex : mState.mSamplerUniformRange)
{
const auto &samplerUniform = mState.mUniforms[samplerIndex];
GLenum textureType = SamplerTypeToTextureType(samplerUniform.type);
......@@ -2763,8 +2768,7 @@ void Program::linkOutputVariables(const Context *context)
void Program::setUniformValuesFromBindingQualifiers()
{
for (unsigned int samplerIndex = mState.mSamplerUniformRange.start;
samplerIndex < mState.mSamplerUniformRange.end; ++samplerIndex)
for (unsigned int samplerIndex : mState.mSamplerUniformRange)
{
const auto &samplerUniform = mState.mUniforms[samplerIndex];
if (samplerUniform.binding != -1)
......
......@@ -910,9 +910,7 @@ gl::Error StateManager11::clearTextures(gl::SamplerType samplerType,
auto &currentSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs);
gl::Range<size_t> clearRange(rangeStart, rangeStart);
clearRange.extend(std::min(rangeEnd, currentSRVs.highestUsed()));
gl::Range<size_t> clearRange(rangeStart, std::min(rangeEnd, currentSRVs.highestUsed()));
if (clearRange.empty())
{
return gl::NoError();
......@@ -921,18 +919,18 @@ gl::Error StateManager11::clearTextures(gl::SamplerType samplerType,
auto deviceContext = mRenderer->getDeviceContext();
if (samplerType == gl::SAMPLER_VERTEX)
{
deviceContext->VSSetShaderResources(static_cast<unsigned int>(rangeStart),
static_cast<unsigned int>(rangeEnd - rangeStart),
deviceContext->VSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
static_cast<unsigned int>(clearRange.length()),
&mNullSRVs[0]);
}
else
{
deviceContext->PSSetShaderResources(static_cast<unsigned int>(rangeStart),
static_cast<unsigned int>(rangeEnd - rangeStart),
deviceContext->PSSetShaderResources(static_cast<unsigned int>(clearRange.low()),
static_cast<unsigned int>(clearRange.length()),
&mNullSRVs[0]);
}
for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; ++samplerIndex)
for (size_t samplerIndex : clearRange)
{
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