Commit 79b91407 by Geoff Lang Committed by Commit Bot

Add an extension for querying esimated GPU memory size of resources.

BUG=892288 Change-Id: I56fc3ab00c06d711e1a21eb1ad4b2224126730dc Reviewed-on: https://chromium-review.googlesource.com/c/1262021Reviewed-by: 's avatarYuly Novikov <ynovikov@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent c97e3f66
...@@ -46,6 +46,11 @@ GL_APICALL void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components); ...@@ -46,6 +46,11 @@ GL_APICALL void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components);
#define GL_BIND_GENERATES_RESOURCE_CHROMIUM 0x9244 #define GL_BIND_GENERATES_RESOURCE_CHROMIUM 0x9244
#endif /* GL_CHROMIUM_bind_generates_resource */ #endif /* GL_CHROMIUM_bind_generates_resource */
#ifndef GL_ANGLE_memory_size
#define GL_ANGLE_memory_size
#define GL_MEMORY_SIZE_ANGLE 0x93AD
#endif /* GL_ANGLE_memory_size */
// needed by NV_path_rendering (and thus CHROMIUM_path_rendering) // needed by NV_path_rendering (and thus CHROMIUM_path_rendering)
// but CHROMIUM_path_rendering only needs MatrixLoadfEXT, MatrixLoadIdentityEXT // but CHROMIUM_path_rendering only needs MatrixLoadfEXT, MatrixLoadIdentityEXT
#ifndef GL_EXT_direct_state_access #ifndef GL_EXT_direct_state_access
......
...@@ -239,6 +239,12 @@ Error Buffer::getIndexRange(const gl::Context *context, ...@@ -239,6 +239,12 @@ Error Buffer::getIndexRange(const gl::Context *context,
return NoError(); return NoError();
} }
GLint Buffer::getMemorySize() const
{
GLint implSize = mImpl->getMemorySize();
return implSize > 0 ? implSize : clampCast<GLint>(mState.mSize);
}
bool Buffer::isBound() const bool Buffer::isBound() const
{ {
return mState.mBindingCount; return mState.mBindingCount;
......
...@@ -112,6 +112,7 @@ class Buffer final : public RefCountObject, public LabeledObject ...@@ -112,6 +112,7 @@ class Buffer final : public RefCountObject, public LabeledObject
GLint64 getMapOffset() const { return mState.mMapOffset; } GLint64 getMapOffset() const { return mState.mMapOffset; }
GLint64 getMapLength() const { return mState.mMapLength; } GLint64 getMapLength() const { return mState.mMapLength; }
GLint64 getSize() const { return mState.mSize; } GLint64 getSize() const { return mState.mSize; }
GLint getMemorySize() const;
rx::BufferImpl *getImplementation() const { return mImpl; } rx::BufferImpl *getImplementation() const { return mImpl; }
......
...@@ -255,7 +255,8 @@ Extensions::Extensions() ...@@ -255,7 +255,8 @@ Extensions::Extensions()
textureStorageMultisample2DArray(false), textureStorageMultisample2DArray(false),
multiviewMultisample(false), multiviewMultisample(false),
blendFuncExtended(false), blendFuncExtended(false),
maxDualSourceDrawBuffers(0) maxDualSourceDrawBuffers(0),
memorySize(false)
{ {
} }
...@@ -894,6 +895,7 @@ const ExtensionInfoMap &GetExtensionInfoMap() ...@@ -894,6 +895,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
map["GL_OES_texture_cube_map"] = enableableExtension(&Extensions::textureCubeMap); map["GL_OES_texture_cube_map"] = enableableExtension(&Extensions::textureCubeMap);
map["GL_OES_point_sprite"] = enableableExtension(&Extensions::pointSprite); map["GL_OES_point_sprite"] = enableableExtension(&Extensions::pointSprite);
map["GL_OES_draw_texture"] = enableableExtension(&Extensions::drawTexture); map["GL_OES_draw_texture"] = enableableExtension(&Extensions::drawTexture);
map["GL_ANGLE_memory_size"] = enableableExtension(&Extensions::memorySize);
// clang-format on // clang-format on
return map; return map;
......
...@@ -443,6 +443,9 @@ struct Extensions ...@@ -443,6 +443,9 @@ struct Extensions
// GL_EXT_blend_func_extended // GL_EXT_blend_func_extended
bool blendFuncExtended; bool blendFuncExtended;
GLuint maxDualSourceDrawBuffers; GLuint maxDualSourceDrawBuffers;
// GL_ANGLE_memory_size
bool memorySize;
}; };
struct ExtensionInfo struct ExtensionInfo
......
...@@ -3243,6 +3243,8 @@ Extensions Context::generateSupportedExtensions() const ...@@ -3243,6 +3243,8 @@ Extensions Context::generateSupportedExtensions() const
supportedExtensions.explicitContext = true; supportedExtensions.explicitContext = true;
} }
supportedExtensions.memorySize = true;
return supportedExtensions; return supportedExtensions;
} }
......
...@@ -200,6 +200,23 @@ GLuint Renderbuffer::getStencilSize() const ...@@ -200,6 +200,23 @@ GLuint Renderbuffer::getStencilSize() const
return mState.mFormat.info->stencilBits; return mState.mFormat.info->stencilBits;
} }
GLint Renderbuffer::getMemorySize() const
{
GLint implSize = mImplementation->getMemorySize();
if (implSize > 0)
{
return implSize;
}
// Assume allocated size is around width * height * samples * pixelBytes
angle::CheckedNumeric<GLint> size = 1;
size *= mState.mFormat.info->pixelBytes;
size *= mState.mWidth;
size *= mState.mHeight;
size *= std::max(mState.mSamples, 1);
return size.ValueOrDefault(std::numeric_limits<GLint>::max());
}
void Renderbuffer::onAttach(const Context *context) void Renderbuffer::onAttach(const Context *context)
{ {
addRef(); addRef();
......
...@@ -93,6 +93,8 @@ class Renderbuffer final : public RefCountObject, public egl::ImageSibling, publ ...@@ -93,6 +93,8 @@ class Renderbuffer final : public RefCountObject, public egl::ImageSibling, publ
GLuint getDepthSize() const; GLuint getDepthSize() const;
GLuint getStencilSize() const; GLuint getStencilSize() const;
GLint getMemorySize() const;
// FramebufferAttachmentObject Impl // FramebufferAttachmentObject Impl
Extents getAttachmentSize(const ImageIndex &imageIndex) const override; Extents getAttachmentSize(const ImageIndex &imageIndex) const override;
Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override; Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override;
......
...@@ -493,6 +493,18 @@ ImageDesc::ImageDesc(const Extents &size, ...@@ -493,6 +493,18 @@ ImageDesc::ImageDesc(const Extents &size,
{ {
} }
GLint ImageDesc::getMemorySize() const
{
// Assume allocated size is around width * height * depth * samples * pixelBytes
angle::CheckedNumeric<GLint> levelSize = 1;
levelSize *= format.info->pixelBytes;
levelSize *= size.width;
levelSize *= size.height;
levelSize *= size.depth;
levelSize *= std::max(samples, 1);
return levelSize.ValueOrDefault(std::numeric_limits<GLint>::max());
}
const ImageDesc &TextureState::getImageDesc(TextureTarget target, size_t level) const const ImageDesc &TextureState::getImageDesc(TextureTarget target, size_t level) const
{ {
size_t descIndex = GetImageDescIndex(target, level); size_t descIndex = GetImageDescIndex(target, level);
...@@ -930,6 +942,33 @@ egl::Stream *Texture::getBoundStream() const ...@@ -930,6 +942,33 @@ egl::Stream *Texture::getBoundStream() const
return mBoundStream; return mBoundStream;
} }
GLint Texture::getMemorySize() const
{
GLint implSize = mTexture->getMemorySize();
if (implSize > 0)
{
return implSize;
}
angle::CheckedNumeric<GLint> size = 0;
for (const ImageDesc &imageDesc : mState.mImageDescs)
{
size += imageDesc.getMemorySize();
}
return size.ValueOrDefault(std::numeric_limits<GLint>::max());
}
GLint Texture::getLevelMemorySize(TextureTarget target, GLint level) const
{
GLint implSize = mTexture->getLevelMemorySize(target, level);
if (implSize > 0)
{
return implSize;
}
return mState.getImageDesc(target, level).getMemorySize();
}
void Texture::signalDirty(const Context *context, InitState initState) void Texture::signalDirty(const Context *context, InitState initState)
{ {
mState.mInitState = initState; mState.mInitState = initState;
......
...@@ -61,6 +61,8 @@ struct ImageDesc final ...@@ -61,6 +61,8 @@ struct ImageDesc final
ImageDesc(const ImageDesc &other) = default; ImageDesc(const ImageDesc &other) = default;
ImageDesc &operator=(const ImageDesc &other) = default; ImageDesc &operator=(const ImageDesc &other) = default;
GLint getMemorySize() const;
Extents size; Extents size;
Format format; Format format;
GLsizei samples; GLsizei samples;
...@@ -372,6 +374,9 @@ class Texture final : public RefCountObject, ...@@ -372,6 +374,9 @@ class Texture final : public RefCountObject,
egl::Surface *getBoundSurface() const; egl::Surface *getBoundSurface() const;
egl::Stream *getBoundStream() const; egl::Stream *getBoundStream() const;
GLint getMemorySize() const;
GLint getLevelMemorySize(TextureTarget target, GLint level) const;
void signalDirty(const Context *context, InitState initState); void signalDirty(const Context *context, InitState initState);
bool isSamplerComplete(const Context *context, const Sampler *optionalSampler); bool isSamplerComplete(const Context *context, const Sampler *optionalSampler);
......
...@@ -111,6 +111,10 @@ void QueryTexLevelParameterBase(const Texture *texture, ...@@ -111,6 +111,10 @@ void QueryTexLevelParameterBase(const Texture *texture,
case GL_TEXTURE_COMPRESSED: case GL_TEXTURE_COMPRESSED:
*params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(info->compressed)); *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(info->compressed));
break; break;
case GL_MEMORY_SIZE_ANGLE:
*params =
CastFromStateValue<ParamType>(pname, texture->getLevelMemorySize(target, level));
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -200,6 +204,9 @@ void QueryTexParameterBase(const Texture *texture, GLenum pname, ParamType *para ...@@ -200,6 +204,9 @@ void QueryTexParameterBase(const Texture *texture, GLenum pname, ParamType *para
case GL_GENERATE_MIPMAP: case GL_GENERATE_MIPMAP:
*params = CastFromGLintStateValue<ParamType>(pname, texture->getGenerateMipmapHint()); *params = CastFromGLintStateValue<ParamType>(pname, texture->getGenerateMipmapHint());
break; break;
case GL_MEMORY_SIZE_ANGLE:
*params = CastFromStateValue<ParamType>(pname, texture->getMemorySize());
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -461,6 +468,9 @@ void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *par ...@@ -461,6 +468,9 @@ void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *par
case GL_BUFFER_MAP_LENGTH: case GL_BUFFER_MAP_LENGTH:
*params = CastFromStateValue<ParamType>(pname, buffer->getMapLength()); *params = CastFromStateValue<ParamType>(pname, buffer->getMapLength());
break; break;
case GL_MEMORY_SIZE_ANGLE:
*params = CastFromStateValue<ParamType>(pname, buffer->getMemorySize());
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
...@@ -1154,6 +1164,9 @@ void QueryRenderbufferiv(const Context *context, ...@@ -1154,6 +1164,9 @@ void QueryRenderbufferiv(const Context *context,
case GL_RENDERBUFFER_SAMPLES_ANGLE: case GL_RENDERBUFFER_SAMPLES_ANGLE:
*params = renderbuffer->getSamples(); *params = renderbuffer->getSamples();
break; break;
case GL_MEMORY_SIZE_ANGLE:
*params = renderbuffer->getMemorySize();
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
......
...@@ -65,6 +65,9 @@ class BufferImpl : public angle::Subject ...@@ -65,6 +65,9 @@ class BufferImpl : public angle::Subject
bool primitiveRestartEnabled, bool primitiveRestartEnabled,
gl::IndexRange *outRange) = 0; gl::IndexRange *outRange) = 0;
// Override if accurate native memory size information is available
virtual GLint getMemorySize() const { return 0; }
protected: protected:
const gl::BufferState &mState; const gl::BufferState &mState;
}; };
......
...@@ -45,6 +45,9 @@ class RenderbufferImpl : public FramebufferAttachmentObjectImpl ...@@ -45,6 +45,9 @@ class RenderbufferImpl : public FramebufferAttachmentObjectImpl
size_t height) = 0; size_t height) = 0;
virtual gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) = 0; virtual gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) = 0;
// Override if accurate native memory size information is available
virtual GLint getMemorySize() const { return 0; }
protected: protected:
const gl::RenderbufferState &mState; const gl::RenderbufferState &mState;
}; };
......
...@@ -162,6 +162,10 @@ class TextureImpl : public FramebufferAttachmentObjectImpl ...@@ -162,6 +162,10 @@ class TextureImpl : public FramebufferAttachmentObjectImpl
virtual gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) = 0; virtual gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) = 0;
virtual gl::Error releaseTexImage(const gl::Context *context) = 0; virtual gl::Error releaseTexImage(const gl::Context *context) = 0;
// Override if accurate native memory size information is available
virtual GLint getMemorySize() const { return 0; }
virtual GLint getLevelMemorySize(gl::TextureTarget target, GLint level) const { return 0; }
virtual angle::Result syncState(const gl::Context *context, virtual angle::Result syncState(const gl::Context *context,
const gl::Texture::DirtyBits &dirtyBits) = 0; const gl::Texture::DirtyBits &dirtyBits) = 0;
......
...@@ -5281,6 +5281,14 @@ bool ValidateGetBufferParameterBase(Context *context, ...@@ -5281,6 +5281,14 @@ bool ValidateGetBufferParameterBase(Context *context,
} }
break; break;
case GL_MEMORY_SIZE_ANGLE:
if (!context->getExtensions().memorySize)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
return false;
}
break;
default: default:
ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
return false; return false;
...@@ -5339,6 +5347,14 @@ bool ValidateGetRenderbufferParameterivBase(Context *context, ...@@ -5339,6 +5347,14 @@ bool ValidateGetRenderbufferParameterivBase(Context *context,
} }
break; break;
case GL_MEMORY_SIZE_ANGLE:
if (!context->getExtensions().memorySize)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
return false;
}
break;
default: default:
ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
return false; return false;
...@@ -5505,6 +5521,15 @@ bool ValidateGetTexParameterBase(Context *context, ...@@ -5505,6 +5521,15 @@ bool ValidateGetTexParameterBase(Context *context,
return false; return false;
} }
break; break;
case GL_MEMORY_SIZE_ANGLE:
if (!context->getExtensions().memorySize)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
return false;
}
break;
default: default:
ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
return false; return false;
......
...@@ -954,6 +954,14 @@ bool ValidateGetTexLevelParameterBase(Context *context, ...@@ -954,6 +954,14 @@ bool ValidateGetTexLevelParameterBase(Context *context,
break; break;
case GL_TEXTURE_COMPRESSED: case GL_TEXTURE_COMPRESSED:
break; break;
case GL_MEMORY_SIZE_ANGLE:
if (!context->getExtensions().memorySize)
{
ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
return false;
}
break;
default: default:
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname); ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
return false; return false;
......
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