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