Commit e3e680ca by Jamie Madill Committed by Commit Bot

Remove State::syncProgramTextures.

Removes the concept of the program textures dirty object. Instead we use a set of dirty bits to represent dirty texture samples. We mark certain textures dirty and update state structures whenever there is a new Texture/Program/Sampler bound, or when Texture/Program/Sampler state changes. This is in preparation for making clearing the uncleared active textures into a dirty bit as well. Also includes new dirty bit handling for texture image units. These are a GLES 3.1 feature. Bug: angleproject:2966 Change-Id: Ibb8619dd2669bb39fdbcd75e3685be9a8aeeee91 Reviewed-on: https://chromium-review.googlesource.com/c/1346649 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent ff03e51e
...@@ -60,6 +60,7 @@ enum ...@@ -60,6 +60,7 @@ enum
// Limit active textures so we can use fast bitsets. // Limit active textures so we can use fast bitsets.
IMPLEMENTATION_MAX_SHADER_TEXTURES = 32, IMPLEMENTATION_MAX_SHADER_TEXTURES = 32,
IMPLEMENTATION_MAX_ACTIVE_TEXTURES = IMPLEMENTATION_MAX_SHADER_TEXTURES * 2, IMPLEMENTATION_MAX_ACTIVE_TEXTURES = IMPLEMENTATION_MAX_SHADER_TEXTURES * 2,
IMPLEMENTATION_MAX_IMAGE_UNITS = IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
}; };
} // namespace gl } // namespace gl
......
...@@ -284,12 +284,14 @@ constexpr angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMod ...@@ -284,12 +284,14 @@ constexpr angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMod
enum SubjectIndexes : angle::SubjectIndex enum SubjectIndexes : angle::SubjectIndex
{ {
kTexture0SubjectIndex = 0, kTexture0SubjectIndex = 0,
kTextureMaxSubjectIndex = kTexture0SubjectIndex + gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES, kTextureMaxSubjectIndex = kTexture0SubjectIndex + IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
kUniformBuffer0SubjectIndex = kTextureMaxSubjectIndex, kImage0SubjectIndex = kTextureMaxSubjectIndex,
kImageMaxSubjectIndex = kImage0SubjectIndex + IMPLEMENTATION_MAX_IMAGE_UNITS,
kUniformBuffer0SubjectIndex = kImageMaxSubjectIndex,
kUniformBufferMaxSubjectIndex = kUniformBufferMaxSubjectIndex =
kUniformBuffer0SubjectIndex + gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS, kUniformBuffer0SubjectIndex + IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS,
kSampler0SubjectIndex = kUniformBufferMaxSubjectIndex, kSampler0SubjectIndex = kUniformBufferMaxSubjectIndex,
kSamplerMaxSubjectIndex = kSampler0SubjectIndex + gl::IMPLEMENTATION_MAX_ACTIVE_TEXTURES, kSamplerMaxSubjectIndex = kSampler0SubjectIndex + IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
kVertexArraySubjectIndex = kSamplerMaxSubjectIndex, kVertexArraySubjectIndex = kSamplerMaxSubjectIndex,
kReadFramebufferSubjectIndex, kReadFramebufferSubjectIndex,
kDrawFramebufferSubjectIndex kDrawFramebufferSubjectIndex
...@@ -357,6 +359,12 @@ Context::Context(rx::EGLImplFactory *implFactory, ...@@ -357,6 +359,12 @@ Context::Context(rx::EGLImplFactory *implFactory,
{ {
mSamplerObserverBindings.emplace_back(this, samplerIndex); mSamplerObserverBindings.emplace_back(this, samplerIndex);
} }
for (angle::SubjectIndex imageIndex = kImage0SubjectIndex; imageIndex < kImageMaxSubjectIndex;
++imageIndex)
{
mImageObserverBindings.emplace_back(this, imageIndex);
}
} }
void Context::initialize() void Context::initialize()
...@@ -463,13 +471,13 @@ void Context::initialize() ...@@ -463,13 +471,13 @@ void Context::initialize()
mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER); mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
mDrawDirtyObjects.set(State::DIRTY_OBJECT_VERTEX_ARRAY); mDrawDirtyObjects.set(State::DIRTY_OBJECT_VERTEX_ARRAY);
mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_TEXTURES); mDrawDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES);
mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM); mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM);
mDrawDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS); mDrawDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS);
mPathOperationDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER); mPathOperationDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
mPathOperationDirtyObjects.set(State::DIRTY_OBJECT_VERTEX_ARRAY); mPathOperationDirtyObjects.set(State::DIRTY_OBJECT_VERTEX_ARRAY);
mPathOperationDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_TEXTURES); mPathOperationDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES);
mPathOperationDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS); mPathOperationDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS);
mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE); mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE);
...@@ -513,7 +521,7 @@ void Context::initialize() ...@@ -513,7 +521,7 @@ void Context::initialize()
mComputeDirtyBits.set(State::DIRTY_BIT_SAMPLER_BINDINGS); mComputeDirtyBits.set(State::DIRTY_BIT_SAMPLER_BINDINGS);
mComputeDirtyBits.set(State::DIRTY_BIT_IMAGE_BINDINGS); mComputeDirtyBits.set(State::DIRTY_BIT_IMAGE_BINDINGS);
mComputeDirtyBits.set(State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING); mComputeDirtyBits.set(State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING);
mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_TEXTURES); mComputeDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES);
mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM); mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM);
mComputeDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS); mComputeDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS);
...@@ -1090,7 +1098,7 @@ void Context::bindTexture(TextureType target, GLuint handle) ...@@ -1090,7 +1098,7 @@ void Context::bindTexture(TextureType target, GLuint handle)
} }
ASSERT(texture); ASSERT(texture);
ANGLE_CONTEXT_TRY(mGLState.setSamplerTexture(this, target, texture)); mGLState.setSamplerTexture(this, target, texture);
mStateCache.onActiveTextureChange(this); mStateCache.onActiveTextureChange(this);
} }
...@@ -1148,6 +1156,7 @@ void Context::bindImageTexture(GLuint unit, ...@@ -1148,6 +1156,7 @@ void Context::bindImageTexture(GLuint unit,
{ {
Texture *tex = mState.mTextures->getTexture(texture); Texture *tex = mState.mTextures->getTexture(texture);
mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format); mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
mImageObserverBindings[unit].bind(tex);
} }
void Context::useProgram(GLuint program) void Context::useProgram(GLuint program)
...@@ -2139,14 +2148,12 @@ void Context::texParameterf(TextureType target, GLenum pname, GLfloat param) ...@@ -2139,14 +2148,12 @@ void Context::texParameterf(TextureType target, GLenum pname, GLfloat param)
{ {
Texture *const texture = getTargetTexture(target); Texture *const texture = getTargetTexture(target);
SetTexParameterf(this, texture, pname, param); SetTexParameterf(this, texture, pname, param);
onTextureChange(texture);
} }
void Context::texParameterfv(TextureType target, GLenum pname, const GLfloat *params) void Context::texParameterfv(TextureType target, GLenum pname, const GLfloat *params)
{ {
Texture *const texture = getTargetTexture(target); Texture *const texture = getTargetTexture(target);
SetTexParameterfv(this, texture, pname, params); SetTexParameterfv(this, texture, pname, params);
onTextureChange(texture);
} }
void Context::texParameterfvRobust(TextureType target, void Context::texParameterfvRobust(TextureType target,
...@@ -2161,28 +2168,24 @@ void Context::texParameteri(TextureType target, GLenum pname, GLint param) ...@@ -2161,28 +2168,24 @@ void Context::texParameteri(TextureType target, GLenum pname, GLint param)
{ {
Texture *const texture = getTargetTexture(target); Texture *const texture = getTargetTexture(target);
SetTexParameteri(this, texture, pname, param); SetTexParameteri(this, texture, pname, param);
onTextureChange(texture);
} }
void Context::texParameteriv(TextureType target, GLenum pname, const GLint *params) void Context::texParameteriv(TextureType target, GLenum pname, const GLint *params)
{ {
Texture *const texture = getTargetTexture(target); Texture *const texture = getTargetTexture(target);
SetTexParameteriv(this, texture, pname, params); SetTexParameteriv(this, texture, pname, params);
onTextureChange(texture);
} }
void Context::texParameterIiv(TextureType target, GLenum pname, const GLint *params) void Context::texParameterIiv(TextureType target, GLenum pname, const GLint *params)
{ {
Texture *const texture = getTargetTexture(target); Texture *const texture = getTargetTexture(target);
SetTexParameterIiv(this, texture, pname, params); SetTexParameterIiv(this, texture, pname, params);
onTextureChange(texture);
} }
void Context::texParameterIuiv(TextureType target, GLenum pname, const GLuint *params) void Context::texParameterIuiv(TextureType target, GLenum pname, const GLuint *params)
{ {
Texture *const texture = getTargetTexture(target); Texture *const texture = getTargetTexture(target);
SetTexParameterIuiv(this, texture, pname, params); SetTexParameterIuiv(this, texture, pname, params);
onTextureChange(texture);
} }
void Context::texParameterivRobust(TextureType target, void Context::texParameterivRobust(TextureType target,
...@@ -3145,7 +3148,7 @@ void Context::requestExtension(const char *name) ...@@ -3145,7 +3148,7 @@ void Context::requestExtension(const char *name)
{ {
if (zeroTexture.get() != nullptr) if (zeroTexture.get() != nullptr)
{ {
zeroTexture->signalDirty(this, InitState::Initialized); zeroTexture->signalDirtyStorage(this, InitState::Initialized);
} }
} }
...@@ -3331,6 +3334,8 @@ void Context::initCaps() ...@@ -3331,6 +3334,8 @@ void Context::initCaps()
LimitCap(&mCaps.maxShaderTextureImageUnits[ShaderType::Fragment], LimitCap(&mCaps.maxShaderTextureImageUnits[ShaderType::Fragment],
IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2); IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2);
LimitCap(&mCaps.maxImageUnits, IMPLEMENTATION_MAX_IMAGE_UNITS);
mCaps.maxSampleMaskWords = std::min<GLuint>(mCaps.maxSampleMaskWords, MAX_SAMPLE_MASK_WORDS); mCaps.maxSampleMaskWords = std::min<GLuint>(mCaps.maxSampleMaskWords, MAX_SAMPLE_MASK_WORDS);
// WebGL compatibility // WebGL compatibility
...@@ -6093,11 +6098,13 @@ void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v) ...@@ -6093,11 +6098,13 @@ void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v)
void Context::setUniform1iImpl(Program *program, GLint location, GLsizei count, const GLint *v) void Context::setUniform1iImpl(Program *program, GLint location, GLsizei count, const GLint *v)
{ {
if (program->setUniform1iv(location, count, v) == Program::SetUniformResult::SamplerChanged) program->setUniform1iv(this, location, count, v);
{ }
mGLState.setObjectDirty(GL_PROGRAM);
mStateCache.onActiveTextureChange(this); void Context::onSamplerUniformChange(size_t textureUnitIndex)
} {
mGLState.onActiveTextureChange(this, textureUnitIndex);
mStateCache.onActiveTextureChange(this);
} }
void Context::uniform1i(GLint location, GLint x) void Context::uniform1i(GLint location, GLint x)
...@@ -7013,13 +7020,6 @@ void Context::programUniformMatrix4x3fv(GLuint program, ...@@ -7013,13 +7020,6 @@ void Context::programUniformMatrix4x3fv(GLuint program,
programObject->setUniformMatrix4x3fv(location, count, transpose, value); programObject->setUniformMatrix4x3fv(location, count, transpose, value);
} }
void Context::onTextureChange(const Texture *texture)
{
// Conservatively assume all textures are dirty.
// TODO(jmadill): More fine-grained update.
mGLState.setObjectDirty(GL_TEXTURE);
}
bool Context::isCurrentTransformFeedback(const TransformFeedback *tf) const bool Context::isCurrentTransformFeedback(const TransformFeedback *tf) const
{ {
return mGLState.isCurrentTransformFeedback(tf); return mGLState.isCurrentTransformFeedback(tf);
...@@ -8117,9 +8117,13 @@ void Context::onSubjectStateChange(const Context *context, ...@@ -8117,9 +8117,13 @@ void Context::onSubjectStateChange(const Context *context,
default: default:
if (index < kTextureMaxSubjectIndex) if (index < kTextureMaxSubjectIndex)
{ {
mGLState.onActiveTextureStateChange(index); mGLState.onActiveTextureStateChange(this, index);
mStateCache.onActiveTextureChange(this); mStateCache.onActiveTextureChange(this);
} }
else if (index < kImageMaxSubjectIndex)
{
mGLState.onImageStateChange(this, index - kImage0SubjectIndex);
}
else if (index < kUniformBufferMaxSubjectIndex) else if (index < kUniformBufferMaxSubjectIndex)
{ {
mGLState.onUniformBufferStateChange(index - kUniformBuffer0SubjectIndex); mGLState.onUniformBufferStateChange(index - kUniformBuffer0SubjectIndex);
......
...@@ -1648,9 +1648,6 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -1648,9 +1648,6 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
MemoryProgramCache *getMemoryProgramCache() const { return mMemoryProgramCache; } MemoryProgramCache *getMemoryProgramCache() const { return mMemoryProgramCache; }
// Notification for a state change in a Texture.
void onTextureChange(const Texture *texture);
bool hasBeenCurrent() const { return mHasBeenCurrent; } bool hasBeenCurrent() const { return mHasBeenCurrent; }
egl::Display *getCurrentDisplay() const { return mCurrentDisplay; } egl::Display *getCurrentDisplay() const { return mCurrentDisplay; }
egl::Surface *getCurrentDrawSurface() const { return mCurrentSurface; } egl::Surface *getCurrentDrawSurface() const { return mCurrentSurface; }
...@@ -1732,6 +1729,8 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -1732,6 +1729,8 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
angle::SubjectIndex index, angle::SubjectIndex index,
angle::SubjectMessage message) override; angle::SubjectMessage message) override;
void onSamplerUniformChange(size_t textureUnitIndex);
private: private:
void initialize(); void initialize();
...@@ -1879,6 +1878,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -1879,6 +1878,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
angle::ObserverBinding mReadFramebufferObserverBinding; angle::ObserverBinding mReadFramebufferObserverBinding;
std::vector<angle::ObserverBinding> mUniformBufferObserverBindings; std::vector<angle::ObserverBinding> mUniformBufferObserverBindings;
std::vector<angle::ObserverBinding> mSamplerObserverBindings; std::vector<angle::ObserverBinding> mSamplerObserverBindings;
std::vector<angle::ObserverBinding> mImageObserverBindings;
// Not really a property of context state. The size and contexts change per-api-call. // Not really a property of context state. The size and contexts change per-api-call.
mutable angle::ScratchBuffer mScratchBuffer; mutable angle::ScratchBuffer mScratchBuffer;
......
...@@ -164,12 +164,12 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context ...@@ -164,12 +164,12 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context
} }
} }
setUniform1iv(programObject, mProgramState.enableTexture2DLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.enableTexture2DLoc, kTexUnitCount,
tex2DEnables.data()); tex2DEnables.data());
setUniform1iv(programObject, mProgramState.enableTextureCubeMapLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.enableTextureCubeMapLoc, kTexUnitCount,
texCubeEnables.data()); texCubeEnables.data());
setUniform1iv(programObject, mProgramState.textureFormatLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.textureFormatLoc, kTexUnitCount,
tex2DFormats.data()); tex2DFormats.data());
setUniform4fv(programObject, mProgramState.drawTextureNormalizedCropRectLoc, kTexUnitCount, setUniform4fv(programObject, mProgramState.drawTextureNormalizedCropRectLoc, kTexUnitCount,
...@@ -208,37 +208,37 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context ...@@ -208,37 +208,37 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context
uniformBuffers.pointSpriteCoordReplaces[i] = env.pointSpriteCoordReplace; uniformBuffers.pointSpriteCoordReplaces[i] = env.pointSpriteCoordReplace;
} }
setUniform1iv(programObject, mProgramState.textureEnvModeLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.textureEnvModeLoc, kTexUnitCount,
uniformBuffers.texEnvModes.data()); uniformBuffers.texEnvModes.data());
setUniform1iv(programObject, mProgramState.combineRgbLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.combineRgbLoc, kTexUnitCount,
uniformBuffers.texCombineRgbs.data()); uniformBuffers.texCombineRgbs.data());
setUniform1iv(programObject, mProgramState.combineAlphaLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.combineAlphaLoc, kTexUnitCount,
uniformBuffers.texCombineAlphas.data()); uniformBuffers.texCombineAlphas.data());
setUniform1iv(programObject, mProgramState.src0rgbLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.src0rgbLoc, kTexUnitCount,
uniformBuffers.texCombineSrc0Rgbs.data()); uniformBuffers.texCombineSrc0Rgbs.data());
setUniform1iv(programObject, mProgramState.src0alphaLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.src0alphaLoc, kTexUnitCount,
uniformBuffers.texCombineSrc0Alphas.data()); uniformBuffers.texCombineSrc0Alphas.data());
setUniform1iv(programObject, mProgramState.src1rgbLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.src1rgbLoc, kTexUnitCount,
uniformBuffers.texCombineSrc1Rgbs.data()); uniformBuffers.texCombineSrc1Rgbs.data());
setUniform1iv(programObject, mProgramState.src1alphaLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.src1alphaLoc, kTexUnitCount,
uniformBuffers.texCombineSrc1Alphas.data()); uniformBuffers.texCombineSrc1Alphas.data());
setUniform1iv(programObject, mProgramState.src2rgbLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.src2rgbLoc, kTexUnitCount,
uniformBuffers.texCombineSrc2Rgbs.data()); uniformBuffers.texCombineSrc2Rgbs.data());
setUniform1iv(programObject, mProgramState.src2alphaLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.src2alphaLoc, kTexUnitCount,
uniformBuffers.texCombineSrc2Alphas.data()); uniformBuffers.texCombineSrc2Alphas.data());
setUniform1iv(programObject, mProgramState.op0rgbLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.op0rgbLoc, kTexUnitCount,
uniformBuffers.texCombineOp0Rgbs.data()); uniformBuffers.texCombineOp0Rgbs.data());
setUniform1iv(programObject, mProgramState.op0alphaLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.op0alphaLoc, kTexUnitCount,
uniformBuffers.texCombineOp0Alphas.data()); uniformBuffers.texCombineOp0Alphas.data());
setUniform1iv(programObject, mProgramState.op1rgbLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.op1rgbLoc, kTexUnitCount,
uniformBuffers.texCombineOp1Rgbs.data()); uniformBuffers.texCombineOp1Rgbs.data());
setUniform1iv(programObject, mProgramState.op1alphaLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.op1alphaLoc, kTexUnitCount,
uniformBuffers.texCombineOp1Alphas.data()); uniformBuffers.texCombineOp1Alphas.data());
setUniform1iv(programObject, mProgramState.op2rgbLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.op2rgbLoc, kTexUnitCount,
uniformBuffers.texCombineOp2Rgbs.data()); uniformBuffers.texCombineOp2Rgbs.data());
setUniform1iv(programObject, mProgramState.op2alphaLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.op2alphaLoc, kTexUnitCount,
uniformBuffers.texCombineOp2Alphas.data()); uniformBuffers.texCombineOp2Alphas.data());
setUniform4fv(programObject, mProgramState.textureEnvColorLoc, kTexUnitCount, setUniform4fv(programObject, mProgramState.textureEnvColorLoc, kTexUnitCount,
...@@ -248,30 +248,30 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context ...@@ -248,30 +248,30 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context
setUniform1fv(programObject, mProgramState.alphaScaleLoc, kTexUnitCount, setUniform1fv(programObject, mProgramState.alphaScaleLoc, kTexUnitCount,
uniformBuffers.texEnvAlphaScales.data()); uniformBuffers.texEnvAlphaScales.data());
setUniform1iv(programObject, mProgramState.pointSpriteCoordReplaceLoc, kTexUnitCount, setUniform1iv(context, programObject, mProgramState.pointSpriteCoordReplaceLoc,
uniformBuffers.pointSpriteCoordReplaces.data()); kTexUnitCount, uniformBuffers.pointSpriteCoordReplaces.data());
} }
// Alpha test // Alpha test
{ {
setUniform1i(programObject, mProgramState.enableAlphaTestLoc, setUniform1i(context, programObject, mProgramState.enableAlphaTestLoc,
glState->getEnableFeature(GL_ALPHA_TEST)); glState->getEnableFeature(GL_ALPHA_TEST));
setUniform1i(programObject, mProgramState.alphaFuncLoc, setUniform1i(context, programObject, mProgramState.alphaFuncLoc,
ToGLenum(gles1State.mAlphaTestFunc)); ToGLenum(gles1State.mAlphaTestFunc));
setUniform1f(programObject, mProgramState.alphaTestRefLoc, gles1State.mAlphaTestRef); setUniform1f(programObject, mProgramState.alphaTestRefLoc, gles1State.mAlphaTestRef);
} }
// Shading, materials, and lighting // Shading, materials, and lighting
{ {
setUniform1i(programObject, mProgramState.shadeModelFlatLoc, setUniform1i(context, programObject, mProgramState.shadeModelFlatLoc,
gles1State.mShadeModel == ShadingModel::Flat); gles1State.mShadeModel == ShadingModel::Flat);
setUniform1i(programObject, mProgramState.enableLightingLoc, setUniform1i(context, programObject, mProgramState.enableLightingLoc,
glState->getEnableFeature(GL_LIGHTING)); glState->getEnableFeature(GL_LIGHTING));
setUniform1i(programObject, mProgramState.enableRescaleNormalLoc, setUniform1i(context, programObject, mProgramState.enableRescaleNormalLoc,
glState->getEnableFeature(GL_RESCALE_NORMAL)); glState->getEnableFeature(GL_RESCALE_NORMAL));
setUniform1i(programObject, mProgramState.enableNormalizeLoc, setUniform1i(context, programObject, mProgramState.enableNormalizeLoc,
glState->getEnableFeature(GL_NORMALIZE)); glState->getEnableFeature(GL_NORMALIZE));
setUniform1i(programObject, mProgramState.enableColorMaterialLoc, setUniform1i(context, programObject, mProgramState.enableColorMaterialLoc,
glState->getEnableFeature(GL_COLOR_MATERIAL)); glState->getEnableFeature(GL_COLOR_MATERIAL));
const auto &material = gles1State.mMaterial; const auto &material = gles1State.mMaterial;
...@@ -314,7 +314,7 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context ...@@ -314,7 +314,7 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context
uniformBuffers.attenuationQuadratics[i] = light.attenuationQuadratic; uniformBuffers.attenuationQuadratics[i] = light.attenuationQuadratic;
} }
setUniform1iv(programObject, mProgramState.lightEnablesLoc, kLightCount, setUniform1iv(context, programObject, mProgramState.lightEnablesLoc, kLightCount,
uniformBuffers.lightEnables.data()); uniformBuffers.lightEnables.data());
setUniform4fv(programObject, mProgramState.lightAmbientsLoc, kLightCount, setUniform4fv(programObject, mProgramState.lightAmbientsLoc, kLightCount,
reinterpret_cast<float *>(uniformBuffers.lightAmbients.data())); reinterpret_cast<float *>(uniformBuffers.lightAmbients.data()));
...@@ -341,8 +341,9 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context ...@@ -341,8 +341,9 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context
// Fog // Fog
{ {
const FogParameters &fog = gles1State.fogParameters(); const FogParameters &fog = gles1State.fogParameters();
setUniform1i(programObject, mProgramState.fogEnableLoc, glState->getEnableFeature(GL_FOG)); setUniform1i(context, programObject, mProgramState.fogEnableLoc,
setUniform1i(programObject, mProgramState.fogModeLoc, ToGLenum(fog.mode)); glState->getEnableFeature(GL_FOG));
setUniform1i(context, programObject, mProgramState.fogModeLoc, ToGLenum(fog.mode));
setUniform1f(programObject, mProgramState.fogDensityLoc, fog.density); setUniform1f(programObject, mProgramState.fogDensityLoc, fog.density);
setUniform1f(programObject, mProgramState.fogStartLoc, fog.start); setUniform1f(programObject, mProgramState.fogStartLoc, fog.start);
setUniform1f(programObject, mProgramState.fogEndLoc, fog.end); setUniform1f(programObject, mProgramState.fogEndLoc, fog.end);
...@@ -360,8 +361,8 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context ...@@ -360,8 +361,8 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context
i, reinterpret_cast<float *>(uniformBuffers.clipPlanes.data() + i)); i, reinterpret_cast<float *>(uniformBuffers.clipPlanes.data() + i));
} }
setUniform1i(programObject, mProgramState.enableClipPlanesLoc, enableClipPlanes); setUniform1i(context, programObject, mProgramState.enableClipPlanesLoc, enableClipPlanes);
setUniform1iv(programObject, mProgramState.clipPlaneEnablesLoc, kClipPlaneCount, setUniform1iv(context, programObject, mProgramState.clipPlaneEnablesLoc, kClipPlaneCount,
uniformBuffers.clipPlaneEnables.data()); uniformBuffers.clipPlaneEnables.data());
setUniform4fv(programObject, mProgramState.clipPlanesLoc, kClipPlaneCount, setUniform4fv(programObject, mProgramState.clipPlanesLoc, kClipPlaneCount,
reinterpret_cast<float *>(uniformBuffers.clipPlanes.data())); reinterpret_cast<float *>(uniformBuffers.clipPlanes.data()));
...@@ -371,9 +372,9 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context ...@@ -371,9 +372,9 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context
{ {
const PointParameters &pointParams = gles1State.mPointParameters; const PointParameters &pointParams = gles1State.mPointParameters;
setUniform1i(programObject, mProgramState.pointRasterizationLoc, setUniform1i(context, programObject, mProgramState.pointRasterizationLoc,
mode == PrimitiveMode::Points); mode == PrimitiveMode::Points);
setUniform1i(programObject, mProgramState.pointSpriteEnabledLoc, setUniform1i(context, programObject, mProgramState.pointSpriteEnabledLoc,
glState->getEnableFeature(GL_POINT_SPRITE_OES)); glState->getEnableFeature(GL_POINT_SPRITE_OES));
setUniform1f(programObject, mProgramState.pointSizeMinLoc, pointParams.pointSizeMin); setUniform1f(programObject, mProgramState.pointSizeMinLoc, pointParams.pointSizeMin);
setUniform1f(programObject, mProgramState.pointSizeMaxLoc, pointParams.pointSizeMax); setUniform1f(programObject, mProgramState.pointSizeMaxLoc, pointParams.pointSizeMax);
...@@ -383,7 +384,7 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context ...@@ -383,7 +384,7 @@ angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context
// Draw texture // Draw texture
{ {
setUniform1i(programObject, mProgramState.enableDrawTextureLoc, setUniform1i(context, programObject, mProgramState.enableDrawTextureLoc,
mDrawTextureEnabled ? 1 : 0); mDrawTextureEnabled ? 1 : 0);
setUniform4fv(programObject, mProgramState.drawTextureCoordsLoc, 1, mDrawTextureCoords); setUniform4fv(programObject, mProgramState.drawTextureCoordsLoc, 1, mDrawTextureCoords);
setUniform2fv(programObject, mProgramState.drawTextureDimsLoc, 1, mDrawTextureDims); setUniform2fv(programObject, mProgramState.drawTextureDimsLoc, 1, mDrawTextureDims);
...@@ -710,8 +711,9 @@ angle::Result GLES1Renderer::initializeRendererProgram(Context *context, State * ...@@ -710,8 +711,9 @@ angle::Result GLES1Renderer::initializeRendererProgram(Context *context, State *
for (int i = 0; i < kTexUnitCount; i++) for (int i = 0; i < kTexUnitCount; i++)
{ {
setUniform1i(programObject, mProgramState.tex2DSamplerLocs[i], i); setUniform1i(context, programObject, mProgramState.tex2DSamplerLocs[i], i);
setUniform1i(programObject, mProgramState.texCubeSamplerLocs[i], i + kTexUnitCount); setUniform1i(context, programObject, mProgramState.texCubeSamplerLocs[i],
i + kTexUnitCount);
} }
glState->setObjectDirty(GL_PROGRAM); glState->setObjectDirty(GL_PROGRAM);
...@@ -720,21 +722,22 @@ angle::Result GLES1Renderer::initializeRendererProgram(Context *context, State * ...@@ -720,21 +722,22 @@ angle::Result GLES1Renderer::initializeRendererProgram(Context *context, State *
return angle::Result::Continue(); return angle::Result::Continue();
} }
void GLES1Renderer::setUniform1i(Program *programObject, GLint loc, GLint value) void GLES1Renderer::setUniform1i(Context *context, Program *programObject, GLint loc, GLint value)
{ {
if (loc == -1) if (loc == -1)
return; return;
programObject->setUniform1iv(loc, 1, &value); programObject->setUniform1iv(context, loc, 1, &value);
} }
void GLES1Renderer::setUniform1iv(Program *programObject, void GLES1Renderer::setUniform1iv(Context *context,
Program *programObject,
GLint loc, GLint loc,
GLint count, GLint count,
const GLint *value) const GLint *value)
{ {
if (loc == -1) if (loc == -1)
return; return;
programObject->setUniform1iv(loc, count, value); programObject->setUniform1iv(context, loc, count, value);
} }
void GLES1Renderer::setUniformMatrix4fv(Program *programObject, void GLES1Renderer::setUniformMatrix4fv(Program *programObject,
......
...@@ -70,8 +70,12 @@ class GLES1Renderer final : angle::NonCopyable ...@@ -70,8 +70,12 @@ class GLES1Renderer final : angle::NonCopyable
GLuint *programOut); GLuint *programOut);
angle::Result initializeRendererProgram(Context *context, State *glState); angle::Result initializeRendererProgram(Context *context, State *glState);
void setUniform1i(Program *programObject, GLint loc, GLint value); void setUniform1i(Context *context, Program *programObject, GLint loc, GLint value);
void setUniform1iv(Program *programObject, GLint loc, GLint count, const GLint *value); void setUniform1iv(Context *context,
Program *programObject,
GLint loc,
GLint count,
const GLint *value);
void setUniformMatrix4fv(Program *programObject, void setUniformMatrix4fv(Program *programObject,
GLint loc, GLint loc,
GLint count, GLint count,
......
...@@ -2052,7 +2052,7 @@ void Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) ...@@ -2052,7 +2052,7 @@ void Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
mProgram->setUniform4fv(location, clampedCount, v); mProgram->setUniform4fv(location, clampedCount, v);
} }
Program::SetUniformResult Program::setUniform1iv(GLint location, GLsizei count, const GLint *v) void Program::setUniform1iv(Context *context, GLint location, GLsizei count, const GLint *v)
{ {
ASSERT(mLinkResolved); ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location]; const VariableLocation &locationInfo = mState.mUniformLocations[location];
...@@ -2062,11 +2062,8 @@ Program::SetUniformResult Program::setUniform1iv(GLint location, GLsizei count, ...@@ -2062,11 +2062,8 @@ Program::SetUniformResult Program::setUniform1iv(GLint location, GLsizei count,
if (mState.isSamplerUniformIndex(locationInfo.index)) if (mState.isSamplerUniformIndex(locationInfo.index))
{ {
updateSamplerUniform(locationInfo, clampedCount, v); updateSamplerUniform(context, locationInfo, clampedCount, v);
return SetUniformResult::SamplerChanged;
} }
return SetUniformResult::NoSamplerChange;
} }
void Program::setUniform2iv(GLint location, GLsizei count, const GLint *v) void Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
...@@ -3858,7 +3855,10 @@ void Program::setUniformValuesFromBindingQualifiers() ...@@ -3858,7 +3855,10 @@ void Program::setUniformValuesFromBindingQualifiers()
{ {
boundTextureUnits.push_back(samplerUniform.binding + elementIndex); boundTextureUnits.push_back(samplerUniform.binding + elementIndex);
} }
setUniform1iv(location, static_cast<GLsizei>(boundTextureUnits.size()),
// Here we pass nullptr to avoid a large chain of calls that need a non-const Context.
// We know it's safe not to notify the Context because this is only called after link.
setUniform1iv(nullptr, location, static_cast<GLsizei>(boundTextureUnits.size()),
boundTextureUnits.data()); boundTextureUnits.data());
} }
} }
...@@ -3874,7 +3874,8 @@ void Program::initInterfaceBlockBindings() ...@@ -3874,7 +3874,8 @@ void Program::initInterfaceBlockBindings()
} }
} }
void Program::updateSamplerUniform(const VariableLocation &locationInfo, void Program::updateSamplerUniform(Context *context,
const VariableLocation &locationInfo,
GLsizei clampedCount, GLsizei clampedCount,
const GLint *v) const GLint *v)
{ {
...@@ -3889,30 +3890,30 @@ void Program::updateSamplerUniform(const VariableLocation &locationInfo, ...@@ -3889,30 +3890,30 @@ void Program::updateSamplerUniform(const VariableLocation &locationInfo,
// Update the sampler uniforms. // Update the sampler uniforms.
for (GLsizei arrayIndex = 0; arrayIndex < clampedCount; ++arrayIndex) for (GLsizei arrayIndex = 0; arrayIndex < clampedCount; ++arrayIndex)
{ {
GLint oldSamplerIndex = boundTextureUnits[arrayIndex + locationInfo.arrayIndex]; GLint oldTextureUnit = boundTextureUnits[arrayIndex + locationInfo.arrayIndex];
GLint newSamplerIndex = v[arrayIndex]; GLint newTextureUnit = v[arrayIndex];
if (oldSamplerIndex == newSamplerIndex) if (oldTextureUnit == newTextureUnit)
continue; continue;
boundTextureUnits[arrayIndex + locationInfo.arrayIndex] = newSamplerIndex; boundTextureUnits[arrayIndex + locationInfo.arrayIndex] = newTextureUnit;
// Update the reference counts. // Update the reference counts.
uint32_t &oldRefCount = mState.mActiveSamplerRefCounts[oldSamplerIndex]; uint32_t &oldRefCount = mState.mActiveSamplerRefCounts[oldTextureUnit];
uint32_t &newRefCount = mState.mActiveSamplerRefCounts[newSamplerIndex]; uint32_t &newRefCount = mState.mActiveSamplerRefCounts[newTextureUnit];
ASSERT(oldRefCount > 0); ASSERT(oldRefCount > 0);
ASSERT(newRefCount < std::numeric_limits<uint32_t>::max()); ASSERT(newRefCount < std::numeric_limits<uint32_t>::max());
oldRefCount--; oldRefCount--;
newRefCount++; newRefCount++;
// Check for binding type change. // Check for binding type change.
TextureType &newSamplerType = mState.mActiveSamplerTypes[newSamplerIndex]; TextureType &newSamplerType = mState.mActiveSamplerTypes[newTextureUnit];
TextureType &oldSamplerType = mState.mActiveSamplerTypes[oldSamplerIndex]; TextureType &oldSamplerType = mState.mActiveSamplerTypes[oldTextureUnit];
if (newRefCount == 1) if (newRefCount == 1)
{ {
newSamplerType = samplerBinding.textureType; newSamplerType = samplerBinding.textureType;
mState.mActiveSamplersMask.set(newSamplerIndex); mState.mActiveSamplersMask.set(newTextureUnit);
} }
else if (newSamplerType != samplerBinding.textureType) else if (newSamplerType != samplerBinding.textureType)
{ {
...@@ -3924,12 +3925,19 @@ void Program::updateSamplerUniform(const VariableLocation &locationInfo, ...@@ -3924,12 +3925,19 @@ void Program::updateSamplerUniform(const VariableLocation &locationInfo,
if (oldRefCount == 0) if (oldRefCount == 0)
{ {
oldSamplerType = TextureType::InvalidEnum; oldSamplerType = TextureType::InvalidEnum;
mState.mActiveSamplersMask.reset(oldSamplerIndex); mState.mActiveSamplersMask.reset(oldTextureUnit);
} }
else if (oldSamplerType == TextureType::InvalidEnum) else if (oldSamplerType == TextureType::InvalidEnum)
{ {
// Previous conflict. Check if this new change fixed the conflict. // Previous conflict. Check if this new change fixed the conflict.
oldSamplerType = mState.getSamplerUniformTextureType(oldSamplerIndex); oldSamplerType = mState.getSamplerUniformTextureType(oldTextureUnit);
}
// Notify context.
if (context)
{
context->onSamplerUniformChange(newTextureUnit);
context->onSamplerUniformChange(oldTextureUnit);
} }
} }
......
...@@ -625,7 +625,7 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -625,7 +625,7 @@ class Program final : angle::NonCopyable, public LabeledObject
void setUniform2fv(GLint location, GLsizei count, const GLfloat *v); void setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
void setUniform3fv(GLint location, GLsizei count, const GLfloat *v); void setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
void setUniform4fv(GLint location, GLsizei count, const GLfloat *v); void setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
SetUniformResult setUniform1iv(GLint location, GLsizei count, const GLint *v); void setUniform1iv(Context *context, GLint location, GLsizei count, const GLint *v);
void setUniform2iv(GLint location, GLsizei count, const GLint *v); void setUniform2iv(GLint location, GLsizei count, const GLint *v);
void setUniform3iv(GLint location, GLsizei count, const GLint *v); void setUniform3iv(GLint location, GLsizei count, const GLint *v);
void setUniform4iv(GLint location, GLsizei count, const GLint *v); void setUniform4iv(GLint location, GLsizei count, const GLint *v);
...@@ -932,7 +932,8 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -932,7 +932,8 @@ class Program final : angle::NonCopyable, public LabeledObject
template <size_t cols, size_t rows, typename T> template <size_t cols, size_t rows, typename T>
GLsizei clampMatrixUniformCount(GLint location, GLsizei count, GLboolean transpose, const T *v); GLsizei clampMatrixUniformCount(GLint location, GLsizei count, GLboolean transpose, const T *v);
void updateSamplerUniform(const VariableLocation &locationInfo, void updateSamplerUniform(Context *context,
const VariableLocation &locationInfo,
GLsizei clampedCount, GLsizei clampedCount,
const GLint *v); const GLint *v);
......
...@@ -243,7 +243,7 @@ void TextureManager::signalAllTexturesDirty(const Context *context) const ...@@ -243,7 +243,7 @@ void TextureManager::signalAllTexturesDirty(const Context *context) const
{ {
// We don't know if the Texture needs init, but that's ok, since it will only force // We don't know if the Texture needs init, but that's ok, since it will only force
// a re-check, and will not initialize the pixels if it's not needed. // a re-check, and will not initialize the pixels if it's not needed.
texture.second->signalDirty(context, InitState::MayNeedInit); texture.second->signalDirtyStorage(context, InitState::MayNeedInit);
} }
} }
} }
......
...@@ -455,40 +455,49 @@ ANGLE_INLINE void State::unsetActiveTextures(ActiveTextureMask textureMask) ...@@ -455,40 +455,49 @@ ANGLE_INLINE void State::unsetActiveTextures(ActiveTextureMask textureMask)
} }
} }
ANGLE_INLINE angle::Result State::updateActiveTexture(const Context *context, ANGLE_INLINE void State::updateActiveTextureState(const Context *context,
size_t textureIndex, size_t textureIndex,
Texture *texture) const Sampler *sampler,
Texture *texture)
{ {
const Sampler *sampler = mSamplers[textureIndex].get(); if (!texture->isSamplerComplete(context, sampler))
if (!texture)
{ {
mActiveTexturesCache[textureIndex] = nullptr; mActiveTexturesCache[textureIndex] = nullptr;
mCompleteTextureBindings[textureIndex].bind(nullptr);
return angle::Result::Continue();
} }
else
{
mActiveTexturesCache[textureIndex] = texture;
mCompleteTextureBindings[textureIndex].bind(texture); if (texture->hasAnyDirtyBit())
{
setTextureDirty(textureIndex);
}
if (!texture->isSamplerComplete(context, sampler)) if (texture->initState() == InitState::MayNeedInit)
{ {
mActiveTexturesCache[textureIndex] = nullptr; mCachedTexturesInitState = InitState::MayNeedInit;
return angle::Result::Continue(); }
} }
mActiveTexturesCache[textureIndex] = texture; mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
}
if (texture->hasAnyDirtyBit()) ANGLE_INLINE void State::updateActiveTexture(const Context *context,
{ size_t textureIndex,
ANGLE_TRY(texture->syncState(context)); Texture *texture)
} {
const Sampler *sampler = mSamplers[textureIndex].get();
if (texture->initState() == InitState::MayNeedInit) mCompleteTextureBindings[textureIndex].bind(texture);
if (!texture)
{ {
mCachedTexturesInitState = InitState::MayNeedInit; mActiveTexturesCache[textureIndex] = nullptr;
mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
return;
} }
return angle::Result::Continue(); updateActiveTextureState(context, textureIndex, sampler, texture);
} }
const RasterizerState &State::getRasterizerState() const const RasterizerState &State::getRasterizerState() const
...@@ -1013,19 +1022,17 @@ void State::setActiveSampler(unsigned int active) ...@@ -1013,19 +1022,17 @@ void State::setActiveSampler(unsigned int active)
mActiveSampler = active; mActiveSampler = active;
} }
angle::Result State::setSamplerTexture(const Context *context, TextureType type, Texture *texture) void State::setSamplerTexture(const Context *context, TextureType type, Texture *texture)
{ {
mSamplerTextures[type][mActiveSampler].set(context, texture); mSamplerTextures[type][mActiveSampler].set(context, texture);
if (mProgram && mProgram->getActiveSamplersMask()[mActiveSampler] && if (mProgram && mProgram->getActiveSamplersMask()[mActiveSampler] &&
mProgram->getActiveSamplerTypes()[mActiveSampler] == type) mProgram->getActiveSamplerTypes()[mActiveSampler] == type)
{ {
ANGLE_TRY(updateActiveTexture(context, mActiveSampler, texture)); updateActiveTexture(context, mActiveSampler, texture);
} }
mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS); mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
return angle::Result::Continue();
} }
Texture *State::getTargetTexture(TextureType type) const Texture *State::getTargetTexture(TextureType type) const
...@@ -1111,9 +1118,9 @@ void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sample ...@@ -1111,9 +1118,9 @@ void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sample
{ {
mSamplers[textureUnit].set(context, sampler); mSamplers[textureUnit].set(context, sampler);
mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS); mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
// This is overly conservative as it assumes the sampler has never been bound. // This is overly conservative as it assumes the sampler has never been bound.
setSamplerDirty(textureUnit); setSamplerDirty(textureUnit);
onActiveTextureChange(context, textureUnit);
} }
void State::detachSampler(const Context *context, GLuint sampler) void State::detachSampler(const Context *context, GLuint sampler)
...@@ -2507,15 +2514,39 @@ angle::Result State::syncDrawAttachments(const Context *context) ...@@ -2507,15 +2514,39 @@ angle::Result State::syncDrawAttachments(const Context *context)
return mDrawFramebuffer->ensureDrawAttachmentsInitialized(context); return mDrawFramebuffer->ensureDrawAttachmentsInitialized(context);
} }
angle::Result State::syncVertexArray(const Context *context) angle::Result State::syncTextures(const Context *context)
{ {
ASSERT(mVertexArray); if (mDirtyTextures.none())
return mVertexArray->syncState(context); return angle::Result::Continue();
for (size_t textureIndex : mDirtyTextures)
{
Texture *texture = mActiveTexturesCache[textureIndex];
if (texture && texture->hasAnyDirtyBit())
{
ANGLE_TRY(texture->syncState(context));
}
}
mDirtyTextures.reset();
return angle::Result::Continue();
} }
angle::Result State::syncProgram(const Context *context) angle::Result State::syncImages(const Context *context)
{ {
return mProgram->syncState(context); if (mDirtyImages.none())
return angle::Result::Continue();
for (size_t imageUnitIndex : mDirtyImages)
{
Texture *texture = mImageUnits[imageUnitIndex].texture.get();
if (texture && texture->hasAnyDirtyBit())
{
ANGLE_TRY(texture->syncState(context));
}
}
return angle::Result::Continue();
} }
angle::Result State::syncSamplers(const Context *context) angle::Result State::syncSamplers(const Context *context)
...@@ -2523,7 +2554,6 @@ angle::Result State::syncSamplers(const Context *context) ...@@ -2523,7 +2554,6 @@ angle::Result State::syncSamplers(const Context *context)
if (mDirtySamplers.none()) if (mDirtySamplers.none())
return angle::Result::Continue(); return angle::Result::Continue();
// This could be optimized by tracking which samplers are dirty.
for (size_t samplerIndex : mDirtySamplers) for (size_t samplerIndex : mDirtySamplers)
{ {
BindingPointer<Sampler> &sampler = mSamplers[samplerIndex]; BindingPointer<Sampler> &sampler = mSamplers[samplerIndex];
...@@ -2538,66 +2568,15 @@ angle::Result State::syncSamplers(const Context *context) ...@@ -2538,66 +2568,15 @@ angle::Result State::syncSamplers(const Context *context)
return angle::Result::Continue(); return angle::Result::Continue();
} }
angle::Result State::syncProgramTextures(const Context *context) angle::Result State::syncVertexArray(const Context *context)
{ {
// TODO(jmadill): Fine-grained updates. ASSERT(mVertexArray);
if (!mProgram) return mVertexArray->syncState(context);
{ }
return angle::Result::Continue();
}
ASSERT(mDirtyObjects[DIRTY_OBJECT_PROGRAM_TEXTURES]);
mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
ActiveTextureMask newActiveTextures;
// Initialize to the 'Initialized' state and set to 'MayNeedInit' if any texture is not
// initialized.
mCachedTexturesInitState = InitState::Initialized;
mCachedImageTexturesInitState = InitState::Initialized;
const ActiveTextureMask &activeTextures = mProgram->getActiveSamplersMask();
const ActiveTextureArray<TextureType> &textureTypes = mProgram->getActiveSamplerTypes();
for (size_t textureUnitIndex : activeTextures)
{
TextureType textureType = textureTypes[textureUnitIndex];
Texture *texture =
getSamplerTexture(static_cast<unsigned int>(textureUnitIndex), textureType);
ASSERT(static_cast<size_t>(textureUnitIndex) < newActiveTextures.size());
ASSERT(texture);
newActiveTextures.set(textureUnitIndex);
ANGLE_TRY(updateActiveTexture(context, textureUnitIndex, texture));
}
// Unset now missing textures.
ActiveTextureMask negativeMask = activeTextures & ~newActiveTextures;
if (negativeMask.any())
{
unsetActiveTextures(negativeMask);
}
for (size_t imageUnitIndex : mProgram->getActiveImagesMask())
{
Texture *texture = mImageUnits[imageUnitIndex].texture.get();
if (!texture)
{
continue;
}
if (texture->hasAnyDirtyBit())
{
ANGLE_TRY(texture->syncState(context));
}
if (texture->initState() == InitState::MayNeedInit)
{
mCachedImageTexturesInitState = InitState::MayNeedInit;
}
}
return angle::Result::Continue(); angle::Result State::syncProgram(const Context *context)
{
return mProgram->syncState(context);
} }
angle::Result State::syncDirtyObject(const Context *context, GLenum target) angle::Result State::syncDirtyObject(const Context *context, GLenum target)
...@@ -2620,14 +2599,12 @@ angle::Result State::syncDirtyObject(const Context *context, GLenum target) ...@@ -2620,14 +2599,12 @@ angle::Result State::syncDirtyObject(const Context *context, GLenum target)
localSet.set(DIRTY_OBJECT_VERTEX_ARRAY); localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
break; break;
case GL_TEXTURE: case GL_TEXTURE:
localSet.set(DIRTY_OBJECT_PROGRAM_TEXTURES); localSet.set(DIRTY_OBJECT_TEXTURES);
break; break;
case GL_SAMPLER: case GL_SAMPLER:
localSet.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
localSet.set(DIRTY_OBJECT_SAMPLERS); localSet.set(DIRTY_OBJECT_SAMPLERS);
break; break;
case GL_PROGRAM: case GL_PROGRAM:
localSet.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
localSet.set(DIRTY_OBJECT_PROGRAM); localSet.set(DIRTY_OBJECT_PROGRAM);
break; break;
} }
...@@ -2652,14 +2629,10 @@ void State::setObjectDirty(GLenum target) ...@@ -2652,14 +2629,10 @@ void State::setObjectDirty(GLenum target)
case GL_VERTEX_ARRAY: case GL_VERTEX_ARRAY:
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
break; break;
case GL_TEXTURE:
mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
break;
case GL_PROGRAM: case GL_PROGRAM:
mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
mDirtyObjects.set(DIRTY_OBJECT_PROGRAM); mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS); break;
default:
break; break;
} }
} }
...@@ -2690,7 +2663,7 @@ angle::Result State::onProgramExecutableChange(const Context *context, Program * ...@@ -2690,7 +2663,7 @@ angle::Result State::onProgramExecutableChange(const Context *context, Program *
continue; continue;
Texture *texture = mSamplerTextures[type][textureIndex].get(); Texture *texture = mSamplerTextures[type][textureIndex].get();
ANGLE_TRY(updateActiveTexture(context, textureIndex, texture)); updateActiveTexture(context, textureIndex, texture);
} }
for (size_t imageUnitIndex : program->getActiveImagesMask()) for (size_t imageUnitIndex : program->getActiveImagesMask())
...@@ -2713,6 +2686,12 @@ angle::Result State::onProgramExecutableChange(const Context *context, Program * ...@@ -2713,6 +2686,12 @@ angle::Result State::onProgramExecutableChange(const Context *context, Program *
return angle::Result::Continue(); return angle::Result::Continue();
} }
void State::setTextureDirty(size_t textureUnitIndex)
{
mDirtyObjects.set(DIRTY_OBJECT_TEXTURES);
mDirtyTextures.set(textureUnitIndex);
}
void State::setSamplerDirty(size_t samplerIndex) void State::setSamplerDirty(size_t samplerIndex)
{ {
mDirtyObjects.set(DIRTY_OBJECT_SAMPLERS); mDirtyObjects.set(DIRTY_OBJECT_SAMPLERS);
...@@ -2735,19 +2714,53 @@ void State::setImageUnit(const Context *context, ...@@ -2735,19 +2714,53 @@ void State::setImageUnit(const Context *context,
mImageUnits[unit].access = access; mImageUnits[unit].access = access;
mImageUnits[unit].format = format; mImageUnits[unit].format = format;
mDirtyBits.set(DIRTY_BIT_IMAGE_BINDINGS); mDirtyBits.set(DIRTY_BIT_IMAGE_BINDINGS);
onImageStateChange(context, unit);
} }
// Handle a dirty texture event. // Handle a dirty texture event.
void State::onActiveTextureStateChange(size_t textureIndex) void State::onActiveTextureChange(const Context *context, size_t textureUnit)
{ {
// Conservatively assume all textures are dirty. if (mProgram)
// TODO(jmadill): More fine-grained update. {
mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES); TextureType type = mProgram->getActiveSamplerTypes()[textureUnit];
if (type != TextureType::InvalidEnum)
{
Texture *activeTexture = mSamplerTextures[type][textureUnit].get();
updateActiveTexture(context, textureUnit, activeTexture);
}
}
}
if (!mActiveTexturesCache[textureIndex] || void State::onActiveTextureStateChange(const Context *context, size_t textureUnit)
mActiveTexturesCache[textureIndex]->initState() == InitState::MayNeedInit) {
if (mProgram)
{ {
mCachedTexturesInitState = InitState::MayNeedInit; TextureType type = mProgram->getActiveSamplerTypes()[textureUnit];
if (type != TextureType::InvalidEnum)
{
Texture *activeTexture = mSamplerTextures[type][textureUnit].get();
const Sampler *sampler = mSamplers[textureUnit].get();
updateActiveTextureState(context, textureUnit, sampler, activeTexture);
}
}
}
void State::onImageStateChange(const Context *context, size_t unit)
{
if (mProgram)
{
const ImageUnit &image = mImageUnits[unit];
ASSERT(image.texture.get());
if (image.texture->hasAnyDirtyBit())
{
mDirtyImages.set(unit);
}
if (image.texture->initState() == InitState::MayNeedInit)
{
mCachedImageTexturesInitState = InitState::MayNeedInit;
}
} }
} }
...@@ -2760,7 +2773,6 @@ void State::onUniformBufferStateChange(size_t uniformBufferIndex) ...@@ -2760,7 +2773,6 @@ void State::onUniformBufferStateChange(size_t uniformBufferIndex)
angle::Result State::clearUnclearedActiveTextures(const Context *context) angle::Result State::clearUnclearedActiveTextures(const Context *context)
{ {
ASSERT(mRobustResourceInit); ASSERT(mRobustResourceInit);
ASSERT(!mDirtyObjects[DIRTY_OBJECT_PROGRAM_TEXTURES]);
if (!mProgram) if (!mProgram)
return angle::Result::Continue(); return angle::Result::Continue();
......
...@@ -179,7 +179,7 @@ class State : angle::NonCopyable ...@@ -179,7 +179,7 @@ class State : angle::NonCopyable
void setActiveSampler(unsigned int active); void setActiveSampler(unsigned int active);
unsigned int getActiveSampler() const { return static_cast<unsigned int>(mActiveSampler); } unsigned int getActiveSampler() const { return static_cast<unsigned int>(mActiveSampler); }
angle::Result setSamplerTexture(const Context *context, TextureType type, Texture *texture); void setSamplerTexture(const Context *context, TextureType type, Texture *texture);
Texture *getTargetTexture(TextureType type) const; Texture *getTargetTexture(TextureType type) const;
Texture *getSamplerTexture(unsigned int sampler, TextureType type) const Texture *getSamplerTexture(unsigned int sampler, TextureType type) const
...@@ -487,10 +487,9 @@ class State : angle::NonCopyable ...@@ -487,10 +487,9 @@ class State : angle::NonCopyable
DIRTY_OBJECT_DRAW_FRAMEBUFFER, DIRTY_OBJECT_DRAW_FRAMEBUFFER,
DIRTY_OBJECT_DRAW_ATTACHMENTS, DIRTY_OBJECT_DRAW_ATTACHMENTS,
DIRTY_OBJECT_VERTEX_ARRAY, DIRTY_OBJECT_VERTEX_ARRAY,
DIRTY_OBJECT_SAMPLERS, DIRTY_OBJECT_TEXTURES, // Top-level dirty bit. Also see mDirtyTextures.
// Use a very coarse bit for any program or texture change. DIRTY_OBJECT_IMAGES, // Top-level dirty bit. Also see mDirtyImages.
// TODO(jmadill): Fine-grained dirty bits for each texture/sampler. DIRTY_OBJECT_SAMPLERS, // Top-level dirty bit. Also see mDirtySamplers.
DIRTY_OBJECT_PROGRAM_TEXTURES,
DIRTY_OBJECT_PROGRAM, DIRTY_OBJECT_PROGRAM,
DIRTY_OBJECT_UNKNOWN, DIRTY_OBJECT_UNKNOWN,
DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN, DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN,
...@@ -508,6 +507,7 @@ class State : angle::NonCopyable ...@@ -508,6 +507,7 @@ class State : angle::NonCopyable
angle::Result syncDirtyObjects(const Context *context, const DirtyObjects &bitset); angle::Result syncDirtyObjects(const Context *context, const DirtyObjects &bitset);
angle::Result syncDirtyObject(const Context *context, GLenum target); angle::Result syncDirtyObject(const Context *context, GLenum target);
void setObjectDirty(GLenum target); void setObjectDirty(GLenum target);
void setTextureDirty(size_t textureUnitIndex);
void setSamplerDirty(size_t samplerIndex); void setSamplerDirty(size_t samplerIndex);
ANGLE_INLINE void setDrawFramebufferDirty() ANGLE_INLINE void setDrawFramebufferDirty()
...@@ -533,7 +533,14 @@ class State : angle::NonCopyable ...@@ -533,7 +533,14 @@ class State : angle::NonCopyable
const ActiveTexturePointerArray &getActiveTexturesCache() const { return mActiveTexturesCache; } const ActiveTexturePointerArray &getActiveTexturesCache() const { return mActiveTexturesCache; }
ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; } ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; }
void onActiveTextureStateChange(size_t textureIndex); // "onActiveTextureChange" is called when a texture binding changes.
void onActiveTextureChange(const Context *context, size_t textureUnit);
// "onActiveTextureStateChange" calls when the Texture itself changed but the binding did not.
void onActiveTextureStateChange(const Context *context, size_t textureUnit);
void onImageStateChange(const Context *context, size_t unit);
void onUniformBufferStateChange(size_t uniformBufferIndex); void onUniformBufferStateChange(size_t uniformBufferIndex);
angle::Result clearUnclearedActiveTextures(const Context *context); angle::Result clearUnclearedActiveTextures(const Context *context);
...@@ -559,32 +566,36 @@ class State : angle::NonCopyable ...@@ -559,32 +566,36 @@ class State : angle::NonCopyable
private: private:
void unsetActiveTextures(ActiveTextureMask textureMask); void unsetActiveTextures(ActiveTextureMask textureMask);
angle::Result updateActiveTexture(const Context *context, void updateActiveTexture(const Context *context, size_t textureIndex, Texture *texture);
size_t textureIndex, void updateActiveTextureState(const Context *context,
Texture *texture); size_t textureIndex,
const Sampler *sampler,
Texture *texture);
// Functions to synchronize dirty states // Functions to synchronize dirty states
angle::Result syncReadFramebuffer(const Context *context); angle::Result syncReadFramebuffer(const Context *context);
angle::Result syncDrawFramebuffer(const Context *context); angle::Result syncDrawFramebuffer(const Context *context);
angle::Result syncDrawAttachments(const Context *context); angle::Result syncDrawAttachments(const Context *context);
angle::Result syncVertexArray(const Context *context); angle::Result syncVertexArray(const Context *context);
angle::Result syncTextures(const Context *context);
angle::Result syncImages(const Context *context);
angle::Result syncSamplers(const Context *context); angle::Result syncSamplers(const Context *context);
angle::Result syncProgramTextures(const Context *context);
angle::Result syncProgram(const Context *context); angle::Result syncProgram(const Context *context);
using DirtyObjectHandler = angle::Result (State::*)(const Context *context); using DirtyObjectHandler = angle::Result (State::*)(const Context *context);
static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = { static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = {
&State::syncReadFramebuffer, &State::syncDrawFramebuffer, &State::syncDrawAttachments, &State::syncReadFramebuffer, &State::syncDrawFramebuffer, &State::syncDrawAttachments,
&State::syncVertexArray, &State::syncSamplers, &State::syncProgramTextures, &State::syncVertexArray, &State::syncTextures, &State::syncImages,
&State::syncProgram}; &State::syncSamplers, &State::syncProgram};
static_assert(DIRTY_OBJECT_READ_FRAMEBUFFER == 0, "check DIRTY_OBJECT_READ_FRAMEBUFFER index"); static_assert(DIRTY_OBJECT_READ_FRAMEBUFFER == 0, "check DIRTY_OBJECT_READ_FRAMEBUFFER index");
static_assert(DIRTY_OBJECT_DRAW_FRAMEBUFFER == 1, "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index"); static_assert(DIRTY_OBJECT_DRAW_FRAMEBUFFER == 1, "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index");
static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS == 2, "check DIRTY_OBJECT_DRAW_ATTACHMENTS index"); static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS == 2, "check DIRTY_OBJECT_DRAW_ATTACHMENTS index");
static_assert(DIRTY_OBJECT_VERTEX_ARRAY == 3, "check DIRTY_OBJECT_VERTEX_ARRAY index"); static_assert(DIRTY_OBJECT_VERTEX_ARRAY == 3, "check DIRTY_OBJECT_VERTEX_ARRAY index");
static_assert(DIRTY_OBJECT_SAMPLERS == 4, "check DIRTY_OBJECT_SAMPLERS index"); static_assert(DIRTY_OBJECT_TEXTURES == 4, "check DIRTY_OBJECT_TEXTURES index");
static_assert(DIRTY_OBJECT_PROGRAM_TEXTURES == 5, "check DIRTY_OBJECT_PROGRAM_TEXTURES index"); static_assert(DIRTY_OBJECT_IMAGES == 5, "check DIRTY_OBJECT_IMAGES index");
static_assert(DIRTY_OBJECT_PROGRAM == 6, "check DIRTY_OBJECT_PROGRAM index"); static_assert(DIRTY_OBJECT_SAMPLERS == 6, "check DIRTY_OBJECT_SAMPLERS index");
static_assert(DIRTY_OBJECT_PROGRAM == 7, "check DIRTY_OBJECT_PROGRAM index");
// Dispatch table for buffer update functions. // Dispatch table for buffer update functions.
static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters; static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;
...@@ -666,8 +677,8 @@ class State : angle::NonCopyable ...@@ -666,8 +677,8 @@ class State : angle::NonCopyable
SamplerBindingVector mSamplers; SamplerBindingVector mSamplers;
using ImageUnitVector = std::vector<ImageUnit>; // It would be nice to merge the image and observer binding. Same for textures.
ImageUnitVector mImageUnits; std::vector<ImageUnit> mImageUnits;
using ActiveQueryMap = angle::PackedEnumMap<QueryType, BindingPointer<Query>>; using ActiveQueryMap = angle::PackedEnumMap<QueryType, BindingPointer<Query>>;
ActiveQueryMap mActiveQueries; ActiveQueryMap mActiveQueries;
...@@ -722,7 +733,9 @@ class State : angle::NonCopyable ...@@ -722,7 +733,9 @@ class State : angle::NonCopyable
DirtyBits mDirtyBits; DirtyBits mDirtyBits;
DirtyObjects mDirtyObjects; DirtyObjects mDirtyObjects;
mutable AttributesMask mDirtyCurrentValues; mutable AttributesMask mDirtyCurrentValues;
ActiveTextureMask mDirtyTextures;
ActiveTextureMask mDirtySamplers; ActiveTextureMask mDirtySamplers;
ImageUnitMask mDirtyImages;
}; };
ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context, ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context,
......
...@@ -630,7 +630,7 @@ Texture::~Texture() ...@@ -630,7 +630,7 @@ Texture::~Texture()
void Texture::setLabel(const Context *context, const std::string &label) void Texture::setLabel(const Context *context, const std::string &label)
{ {
mLabel = label; mLabel = label;
mDirtyBits.set(DIRTY_BIT_LABEL); signalDirtyState(context, DIRTY_BIT_LABEL);
} }
const std::string &Texture::getLabel() const const std::string &Texture::getLabel() const
...@@ -638,10 +638,10 @@ const std::string &Texture::getLabel() const ...@@ -638,10 +638,10 @@ const std::string &Texture::getLabel() const
return mLabel; return mLabel;
} }
void Texture::setSwizzleRed(GLenum swizzleRed) void Texture::setSwizzleRed(const Context *context, GLenum swizzleRed)
{ {
mState.mSwizzleState.swizzleRed = swizzleRed; mState.mSwizzleState.swizzleRed = swizzleRed;
mDirtyBits.set(DIRTY_BIT_SWIZZLE_RED); signalDirtyState(context, DIRTY_BIT_SWIZZLE_RED);
} }
GLenum Texture::getSwizzleRed() const GLenum Texture::getSwizzleRed() const
...@@ -649,10 +649,10 @@ GLenum Texture::getSwizzleRed() const ...@@ -649,10 +649,10 @@ GLenum Texture::getSwizzleRed() const
return mState.mSwizzleState.swizzleRed; return mState.mSwizzleState.swizzleRed;
} }
void Texture::setSwizzleGreen(GLenum swizzleGreen) void Texture::setSwizzleGreen(const Context *context, GLenum swizzleGreen)
{ {
mState.mSwizzleState.swizzleGreen = swizzleGreen; mState.mSwizzleState.swizzleGreen = swizzleGreen;
mDirtyBits.set(DIRTY_BIT_SWIZZLE_GREEN); signalDirtyState(context, DIRTY_BIT_SWIZZLE_GREEN);
} }
GLenum Texture::getSwizzleGreen() const GLenum Texture::getSwizzleGreen() const
...@@ -660,10 +660,10 @@ GLenum Texture::getSwizzleGreen() const ...@@ -660,10 +660,10 @@ GLenum Texture::getSwizzleGreen() const
return mState.mSwizzleState.swizzleGreen; return mState.mSwizzleState.swizzleGreen;
} }
void Texture::setSwizzleBlue(GLenum swizzleBlue) void Texture::setSwizzleBlue(const Context *context, GLenum swizzleBlue)
{ {
mState.mSwizzleState.swizzleBlue = swizzleBlue; mState.mSwizzleState.swizzleBlue = swizzleBlue;
mDirtyBits.set(DIRTY_BIT_SWIZZLE_BLUE); signalDirtyState(context, DIRTY_BIT_SWIZZLE_BLUE);
} }
GLenum Texture::getSwizzleBlue() const GLenum Texture::getSwizzleBlue() const
...@@ -671,10 +671,10 @@ GLenum Texture::getSwizzleBlue() const ...@@ -671,10 +671,10 @@ GLenum Texture::getSwizzleBlue() const
return mState.mSwizzleState.swizzleBlue; return mState.mSwizzleState.swizzleBlue;
} }
void Texture::setSwizzleAlpha(GLenum swizzleAlpha) void Texture::setSwizzleAlpha(const Context *context, GLenum swizzleAlpha)
{ {
mState.mSwizzleState.swizzleAlpha = swizzleAlpha; mState.mSwizzleState.swizzleAlpha = swizzleAlpha;
mDirtyBits.set(DIRTY_BIT_SWIZZLE_ALPHA); signalDirtyState(context, DIRTY_BIT_SWIZZLE_ALPHA);
} }
GLenum Texture::getSwizzleAlpha() const GLenum Texture::getSwizzleAlpha() const
...@@ -682,10 +682,10 @@ GLenum Texture::getSwizzleAlpha() const ...@@ -682,10 +682,10 @@ GLenum Texture::getSwizzleAlpha() const
return mState.mSwizzleState.swizzleAlpha; return mState.mSwizzleState.swizzleAlpha;
} }
void Texture::setMinFilter(GLenum minFilter) void Texture::setMinFilter(const Context *context, GLenum minFilter)
{ {
mState.mSamplerState.setMinFilter(minFilter); mState.mSamplerState.setMinFilter(minFilter);
mDirtyBits.set(DIRTY_BIT_MIN_FILTER); signalDirtyState(context, DIRTY_BIT_MIN_FILTER);
} }
GLenum Texture::getMinFilter() const GLenum Texture::getMinFilter() const
...@@ -693,10 +693,10 @@ GLenum Texture::getMinFilter() const ...@@ -693,10 +693,10 @@ GLenum Texture::getMinFilter() const
return mState.mSamplerState.getMinFilter(); return mState.mSamplerState.getMinFilter();
} }
void Texture::setMagFilter(GLenum magFilter) void Texture::setMagFilter(const Context *context, GLenum magFilter)
{ {
mState.mSamplerState.setMagFilter(magFilter); mState.mSamplerState.setMagFilter(magFilter);
mDirtyBits.set(DIRTY_BIT_MAG_FILTER); signalDirtyState(context, DIRTY_BIT_MAG_FILTER);
} }
GLenum Texture::getMagFilter() const GLenum Texture::getMagFilter() const
...@@ -704,10 +704,10 @@ GLenum Texture::getMagFilter() const ...@@ -704,10 +704,10 @@ GLenum Texture::getMagFilter() const
return mState.mSamplerState.getMagFilter(); return mState.mSamplerState.getMagFilter();
} }
void Texture::setWrapS(GLenum wrapS) void Texture::setWrapS(const Context *context, GLenum wrapS)
{ {
mState.mSamplerState.setWrapS(wrapS); mState.mSamplerState.setWrapS(wrapS);
mDirtyBits.set(DIRTY_BIT_WRAP_S); signalDirtyState(context, DIRTY_BIT_WRAP_S);
} }
GLenum Texture::getWrapS() const GLenum Texture::getWrapS() const
...@@ -715,10 +715,10 @@ GLenum Texture::getWrapS() const ...@@ -715,10 +715,10 @@ GLenum Texture::getWrapS() const
return mState.mSamplerState.getWrapS(); return mState.mSamplerState.getWrapS();
} }
void Texture::setWrapT(GLenum wrapT) void Texture::setWrapT(const Context *context, GLenum wrapT)
{ {
mState.mSamplerState.setWrapT(wrapT); mState.mSamplerState.setWrapT(wrapT);
mDirtyBits.set(DIRTY_BIT_WRAP_T); signalDirtyState(context, DIRTY_BIT_WRAP_T);
} }
GLenum Texture::getWrapT() const GLenum Texture::getWrapT() const
...@@ -726,10 +726,10 @@ GLenum Texture::getWrapT() const ...@@ -726,10 +726,10 @@ GLenum Texture::getWrapT() const
return mState.mSamplerState.getWrapT(); return mState.mSamplerState.getWrapT();
} }
void Texture::setWrapR(GLenum wrapR) void Texture::setWrapR(const Context *context, GLenum wrapR)
{ {
mState.mSamplerState.setWrapR(wrapR); mState.mSamplerState.setWrapR(wrapR);
mDirtyBits.set(DIRTY_BIT_WRAP_R); signalDirtyState(context, DIRTY_BIT_WRAP_R);
} }
GLenum Texture::getWrapR() const GLenum Texture::getWrapR() const
...@@ -737,10 +737,10 @@ GLenum Texture::getWrapR() const ...@@ -737,10 +737,10 @@ GLenum Texture::getWrapR() const
return mState.mSamplerState.getWrapR(); return mState.mSamplerState.getWrapR();
} }
void Texture::setMaxAnisotropy(float maxAnisotropy) void Texture::setMaxAnisotropy(const Context *context, float maxAnisotropy)
{ {
mState.mSamplerState.setMaxAnisotropy(maxAnisotropy); mState.mSamplerState.setMaxAnisotropy(maxAnisotropy);
mDirtyBits.set(DIRTY_BIT_MAX_ANISOTROPY); signalDirtyState(context, DIRTY_BIT_MAX_ANISOTROPY);
} }
float Texture::getMaxAnisotropy() const float Texture::getMaxAnisotropy() const
...@@ -748,10 +748,10 @@ float Texture::getMaxAnisotropy() const ...@@ -748,10 +748,10 @@ float Texture::getMaxAnisotropy() const
return mState.mSamplerState.getMaxAnisotropy(); return mState.mSamplerState.getMaxAnisotropy();
} }
void Texture::setMinLod(GLfloat minLod) void Texture::setMinLod(const Context *context, GLfloat minLod)
{ {
mState.mSamplerState.setMinLod(minLod); mState.mSamplerState.setMinLod(minLod);
mDirtyBits.set(DIRTY_BIT_MIN_LOD); signalDirtyState(context, DIRTY_BIT_MIN_LOD);
} }
GLfloat Texture::getMinLod() const GLfloat Texture::getMinLod() const
...@@ -759,10 +759,10 @@ GLfloat Texture::getMinLod() const ...@@ -759,10 +759,10 @@ GLfloat Texture::getMinLod() const
return mState.mSamplerState.getMinLod(); return mState.mSamplerState.getMinLod();
} }
void Texture::setMaxLod(GLfloat maxLod) void Texture::setMaxLod(const Context *context, GLfloat maxLod)
{ {
mState.mSamplerState.setMaxLod(maxLod); mState.mSamplerState.setMaxLod(maxLod);
mDirtyBits.set(DIRTY_BIT_MAX_LOD); signalDirtyState(context, DIRTY_BIT_MAX_LOD);
} }
GLfloat Texture::getMaxLod() const GLfloat Texture::getMaxLod() const
...@@ -770,10 +770,10 @@ GLfloat Texture::getMaxLod() const ...@@ -770,10 +770,10 @@ GLfloat Texture::getMaxLod() const
return mState.mSamplerState.getMaxLod(); return mState.mSamplerState.getMaxLod();
} }
void Texture::setCompareMode(GLenum compareMode) void Texture::setCompareMode(const Context *context, GLenum compareMode)
{ {
mState.mSamplerState.setCompareMode(compareMode); mState.mSamplerState.setCompareMode(compareMode);
mDirtyBits.set(DIRTY_BIT_COMPARE_MODE); signalDirtyState(context, DIRTY_BIT_COMPARE_MODE);
} }
GLenum Texture::getCompareMode() const GLenum Texture::getCompareMode() const
...@@ -781,10 +781,10 @@ GLenum Texture::getCompareMode() const ...@@ -781,10 +781,10 @@ GLenum Texture::getCompareMode() const
return mState.mSamplerState.getCompareMode(); return mState.mSamplerState.getCompareMode();
} }
void Texture::setCompareFunc(GLenum compareFunc) void Texture::setCompareFunc(const Context *context, GLenum compareFunc)
{ {
mState.mSamplerState.setCompareFunc(compareFunc); mState.mSamplerState.setCompareFunc(compareFunc);
mDirtyBits.set(DIRTY_BIT_COMPARE_FUNC); signalDirtyState(context, DIRTY_BIT_COMPARE_FUNC);
} }
GLenum Texture::getCompareFunc() const GLenum Texture::getCompareFunc() const
...@@ -792,10 +792,10 @@ GLenum Texture::getCompareFunc() const ...@@ -792,10 +792,10 @@ GLenum Texture::getCompareFunc() const
return mState.mSamplerState.getCompareFunc(); return mState.mSamplerState.getCompareFunc();
} }
void Texture::setSRGBDecode(GLenum sRGBDecode) void Texture::setSRGBDecode(const Context *context, GLenum sRGBDecode)
{ {
mState.mSamplerState.setSRGBDecode(sRGBDecode); mState.mSamplerState.setSRGBDecode(sRGBDecode);
mDirtyBits.set(DIRTY_BIT_SRGB_DECODE); signalDirtyState(context, DIRTY_BIT_SRGB_DECODE);
} }
GLenum Texture::getSRGBDecode() const GLenum Texture::getSRGBDecode() const
...@@ -813,8 +813,7 @@ angle::Result Texture::setBaseLevel(const Context *context, GLuint baseLevel) ...@@ -813,8 +813,7 @@ angle::Result Texture::setBaseLevel(const Context *context, GLuint baseLevel)
if (mState.setBaseLevel(baseLevel)) if (mState.setBaseLevel(baseLevel))
{ {
ANGLE_TRY(mTexture->setBaseLevel(context, mState.getEffectiveBaseLevel())); ANGLE_TRY(mTexture->setBaseLevel(context, mState.getEffectiveBaseLevel()));
mDirtyBits.set(DIRTY_BIT_BASE_LEVEL); signalDirtyState(context, DIRTY_BIT_BASE_LEVEL);
invalidateCompletenessCache();
} }
return angle::Result::Continue(); return angle::Result::Continue();
...@@ -825,12 +824,11 @@ GLuint Texture::getBaseLevel() const ...@@ -825,12 +824,11 @@ GLuint Texture::getBaseLevel() const
return mState.mBaseLevel; return mState.mBaseLevel;
} }
void Texture::setMaxLevel(GLuint maxLevel) void Texture::setMaxLevel(const Context *context, GLuint maxLevel)
{ {
if (mState.setMaxLevel(maxLevel)) if (mState.setMaxLevel(maxLevel))
{ {
mDirtyBits.set(DIRTY_BIT_MAX_LEVEL); signalDirtyState(context, DIRTY_BIT_MAX_LEVEL);
invalidateCompletenessCache();
} }
} }
...@@ -839,13 +837,12 @@ GLuint Texture::getMaxLevel() const ...@@ -839,13 +837,12 @@ GLuint Texture::getMaxLevel() const
return mState.mMaxLevel; return mState.mMaxLevel;
} }
void Texture::setDepthStencilTextureMode(GLenum mode) void Texture::setDepthStencilTextureMode(const Context *context, GLenum mode)
{ {
if (mState.mDepthStencilTextureMode != mode) if (mState.mDepthStencilTextureMode != mode)
{ {
mState.mDepthStencilTextureMode = mode; mState.mDepthStencilTextureMode = mode;
mDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE); signalDirtyState(context, DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE);
invalidateCompletenessCache();
} }
} }
...@@ -864,10 +861,10 @@ GLuint Texture::getImmutableLevels() const ...@@ -864,10 +861,10 @@ GLuint Texture::getImmutableLevels() const
return mState.mImmutableLevels; return mState.mImmutableLevels;
} }
void Texture::setUsage(GLenum usage) void Texture::setUsage(const Context *context, GLenum usage)
{ {
mState.mUsage = usage; mState.mUsage = usage;
mDirtyBits.set(DIRTY_BIT_USAGE); signalDirtyState(context, DIRTY_BIT_USAGE);
} }
GLenum Texture::getUsage() const GLenum Texture::getUsage() const
...@@ -963,11 +960,18 @@ GLint Texture::getLevelMemorySize(TextureTarget target, GLint level) const ...@@ -963,11 +960,18 @@ GLint Texture::getLevelMemorySize(TextureTarget target, GLint level) const
return mState.getImageDesc(target, level).getMemorySize(); return mState.getImageDesc(target, level).getMemorySize();
} }
void Texture::signalDirty(const Context *context, InitState initState) void Texture::signalDirtyStorage(const Context *context, InitState initState)
{ {
mState.mInitState = initState; mState.mInitState = initState;
invalidateCompletenessCache();
onStateChange(context, angle::SubjectMessage::STORAGE_CHANGED); onStateChange(context, angle::SubjectMessage::STORAGE_CHANGED);
}
void Texture::signalDirtyState(const Context *context, size_t dirtyBit)
{
mDirtyBits.set(dirtyBit);
invalidateCompletenessCache(); invalidateCompletenessCache();
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
} }
angle::Result Texture::setImage(Context *context, angle::Result Texture::setImage(Context *context,
...@@ -996,7 +1000,7 @@ angle::Result Texture::setImage(Context *context, ...@@ -996,7 +1000,7 @@ angle::Result Texture::setImage(Context *context,
ANGLE_TRY(handleMipmapGenerationHint(context, level)); ANGLE_TRY(handleMipmapGenerationHint(context, level));
signalDirty(context, initState); signalDirtyStorage(context, initState);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1047,7 +1051,7 @@ angle::Result Texture::setCompressedImage(Context *context, ...@@ -1047,7 +1051,7 @@ angle::Result Texture::setCompressedImage(Context *context,
InitState initState = DetermineInitState(context, pixels); InitState initState = DetermineInitState(context, pixels);
mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat), initState)); mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat), initState));
signalDirty(context, initState); signalDirtyStorage(context, initState);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1105,7 +1109,7 @@ angle::Result Texture::copyImage(Context *context, ...@@ -1105,7 +1109,7 @@ angle::Result Texture::copyImage(Context *context,
ANGLE_TRY(handleMipmapGenerationHint(context, level)); ANGLE_TRY(handleMipmapGenerationHint(context, level));
// We need to initialize this texture only if the source attachment is not initialized. // We need to initialize this texture only if the source attachment is not initialized.
signalDirty(context, InitState::Initialized); signalDirtyStorage(context, InitState::Initialized);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1167,7 +1171,7 @@ angle::Result Texture::copyTexture(Context *context, ...@@ -1167,7 +1171,7 @@ angle::Result Texture::copyTexture(Context *context,
target, level, target, level,
ImageDesc(sourceDesc.size, Format(internalFormatInfo), InitState::Initialized)); ImageDesc(sourceDesc.size, Format(internalFormatInfo), InitState::Initialized));
signalDirty(context, InitState::Initialized); signalDirtyStorage(context, InitState::Initialized);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1241,7 +1245,7 @@ angle::Result Texture::setStorage(Context *context, ...@@ -1241,7 +1245,7 @@ angle::Result Texture::setStorage(Context *context,
mDirtyBits.set(DIRTY_BIT_BASE_LEVEL); mDirtyBits.set(DIRTY_BIT_BASE_LEVEL);
mDirtyBits.set(DIRTY_BIT_MAX_LEVEL); mDirtyBits.set(DIRTY_BIT_MAX_LEVEL);
signalDirty(context, InitState::MayNeedInit); signalDirtyStorage(context, InitState::MayNeedInit);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1268,7 +1272,7 @@ angle::Result Texture::setStorageMultisample(Context *context, ...@@ -1268,7 +1272,7 @@ angle::Result Texture::setStorageMultisample(Context *context,
mState.setImageDescChainMultisample(size, Format(internalFormat), samples, fixedSampleLocations, mState.setImageDescChainMultisample(size, Format(internalFormat), samples, fixedSampleLocations,
InitState::MayNeedInit); InitState::MayNeedInit);
signalDirty(context, InitState::MayNeedInit); signalDirtyStorage(context, InitState::MayNeedInit);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1324,7 +1328,7 @@ angle::Result Texture::generateMipmap(Context *context) ...@@ -1324,7 +1328,7 @@ angle::Result Texture::generateMipmap(Context *context)
mState.setImageDescChain(baseLevel, maxLevel, baseImageInfo.size, baseImageInfo.format, mState.setImageDescChain(baseLevel, maxLevel, baseImageInfo.size, baseImageInfo.format,
InitState::Initialized); InitState::Initialized);
signalDirty(context, InitState::Initialized); signalDirtyStorage(context, InitState::Initialized);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1346,7 +1350,7 @@ angle::Result Texture::bindTexImageFromSurface(Context *context, egl::Surface *s ...@@ -1346,7 +1350,7 @@ angle::Result Texture::bindTexImageFromSurface(Context *context, egl::Surface *s
Extents size(surface->getWidth(), surface->getHeight(), 1); Extents size(surface->getWidth(), surface->getHeight(), 1);
ImageDesc desc(size, surface->getBindTexImageFormat(), InitState::Initialized); ImageDesc desc(size, surface->getBindTexImageFormat(), InitState::Initialized);
mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0, desc); mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0, desc);
signalDirty(context, InitState::Initialized); signalDirtyStorage(context, InitState::Initialized);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1359,7 +1363,7 @@ angle::Result Texture::releaseTexImageFromSurface(const Context *context) ...@@ -1359,7 +1363,7 @@ angle::Result Texture::releaseTexImageFromSurface(const Context *context)
// Erase the image info for level 0 // Erase the image info for level 0
ASSERT(mState.mType == TextureType::_2D || mState.mType == TextureType::Rectangle); ASSERT(mState.mType == TextureType::_2D || mState.mType == TextureType::Rectangle);
mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0); mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0);
signalDirty(context, InitState::Initialized); signalDirtyStorage(context, InitState::Initialized);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1390,7 +1394,7 @@ angle::Result Texture::acquireImageFromStream(const Context *context, ...@@ -1390,7 +1394,7 @@ angle::Result Texture::acquireImageFromStream(const Context *context,
Extents size(desc.width, desc.height, 1); Extents size(desc.width, desc.height, 1);
mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0, mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0,
ImageDesc(size, Format(desc.internalFormat), InitState::Initialized)); ImageDesc(size, Format(desc.internalFormat), InitState::Initialized));
signalDirty(context, InitState::Initialized); signalDirtyStorage(context, InitState::Initialized);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1402,7 +1406,7 @@ angle::Result Texture::releaseImageFromStream(const Context *context) ...@@ -1402,7 +1406,7 @@ angle::Result Texture::releaseImageFromStream(const Context *context)
// Set to incomplete // Set to incomplete
mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0); mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0);
signalDirty(context, InitState::Initialized); signalDirtyStorage(context, InitState::Initialized);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1448,7 +1452,7 @@ angle::Result Texture::setEGLImageTarget(Context *context, ...@@ -1448,7 +1452,7 @@ angle::Result Texture::setEGLImageTarget(Context *context,
mState.clearImageDescs(); mState.clearImageDescs();
mState.setImageDesc(NonCubeTextureTypeToTarget(type), 0, mState.setImageDesc(NonCubeTextureTypeToTarget(type), 0,
ImageDesc(size, imageTarget->getFormat(), initState)); ImageDesc(size, imageTarget->getFormat(), initState));
signalDirty(context, initState); signalDirtyStorage(context, initState);
return angle::Result::Continue(); return angle::Result::Continue();
} }
...@@ -1527,10 +1531,10 @@ bool Texture::getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) co ...@@ -1527,10 +1531,10 @@ bool Texture::getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) co
return getFixedSampleLocations(imageIndex.getTarget(), imageIndex.getLevelIndex()); return getFixedSampleLocations(imageIndex.getTarget(), imageIndex.getLevelIndex());
} }
void Texture::setBorderColor(const ColorGeneric &color) void Texture::setBorderColor(const Context *context, const ColorGeneric &color)
{ {
mState.mSamplerState.setBorderColor(color); mState.mSamplerState.setBorderColor(color);
mDirtyBits.set(DIRTY_BIT_BORDER_COLOR); signalDirtyState(context, DIRTY_BIT_BORDER_COLOR);
} }
const ColorGeneric &Texture::getBorderColor() const const ColorGeneric &Texture::getBorderColor() const
...@@ -1640,7 +1644,7 @@ angle::Result Texture::ensureInitialized(const Context *context) ...@@ -1640,7 +1644,7 @@ angle::Result Texture::ensureInitialized(const Context *context)
} }
if (anyDirty) if (anyDirty)
{ {
signalDirty(context, InitState::Initialized); signalDirtyStorage(context, InitState::Initialized);
} }
mState.mInitState = InitState::Initialized; mState.mInitState = InitState::Initialized;
......
...@@ -206,49 +206,49 @@ class Texture final : public RefCountObject, ...@@ -206,49 +206,49 @@ class Texture final : public RefCountObject,
TextureType getType() const { return mState.mType; } TextureType getType() const { return mState.mType; }
void setSwizzleRed(GLenum swizzleRed); void setSwizzleRed(const Context *context, GLenum swizzleRed);
GLenum getSwizzleRed() const; GLenum getSwizzleRed() const;
void setSwizzleGreen(GLenum swizzleGreen); void setSwizzleGreen(const Context *context, GLenum swizzleGreen);
GLenum getSwizzleGreen() const; GLenum getSwizzleGreen() const;
void setSwizzleBlue(GLenum swizzleBlue); void setSwizzleBlue(const Context *context, GLenum swizzleBlue);
GLenum getSwizzleBlue() const; GLenum getSwizzleBlue() const;
void setSwizzleAlpha(GLenum swizzleAlpha); void setSwizzleAlpha(const Context *context, GLenum swizzleAlpha);
GLenum getSwizzleAlpha() const; GLenum getSwizzleAlpha() const;
void setMinFilter(GLenum minFilter); void setMinFilter(const Context *context, GLenum minFilter);
GLenum getMinFilter() const; GLenum getMinFilter() const;
void setMagFilter(GLenum magFilter); void setMagFilter(const Context *context, GLenum magFilter);
GLenum getMagFilter() const; GLenum getMagFilter() const;
void setWrapS(GLenum wrapS); void setWrapS(const Context *context, GLenum wrapS);
GLenum getWrapS() const; GLenum getWrapS() const;
void setWrapT(GLenum wrapT); void setWrapT(const Context *context, GLenum wrapT);
GLenum getWrapT() const; GLenum getWrapT() const;
void setWrapR(GLenum wrapR); void setWrapR(const Context *context, GLenum wrapR);
GLenum getWrapR() const; GLenum getWrapR() const;
void setMaxAnisotropy(float maxAnisotropy); void setMaxAnisotropy(const Context *context, float maxAnisotropy);
float getMaxAnisotropy() const; float getMaxAnisotropy() const;
void setMinLod(GLfloat minLod); void setMinLod(const Context *context, GLfloat minLod);
GLfloat getMinLod() const; GLfloat getMinLod() const;
void setMaxLod(GLfloat maxLod); void setMaxLod(const Context *context, GLfloat maxLod);
GLfloat getMaxLod() const; GLfloat getMaxLod() const;
void setCompareMode(GLenum compareMode); void setCompareMode(const Context *context, GLenum compareMode);
GLenum getCompareMode() const; GLenum getCompareMode() const;
void setCompareFunc(GLenum compareFunc); void setCompareFunc(const Context *context, GLenum compareFunc);
GLenum getCompareFunc() const; GLenum getCompareFunc() const;
void setSRGBDecode(GLenum sRGBDecode); void setSRGBDecode(const Context *context, GLenum sRGBDecode);
GLenum getSRGBDecode() const; GLenum getSRGBDecode() const;
const SamplerState &getSamplerState() const; const SamplerState &getSamplerState() const;
...@@ -256,19 +256,22 @@ class Texture final : public RefCountObject, ...@@ -256,19 +256,22 @@ class Texture final : public RefCountObject,
angle::Result setBaseLevel(const Context *context, GLuint baseLevel); angle::Result setBaseLevel(const Context *context, GLuint baseLevel);
GLuint getBaseLevel() const; GLuint getBaseLevel() const;
void setMaxLevel(GLuint maxLevel); void setMaxLevel(const Context *context, GLuint maxLevel);
GLuint getMaxLevel() const; GLuint getMaxLevel() const;
void setDepthStencilTextureMode(GLenum mode); void setDepthStencilTextureMode(const Context *context, GLenum mode);
GLenum getDepthStencilTextureMode() const; GLenum getDepthStencilTextureMode() const;
bool getImmutableFormat() const; bool getImmutableFormat() const;
GLuint getImmutableLevels() const; GLuint getImmutableLevels() const;
void setUsage(GLenum usage); void setUsage(const Context *context, GLenum usage);
GLenum getUsage() const; GLenum getUsage() const;
void setBorderColor(const Context *context, const ColorGeneric &color);
const ColorGeneric &getBorderColor() const;
const TextureState &getTextureState() const; const TextureState &getTextureState() const;
size_t getWidth(TextureTarget target, size_t level) const; size_t getWidth(TextureTarget target, size_t level) const;
...@@ -377,7 +380,7 @@ class Texture final : public RefCountObject, ...@@ -377,7 +380,7 @@ class Texture final : public RefCountObject,
GLint getMemorySize() const; GLint getMemorySize() const;
GLint getLevelMemorySize(TextureTarget target, GLint level) const; GLint getLevelMemorySize(TextureTarget target, GLint level) const;
void signalDirty(const Context *context, InitState initState); void signalDirtyStorage(const Context *context, InitState initState);
bool isSamplerComplete(const Context *context, const Sampler *optionalSampler); bool isSamplerComplete(const Context *context, const Sampler *optionalSampler);
...@@ -393,9 +396,6 @@ class Texture final : public RefCountObject, ...@@ -393,9 +396,6 @@ class Texture final : public RefCountObject,
bool getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const; bool getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const;
void setBorderColor(const ColorGeneric &color);
const ColorGeneric &getBorderColor() const;
// GLES1 emulation // GLES1 emulation
void setCrop(const gl::Rectangle &rect); void setCrop(const gl::Rectangle &rect);
const gl::Rectangle &getCrop() const; const gl::Rectangle &getCrop() const;
...@@ -480,6 +480,8 @@ class Texture final : public RefCountObject, ...@@ -480,6 +480,8 @@ class Texture final : public RefCountObject,
angle::Result handleMipmapGenerationHint(Context *context, int level); angle::Result handleMipmapGenerationHint(Context *context, int level);
void signalDirtyState(const Context *context, size_t dirtyBit);
TextureState mState; TextureState mState;
DirtyBits mDirtyBits; DirtyBits mDirtyBits;
rx::TextureImpl *mTexture; rx::TextureImpl *mTexture;
......
...@@ -428,6 +428,8 @@ using ActiveTextureArray = std::array<T, IMPLEMENTATION_MAX_ACTIVE_TEXTURES>; ...@@ -428,6 +428,8 @@ using ActiveTextureArray = std::array<T, IMPLEMENTATION_MAX_ACTIVE_TEXTURES>;
using ActiveTexturePointerArray = ActiveTextureArray<Texture *>; using ActiveTexturePointerArray = ActiveTextureArray<Texture *>;
using ActiveTextureTypeArray = ActiveTextureArray<TextureType>; using ActiveTextureTypeArray = ActiveTextureArray<TextureType>;
using ImageUnitMask = angle::BitSet<IMPLEMENTATION_MAX_IMAGE_UNITS>;
// OffsetBindingPointer.getSize() returns the size specified by the user, which may be larger than // OffsetBindingPointer.getSize() returns the size specified by the user, which may be larger than
// the size of the bound buffer. This function reduces the returned size to fit the bound buffer if // the size of the bound buffer. This function reduces the returned size to fit the bound buffer if
// necessary. Returns 0 if no buffer is bound or if integer overflow occurs. // necessary. Returns 0 if no buffer is bound or if integer overflow occurs.
......
...@@ -318,43 +318,43 @@ void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ...@@ -318,43 +318,43 @@ void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const
switch (pname) switch (pname)
{ {
case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_S:
texture->setWrapS(ConvertToGLenum(pname, params[0])); texture->setWrapS(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_WRAP_T: case GL_TEXTURE_WRAP_T:
texture->setWrapT(ConvertToGLenum(pname, params[0])); texture->setWrapT(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_WRAP_R: case GL_TEXTURE_WRAP_R:
texture->setWrapR(ConvertToGLenum(pname, params[0])); texture->setWrapR(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MIN_FILTER:
texture->setMinFilter(ConvertToGLenum(pname, params[0])); texture->setMinFilter(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_MAG_FILTER: case GL_TEXTURE_MAG_FILTER:
texture->setMagFilter(ConvertToGLenum(pname, params[0])); texture->setMagFilter(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_USAGE_ANGLE: case GL_TEXTURE_USAGE_ANGLE:
texture->setUsage(ConvertToGLenum(pname, params[0])); texture->setUsage(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_MAX_ANISOTROPY_EXT: case GL_TEXTURE_MAX_ANISOTROPY_EXT:
texture->setMaxAnisotropy(CastQueryValueTo<GLfloat>(pname, params[0])); texture->setMaxAnisotropy(context, CastQueryValueTo<GLfloat>(pname, params[0]));
break; break;
case GL_TEXTURE_COMPARE_MODE: case GL_TEXTURE_COMPARE_MODE:
texture->setCompareMode(ConvertToGLenum(pname, params[0])); texture->setCompareMode(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_COMPARE_FUNC: case GL_TEXTURE_COMPARE_FUNC:
texture->setCompareFunc(ConvertToGLenum(pname, params[0])); texture->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_SWIZZLE_R: case GL_TEXTURE_SWIZZLE_R:
texture->setSwizzleRed(ConvertToGLenum(pname, params[0])); texture->setSwizzleRed(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_SWIZZLE_G: case GL_TEXTURE_SWIZZLE_G:
texture->setSwizzleGreen(ConvertToGLenum(pname, params[0])); texture->setSwizzleGreen(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_SWIZZLE_B: case GL_TEXTURE_SWIZZLE_B:
texture->setSwizzleBlue(ConvertToGLenum(pname, params[0])); texture->setSwizzleBlue(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_SWIZZLE_A: case GL_TEXTURE_SWIZZLE_A:
texture->setSwizzleAlpha(ConvertToGLenum(pname, params[0])); texture->setSwizzleAlpha(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_BASE_LEVEL:
{ {
...@@ -363,19 +363,20 @@ void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ...@@ -363,19 +363,20 @@ void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const
break; break;
} }
case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_MAX_LEVEL:
texture->setMaxLevel(clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0]))); texture->setMaxLevel(context,
clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0])));
break; break;
case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MIN_LOD:
texture->setMinLod(CastQueryValueTo<GLfloat>(pname, params[0])); texture->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
break; break;
case GL_TEXTURE_MAX_LOD: case GL_TEXTURE_MAX_LOD:
texture->setMaxLod(CastQueryValueTo<GLfloat>(pname, params[0])); texture->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
break; break;
case GL_DEPTH_STENCIL_TEXTURE_MODE: case GL_DEPTH_STENCIL_TEXTURE_MODE:
texture->setDepthStencilTextureMode(ConvertToGLenum(pname, params[0])); texture->setDepthStencilTextureMode(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_SRGB_DECODE_EXT: case GL_TEXTURE_SRGB_DECODE_EXT:
texture->setSRGBDecode(ConvertToGLenum(pname, params[0])); texture->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
break; break;
case GL_TEXTURE_CROP_RECT_OES: case GL_TEXTURE_CROP_RECT_OES:
texture->setCrop(gl::Rectangle(CastQueryValueTo<GLint>(pname, params[0]), texture->setCrop(gl::Rectangle(CastQueryValueTo<GLint>(pname, params[0]),
...@@ -387,7 +388,7 @@ void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ...@@ -387,7 +388,7 @@ void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const
texture->setGenerateMipmapHint(ConvertToGLenum(params[0])); texture->setGenerateMipmapHint(ConvertToGLenum(params[0]));
break; break;
case GL_TEXTURE_BORDER_COLOR: case GL_TEXTURE_BORDER_COLOR:
texture->setBorderColor(ConvertToColor<isPureInteger>(params)); texture->setBorderColor(context, ConvertToColor<isPureInteger>(params));
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
......
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