зеркало из https://github.com/AvaloniaUI/angle.git
Allow glDelete* while PLS is active
Banning glDelete* is extremely dangerous. It will almost definitely cause memory leaks in client code, and it makes JS garbage collection needlessly complex. Instead, specify that PLS is implicity deactivated if the client deletes anything that is attached to the current draw framebuffer during a PLS rendering pass. Bug: chromium:1421437 Change-Id: I3a18ee6b5d5567431e6fa3eccea58cb049845502 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4521436 Reviewed-by: Kenneth Russell <kbr@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Chris Dalton <chris@rive.app>
This commit is contained in:
Родитель
b76166d027
Коммит
7d4c6d1d07
|
@ -451,6 +451,7 @@ Additions to the OpenGL ES Specification, Version 3.0.6
|
|||
DebugMessageCallback*
|
||||
DebugMessageControl*
|
||||
DebugMessageInsert*
|
||||
Delete*
|
||||
DepthFunc
|
||||
DepthMask
|
||||
DepthRangef
|
||||
|
@ -654,7 +655,24 @@ Additions to the OpenGL ES Specification, Version 3.0.6
|
|||
|
||||
Modify Section 4.4.2 "Attaching Images to Framebuffer Objects"
|
||||
|
||||
(Insert two new numbered section after 4.4.2.3 "Attaching Texture Images to a
|
||||
(Add a new paragraph to 4.4.2.3 "Attaching Renderbuffer Images to a
|
||||
Framebuffer".)
|
||||
|
||||
If a renderbuffer object is deleted while its image is attached to the
|
||||
currently bound draw framebuffer, and pixel local storage is active, then it
|
||||
is as if EndPixelLocalStorageANGLE() had been called with
|
||||
<n>=PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE and <storeops> of
|
||||
STORE_OP_STORE_ANGLE.
|
||||
|
||||
(Add a new paragraph to 4.4.2.4 "Attaching Texture Images to a Framebuffer".)
|
||||
|
||||
If a texture object is deleted while its image is attached to the currently
|
||||
bound draw framebuffer, and pixel local storage is active, then it is as if
|
||||
EndPixelLocalStorageANGLE() had been called with
|
||||
<n>=PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE and <storeops> of
|
||||
STORE_OP_STORE_ANGLE.
|
||||
|
||||
(Insert two new numbered section after 4.4.2.4 "Attaching Texture Images to a
|
||||
Framebuffer".)
|
||||
|
||||
Section 4.4.2.X "Configuring Pixel Local Storage on a Framebuffer"
|
||||
|
@ -810,6 +828,12 @@ Additions to the OpenGL ES Specification, Version 3.0.6
|
|||
When a texture object is deleted, any pixel local storage plane to which it
|
||||
is bound is automatically deinitialized.
|
||||
|
||||
If a texture object is deleted while its image is bound to a pixel local
|
||||
storage plane on the currently bound draw framebuffer, and pixel local
|
||||
storage is active, then it is as if EndPixelLocalStorageANGLE() had been
|
||||
called with <n>=PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE and <storeops> of
|
||||
STORE_OP_STORE_ANGLE.
|
||||
|
||||
Section 4.4.2.Y "Pixel Local Clear State"
|
||||
|
||||
Each pixel local storage plane on a framebuffer has state for three separate
|
||||
|
@ -1269,7 +1293,7 @@ Issues
|
|||
spec.
|
||||
|
||||
(3) Should we support the ability to enable/disable pixel local storage
|
||||
planes on an individual basis? (e.g., "GL_LOAD_OP_DISABLE_ANGLE.)
|
||||
planes on an individual basis? (e.g., "LOAD_OP_DISABLE_ANGLE".)
|
||||
|
||||
RESOLVED: No. Some implementations need to reserve color attachments for
|
||||
internal use. Allowing any combination of planes to be enabled or disabled
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"scripts/entry_point_packed_gl_enums.json":
|
||||
"1c6b036918aabb9822a638fbf33f87f4",
|
||||
"scripts/generate_entry_points.py":
|
||||
"25a27ff7c9c450a62c98eee8cb5c7a85",
|
||||
"af2e7b9911842300f7cbdd3230e279cb",
|
||||
"scripts/gl_angle_ext.xml":
|
||||
"758f78e8bf6447f118643421110728b7",
|
||||
"scripts/registry_xml.py":
|
||||
|
@ -132,7 +132,7 @@
|
|||
"src/libGLESv2/entry_points_egl_ext_autogen.h":
|
||||
"5a212372e378e0890d2d3ac96c1a3765",
|
||||
"src/libGLESv2/entry_points_gl_1_autogen.cpp":
|
||||
"f64ecfbe03214f2a658efe5c2b15e03b",
|
||||
"19032ff73d0152f7db98f1330dc01781",
|
||||
"src/libGLESv2/entry_points_gl_1_autogen.h":
|
||||
"fc92166806eac5dc285f6a3f06e89d2b",
|
||||
"src/libGLESv2/entry_points_gl_2_autogen.cpp":
|
||||
|
@ -152,15 +152,15 @@
|
|||
"src/libGLESv2/entry_points_gles_1_0_autogen.h":
|
||||
"1d3aef77845a416497070985a8e9cb31",
|
||||
"src/libGLESv2/entry_points_gles_2_0_autogen.cpp":
|
||||
"2051b56158c541d5db8e3d91947cae6d",
|
||||
"0a4061235c23281170a779ab89d5ea94",
|
||||
"src/libGLESv2/entry_points_gles_2_0_autogen.h":
|
||||
"691c60c2dfed9beca68aa1f32aa2c71b",
|
||||
"src/libGLESv2/entry_points_gles_3_0_autogen.cpp":
|
||||
"d39253a1e6ced7bb846911deb79157ad",
|
||||
"dba836d09dcfacfceb03acbed55117a7",
|
||||
"src/libGLESv2/entry_points_gles_3_0_autogen.h":
|
||||
"4ac2582759cdc6a30f78f83ab684d555",
|
||||
"src/libGLESv2/entry_points_gles_3_1_autogen.cpp":
|
||||
"bdcbc67e3a08d5b60eccfd5ba22a037f",
|
||||
"eab6c2e40e05a0f87f5fa7e73e95a31b",
|
||||
"src/libGLESv2/entry_points_gles_3_1_autogen.h":
|
||||
"a7327c330a91665fc31accbb78793b42",
|
||||
"src/libGLESv2/entry_points_gles_3_2_autogen.cpp":
|
||||
|
@ -168,7 +168,7 @@
|
|||
"src/libGLESv2/entry_points_gles_3_2_autogen.h":
|
||||
"647f932a299cdb4726b60bbba059f0d2",
|
||||
"src/libGLESv2/entry_points_gles_ext_autogen.cpp":
|
||||
"6ce59775f5eb6e67688b01ceb415c748",
|
||||
"e6695455270bbda7da7e4f30838905d2",
|
||||
"src/libGLESv2/entry_points_gles_ext_autogen.h":
|
||||
"a410e5f079226a62a48222243c91231b",
|
||||
"src/libGLESv2/libGLESv2_autogen.cpp":
|
||||
|
|
|
@ -105,6 +105,7 @@ PLS_ALLOW_WILDCARDS = [
|
|||
"DebugMessageCallback*",
|
||||
"DebugMessageControl*",
|
||||
"DebugMessageInsert*",
|
||||
"Delete*",
|
||||
"Disablei*",
|
||||
"DrawArrays*",
|
||||
"DrawElements*",
|
||||
|
|
|
@ -1096,6 +1096,28 @@ void Context::deleteProgram(ShaderProgramID program)
|
|||
|
||||
void Context::deleteTexture(TextureID textureID)
|
||||
{
|
||||
// If a texture object is deleted while its image is bound to a pixel local storage plane on the
|
||||
// currently bound draw framebuffer, and pixel local storage is active, then it is as if
|
||||
// EndPixelLocalStorageANGLE() had been called with <n>=PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE
|
||||
// and <storeops> of STORE_OP_STORE_ANGLE.
|
||||
if (mState.getPixelLocalStorageActivePlanes() != 0)
|
||||
{
|
||||
PixelLocalStorage *pls = mState.getDrawFramebuffer()->peekPixelLocalStorage();
|
||||
// Even though there is a nonzero number of active PLS planes, peekPixelLocalStorage() may
|
||||
// still return null if we are in the middle of deleting the active framebuffer.
|
||||
if (pls != nullptr)
|
||||
{
|
||||
for (GLuint i = 0; i < mState.mCaps.maxPixelLocalStoragePlanes; ++i)
|
||||
{
|
||||
if (pls->getPlane(i).getTextureID() == textureID)
|
||||
{
|
||||
endPixelLocalStorageWithStoreOpsStore();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Texture *texture = mState.mTextureManager->getTexture(textureID);
|
||||
if (texture != nullptr)
|
||||
{
|
||||
|
@ -9409,6 +9431,15 @@ void Context::endPixelLocalStorage(GLsizei n, const GLenum storeops[])
|
|||
mState.setPixelLocalStorageActivePlanes(0);
|
||||
}
|
||||
|
||||
void Context::endPixelLocalStorageWithStoreOpsStore()
|
||||
{
|
||||
GLsizei n = mState.getPixelLocalStorageActivePlanes();
|
||||
ASSERT(n >= 1);
|
||||
angle::FixedVector<GLenum, IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES> storeops(
|
||||
n, GL_STORE_OP_STORE_ANGLE);
|
||||
endPixelLocalStorage(n, storeops.data());
|
||||
}
|
||||
|
||||
void Context::pixelLocalStorageBarrier()
|
||||
{
|
||||
if (getExtensions().shaderPixelLocalStorageCoherentANGLE)
|
||||
|
|
|
@ -690,6 +690,9 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
|
|||
// The implementation's ShPixelLocalStorageType must be "PixelLocalStorageEXT".
|
||||
void drawPixelLocalStorageEXTDisable(const PixelLocalStoragePlane[], const GLenum storeops[]);
|
||||
|
||||
// Ends the currently active pixel local storage session with GL_STORE_OP_STORE on all planes.
|
||||
void endPixelLocalStorageWithStoreOpsStore();
|
||||
|
||||
private:
|
||||
void initializeDefaultResources();
|
||||
|
||||
|
|
|
@ -996,17 +996,17 @@ const std::string &Framebuffer::getLabel() const
|
|||
return mState.mLabel;
|
||||
}
|
||||
|
||||
bool Framebuffer::detachTexture(const Context *context, TextureID textureId)
|
||||
bool Framebuffer::detachTexture(Context *context, TextureID textureId)
|
||||
{
|
||||
return detachResourceById(context, GL_TEXTURE, textureId.value);
|
||||
}
|
||||
|
||||
bool Framebuffer::detachRenderbuffer(const Context *context, RenderbufferID renderbufferId)
|
||||
bool Framebuffer::detachRenderbuffer(Context *context, RenderbufferID renderbufferId)
|
||||
{
|
||||
return detachResourceById(context, GL_RENDERBUFFER, renderbufferId.value);
|
||||
}
|
||||
|
||||
bool Framebuffer::detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId)
|
||||
bool Framebuffer::detachResourceById(Context *context, GLenum resourceType, GLuint resourceId)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
|
@ -1047,13 +1047,23 @@ bool Framebuffer::detachResourceById(const Context *context, GLenum resourceType
|
|||
return found;
|
||||
}
|
||||
|
||||
bool Framebuffer::detachMatchingAttachment(const Context *context,
|
||||
bool Framebuffer::detachMatchingAttachment(Context *context,
|
||||
FramebufferAttachment *attachment,
|
||||
GLenum matchType,
|
||||
GLuint matchId)
|
||||
{
|
||||
if (attachment->isAttached() && attachment->type() == matchType && attachment->id() == matchId)
|
||||
{
|
||||
const State &contextState = context->getState();
|
||||
if (contextState.getPixelLocalStorageActivePlanes() != 0 &&
|
||||
this == contextState.getDrawFramebuffer())
|
||||
{
|
||||
// If a (renderbuffer, texture) object is deleted while its image is attached to the
|
||||
// currently bound draw framebuffer object, and pixel local storage is active, then it
|
||||
// is as if EndPixelLocalStorageANGLE() had been called with
|
||||
// <n>=PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE and <storeops> of STORE_OP_STORE_ANGLE.
|
||||
context->endPixelLocalStorageWithStoreOpsStore();
|
||||
}
|
||||
// We go through resetAttachment to make sure that all the required bookkeeping will be done
|
||||
// such as updating enabled draw buffer state.
|
||||
resetAttachment(context, attachment->getBinding());
|
||||
|
|
|
@ -237,8 +237,8 @@ class Framebuffer final : public angle::ObserverInterface,
|
|||
GLint baseViewIndex);
|
||||
void resetAttachment(const Context *context, GLenum binding);
|
||||
|
||||
bool detachTexture(const Context *context, TextureID texture);
|
||||
bool detachRenderbuffer(const Context *context, RenderbufferID renderbuffer);
|
||||
bool detachTexture(Context *context, TextureID texture);
|
||||
bool detachRenderbuffer(Context *context, RenderbufferID renderbuffer);
|
||||
|
||||
const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const;
|
||||
const FramebufferAttachment *getDepthAttachment() const;
|
||||
|
@ -442,15 +442,15 @@ class Framebuffer final : public angle::ObserverInterface,
|
|||
// Lazily creates a PixelLocalStorage object for this Framebuffer.
|
||||
PixelLocalStorage &getPixelLocalStorage(const Context *);
|
||||
// Returns nullptr if the pixel local storage object has not been created yet.
|
||||
const PixelLocalStorage *peekPixelLocalStorage() const { return mPixelLocalStorage.get(); }
|
||||
PixelLocalStorage *peekPixelLocalStorage() const { return mPixelLocalStorage.get(); }
|
||||
// Detaches the the pixel local storage object so the Context can call deleteContextObjects().
|
||||
std::unique_ptr<PixelLocalStorage> detachPixelLocalStorage();
|
||||
|
||||
static const FramebufferID kDefaultDrawFramebufferHandle;
|
||||
|
||||
private:
|
||||
bool detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId);
|
||||
bool detachMatchingAttachment(const Context *context,
|
||||
bool detachResourceById(Context *context, GLenum resourceType, GLuint resourceId);
|
||||
bool detachMatchingAttachment(Context *context,
|
||||
FramebufferAttachment *attachment,
|
||||
GLenum matchType,
|
||||
GLuint matchId);
|
||||
|
|
|
@ -441,8 +441,8 @@ const Texture *PixelLocalStoragePlane::getBackingTexture(const Context *context)
|
|||
return tex;
|
||||
}
|
||||
|
||||
PixelLocalStorage::PixelLocalStorage(const ShPixelLocalStorageOptions &plsOptions)
|
||||
: mPLSOptions(plsOptions)
|
||||
PixelLocalStorage::PixelLocalStorage(const ShPixelLocalStorageOptions &plsOptions, const Caps &caps)
|
||||
: mPLSOptions(plsOptions), mPlanes(caps.maxPixelLocalStoragePlanes)
|
||||
{}
|
||||
|
||||
PixelLocalStorage::~PixelLocalStorage() {}
|
||||
|
@ -450,7 +450,8 @@ PixelLocalStorage::~PixelLocalStorage() {}
|
|||
namespace
|
||||
{
|
||||
bool AllPlanesDeinitialized(
|
||||
const std::array<PixelLocalStoragePlane, IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES> &planes,
|
||||
const angle::FixedVector<PixelLocalStoragePlane, IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES>
|
||||
&planes,
|
||||
const Context *context)
|
||||
{
|
||||
for (const PixelLocalStoragePlane &plane : planes)
|
||||
|
@ -551,9 +552,7 @@ void PixelLocalStorage::interrupt(Context *context)
|
|||
mActivePlanesAtInterrupt <= IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES);
|
||||
if (mActivePlanesAtInterrupt >= 1)
|
||||
{
|
||||
angle::FixedVector<GLenum, IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES> storeops(
|
||||
mActivePlanesAtInterrupt, GL_STORE_OP_STORE_ANGLE);
|
||||
context->endPixelLocalStorage(mActivePlanesAtInterrupt, storeops.data());
|
||||
context->endPixelLocalStorageWithStoreOpsStore();
|
||||
}
|
||||
}
|
||||
++mInterruptCount;
|
||||
|
@ -584,8 +583,8 @@ namespace
|
|||
class PixelLocalStorageImageLoadStore : public PixelLocalStorage
|
||||
{
|
||||
public:
|
||||
PixelLocalStorageImageLoadStore(const ShPixelLocalStorageOptions &plsOptions)
|
||||
: PixelLocalStorage(plsOptions)
|
||||
PixelLocalStorageImageLoadStore(const ShPixelLocalStorageOptions &plsOptions, const Caps &caps)
|
||||
: PixelLocalStorage(plsOptions, caps)
|
||||
{
|
||||
ASSERT(mPLSOptions.type == ShPixelLocalStorageType::ImageLoadStore);
|
||||
}
|
||||
|
@ -808,8 +807,9 @@ class PixelLocalStorageImageLoadStore : public PixelLocalStorage
|
|||
class PixelLocalStorageFramebufferFetch : public PixelLocalStorage
|
||||
{
|
||||
public:
|
||||
PixelLocalStorageFramebufferFetch(const ShPixelLocalStorageOptions &plsOptions)
|
||||
: PixelLocalStorage(plsOptions)
|
||||
PixelLocalStorageFramebufferFetch(const ShPixelLocalStorageOptions &plsOptions,
|
||||
const Caps &caps)
|
||||
: PixelLocalStorage(plsOptions, caps)
|
||||
{
|
||||
ASSERT(mPLSOptions.type == ShPixelLocalStorageType::FramebufferFetch);
|
||||
}
|
||||
|
@ -1021,8 +1021,8 @@ class PixelLocalStorageFramebufferFetch : public PixelLocalStorage
|
|||
class PixelLocalStorageEXT : public PixelLocalStorage
|
||||
{
|
||||
public:
|
||||
PixelLocalStorageEXT(const ShPixelLocalStorageOptions &plsOptions)
|
||||
: PixelLocalStorage(plsOptions)
|
||||
PixelLocalStorageEXT(const ShPixelLocalStorageOptions &plsOptions, const Caps &caps)
|
||||
: PixelLocalStorage(plsOptions, caps)
|
||||
{
|
||||
ASSERT(mPLSOptions.type == ShPixelLocalStorageType::PixelLocalStorageEXT);
|
||||
}
|
||||
|
@ -1092,14 +1092,15 @@ std::unique_ptr<PixelLocalStorage> PixelLocalStorage::Make(const Context *contex
|
|||
{
|
||||
const ShPixelLocalStorageOptions &plsOptions =
|
||||
context->getImplementation()->getNativePixelLocalStorageOptions();
|
||||
const Caps &caps = context->getState().getCaps();
|
||||
switch (plsOptions.type)
|
||||
{
|
||||
case ShPixelLocalStorageType::ImageLoadStore:
|
||||
return std::make_unique<PixelLocalStorageImageLoadStore>(plsOptions);
|
||||
return std::make_unique<PixelLocalStorageImageLoadStore>(plsOptions, caps);
|
||||
case ShPixelLocalStorageType::FramebufferFetch:
|
||||
return std::make_unique<PixelLocalStorageFramebufferFetch>(plsOptions);
|
||||
return std::make_unique<PixelLocalStorageFramebufferFetch>(plsOptions, caps);
|
||||
case ShPixelLocalStorageType::PixelLocalStorageEXT:
|
||||
return std::make_unique<PixelLocalStorageEXT>(plsOptions);
|
||||
return std::make_unique<PixelLocalStorageEXT>(plsOptions, caps);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return nullptr;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
namespace gl
|
||||
{
|
||||
|
||||
struct Caps;
|
||||
class Context;
|
||||
class Texture;
|
||||
|
||||
|
@ -43,22 +44,13 @@ class PixelLocalStoragePlane : angle::NonCopyable, public angle::ObserverInterfa
|
|||
void setTextureBacked(Context *, Texture *, int level, int layer);
|
||||
void onSubjectStateChange(angle::SubjectIndex, angle::SubjectMessage) override;
|
||||
|
||||
bool isMemoryless() const
|
||||
{
|
||||
// isMemoryless() should be false if the plane is deinitialized.
|
||||
ASSERT(!mMemoryless || mInternalformat != GL_NONE);
|
||||
return mMemoryless;
|
||||
}
|
||||
|
||||
// Returns true if the plane is deinitialized, either explicitly or implicitly via deleting the
|
||||
// texture that was attached to it.
|
||||
bool isDeinitialized() const;
|
||||
|
||||
// Ensures we have an internal backing texture for memoryless planes. In some implementations we
|
||||
// need a backing texture even if the plane is memoryless.
|
||||
void ensureBackingTextureIfMemoryless(Context *, Extents plsSize);
|
||||
|
||||
GLenum getInternalformat() const { return mInternalformat; }
|
||||
bool isMemoryless() const { return mMemoryless; }
|
||||
TextureID getTextureID() const { return mTextureID; }
|
||||
|
||||
// Implements glGetIntegeri_v() for GL_PIXEL_LOCAL_FORMAT_ANGLE,
|
||||
// GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, and
|
||||
|
@ -70,6 +62,10 @@ class PixelLocalStoragePlane : angle::NonCopyable, public angle::ObserverInterfa
|
|||
// or memoryless.
|
||||
bool getTextureImageExtents(const Context *, Extents *extents) const;
|
||||
|
||||
// Ensures we have an internal backing texture for memoryless planes. In some implementations we
|
||||
// need a backing texture even if the plane is memoryless.
|
||||
void ensureBackingTextureIfMemoryless(Context *, Extents plsSize);
|
||||
|
||||
// Attaches this plane to the specified color attachment point on the current draw framebuffer.
|
||||
void attachToDrawFramebuffer(Context *, GLenum colorAttachment) const;
|
||||
|
||||
|
@ -172,7 +168,7 @@ class PixelLocalStorage
|
|||
void restore(Context *);
|
||||
|
||||
protected:
|
||||
PixelLocalStorage(const ShPixelLocalStorageOptions &);
|
||||
PixelLocalStorage(const ShPixelLocalStorageOptions &, const Caps &);
|
||||
|
||||
// Called when the context is lost or destroyed. Causes the subclass to clear its GL object
|
||||
// handles.
|
||||
|
@ -190,7 +186,8 @@ class PixelLocalStorage
|
|||
const ShPixelLocalStorageOptions mPLSOptions;
|
||||
|
||||
private:
|
||||
std::array<PixelLocalStoragePlane, IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES> mPlanes;
|
||||
angle::FixedVector<PixelLocalStoragePlane, IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES>
|
||||
mPlanes;
|
||||
size_t mInterruptCount = 0;
|
||||
GLsizei mActivePlanesAtInterrupt = 0;
|
||||
};
|
||||
|
|
|
@ -1745,7 +1745,7 @@ TextureID State::getSamplerTextureId(unsigned int sampler, TextureType type) con
|
|||
return mSamplerTextures[type][sampler].id();
|
||||
}
|
||||
|
||||
void State::detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture)
|
||||
void State::detachTexture(Context *context, const TextureMap &zeroTextures, TextureID texture)
|
||||
{
|
||||
// Textures have a detach method on State rather than a simple
|
||||
// removeBinding, because the zero/null texture objects are managed
|
||||
|
@ -1857,7 +1857,7 @@ void State::setRenderbufferBinding(const Context *context, Renderbuffer *renderb
|
|||
mDirtyBits.set(DIRTY_BIT_RENDERBUFFER_BINDING);
|
||||
}
|
||||
|
||||
void State::detachRenderbuffer(const Context *context, RenderbufferID renderbuffer)
|
||||
void State::detachRenderbuffer(Context *context, RenderbufferID renderbuffer)
|
||||
{
|
||||
// [OpenGL ES 2.0.24] section 4.4 page 109:
|
||||
// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though
|
||||
|
|
|
@ -330,7 +330,7 @@ class State : angle::NonCopyable
|
|||
}
|
||||
|
||||
TextureID getSamplerTextureId(unsigned int sampler, TextureType type) const;
|
||||
void detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture);
|
||||
void detachTexture(Context *context, const TextureMap &zeroTextures, TextureID texture);
|
||||
void initializeZeroTextures(const Context *context, const TextureMap &zeroTextures);
|
||||
|
||||
void invalidateTextureBindings(TextureType type);
|
||||
|
@ -353,7 +353,7 @@ class State : angle::NonCopyable
|
|||
void setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer);
|
||||
RenderbufferID getRenderbufferId() const { return mRenderbuffer.id(); }
|
||||
Renderbuffer *getCurrentRenderbuffer() const { return mRenderbuffer.get(); }
|
||||
void detachRenderbuffer(const Context *context, RenderbufferID renderbuffer);
|
||||
void detachRenderbuffer(Context *context, RenderbufferID renderbuffer);
|
||||
|
||||
// Framebuffer binding manipulation
|
||||
void setReadFramebufferBinding(Framebuffer *framebuffer);
|
||||
|
|
|
@ -1101,8 +1101,7 @@ void GL_APIENTRY GL_DeleteLists(GLuint list, GLsizei range)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context, angle::EntryPoint::GLDeleteLists) &&
|
||||
ValidateDeleteLists(context, angle::EntryPoint::GLDeleteLists, list, range)));
|
||||
ValidateDeleteLists(context, angle::EntryPoint::GLDeleteLists, list, range));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteLists(list, range);
|
||||
|
|
|
@ -876,9 +876,7 @@ void GL_APIENTRY GL_DeleteBuffers(GLsizei n, const GLuint *buffers)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context, angle::EntryPoint::GLDeleteBuffers) &&
|
||||
ValidateDeleteBuffers(context, angle::EntryPoint::GLDeleteBuffers, n,
|
||||
buffersPacked)));
|
||||
ValidateDeleteBuffers(context, angle::EntryPoint::GLDeleteBuffers, n, buffersPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteBuffers(n, buffersPacked);
|
||||
|
@ -904,9 +902,8 @@ void GL_APIENTRY GL_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context, angle::EntryPoint::GLDeleteFramebuffers) &&
|
||||
ValidateDeleteFramebuffers(context, angle::EntryPoint::GLDeleteFramebuffers, n,
|
||||
framebuffersPacked)));
|
||||
ValidateDeleteFramebuffers(context, angle::EntryPoint::GLDeleteFramebuffers, n,
|
||||
framebuffersPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteFramebuffers(n, framebuffersPacked);
|
||||
|
@ -931,8 +928,7 @@ void GL_APIENTRY GL_DeleteProgram(GLuint program)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context, angle::EntryPoint::GLDeleteProgram) &&
|
||||
ValidateDeleteProgram(context, angle::EntryPoint::GLDeleteProgram, programPacked)));
|
||||
ValidateDeleteProgram(context, angle::EntryPoint::GLDeleteProgram, programPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteProgram(programPacked);
|
||||
|
@ -959,10 +955,8 @@ void GL_APIENTRY GL_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context,
|
||||
angle::EntryPoint::GLDeleteRenderbuffers) &&
|
||||
ValidateDeleteRenderbuffers(context, angle::EntryPoint::GLDeleteRenderbuffers, n,
|
||||
renderbuffersPacked)));
|
||||
ValidateDeleteRenderbuffers(context, angle::EntryPoint::GLDeleteRenderbuffers, n,
|
||||
renderbuffersPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteRenderbuffers(n, renderbuffersPacked);
|
||||
|
@ -987,8 +981,7 @@ void GL_APIENTRY GL_DeleteShader(GLuint shader)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context, angle::EntryPoint::GLDeleteShader) &&
|
||||
ValidateDeleteShader(context, angle::EntryPoint::GLDeleteShader, shaderPacked)));
|
||||
ValidateDeleteShader(context, angle::EntryPoint::GLDeleteShader, shaderPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteShader(shaderPacked);
|
||||
|
@ -1012,11 +1005,9 @@ void GL_APIENTRY GL_DeleteTextures(GLsizei n, const GLuint *textures)
|
|||
{
|
||||
const TextureID *texturesPacked = PackParam<const TextureID *>(textures);
|
||||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context, angle::EntryPoint::GLDeleteTextures) &&
|
||||
ValidateDeleteTextures(context, angle::EntryPoint::GLDeleteTextures, n,
|
||||
texturesPacked)));
|
||||
bool isCallValid = (context->skipValidation() ||
|
||||
ValidateDeleteTextures(context, angle::EntryPoint::GLDeleteTextures, n,
|
||||
texturesPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteTextures(n, texturesPacked);
|
||||
|
|
|
@ -588,8 +588,7 @@ void GL_APIENTRY GL_DeleteQueries(GLsizei n, const GLuint *ids)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context, angle::EntryPoint::GLDeleteQueries) &&
|
||||
ValidateDeleteQueries(context, angle::EntryPoint::GLDeleteQueries, n, idsPacked)));
|
||||
ValidateDeleteQueries(context, angle::EntryPoint::GLDeleteQueries, n, idsPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteQueries(n, idsPacked);
|
||||
|
@ -613,11 +612,9 @@ void GL_APIENTRY GL_DeleteSamplers(GLsizei count, const GLuint *samplers)
|
|||
{
|
||||
const SamplerID *samplersPacked = PackParam<const SamplerID *>(samplers);
|
||||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context, angle::EntryPoint::GLDeleteSamplers) &&
|
||||
ValidateDeleteSamplers(context, angle::EntryPoint::GLDeleteSamplers, count,
|
||||
samplersPacked)));
|
||||
bool isCallValid = (context->skipValidation() ||
|
||||
ValidateDeleteSamplers(context, angle::EntryPoint::GLDeleteSamplers,
|
||||
count, samplersPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteSamplers(count, samplersPacked);
|
||||
|
@ -643,8 +640,7 @@ void GL_APIENTRY GL_DeleteSync(GLsync sync)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context, angle::EntryPoint::GLDeleteSync) &&
|
||||
ValidateDeleteSync(context, angle::EntryPoint::GLDeleteSync, syncPacked)));
|
||||
ValidateDeleteSync(context, angle::EntryPoint::GLDeleteSync, syncPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteSync(syncPacked);
|
||||
|
@ -670,10 +666,8 @@ void GL_APIENTRY GL_DeleteTransformFeedbacks(GLsizei n, const GLuint *ids)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context,
|
||||
angle::EntryPoint::GLDeleteTransformFeedbacks) &&
|
||||
ValidateDeleteTransformFeedbacks(
|
||||
context, angle::EntryPoint::GLDeleteTransformFeedbacks, n, idsPacked)));
|
||||
ValidateDeleteTransformFeedbacks(
|
||||
context, angle::EntryPoint::GLDeleteTransformFeedbacks, n, idsPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteTransformFeedbacks(n, idsPacked);
|
||||
|
@ -697,11 +691,9 @@ void GL_APIENTRY GL_DeleteVertexArrays(GLsizei n, const GLuint *arrays)
|
|||
{
|
||||
const VertexArrayID *arraysPacked = PackParam<const VertexArrayID *>(arrays);
|
||||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context, angle::EntryPoint::GLDeleteVertexArrays) &&
|
||||
ValidateDeleteVertexArrays(context, angle::EntryPoint::GLDeleteVertexArrays, n,
|
||||
arraysPacked)));
|
||||
bool isCallValid = (context->skipValidation() ||
|
||||
ValidateDeleteVertexArrays(
|
||||
context, angle::EntryPoint::GLDeleteVertexArrays, n, arraysPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteVertexArrays(n, arraysPacked);
|
||||
|
|
|
@ -203,10 +203,8 @@ void GL_APIENTRY GL_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context,
|
||||
angle::EntryPoint::GLDeleteProgramPipelines) &&
|
||||
ValidateDeleteProgramPipelines(context, angle::EntryPoint::GLDeleteProgramPipelines,
|
||||
n, pipelinesPacked)));
|
||||
ValidateDeleteProgramPipelines(context, angle::EntryPoint::GLDeleteProgramPipelines, n,
|
||||
pipelinesPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteProgramPipelines(n, pipelinesPacked);
|
||||
|
|
|
@ -72,12 +72,9 @@ void GL_APIENTRY GL_DeletePerfMonitorsAMD(GLsizei n, GLuint *monitors)
|
|||
if (context)
|
||||
{
|
||||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context,
|
||||
angle::EntryPoint::GLDeletePerfMonitorsAMD) &&
|
||||
ValidateDeletePerfMonitorsAMD(context, angle::EntryPoint::GLDeletePerfMonitorsAMD, n,
|
||||
monitors)));
|
||||
bool isCallValid = (context->skipValidation() ||
|
||||
ValidateDeletePerfMonitorsAMD(
|
||||
context, angle::EntryPoint::GLDeletePerfMonitorsAMD, n, monitors));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deletePerfMonitors(n, monitors);
|
||||
|
@ -5565,11 +5562,9 @@ void GL_APIENTRY GL_DeleteQueriesEXT(GLsizei n, const GLuint *ids)
|
|||
{
|
||||
const QueryID *idsPacked = PackParam<const QueryID *>(ids);
|
||||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context, angle::EntryPoint::GLDeleteQueriesEXT) &&
|
||||
ValidateDeleteQueriesEXT(context, angle::EntryPoint::GLDeleteQueriesEXT, n,
|
||||
idsPacked)));
|
||||
bool isCallValid = (context->skipValidation() ||
|
||||
ValidateDeleteQueriesEXT(context, angle::EntryPoint::GLDeleteQueriesEXT,
|
||||
n, idsPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteQueries(n, idsPacked);
|
||||
|
@ -6629,10 +6624,8 @@ void GL_APIENTRY GL_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObject
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context,
|
||||
angle::EntryPoint::GLDeleteMemoryObjectsEXT) &&
|
||||
ValidateDeleteMemoryObjectsEXT(context, angle::EntryPoint::GLDeleteMemoryObjectsEXT,
|
||||
n, memoryObjectsPacked)));
|
||||
ValidateDeleteMemoryObjectsEXT(context, angle::EntryPoint::GLDeleteMemoryObjectsEXT, n,
|
||||
memoryObjectsPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteMemoryObjects(n, memoryObjectsPacked);
|
||||
|
@ -7402,10 +7395,8 @@ void GL_APIENTRY GL_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context,
|
||||
angle::EntryPoint::GLDeleteSemaphoresEXT) &&
|
||||
ValidateDeleteSemaphoresEXT(context, angle::EntryPoint::GLDeleteSemaphoresEXT, n,
|
||||
semaphoresPacked)));
|
||||
ValidateDeleteSemaphoresEXT(context, angle::EntryPoint::GLDeleteSemaphoresEXT, n,
|
||||
semaphoresPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteSemaphores(n, semaphoresPacked);
|
||||
|
@ -7770,10 +7761,8 @@ void GL_APIENTRY GL_DeleteProgramPipelinesEXT(GLsizei n, const GLuint *pipelines
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context,
|
||||
angle::EntryPoint::GLDeleteProgramPipelinesEXT) &&
|
||||
ValidateDeleteProgramPipelinesEXT(
|
||||
context, angle::EntryPoint::GLDeleteProgramPipelinesEXT, n, pipelinesPacked)));
|
||||
ValidateDeleteProgramPipelinesEXT(
|
||||
context, angle::EntryPoint::GLDeleteProgramPipelinesEXT, n, pipelinesPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteProgramPipelines(n, pipelinesPacked);
|
||||
|
@ -10151,9 +10140,7 @@ void GL_APIENTRY GL_DeleteFencesNV(GLsizei n, const GLuint *fences)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context, angle::EntryPoint::GLDeleteFencesNV) &&
|
||||
ValidateDeleteFencesNV(context, angle::EntryPoint::GLDeleteFencesNV, n,
|
||||
fencesPacked)));
|
||||
ValidateDeleteFencesNV(context, angle::EntryPoint::GLDeleteFencesNV, n, fencesPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteFencesNV(n, fencesPacked);
|
||||
|
@ -11220,10 +11207,8 @@ void GL_APIENTRY GL_DeleteFramebuffersOES(GLsizei n, const GLuint *framebuffers)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context,
|
||||
angle::EntryPoint::GLDeleteFramebuffersOES) &&
|
||||
ValidateDeleteFramebuffersOES(context, angle::EntryPoint::GLDeleteFramebuffersOES, n,
|
||||
framebuffersPacked)));
|
||||
ValidateDeleteFramebuffersOES(context, angle::EntryPoint::GLDeleteFramebuffersOES, n,
|
||||
framebuffersPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteFramebuffers(n, framebuffersPacked);
|
||||
|
@ -11251,10 +11236,8 @@ void GL_APIENTRY GL_DeleteRenderbuffersOES(GLsizei n, const GLuint *renderbuffer
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context,
|
||||
angle::EntryPoint::GLDeleteRenderbuffersOES) &&
|
||||
ValidateDeleteRenderbuffersOES(context, angle::EntryPoint::GLDeleteRenderbuffersOES,
|
||||
n, renderbuffersPacked)));
|
||||
ValidateDeleteRenderbuffersOES(context, angle::EntryPoint::GLDeleteRenderbuffersOES, n,
|
||||
renderbuffersPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteRenderbuffers(n, renderbuffersPacked);
|
||||
|
@ -12974,10 +12957,8 @@ void GL_APIENTRY GL_DeleteVertexArraysOES(GLsizei n, const GLuint *arrays)
|
|||
SCOPED_SHARE_CONTEXT_LOCK(context);
|
||||
bool isCallValid =
|
||||
(context->skipValidation() ||
|
||||
(ValidatePixelLocalStorageInactive(context,
|
||||
angle::EntryPoint::GLDeleteVertexArraysOES) &&
|
||||
ValidateDeleteVertexArraysOES(context, angle::EntryPoint::GLDeleteVertexArraysOES, n,
|
||||
arraysPacked)));
|
||||
ValidateDeleteVertexArraysOES(context, angle::EntryPoint::GLDeleteVertexArraysOES, n,
|
||||
arraysPacked));
|
||||
if (isCallValid)
|
||||
{
|
||||
context->deleteVertexArrays(n, arraysPacked);
|
||||
|
|
|
@ -12,6 +12,90 @@
|
|||
|
||||
using namespace angle;
|
||||
|
||||
#define ASSERT_GL_INTEGER(pname, expected) \
|
||||
{ \
|
||||
GLint value; \
|
||||
glGetIntegerv(pname, &value); \
|
||||
ASSERT_EQ(value, GLint(expected)); \
|
||||
}
|
||||
|
||||
#define EXPECT_GL_INTEGER(pname, expected) \
|
||||
{ \
|
||||
GLint value; \
|
||||
glGetIntegerv(pname, &value); \
|
||||
EXPECT_EQ(value, GLint(expected)); \
|
||||
}
|
||||
|
||||
#define EXPECT_PLS_INTEGER(plane, pname, expected) \
|
||||
{ \
|
||||
GLint value = 0xbaadc0de; \
|
||||
glGetFramebufferPixelLocalStorageParameterivRobustANGLE(plane, pname, 1, nullptr, &value); \
|
||||
EXPECT_EQ(value, GLint(expected)); \
|
||||
value = 0xbaadc0de; \
|
||||
glGetFramebufferPixelLocalStorageParameterivANGLE(plane, pname, &value); \
|
||||
EXPECT_EQ(value, GLint(expected)); \
|
||||
}
|
||||
|
||||
#define EXPECT_GL_SINGLE_ERROR(err) \
|
||||
EXPECT_GL_ERROR(err); \
|
||||
while (GLenum nextError = glGetError()) \
|
||||
{ \
|
||||
EXPECT_EQ(nextError, GLenum(GL_NO_ERROR)); \
|
||||
}
|
||||
|
||||
#define EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(plane, rgba) \
|
||||
{ \
|
||||
std::array<GLfloat, 4> expected rgba; \
|
||||
std::array<GLfloat, 4> value; \
|
||||
value.fill(std::numeric_limits<GLfloat>::quiet_NaN()); \
|
||||
glGetFramebufferPixelLocalStorageParameterfvANGLE( \
|
||||
plane, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, value.data()); \
|
||||
EXPECT_EQ(value, expected); \
|
||||
value.fill(std::numeric_limits<GLfloat>::quiet_NaN()); \
|
||||
glGetFramebufferPixelLocalStorageParameterfvRobustANGLE( \
|
||||
plane, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 4, nullptr, value.data()); \
|
||||
EXPECT_EQ(value, expected); \
|
||||
}
|
||||
|
||||
#define EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(plane, rgba) \
|
||||
{ \
|
||||
std::array<GLint, 4> expected rgba; \
|
||||
std::array<GLint, 4> value; \
|
||||
value.fill(0xbaadc0de); \
|
||||
glGetFramebufferPixelLocalStorageParameterivANGLE( \
|
||||
plane, GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE, value.data()); \
|
||||
EXPECT_EQ(value, expected); \
|
||||
value.fill(0xbaadc0de); \
|
||||
glGetFramebufferPixelLocalStorageParameterivRobustANGLE( \
|
||||
plane, GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE, 4, nullptr, value.data()); \
|
||||
EXPECT_EQ(value, expected); \
|
||||
}
|
||||
|
||||
#define EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(plane, rgba) \
|
||||
{ \
|
||||
std::array<GLuint, 4> expected rgba; \
|
||||
std::array<GLuint, 4> value; \
|
||||
std::array<GLint, 4> valuei; \
|
||||
valuei.fill(0xbaadc0de); \
|
||||
glGetFramebufferPixelLocalStorageParameterivANGLE( \
|
||||
plane, GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE, valuei.data()); \
|
||||
memcpy(value.data(), valuei.data(), sizeof(value)); \
|
||||
EXPECT_EQ(value, expected); \
|
||||
valuei.fill(0xbaadc0de); \
|
||||
glGetFramebufferPixelLocalStorageParameterivRobustANGLE( \
|
||||
plane, GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE, 4, nullptr, valuei.data()); \
|
||||
memcpy(value.data(), valuei.data(), sizeof(value)); \
|
||||
EXPECT_EQ(value, expected); \
|
||||
}
|
||||
|
||||
#define EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(framebuffer, attachment, value) \
|
||||
{ \
|
||||
GLint attachmentName = 0xbaadc0de; \
|
||||
glGetFramebufferAttachmentParameteriv( \
|
||||
framebuffer, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attachmentName); \
|
||||
EXPECT_EQ(attachmentName, static_cast<GLint>(value)); \
|
||||
}
|
||||
|
||||
constexpr static int W = 128, H = 128;
|
||||
constexpr static std::array<float, 4> FULLSCREEN = {0, 0, W, H};
|
||||
|
||||
|
@ -56,6 +140,11 @@ class PLSTestTexture
|
|||
PLSTestTexture(GLenum internalformat) { reset(internalformat); }
|
||||
PLSTestTexture(GLenum internalformat, int w, int h) { reset(internalformat, w, h); }
|
||||
PLSTestTexture(PLSTestTexture &&that) : mID(std::exchange(that.mID, 0)) {}
|
||||
void reset()
|
||||
{
|
||||
glDeleteTextures(1, &mID);
|
||||
mID = 0;
|
||||
}
|
||||
void reset(GLenum internalformat) { reset(internalformat, W, H); }
|
||||
void reset(GLenum internalformat, int w, int h)
|
||||
{
|
||||
|
@ -610,51 +699,6 @@ TEST_P(PixelLocalStorageTest, R32)
|
|||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
#define EXPECT_PIXEL_LOCAL_CLEAR_VALUE_FLOAT(plane, rgba) \
|
||||
{ \
|
||||
std::array<GLfloat, 4> expected rgba; \
|
||||
std::array<GLfloat, 4> value; \
|
||||
value.fill(std::numeric_limits<GLfloat>::quiet_NaN()); \
|
||||
glGetFramebufferPixelLocalStorageParameterfvANGLE( \
|
||||
plane, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, value.data()); \
|
||||
EXPECT_EQ(value, expected); \
|
||||
value.fill(std::numeric_limits<GLfloat>::quiet_NaN()); \
|
||||
glGetFramebufferPixelLocalStorageParameterfvRobustANGLE( \
|
||||
plane, GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE, 4, nullptr, value.data()); \
|
||||
EXPECT_EQ(value, expected); \
|
||||
}
|
||||
|
||||
#define EXPECT_PIXEL_LOCAL_CLEAR_VALUE_INT(plane, rgba) \
|
||||
{ \
|
||||
std::array<GLint, 4> expected rgba; \
|
||||
std::array<GLint, 4> value; \
|
||||
value.fill(0xbaadc0de); \
|
||||
glGetFramebufferPixelLocalStorageParameterivANGLE( \
|
||||
plane, GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE, value.data()); \
|
||||
EXPECT_EQ(value, expected); \
|
||||
value.fill(0xbaadc0de); \
|
||||
glGetFramebufferPixelLocalStorageParameterivRobustANGLE( \
|
||||
plane, GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE, 4, nullptr, value.data()); \
|
||||
EXPECT_EQ(value, expected); \
|
||||
}
|
||||
|
||||
#define EXPECT_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT(plane, rgba) \
|
||||
{ \
|
||||
std::array<GLuint, 4> expected rgba; \
|
||||
std::array<GLuint, 4> value; \
|
||||
std::array<GLint, 4> valuei; \
|
||||
valuei.fill(0xbaadc0de); \
|
||||
glGetFramebufferPixelLocalStorageParameterivANGLE( \
|
||||
plane, GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE, valuei.data()); \
|
||||
memcpy(value.data(), valuei.data(), sizeof(value)); \
|
||||
EXPECT_EQ(value, expected); \
|
||||
valuei.fill(0xbaadc0de); \
|
||||
glGetFramebufferPixelLocalStorageParameterivRobustANGLE( \
|
||||
plane, GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE, 4, nullptr, valuei.data()); \
|
||||
memcpy(value.data(), valuei.data(), sizeof(value)); \
|
||||
EXPECT_EQ(value, expected); \
|
||||
}
|
||||
|
||||
// Check proper functioning of the clear value state.
|
||||
TEST_P(PixelLocalStorageTest, ClearValues_rgba8)
|
||||
{
|
||||
|
@ -2666,6 +2710,192 @@ TEST_P(PixelLocalStorageTest, Interrupt)
|
|||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
// Check that deleting attachments and PLS bindings on the current draw framebuffer implicitly
|
||||
// deactivates pixel local storage.
|
||||
TEST_P(PixelLocalStorageTest, DeleteAttachments_draw_framebuffer)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
|
||||
|
||||
GLFramebuffer fbo;
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
|
||||
|
||||
GLuint depthStencil;
|
||||
glGenRenderbuffers(1, &depthStencil);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, W, H);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||
depthStencil);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthStencil);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthStencil);
|
||||
|
||||
PLSTestTexture colorTex(GL_RGBA8);
|
||||
if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 0)
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorTex);
|
||||
}
|
||||
|
||||
GLuint colorRenderbuffer;
|
||||
if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 1)
|
||||
{
|
||||
glGenRenderbuffers(1, &colorRenderbuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, W, H);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
|
||||
colorRenderbuffer);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, colorRenderbuffer);
|
||||
}
|
||||
|
||||
PLSTestTexture pls0(GL_RGBA8);
|
||||
glFramebufferTexturePixelLocalStorageANGLE(0, pls0, 0, 0);
|
||||
EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, pls0);
|
||||
|
||||
PLSTestTexture pls1(GL_RGBA8);
|
||||
glFramebufferTexturePixelLocalStorageANGLE(1, pls1, 0, 0);
|
||||
EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, pls1);
|
||||
|
||||
glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
|
||||
EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
|
||||
// Deleting the depth/stencil will implicitly end pixel local storage.
|
||||
glDeleteRenderbuffers(1, &depthStencil);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 0);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 0);
|
||||
|
||||
if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 0)
|
||||
{
|
||||
// Deleting the color texture will implicitly end pixel local storage.
|
||||
glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
|
||||
colorTex.reset();
|
||||
EXPECT_GL_NO_ERROR();
|
||||
EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0);
|
||||
}
|
||||
|
||||
if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 1)
|
||||
{
|
||||
// Deleting the color renderbuffer will implicitly end pixel local storage.
|
||||
glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
|
||||
glDeleteRenderbuffers(1, &colorRenderbuffer);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, 0);
|
||||
}
|
||||
|
||||
// Pixel local storage can't be ended because it's already deactivated.
|
||||
glEndPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
|
||||
EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
|
||||
|
||||
// Deleting an inactive PLS plane will implicitly end pixel local storage.
|
||||
glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
|
||||
pls1.reset();
|
||||
EXPECT_GL_NO_ERROR();
|
||||
EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
|
||||
EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
|
||||
|
||||
// Deleting an active PLS plane will implicitly end pixel local storage.
|
||||
glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
|
||||
pls0.reset();
|
||||
EXPECT_GL_NO_ERROR();
|
||||
EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
|
||||
EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
|
||||
|
||||
// Deleting the textures deinitialized the planes.
|
||||
glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
|
||||
EXPECT_GL_SINGLE_ERROR(GL_INVALID_OPERATION);
|
||||
EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 0);
|
||||
}
|
||||
|
||||
// Check that deleting attachments and PLS bindings on the current read framebuffer does *not*
|
||||
// deactivate pixel local storage.
|
||||
TEST_P(PixelLocalStorageTest, DeleteAttachments_read_framebuffer)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_ANGLE_shader_pixel_local_storage"));
|
||||
|
||||
// Deleting attachments on the read framebuffer does not turn off PLS.
|
||||
GLFramebuffer readFBO;
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
|
||||
|
||||
GLuint depthStencil;
|
||||
glGenRenderbuffers(1, &depthStencil);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, W, H);
|
||||
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||
depthStencil);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthStencil);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthStencil);
|
||||
|
||||
PLSTestTexture colorTex(GL_RGBA8);
|
||||
if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 0)
|
||||
{
|
||||
colorTex.reset(GL_RGBA8);
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex,
|
||||
0);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorTex);
|
||||
}
|
||||
|
||||
GLuint colorRenderbuffer;
|
||||
if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 1)
|
||||
{
|
||||
glGenRenderbuffers(1, &colorRenderbuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, W, H);
|
||||
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
|
||||
colorRenderbuffer);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
|
||||
colorRenderbuffer);
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, readFBO);
|
||||
|
||||
PLSTestTexture inactivePLS0(GL_RGBA8);
|
||||
glFramebufferTexturePixelLocalStorageANGLE(0, inactivePLS0, 0, 0);
|
||||
EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, inactivePLS0);
|
||||
|
||||
PLSTestTexture inactivePLS1(GL_RGBA8);
|
||||
glFramebufferTexturePixelLocalStorageANGLE(1, inactivePLS1, 0, 0);
|
||||
EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, inactivePLS1);
|
||||
|
||||
GLFramebuffer fbo;
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
|
||||
|
||||
PLSTestTexture activePLS(GL_RGBA8);
|
||||
glFramebufferTexturePixelLocalStorageANGLE(0, activePLS, 0, 0);
|
||||
glBeginPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
|
||||
EXPECT_GL_NO_ERROR();
|
||||
EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
|
||||
|
||||
glDeleteRenderbuffers(1, &depthStencil);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 0);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 0);
|
||||
if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 0)
|
||||
{
|
||||
colorTex.reset();
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0);
|
||||
}
|
||||
|
||||
if (MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE > 1)
|
||||
{
|
||||
glDeleteRenderbuffers(1, &colorRenderbuffer);
|
||||
EXPECT_FRAMEBUFFER_ATTACHMENT_NAME(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, 0);
|
||||
}
|
||||
inactivePLS0.reset();
|
||||
inactivePLS1.reset();
|
||||
|
||||
EXPECT_GL_NO_ERROR();
|
||||
EXPECT_GL_INTEGER(GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE, 1);
|
||||
|
||||
glEndPixelLocalStorageANGLE(1, GLenumArray({GL_DONT_CARE}));
|
||||
EXPECT_GL_NO_ERROR();
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, readFBO);
|
||||
EXPECT_PLS_INTEGER(0, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
|
||||
EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, 0);
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PixelLocalStorageTest);
|
||||
#define PLATFORM(API, BACKEND) API##_##BACKEND()
|
||||
#define PLS_INSTANTIATE_RENDERING_TEST_AND(TEST, API, ...) \
|
||||
|
@ -3117,37 +3347,6 @@ class ScopedEnable
|
|||
GLenum mFeature;
|
||||
};
|
||||
|
||||
#define ASSERT_GL_INTEGER(pname, expected) \
|
||||
{ \
|
||||
GLint value; \
|
||||
glGetIntegerv(pname, &value); \
|
||||
ASSERT_EQ(value, GLint(expected)); \
|
||||
}
|
||||
|
||||
#define EXPECT_GL_INTEGER(pname, expected) \
|
||||
{ \
|
||||
GLint value; \
|
||||
glGetIntegerv(pname, &value); \
|
||||
EXPECT_EQ(value, GLint(expected)); \
|
||||
}
|
||||
|
||||
#define EXPECT_PLS_INTEGER(plane, pname, expected) \
|
||||
{ \
|
||||
GLint value = 0xbaadc0de; \
|
||||
glGetFramebufferPixelLocalStorageParameterivRobustANGLE(plane, pname, 1, nullptr, &value); \
|
||||
EXPECT_EQ(value, GLint(expected)); \
|
||||
value = 0xbaadc0de; \
|
||||
glGetFramebufferPixelLocalStorageParameterivANGLE(plane, pname, &value); \
|
||||
EXPECT_EQ(value, GLint(expected)); \
|
||||
}
|
||||
|
||||
#define EXPECT_GL_SINGLE_ERROR(err) \
|
||||
EXPECT_GL_ERROR(err); \
|
||||
while (GLenum nextError = glGetError()) \
|
||||
{ \
|
||||
EXPECT_EQ(nextError, GLenum(GL_NO_ERROR)); \
|
||||
}
|
||||
|
||||
#define EXPECT_GL_SINGLE_ERROR_MSG(msg) \
|
||||
if (mHasDebugKHR) \
|
||||
{ \
|
||||
|
@ -3313,7 +3512,7 @@ TEST_P(PixelLocalStorageValidationTest, FramebufferTexturePixelLocalStorageANGLE
|
|||
{
|
||||
// When a texture object is deleted, any pixel local storage plane to which it was bound is
|
||||
// automatically deinitialized.
|
||||
GLFramebuffer keepalive; // Keep the underlying texture alive after deleting uts ID by
|
||||
GLFramebuffer keepalive; // Keep the underlying texture alive after deleting its ID by
|
||||
// binding it to a framebuffer.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, keepalive);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
|
||||
|
@ -3339,7 +3538,7 @@ TEST_P(PixelLocalStorageValidationTest, FramebufferTexturePixelLocalStorageANGLE
|
|||
EXPECT_PLS_INTEGER(1, GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
{
|
||||
GLFramebuffer keepalive; // Keep the underlying texture alive after deleting uts ID by
|
||||
GLFramebuffer keepalive; // Keep the underlying texture alive after deleting its ID by
|
||||
// binding it to a framebuffer.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, keepalive);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
|
||||
|
@ -3488,7 +3687,7 @@ TEST_P(PixelLocalStorageValidationTest, FramebufferTexturePixelLocalStorageANGLE
|
|||
// When a texture object is deleted, any pixel local storage plane to which it was bound is
|
||||
// automatically deinitialized.
|
||||
{
|
||||
GLFramebuffer keepalive; // Keep the underlying texture alive after deleting uts ID by
|
||||
GLFramebuffer keepalive; // Keep the underlying texture alive after deleting its ID by
|
||||
// binding it to a framebuffer.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, keepalive);
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, 0);
|
||||
|
@ -3521,7 +3720,7 @@ TEST_P(PixelLocalStorageValidationTest, FramebufferTexturePixelLocalStorageANGLE
|
|||
// When a texture object is deleted, any pixel local storage plane to which it was bound is
|
||||
// automatically deinitialized.
|
||||
{
|
||||
GLFramebuffer keepalive; // Keep the underlying texture alive after deleting uts ID by
|
||||
GLFramebuffer keepalive; // Keep the underlying texture alive after deleting its ID by
|
||||
// binding it to a framebuffer.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, keepalive);
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3D, 0, 0);
|
||||
|
@ -3770,7 +3969,7 @@ TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_context_stat
|
|||
}
|
||||
|
||||
// Check that transform feedback is banned when PLS is active.
|
||||
TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_transform_feedback)
|
||||
TEST_P(PixelLocalStorageValidationTest, PLSActive_bans_transform_feedback)
|
||||
{
|
||||
GLFramebuffer fbo;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
|
@ -3823,7 +4022,7 @@ TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_transform_fe
|
|||
}
|
||||
|
||||
// Check that EXT_blend_func_extended is banned when PLS is active.
|
||||
TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_blend_extended)
|
||||
TEST_P(PixelLocalStorageValidationTest, PLSActive_bans_blend_func_extended)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_blend_func_extended"));
|
||||
|
||||
|
@ -3943,7 +4142,7 @@ TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_blend_extend
|
|||
}
|
||||
|
||||
// Check that KHR_blend_equation_advanced is banned when PLS is active.
|
||||
TEST_P(PixelLocalStorageValidationTest, BeginPixelLocalStorageANGLE_blend_advanced)
|
||||
TEST_P(PixelLocalStorageValidationTest, PLSActive_bans_blend_equation_advanced)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
|
||||
|
||||
|
@ -4870,7 +5069,6 @@ TEST_P(PixelLocalStorageValidationTest, BannedCommands)
|
|||
EXPECT_BANNED_DEFAULT_MSG(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 0, 0));
|
||||
EXPECT_BANNED_DEFAULT_MSG(glBlitFramebuffer(0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
|
||||
EXPECT_BANNED_DEFAULT_MSG(glBindFramebuffer(GL_FRAMEBUFFER, 0));
|
||||
EXPECT_BANNED_DEFAULT_MSG(glDeleteFramebuffers(1, nullptr));
|
||||
EXPECT_BANNED_DEFAULT_MSG(glDrawBuffers(0, nullptr));
|
||||
|
||||
// INVALID_OPERATION is generated by Enable(), Disable() if <cap> is not one of: CULL_FACE,
|
||||
|
@ -5858,7 +6056,7 @@ TEST_P(PixelLocalStorageCompilerTest, FragmentTestVariables)
|
|||
|
||||
// Check that the "blend_support" layout qualifiers defined in KHR_blend_equation_advanced are
|
||||
// illegal when PLS is declared.
|
||||
TEST_P(PixelLocalStorageCompilerTest, BlendFuncExtended)
|
||||
TEST_P(PixelLocalStorageCompilerTest, BlendFuncExtended_illegal_with_PLS)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_blend_func_extended"));
|
||||
|
||||
|
@ -5916,7 +6114,7 @@ TEST_P(PixelLocalStorageCompilerTest, BlendFuncExtended)
|
|||
|
||||
// Check that the "blend_support" layout qualifiers defined in KHR_blend_equation_advanced are
|
||||
// illegal when PLS is declared.
|
||||
TEST_P(PixelLocalStorageCompilerTest, BlendEquationAdvanced)
|
||||
TEST_P(PixelLocalStorageCompilerTest, BlendEquationAdvanced_illegal_with_PLS)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче