Commit 32f0dd6a by Geoff Lang Committed by Commit Bot

Add Queries and Setters for resource initialization state.

There are cases where we know that the next draw operation will fully initialize a texture/renderbuffer and we can save the robust resource init cost. Default all resource init state to Initialized, any redefinition will set it back to MayNeedInit. After setting an individual texture image to initialized, check if all images are now initialized and update the TextureState::mInitState to match. The cost of this check is only performed after initializing an image and allows future init checks to be faster. Bug: chromium:1132514 Change-Id: Ia23664ae162559d1614f1eb5643e24a491d87f7f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2475456 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent ed876984
...@@ -4,7 +4,7 @@ Name ...@@ -4,7 +4,7 @@ Name
Name Strings Name Strings
GL_ANGLE_robust_resource_intialization GL_ANGLE_robust_resource_initialization
Contributors Contributors
...@@ -59,6 +59,14 @@ New Tokens ...@@ -59,6 +59,14 @@ New Tokens
ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93A7 ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93A7
Accepted by the <pname> parameter of GetTexParameteriv,
GetTexParameterfv, GetTexLevelParameteriv, GetTexLevelParameterfv,
GetRenderbufferParameteriv, GetBufferParameteriv and
GetBufferParameteri64v:
RESOURCE_INITIALIZED_ANGLE 0x969F
Additions to Chapter 6 of the OpenGL ES 3.1 Specification (Buffer Additions to Chapter 6 of the OpenGL ES 3.1 Specification (Buffer
Objects) Objects)
...@@ -70,6 +78,12 @@ Objects) ...@@ -70,6 +78,12 @@ Objects)
Otherwise, the contents of the buffer object's data store are Otherwise, the contents of the buffer object's data store are
undefined. undefined.
Add to Table 6.2: Buffer object parameters and their values:
Name Type Initial Value Legal Values
---- ---- ------------- ------------
RESOURCE_INITIALIZED_ANGLE boolean TRUE TRUE, FALSE
Additions to Chapter 8 of the OpenGL ES 3.1 Specification (Textures and Additions to Chapter 8 of the OpenGL ES 3.1 Specification (Textures and
Samplers) Samplers)
...@@ -107,6 +121,17 @@ Samplers) ...@@ -107,6 +121,17 @@ Samplers)
as for a call to the appropriate TexSubImage* call for <target>. as for a call to the appropriate TexSubImage* call for <target>.
Otherwise, the contents of texels are undefined. Otherwise, the contents of texels are undefined.
Add to Table 8.20: Texture parameters and their values:
Name Type Legal Values
---- ---- ------------
RESOURCE_INITIALIZED_ANGLE boolean TRUE, FALSE
Add to the end of section 8.10.3 "Texture Level Parameter Queries":
Queries of pname RESOURCE_INITIALIZED_ANGLE return the initialization
state of the image.
Additions to Chapter 9 of the OpenGL ES 3.1 Specification (Framebuffers Additions to Chapter 9 of the OpenGL ES 3.1 Specification (Framebuffers
and Framebuffer Objects) and Framebuffer Objects)
...@@ -120,6 +145,11 @@ and Framebuffer Objects) ...@@ -120,6 +145,11 @@ and Framebuffer Objects)
channel of each sample; otherwise, the contents of the data store channel of each sample; otherwise, the contents of the data store
are undefined. are undefined.
Add to the end of section 9.2.6 "Renderbuffer Object Queries":
If pname is RESOURCE_INITIALIZED_ANGLE then params will contain the
initialization state of the renderbuffer currently bound to target.
Interactions with EGL_ANGLE_create_context_robust_resource_initialization Interactions with EGL_ANGLE_create_context_robust_resource_initialization
If the EGL window-system binding API is used to create a context, If the EGL window-system binding API is used to create a context,
...@@ -133,6 +163,40 @@ Interactions with EGL_ANGLE_create_context_robust_resource_initialization ...@@ -133,6 +163,40 @@ Interactions with EGL_ANGLE_create_context_robust_resource_initialization
query will return GL_TRUE as described above in section 2.6.1.1. query will return GL_TRUE as described above in section 2.6.1.1.
Otherwise queries will return GL_FALSE. Otherwise queries will return GL_FALSE.
New State
(add to Table 20.4: Buffer Object State)
Initial
Get Value Type Get Command Value Description Sec.
---------------------- ---- ------------------- ------ --------------------------- ------
RESOURCE_INITIALIZED_ANGLE B GetBufferParameteriv TRUE Buffer data has been 6.6
initialized
(add to Table 20.9: Textures (state per texture object))
Initial
Get Value Type Get Command Value Description Sec.
---------------------- ---- ------------------- ------ --------------------------- ------
RESOURCE_INITIALIZED_ANGLE B GetTexParameteriv TRUE All specified images have 8.10.2
been initialized
(add to Table 20.10 Textures (state per texture image))
Initial
Get Value Type Get Command Value Description Sec.
---------------------- ---- ------------------- ------ --------------------------- ------
RESOURCE_INITIALIZED_ANGLE B GetTexLevelParameteriv TRUE Image data has been 8.10.3
initialized
(add to Table 20.16: Renderbuffer (state per renderbuffer object))
Initial
Get Value Type Get Command Value Description Sec.
---------------------- ---- ------------------- ------ --------------------------- ------
RESOURCE_INITIALIZED_ANGLE B GetRenderbufferParameteriv TRUE Renderbuffer data has been 9.2.6
initialized
Issues Issues
None None
...@@ -142,3 +206,4 @@ Revision History ...@@ -142,3 +206,4 @@ Revision History
Version 1, 2015/01/07 - first draft. Version 1, 2015/01/07 - first draft.
Version 2, 2017/03/07 - fixed EGL naming and added IsEnabled. Version 2, 2017/03/07 - fixed EGL naming and added IsEnabled.
Version 3, 2017/09/19 - name cleanup. Version 3, 2017/09/19 - name cleanup.
Version 4, 2020/10/12 - Add RESOURCE_INITIALIZED_ANGLE queries.
...@@ -31,6 +31,7 @@ GL_APICALL void GL_APIENTRY glRequestExtensionANGLE (const GLchar *name); ...@@ -31,6 +31,7 @@ GL_APICALL void GL_APIENTRY glRequestExtensionANGLE (const GLchar *name);
#ifndef GL_ANGLE_robust_resource_initialization #ifndef GL_ANGLE_robust_resource_initialization
#define GL_ANGLE_robust_resource_initialization 1 #define GL_ANGLE_robust_resource_initialization 1
#define GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93AB #define GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93AB
#define GL_RESOURCE_INITIALIZED_ANGLE 0x969F
#endif /* GL_ANGLE_robust_resource_initialization */ #endif /* GL_ANGLE_robust_resource_initialization */
#ifndef GL_ANGLE_provoking_vertex #ifndef GL_ANGLE_provoking_vertex
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "libANGLE/IndexRangeCache.h" #include "libANGLE/IndexRangeCache.h"
#include "libANGLE/Observer.h" #include "libANGLE/Observer.h"
#include "libANGLE/RefCountObject.h" #include "libANGLE/RefCountObject.h"
#include "libANGLE/angletypes.h"
namespace rx namespace rx
{ {
...@@ -135,6 +136,9 @@ class Buffer final : public RefCountObject<BufferID>, ...@@ -135,6 +136,9 @@ class Buffer final : public RefCountObject<BufferID>,
GLboolean isImmutable() const { return mState.mImmutable; } GLboolean isImmutable() const { return mState.mImmutable; }
GLbitfield getStorageExtUsageFlags() const { return mState.mStorageExtUsageFlags; } GLbitfield getStorageExtUsageFlags() const { return mState.mStorageExtUsageFlags; }
// Buffers are always initialized immediately when allocated
InitState initState() const { return InitState::Initialized; }
rx::BufferImpl *getImplementation() const { return mImpl; } rx::BufferImpl *getImplementation() const { return mImpl; }
ANGLE_INLINE bool isBound() const { return mState.mBindingCount > 0; } ANGLE_INLINE bool isBound() const { return mState.mBindingCount > 0; }
......
...@@ -428,6 +428,7 @@ MSG kRenderableInternalFormat = "SizedInternalformat must be color-renderable, d ...@@ -428,6 +428,7 @@ MSG kRenderableInternalFormat = "SizedInternalformat must be color-renderable, d
MSG kRenderbufferNotBound = "A renderbuffer must be bound."; MSG kRenderbufferNotBound = "A renderbuffer must be bound.";
MSG kResourceMaxRenderbufferSize = "Desired resource size is greater than max renderbuffer size."; MSG kResourceMaxRenderbufferSize = "Desired resource size is greater than max renderbuffer size.";
MSG kResourceMaxTextureSize = "Desired resource size is greater than max texture size."; MSG kResourceMaxTextureSize = "Desired resource size is greater than max texture size.";
MSG kRobustResourceInitializationExtensionRequired = "EGL_ANGLE_robust_resource_initialization not enabled.";
MSG kSamplerFormatMismatch = "Mismatch between texture format and sampler type (signed/unsigned/float/shadow)."; MSG kSamplerFormatMismatch = "Mismatch between texture format and sampler type (signed/unsigned/float/shadow).";
MSG kSamplerUniformValueOutOfRange = "Sampler uniform value out of range."; MSG kSamplerUniformValueOutOfRange = "Sampler uniform value out of range.";
MSG kSamplesOutOfRange = "Samples must not be greater than maximum supported value for the format."; MSG kSamplesOutOfRange = "Samples must not be greater than maximum supported value for the format.";
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
#include "libANGLE/ImageIndex.h" #include "libANGLE/ImageIndex.h"
#include "libANGLE/Observer.h" #include "libANGLE/Observer.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" #include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
...@@ -43,12 +44,6 @@ class FramebufferAttachmentObject; ...@@ -43,12 +44,6 @@ class FramebufferAttachmentObject;
class Renderbuffer; class Renderbuffer;
class Texture; class Texture;
enum class InitState
{
MayNeedInit,
Initialized,
};
// FramebufferAttachment implements a GL framebuffer attachment. // FramebufferAttachment implements a GL framebuffer attachment.
// Attachments are "light" containers, which store pointers to ref-counted GL objects. // Attachments are "light" containers, which store pointers to ref-counted GL objects.
// We support GL texture (2D/3D/Cube/2D array) and renderbuffer object attachments. // We support GL texture (2D/3D/Cube/2D array) and renderbuffer object attachments.
......
...@@ -51,7 +51,7 @@ class ImageIndex ...@@ -51,7 +51,7 @@ class ImageIndex
static ImageIndex Make2DArray(GLint levelIndex, GLint layerIndex = kEntireLevel); static ImageIndex Make2DArray(GLint levelIndex, GLint layerIndex = kEntireLevel);
static ImageIndex Make2DArrayRange(GLint levelIndex, GLint layerIndex, GLint layerCount); static ImageIndex Make2DArrayRange(GLint levelIndex, GLint layerIndex, GLint layerCount);
static ImageIndex Make3D(GLint levelIndex, GLint layerIndex = kEntireLevel); static ImageIndex Make3D(GLint levelIndex, GLint layerIndex = kEntireLevel);
static ImageIndex MakeFromTarget(TextureTarget target, GLint levelIndex, GLint depth); static ImageIndex MakeFromTarget(TextureTarget target, GLint levelIndex, GLint depth = 0);
static ImageIndex MakeFromType(TextureType type, static ImageIndex MakeFromType(TextureType type,
GLint levelIndex, GLint levelIndex,
GLint layerIndex = kEntireLevel, GLint layerIndex = kEntireLevel,
......
...@@ -34,7 +34,7 @@ RenderbufferState::RenderbufferState() ...@@ -34,7 +34,7 @@ RenderbufferState::RenderbufferState()
mFormat(GL_RGBA4), mFormat(GL_RGBA4),
mSamples(0), mSamples(0),
mMultisamplingMode(MultisamplingMode::Regular), mMultisamplingMode(MultisamplingMode::Regular),
mInitState(InitState::MayNeedInit) mInitState(InitState::Initialized)
{} {}
RenderbufferState::~RenderbufferState() {} RenderbufferState::~RenderbufferState() {}
......
...@@ -134,7 +134,7 @@ TextureState::TextureState(TextureType type) ...@@ -134,7 +134,7 @@ TextureState::TextureState(TextureType type)
mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) * (type == TextureType::CubeMap ? 6 : 1)), mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) * (type == TextureType::CubeMap ? 6 : 1)),
mCropRect(0, 0, 0, 0), mCropRect(0, 0, 0, 0),
mGenerateMipmapHint(GL_FALSE), mGenerateMipmapHint(GL_FALSE),
mInitState(InitState::MayNeedInit), mInitState(InitState::Initialized),
mCachedSamplerFormat(SamplerFormat::InvalidEnum), mCachedSamplerFormat(SamplerFormat::InvalidEnum),
mCachedSamplerCompareMode(GL_NONE), mCachedSamplerCompareMode(GL_NONE),
mCachedSamplerFormatValid(false) mCachedSamplerFormatValid(false)
...@@ -554,7 +554,7 @@ GLuint TextureState::getEnabledLevelCount() const ...@@ -554,7 +554,7 @@ GLuint TextureState::getEnabledLevelCount() const
} }
ImageDesc::ImageDesc() ImageDesc::ImageDesc()
: ImageDesc(Extents(0, 0, 0), Format::Invalid(), 0, GL_TRUE, InitState::MayNeedInit) : ImageDesc(Extents(0, 0, 0), Format::Invalid(), 0, GL_TRUE, InitState::Initialized)
{} {}
ImageDesc::ImageDesc(const Extents &size, const Format &format, const InitState initState) ImageDesc::ImageDesc(const Extents &size, const Format &format, const InitState initState)
...@@ -601,6 +601,27 @@ void TextureState::setImageDesc(TextureTarget target, size_t level, const ImageD ...@@ -601,6 +601,27 @@ void TextureState::setImageDesc(TextureTarget target, size_t level, const ImageD
{ {
mInitState = InitState::MayNeedInit; mInitState = InitState::MayNeedInit;
} }
else
{
// Scan for any uninitialized images. If there are none, set the init state of the entire
// texture to initialized. The cost of the scan is only paid after doing image
// initialization which is already very expensive.
bool allImagesInitialized = true;
for (const ImageDesc &desc : mImageDescs)
{
if (desc.initState == InitState::MayNeedInit)
{
allImagesInitialized = false;
break;
}
}
if (allImagesInitialized)
{
mInitState = InitState::Initialized;
}
}
} }
// Note that an ImageIndex that represents an entire level of a cube map corresponds to 6 // Note that an ImageIndex that represents an entire level of a cube map corresponds to 6
...@@ -1951,6 +1972,19 @@ void Texture::setInitState(const ImageIndex &imageIndex, InitState initState) ...@@ -1951,6 +1972,19 @@ void Texture::setInitState(const ImageIndex &imageIndex, InitState initState)
} }
} }
void Texture::setInitState(InitState initState)
{
for (ImageDesc &imageDesc : mState.mImageDescs)
{
// Only modifiy defined images, undefined images will remain in the initialized state
if (!imageDesc.size.empty())
{
imageDesc.initState = initState;
}
}
mState.mInitState = initState;
}
bool Texture::doesSubImageNeedInit(const Context *context, bool Texture::doesSubImageNeedInit(const Context *context,
const ImageIndex &imageIndex, const ImageIndex &imageIndex,
const Box &area) const const Box &area) const
......
...@@ -503,6 +503,7 @@ class Texture final : public RefCountObject<TextureID>, ...@@ -503,6 +503,7 @@ class Texture final : public RefCountObject<TextureID>,
InitState initState(const ImageIndex &imageIndex) const override; InitState initState(const ImageIndex &imageIndex) const override;
InitState initState() const { return mState.mInitState; } InitState initState() const { return mState.mInitState; }
void setInitState(const ImageIndex &imageIndex, InitState initState) override; void setInitState(const ImageIndex &imageIndex, InitState initState) override;
void setInitState(InitState initState);
bool isBoundToFramebuffer(rx::Serial framebufferSerial) const bool isBoundToFramebuffer(rx::Serial framebufferSerial) const
{ {
......
...@@ -43,6 +43,12 @@ enum class Command ...@@ -43,6 +43,12 @@ enum class Command
Other Other
}; };
enum class InitState
{
MayNeedInit,
Initialized,
};
struct Rectangle struct Rectangle
{ {
Rectangle() : x(0), y(0), width(0), height(0) {} Rectangle() : x(0), y(0), width(0), height(0) {}
......
...@@ -212,6 +212,11 @@ void QueryTexLevelParameterBase(const Texture *texture, ...@@ -212,6 +212,11 @@ void QueryTexLevelParameterBase(const Texture *texture,
*params = *params =
CastFromStateValue<ParamType>(pname, texture->getLevelMemorySize(target, level)); CastFromStateValue<ParamType>(pname, texture->getLevelMemorySize(target, level));
break; break;
case GL_RESOURCE_INITIALIZED_ANGLE:
*params = CastFromGLintStateValue<ParamType>(
pname, texture->initState(ImageIndex::MakeFromTarget(target, level)) ==
InitState::Initialized);
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -344,6 +349,10 @@ void QueryTexParameterBase(const Context *context, ...@@ -344,6 +349,10 @@ void QueryTexParameterBase(const Context *context,
*params = *params =
CastFromGLintStateValue<ParamType>(pname, GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE); CastFromGLintStateValue<ParamType>(pname, GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE);
break; break;
case GL_RESOURCE_INITIALIZED_ANGLE:
*params = CastFromGLintStateValue<ParamType>(
pname, texture->initState() == InitState::Initialized);
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -450,6 +459,10 @@ void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ...@@ -450,6 +459,10 @@ void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const
case GL_TEXTURE_BORDER_COLOR: case GL_TEXTURE_BORDER_COLOR:
texture->setBorderColor(context, ConvertToColor<isPureInteger>(params)); texture->setBorderColor(context, ConvertToColor<isPureInteger>(params));
break; break;
case GL_RESOURCE_INITIALIZED_ANGLE:
texture->setInitState(ConvertToBool(params[0]) ? InitState::Initialized
: InitState::MayNeedInit);
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -646,6 +659,10 @@ void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *par ...@@ -646,6 +659,10 @@ void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *par
case GL_BUFFER_STORAGE_FLAGS_EXT: case GL_BUFFER_STORAGE_FLAGS_EXT:
*params = CastFromGLintStateValue<ParamType>(pname, buffer->getStorageExtUsageFlags()); *params = CastFromGLintStateValue<ParamType>(pname, buffer->getStorageExtUsageFlags());
break; break;
case GL_RESOURCE_INITIALIZED_ANGLE:
*params = CastFromStateValue<ParamType>(
pname, ConvertToGLBoolean(buffer->initState() == InitState::Initialized));
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1377,6 +1394,9 @@ void QueryRenderbufferiv(const Context *context, ...@@ -1377,6 +1394,9 @@ void QueryRenderbufferiv(const Context *context,
case GL_IMPLEMENTATION_COLOR_READ_TYPE: case GL_IMPLEMENTATION_COLOR_READ_TYPE:
*params = static_cast<GLint>(renderbuffer->getImplementationColorReadType(context)); *params = static_cast<GLint>(renderbuffer->getImplementationColorReadType(context));
break; break;
case GL_RESOURCE_INITIALIZED_ANGLE:
*params = (renderbuffer->initState(ImageIndex()) == InitState::Initialized);
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
......
...@@ -5293,6 +5293,15 @@ bool ValidateGetBufferParameterBase(const Context *context, ...@@ -5293,6 +5293,15 @@ bool ValidateGetBufferParameterBase(const Context *context,
} }
break; break;
case GL_RESOURCE_INITIALIZED_ANGLE:
if (!context->getExtensions().robustResourceInitialization)
{
context->validationError(GL_INVALID_ENUM,
kRobustResourceInitializationExtensionRequired);
return false;
}
break;
default: default:
context->validationError(GL_INVALID_ENUM, kEnumNotSupported); context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
return false; return false;
...@@ -5368,6 +5377,15 @@ bool ValidateGetRenderbufferParameterivBase(const Context *context, ...@@ -5368,6 +5377,15 @@ bool ValidateGetRenderbufferParameterivBase(const Context *context,
} }
break; break;
case GL_RESOURCE_INITIALIZED_ANGLE:
if (!context->getExtensions().robustResourceInitialization)
{
context->validationError(GL_INVALID_ENUM,
kRobustResourceInitializationExtensionRequired);
return false;
}
break;
default: default:
context->validationError(GL_INVALID_ENUM, kEnumNotSupported); context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
return false; return false;
...@@ -5595,6 +5613,15 @@ bool ValidateGetTexParameterBase(const Context *context, ...@@ -5595,6 +5613,15 @@ bool ValidateGetTexParameterBase(const Context *context,
} }
break; break;
case GL_RESOURCE_INITIALIZED_ANGLE:
if (!context->getExtensions().robustResourceInitialization)
{
context->validationError(GL_INVALID_ENUM,
kRobustResourceInitializationExtensionRequired);
return false;
}
break;
default: default:
context->validationError(GL_INVALID_ENUM, kEnumNotSupported); context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
return false; return false;
...@@ -6288,6 +6315,16 @@ bool ValidateTexParameterBase(const Context *context, ...@@ -6288,6 +6315,16 @@ bool ValidateTexParameterBase(const Context *context,
} }
break; break;
case GL_RESOURCE_INITIALIZED_ANGLE:
if (!context->getExtensions().robustResourceInitialization)
{
context->validationError(GL_INVALID_ENUM,
kRobustResourceInitializationExtensionRequired);
return false;
}
break;
default: default:
context->validationError(GL_INVALID_ENUM, kEnumNotSupported); context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
return false; return false;
...@@ -6811,7 +6848,6 @@ bool ValidateGetTexLevelParameterBase(const Context *context, ...@@ -6811,7 +6848,6 @@ bool ValidateGetTexLevelParameterBase(const Context *context,
case GL_TEXTURE_BLUE_TYPE: case GL_TEXTURE_BLUE_TYPE:
case GL_TEXTURE_ALPHA_TYPE: case GL_TEXTURE_ALPHA_TYPE:
case GL_TEXTURE_DEPTH_TYPE: case GL_TEXTURE_DEPTH_TYPE:
break;
case GL_TEXTURE_RED_SIZE: case GL_TEXTURE_RED_SIZE:
case GL_TEXTURE_GREEN_SIZE: case GL_TEXTURE_GREEN_SIZE:
case GL_TEXTURE_BLUE_SIZE: case GL_TEXTURE_BLUE_SIZE:
...@@ -6819,17 +6855,24 @@ bool ValidateGetTexLevelParameterBase(const Context *context, ...@@ -6819,17 +6855,24 @@ bool ValidateGetTexLevelParameterBase(const Context *context,
case GL_TEXTURE_DEPTH_SIZE: case GL_TEXTURE_DEPTH_SIZE:
case GL_TEXTURE_STENCIL_SIZE: case GL_TEXTURE_STENCIL_SIZE:
case GL_TEXTURE_SHARED_SIZE: case GL_TEXTURE_SHARED_SIZE:
break;
case GL_TEXTURE_INTERNAL_FORMAT: case GL_TEXTURE_INTERNAL_FORMAT:
case GL_TEXTURE_WIDTH: case GL_TEXTURE_WIDTH:
case GL_TEXTURE_HEIGHT: case GL_TEXTURE_HEIGHT:
case GL_TEXTURE_DEPTH: case GL_TEXTURE_DEPTH:
break;
case GL_TEXTURE_SAMPLES: case GL_TEXTURE_SAMPLES:
case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
break;
case GL_TEXTURE_COMPRESSED: case GL_TEXTURE_COMPRESSED:
break; break;
case GL_RESOURCE_INITIALIZED_ANGLE:
if (!context->getExtensions().robustResourceInitialization)
{
context->validationError(GL_INVALID_ENUM,
kRobustResourceInitializationExtensionRequired);
return false;
}
break;
default: default:
context->validationError(GL_INVALID_ENUM, kInvalidPname); context->validationError(GL_INVALID_ENUM, kInvalidPname);
return false; return false;
......
...@@ -331,6 +331,30 @@ TEST_P(RobustResourceInitTest, Queries) ...@@ -331,6 +331,30 @@ TEST_P(RobustResourceInitTest, Queries)
EXPECT_GL_TRUE(glIsEnabled(GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE)); EXPECT_GL_TRUE(glIsEnabled(GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE));
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
// Can't verify the init state after glTexImage2D, the implementation is free to initialize
// any time before the resource is read.
{
// Force to uninitialized
glTexParameteri(GL_TEXTURE_2D, GL_RESOURCE_INITIALIZED_ANGLE, GL_FALSE);
GLint initState = 0;
glGetTexParameteriv(GL_TEXTURE_2D, GL_RESOURCE_INITIALIZED_ANGLE, &initState);
EXPECT_GL_FALSE(initState);
}
{
// Force to initialized
glTexParameteri(GL_TEXTURE_2D, GL_RESOURCE_INITIALIZED_ANGLE, GL_TRUE);
GLint initState = 0;
glGetTexParameteriv(GL_TEXTURE_2D, GL_RESOURCE_INITIALIZED_ANGLE, &initState);
EXPECT_GL_TRUE(initState);
}
} }
else else
{ {
...@@ -384,6 +408,11 @@ TEST_P(RobustResourceInitTest, BufferData) ...@@ -384,6 +408,11 @@ TEST_P(RobustResourceInitTest, BufferData)
glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
actual.data()); actual.data());
EXPECT_EQ(expected, actual); EXPECT_EQ(expected, actual);
GLint initState = 0;
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_RESOURCE_INITIALIZED_ANGLE, &initState);
EXPECT_GL_TRUE(initState);
} }
// Regression test for passing a zero size init buffer with the extension. // Regression test for passing a zero size init buffer with the extension.
...@@ -973,6 +1002,11 @@ TEST_P(RobustResourceInitTest, Texture) ...@@ -973,6 +1002,11 @@ TEST_P(RobustResourceInitTest, Texture)
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
checkFramebufferNonZeroPixels(0, 0, 0, 0, GLColor::black); checkFramebufferNonZeroPixels(0, 0, 0, 0, GLColor::black);
GLint initState = 0;
glBindTexture(GL_TEXTURE_2D, texture);
glGetTexParameteriv(GL_TEXTURE_2D, GL_RESOURCE_INITIALIZED_ANGLE, &initState);
EXPECT_GL_TRUE(initState);
} }
// Test that uploading texture data with an unpack state set correctly initializes the texture and // Test that uploading texture data with an unpack state set correctly initializes the texture and
...@@ -1040,6 +1074,20 @@ void RobustResourceInitTestES3::testIntegerTextureInit(const char *samplerType, ...@@ -1040,6 +1074,20 @@ void RobustResourceInitTestES3::testIntegerTextureInit(const char *samplerType,
// Blit from the texture to the framebuffer. // Blit from the texture to the framebuffer.
drawQuad(program, "position", 0.5f); drawQuad(program, "position", 0.5f);
// Verify both textures have been initialized
{
GLint initState = 0;
glBindTexture(GL_TEXTURE_2D, framebufferTexture);
glGetTexParameteriv(GL_TEXTURE_2D, GL_RESOURCE_INITIALIZED_ANGLE, &initState);
EXPECT_GL_TRUE(initState);
}
{
GLint initState = 0;
glBindTexture(GL_TEXTURE_2D, texture);
glGetTexParameteriv(GL_TEXTURE_2D, GL_RESOURCE_INITIALIZED_ANGLE, &initState);
EXPECT_GL_TRUE(initState);
}
std::array<PixelT, kWidth * kHeight * 4> data; std::array<PixelT, kWidth * kHeight * 4> data;
glReadPixels(0, 0, kWidth, kHeight, GL_RGBA_INTEGER, type, data.data()); glReadPixels(0, 0, kWidth, kHeight, GL_RGBA_INTEGER, type, data.data());
...@@ -1881,6 +1929,10 @@ TEST_P(RobustResourceInitTest, ClearWithScissor) ...@@ -1881,6 +1929,10 @@ TEST_P(RobustResourceInitTest, ClearWithScissor)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::transparentBlack); EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::transparentBlack);
GLint initState = 0;
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RESOURCE_INITIALIZED_ANGLE, &initState);
EXPECT_GL_TRUE(initState);
} }
// Tests that surfaces are initialized when they are created // Tests that surfaces are initialized when they are created
......
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