Commit 13ea5b7f by Geoff Lang Committed by Commit Bot

Implement gl[Get]MemoryObjectParameterivEXT

These functions are required to tell the driver that the memory object is dedicated memory. This is required for AMD drivers on Linux. Bug: chromium:1049218 Change-Id: I17d69cde5e6308791dc90784f4d6e348503a6ed6 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2110051Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent dd4e09ef
......@@ -7662,16 +7662,18 @@ void Context::createMemoryObjects(GLsizei n, MemoryObjectID *memoryObjects)
}
}
void Context::memoryObjectParameteriv(MemoryObjectID memoryObject,
GLenum pname,
const GLint *params)
void Context::memoryObjectParameteriv(MemoryObjectID memory, GLenum pname, const GLint *params)
{
UNIMPLEMENTED();
MemoryObject *memoryObject = getMemoryObject(memory);
ASSERT(memoryObject);
ANGLE_CONTEXT_TRY(SetMemoryObjectParameteriv(this, memoryObject, pname, params));
}
void Context::getMemoryObjectParameteriv(MemoryObjectID memoryObject, GLenum pname, GLint *params)
void Context::getMemoryObjectParameteriv(MemoryObjectID memory, GLenum pname, GLint *params)
{
UNIMPLEMENTED();
const MemoryObject *memoryObject = getMemoryObject(memory);
ASSERT(memoryObject);
QueryMemoryObjectParameteriv(memoryObject, pname, params);
}
void Context::texStorageMem2D(TextureType target,
......
......@@ -141,6 +141,7 @@ MSG kGetImageExtensionNotEnabled = "GL_ANGLE_get_image extension not enabled.";
MSG kGLES1Only = "GLES1-only function.";
MSG kImageSizeMustBeZero = "imageSize must be 0 if no texture data is provided.";
MSG kImageSizeTooSmall = "imageSize is too small.";
MSG kImmutableMemoryObject = "The memory object is immutable.";
MSG kImmutableTextureBound = "The value of TEXTURE_IMMUTABLE_FORMAT for the texture currently bound to target on the active texture unit is true.";
MSG kIncompatibleDrawModeAgainstGeometryShader = "Primitive mode is incompatible with the input primitive type of the geometry shader.";
MSG kIndexExceedsActiveUniformBlockCount = "Index exceeds active uniform block count.";
......@@ -240,6 +241,8 @@ MSG kInvalidMaterialFace = "Invalid material face.";
MSG kInvalidMaterialParameter = "Invalid material parameter.";
MSG kInvalidMatrixMode = "Invalid matrix mode.";
MSG kInvalidMemoryBarrierBit = "Invalid memory barrier bit.";
MSG kInvalidMemoryObject = "Invalid memory object.";
MSG kInvalidMemoryObjectParameter = "Invalid memory object parameter.";
MSG kInvalidMipLevel = "Level of detail outside of range.";
MSG kInvalidMipLevels = "Invalid level count.";
MSG kInvalidMultisampledFramebufferOperation = "Invalid operation on multisampled framebuffer";
......
......@@ -15,7 +15,10 @@ namespace gl
{
MemoryObject::MemoryObject(rx::GLImplFactory *factory, MemoryObjectID id)
: RefCountObject(factory->generateSerial(), id), mImplementation(factory->createMemoryObject())
: RefCountObject(factory->generateSerial(), id),
mImplementation(factory->createMemoryObject()),
mImmutable(false),
mDedicatedMemory(false)
{}
MemoryObject::~MemoryObject() {}
......@@ -25,12 +28,21 @@ void MemoryObject::onDestroy(const Context *context)
mImplementation->onDestroy(context);
}
angle::Result MemoryObject::setDedicatedMemory(const Context *context, bool dedicatedMemory)
{
ANGLE_TRY(mImplementation->setDedicatedMemory(context, dedicatedMemory));
mDedicatedMemory = dedicatedMemory;
return angle::Result::Continue;
}
angle::Result MemoryObject::importFd(Context *context,
GLuint64 size,
HandleType handleType,
GLint fd)
{
return mImplementation->importFd(context, size, handleType, fd);
ANGLE_TRY(mImplementation->importFd(context, size, handleType, fd));
mImmutable = true;
return angle::Result::Continue;
}
angle::Result MemoryObject::importZirconHandle(Context *context,
......@@ -38,7 +50,9 @@ angle::Result MemoryObject::importZirconHandle(Context *context,
HandleType handleType,
GLuint handle)
{
return mImplementation->importZirconHandle(context, size, handleType, handle);
ANGLE_TRY(mImplementation->importZirconHandle(context, size, handleType, handle));
mImmutable = true;
return angle::Result::Continue;
}
} // namespace gl
......@@ -34,6 +34,11 @@ class MemoryObject final : public RefCountObject<MemoryObjectID>
rx::MemoryObjectImpl *getImplementation() const { return mImplementation.get(); }
bool isImmutable() const { return mImmutable; }
angle::Result setDedicatedMemory(const Context *context, bool dedicatedMemory);
bool isDedicatedMemory() const { return mDedicatedMemory; }
angle::Result importFd(Context *context, GLuint64 size, HandleType handleType, GLint fd);
angle::Result importZirconHandle(Context *context,
GLuint64 size,
......@@ -42,6 +47,9 @@ class MemoryObject final : public RefCountObject<MemoryObjectID>
private:
std::unique_ptr<rx::MemoryObjectImpl> mImplementation;
bool mImmutable;
bool mDedicatedMemory;
};
} // namespace gl
......
......@@ -18,6 +18,7 @@
#include "libANGLE/Fence.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/GLES1State.h"
#include "libANGLE/MemoryObject.h"
#include "libANGLE/Program.h"
#include "libANGLE/Renderbuffer.h"
#include "libANGLE/Sampler.h"
......@@ -2075,6 +2076,37 @@ void QueryProgramInterfaceiv(const Program *program,
}
}
angle::Result SetMemoryObjectParameteriv(const Context *context,
MemoryObject *memoryObject,
GLenum pname,
const GLint *params)
{
switch (pname)
{
case GL_DEDICATED_MEMORY_OBJECT_EXT:
ANGLE_TRY(memoryObject->setDedicatedMemory(context, ConvertToBool(params[0])));
break;
default:
UNREACHABLE();
}
return angle::Result::Continue;
}
void QueryMemoryObjectParameteriv(const MemoryObject *memoryObject, GLenum pname, GLint *params)
{
switch (pname)
{
case GL_DEDICATED_MEMORY_OBJECT_EXT:
*params = memoryObject->isDedicatedMemory();
break;
default:
UNREACHABLE();
}
}
ClientVertexArrayType ParamToVertexArrayType(GLenum param)
{
switch (param)
......
......@@ -183,6 +183,13 @@ void QueryProgramInterfaceiv(const Program *program,
GLenum programInterface,
GLenum pname,
GLint *params);
angle::Result SetMemoryObjectParameteriv(const Context *context,
MemoryObject *memoryObject,
GLenum pname,
const GLint *params);
void QueryMemoryObjectParameteriv(const MemoryObject *memoryObject, GLenum pname, GLint *params);
// GLES1 emulation
ClientVertexArrayType ParamToVertexArrayType(GLenum param);
......
......@@ -29,6 +29,8 @@ class MemoryObjectImpl : angle::NonCopyable
virtual void onDestroy(const gl::Context *context) = 0;
virtual angle::Result setDedicatedMemory(const gl::Context *context, bool dedicatedMemory) = 0;
virtual angle::Result importFd(gl::Context *context,
GLuint64 size,
gl::HandleType handleType,
......
......@@ -6,6 +6,7 @@
#include "libANGLE/renderer/gl/MemoryObjectGL.h"
#include "libANGLE/Context.h"
#include "libANGLE/queryconversions.h"
#include "libANGLE/renderer/gl/ContextGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/renderergl_utils.h"
......@@ -29,13 +30,24 @@ void MemoryObjectGL::onDestroy(const gl::Context *context)
mMemoryObject = 0;
}
angle::Result MemoryObjectGL::setDedicatedMemory(const gl::Context *context, bool dedicatedMemory)
{
const FunctionsGL *functions = GetFunctionsGL(context);
GLint params = gl::ConvertToGLBoolean(dedicatedMemory);
ANGLE_GL_TRY(context, functions->memoryObjectParameterivEXT(
mMemoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT, &params));
return angle::Result::Continue;
}
angle::Result MemoryObjectGL::importFd(gl::Context *context,
GLuint64 size,
gl::HandleType handleType,
GLint fd)
{
const FunctionsGL *functions = GetFunctionsGL(context);
functions->importMemoryFdEXT(mMemoryObject, size, ToGLenum(handleType), fd);
ANGLE_GL_TRY(context,
functions->importMemoryFdEXT(mMemoryObject, size, ToGLenum(handleType), fd));
return angle::Result::Continue;
}
......
......@@ -21,6 +21,8 @@ class MemoryObjectGL : public MemoryObjectImpl
void onDestroy(const gl::Context *context) override;
angle::Result setDedicatedMemory(const gl::Context *context, bool dedicatedMemory) override;
angle::Result importFd(gl::Context *context,
GLuint64 size,
gl::HandleType handleType,
......
......@@ -95,6 +95,12 @@ void MemoryObjectVk::onDestroy(const gl::Context *context)
}
}
angle::Result MemoryObjectVk::setDedicatedMemory(const gl::Context *context, bool dedicatedMemory)
{
UNIMPLEMENTED();
return angle::Result::Continue;
}
angle::Result MemoryObjectVk::importFd(gl::Context *context,
GLuint64 size,
gl::HandleType handleType,
......
......@@ -23,6 +23,8 @@ class MemoryObjectVk : public MemoryObjectImpl
void onDestroy(const gl::Context *context) override;
angle::Result setDedicatedMemory(const gl::Context *context, bool dedicatedMemory) override;
angle::Result importFd(gl::Context *context,
GLuint64 size,
gl::HandleType handleType,
......
......@@ -18,6 +18,7 @@
#include "libANGLE/Fence.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/MemoryObject.h"
#include "libANGLE/Renderbuffer.h"
#include "libANGLE/Shader.h"
#include "libANGLE/Texture.h"
......@@ -1051,6 +1052,18 @@ bool ValidateES2TexImageParameters(const Context *context,
format, type, imageSize, pixels);
}
bool IsValidMemoryObjectParamater(const Context *context, GLenum pname)
{
switch (pname)
{
case GL_DEDICATED_MEMORY_OBJECT_EXT:
return true;
default:
return false;
}
}
} // anonymous namespace
bool ValidateES2TexImageParametersBase(const Context *context,
......@@ -3291,8 +3304,19 @@ bool ValidateGetMemoryObjectParameterivEXT(const Context *context,
return false;
}
UNIMPLEMENTED();
return false;
const MemoryObject *memory = context->getMemoryObject(memoryObject);
if (memory == nullptr)
{
context->validationError(GL_INVALID_VALUE, kInvalidMemoryObject);
}
if (!IsValidMemoryObjectParamater(context, pname))
{
context->validationError(GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
return false;
}
return true;
}
bool ValidateGetUnsignedBytevEXT(const Context *context, GLenum pname, const GLubyte *data)
......@@ -3344,8 +3368,26 @@ bool ValidateMemoryObjectParameterivEXT(const Context *context,
return false;
}
UNIMPLEMENTED();
return false;
const MemoryObject *memory = context->getMemoryObject(memoryObject);
if (memory == nullptr)
{
context->validationError(GL_INVALID_VALUE, kInvalidMemoryObject);
return false;
}
if (memory->isImmutable())
{
context->validationError(GL_INVALID_OPERATION, kImmutableMemoryObject);
return false;
}
if (!IsValidMemoryObjectParamater(context, pname))
{
context->validationError(GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
return false;
}
return true;
}
bool ValidateTexStorageMem2DEXT(const Context *context,
......
......@@ -64,6 +64,42 @@ TEST_P(MemoryObjectTest, ShouldFailValidationOnImportFdUnsupportedHandleType)
EXPECT_GL_NO_ERROR();
}
// Test memory object queries
TEST_P(MemoryObjectTest, MemoryObjectQueries)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_memory_object"));
GLMemoryObject memoryObject;
// Validate that the initial state of GL_DEDICATED_MEMORY_OBJECT_EXT is GL_FALSE
{
GLint dedicatedMemory = 0;
glGetMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
&dedicatedMemory);
EXPECT_GL_NO_ERROR();
EXPECT_GL_FALSE(dedicatedMemory);
}
// Change GL_DEDICATED_MEMORY_OBJECT_EXT to GL_TRUE
{
GLint dedicatedMemory = GL_TRUE;
glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
&dedicatedMemory);
EXPECT_GL_NO_ERROR();
}
// Confirm that GL_DEDICATED_MEMORY_OBJECT_EXT is now TRUE
{
GLint dedicatedMemory = 0;
glGetMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
&dedicatedMemory);
EXPECT_GL_NO_ERROR();
EXPECT_GL_TRUE(dedicatedMemory);
}
EXPECT_GL_NO_ERROR();
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(MemoryObjectTest);
......
......@@ -111,6 +111,13 @@ TEST_P(VulkanExternalImageTest, ShouldImportMemoryOpaqueFd)
{
GLMemoryObject memoryObject;
glImportMemoryFdEXT(memoryObject, deviceMemorySize, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd);
// Test that after calling glImportMemoryFdEXT, the parameters of the memory object cannot
// be changed
GLint dedicatedMemory = GL_TRUE;
glMemoryObjectParameterivEXT(memoryObject, GL_DEDICATED_MEMORY_OBJECT_EXT,
&dedicatedMemory);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
EXPECT_GL_NO_ERROR();
......
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