[Mesa-dev] [PATCH 06/23] mesa: hook up memoryobject tex(ture)storage api
Samuel Pitoiset
samuel.pitoiset at gmail.com
Fri Aug 4 09:17:13 UTC 2017
On 08/04/2017 11:10 AM, Timothy Arceri wrote:
>
>
> On 04/08/17 18:45, Samuel Pitoiset wrote:
>>
>>
>> On 08/04/2017 03:54 AM, Timothy Arceri wrote:
>>> From: Andres Rodriguez <andresx7 at gmail.com>
>>>
>>> V2 (Timothy Arceri):
>>> - formating fixes
>>>
>>> V3 (Timothy):
>>> - error check memory == 0 before lookup
>>>
>>> Signed-off-by: Andres Rodriguez <andresx7 at gmail.com>
>>> Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com> (v2)
>>> ---
>>> src/mesa/main/dd.h | 10 ++++
>>> src/mesa/main/externalobjects.c | 128
>>> ++++++++++++++++++++++++++++++++++++----
>>> src/mesa/main/texstorage.c | 76 +++++++++++++++++-------
>>> src/mesa/main/texstorage.h | 9 +++
>>> 4 files changed, 191 insertions(+), 32 deletions(-)
>>>
>>> diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
>>> index 6d6bdecb4d..fbe70cdfab 100644
>>> --- a/src/mesa/main/dd.h
>>> +++ b/src/mesa/main/dd.h
>>> @@ -1080,20 +1080,30 @@ struct dd_function_table {
>>> * allocate/return a subclass of gl_memory_object.
>>> */
>>> struct gl_memory_object * (*NewMemoryObject)(struct gl_context
>>> *ctx,
>>> GLuint name);
>>> /**
>>> * Called to delete/free a memory object. Drivers should free the
>>> * object and any image data it contains.
>>> */
>>> void (*DeleteMemoryObject)(struct gl_context *ctx,
>>> struct gl_memory_object *memObj);
>>> +
>>> + /**
>>> + * Set the given memory object as the texture's storage.
>>> + */
>>> + GLboolean (*SetTextureStorageForMemoryObject)(struct gl_context
>>> *ctx,
>>> + struct
>>> gl_texture_object *tex_obj,
>>> + struct
>>> gl_memory_object *mem_obj,
>>> + GLsizei levels,
>>> GLsizei width,
>>> + GLsizei height,
>>> GLsizei depth,
>>> + GLuint64 offset);
>>> /*@}*/
>>> /**
>>> * \name GL_EXT_external_objects_fd interface
>>> */
>>> /*@{*/
>>> /**
>>> * Called to import a memory object. The caller relinquishes
>>> ownership
>>> * of fd after the call returns.
>>> *
>>> diff --git a/src/mesa/main/externalobjects.c
>>> b/src/mesa/main/externalobjects.c
>>> index c0c97f645c..d10d414f02 100644
>>> --- a/src/mesa/main/externalobjects.c
>>> +++ b/src/mesa/main/externalobjects.c
>>> @@ -17,20 +17,24 @@
>>> * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
>>> EVENT SHALL
>>> * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
>>> DAMAGES OR OTHER
>>> * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
>>> ARISING
>>> * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
>>> * DEALINGS IN THE SOFTWARE.
>>> */
>>> #include "macros.h"
>>> #include "mtypes.h"
>>> #include "externalobjects.h"
>>> +#include "teximage.h"
>>> +#include "texobj.h"
>>> +#include "glformats.h"
>>> +#include "texstorage.h"
>>> /**
>>> * Allocate and initialize a new memory object. But don't put it
>>> into the
>>> * memory object hash table.
>>> *
>>> * Called via ctx->Driver.NewMemoryObject, unless overridden by a
>>> device
>>> * driver.
>>> *
>>> * \return pointer to new memory object.
>>> */
>>> @@ -221,144 +225,248 @@ _mesa_GetMemoryObjectParameterivEXT(GLuint
>>> memoryObject,
>>> default:
>>> goto invalid_pname;
>>> }
>>> return;
>>> invalid_pname:
>>> _mesa_error(ctx, GL_INVALID_ENUM,
>>> "glGetMemoryObjectParameterivEXT(pname=0x%x)", pname);
>>> }
>>> +static struct gl_memory_object *
>>> +lookup_memory_object_err(struct gl_context *ctx, unsigned memory,
>>> + const char* func)
>>> +{
>>> + if (memory == 0) {
>>> + _mesa_error(ctx, GL_INVALID_VALUE, "%s(memory=0)", func);
>>> + return NULL;
>>> + }
>>> +
>>> + struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx,
>>> memory);
>>> + if (!memObj)
>>> + return NULL;
>>> +
>>> + if (!memObj->Immutable) {
>>> + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no associated
>>> memory)",
>>> + func);
>>> + return NULL;
>>> + }
>>
>> I haven't read the spec carefully, but do all memory objects have to
>> be immutable?
>
> From the EXT_external_objects_fd spec:
>
> A successful import operation transfers ownership of <fd> to the GL
> implementation, and performing any operation on <fd> in the application
> after an import results in undefined behavior.
Ah okay, is Immutable the right term? How about Imported?
>
>>
>>> +
>>> + return memObj;
>>> +}
>>> +
>>> +/**
>>> + * Helper used by _mesa_TexStorageMem1/2/3DEXT().
>>> + */
>>> +static void
>>> +texstorage_memory(GLuint dims, GLenum target, GLsizei levels,
>>> + GLenum internalFormat, GLsizei width, GLsizei height,
>>> + GLsizei depth, GLuint memory, GLuint64 offset,
>>> + const char *func)
>>> +{
>>> + struct gl_texture_object *texObj;
>>> + struct gl_memory_object *memObj;
>>> +
>>> + GET_CURRENT_CONTEXT(ctx);
>>> +
>>> + texObj = _mesa_get_current_tex_object(ctx, target);
>>> + if (!texObj)
>>> + return;
>>> +
>>> + memObj = lookup_memory_object_err(ctx, memory, func);
>>> + if (!memObj)
>>> + return;
>>> +
>>> + _mesa_texture_storage_memory(ctx, dims, texObj, memObj, target,
>>> + levels, internalFormat,
>>> + width, height, depth, offset, false);
>>> +}
>>> +
>>> +static void
>>> +texstorage_memory_ms(GLuint dims, GLenum target, GLsizei samples,
>>> + GLenum internalFormat, GLsizei width, GLsizei
>>> height,
>>> + GLsizei depth, GLboolean fixedSampleLocations,
>>> + GLuint memory, GLuint64 offset)
>>> +{
>>> +
>>> +}
>>> +
>>> +/**
>>> + * Helper used by _mesa_TextureStorageMem1/2/3DEXT().
>>> + */
>>> +static void
>>> +texturestorage_memory(GLuint dims, GLuint texture, GLsizei levels,
>>> + GLenum internalFormat, GLsizei width, GLsizei
>>> height,
>>> + GLsizei depth, GLuint memory, GLuint64 offset,
>>> + const char *func)
>>> +{
>>> + struct gl_texture_object *texObj;
>>> + struct gl_memory_object *memObj;
>>> +
>>> + GET_CURRENT_CONTEXT(ctx);
>>> +
>>> + texObj = _mesa_lookup_texture(ctx, texture);
>>> + if (!texObj)
>>> + return;
>>> +
>>> + memObj = lookup_memory_object_err(ctx, memory, func);
>>> + if (!memObj)
>>> + return;
>>> +
>>> + _mesa_texture_storage_memory(ctx, dims, texObj, memObj,
>>> texObj->Target,
>>> + levels, internalFormat,
>>> + width, height, depth, offset, true);
>>> +}
>>> +
>>> +static void
>>> +texturestorage_memory_ms(GLuint dims, GLuint texture, GLsizei samples,
>>> + GLenum internalFormat, GLsizei width,
>>> GLsizei height,
>>> + GLsizei depth, GLboolean fixedSampleLocations,
>>> + GLuint memory, GLuint64 offset)
>>> +{
>>> +
>>> +}
>>> +
>>> void GLAPIENTRY
>>> _mesa_TexStorageMem2DEXT(GLenum target,
>>> GLsizei levels,
>>> GLenum internalFormat,
>>> GLsizei width,
>>> GLsizei height,
>>> GLuint memory,
>>> GLuint64 offset)
>>> {
>>> -
>>> + texstorage_memory(2, target, levels, internalFormat, width,
>>> height, 1,
>>> + memory, offset, "glTexStorageMem2DEXT");
>>> }
>>> void GLAPIENTRY
>>> _mesa_TexStorageMem2DMultisampleEXT(GLenum target,
>>> GLsizei samples,
>>> GLenum internalFormat,
>>> GLsizei width,
>>> GLsizei height,
>>> GLboolean fixedSampleLocations,
>>> GLuint memory,
>>> GLuint64 offset)
>>> {
>>> -
>>> + texstorage_memory_ms(2, target, samples, internalFormat, width,
>>> height, 1,
>>> + fixedSampleLocations, memory, offset);
>>> }
>>> void GLAPIENTRY
>>> _mesa_TexStorageMem3DEXT(GLenum target,
>>> GLsizei levels,
>>> GLenum internalFormat,
>>> GLsizei width,
>>> GLsizei height,
>>> GLsizei depth,
>>> GLuint memory,
>>> GLuint64 offset)
>>> {
>>> -
>>> + texstorage_memory(3, target, levels, internalFormat, width,
>>> height, depth,
>>> + memory, offset, "glTexStorageMem3DEXT");
>>> }
>>> void GLAPIENTRY
>>> _mesa_TexStorageMem3DMultisampleEXT(GLenum target,
>>> GLsizei samples,
>>> GLenum internalFormat,
>>> GLsizei width,
>>> GLsizei height,
>>> GLsizei depth,
>>> GLboolean fixedSampleLocations,
>>> GLuint memory,
>>> GLuint64 offset)
>>> {
>>> -
>>> + texstorage_memory_ms(3, target, samples, internalFormat, width,
>>> height,
>>> + depth, fixedSampleLocations, memory, offset);
>>> }
>>> void GLAPIENTRY
>>> _mesa_TextureStorageMem2DEXT(GLuint texture,
>>> GLsizei levels,
>>> GLenum internalFormat,
>>> GLsizei width,
>>> GLsizei height,
>>> GLuint memory,
>>> GLuint64 offset)
>>> {
>>> -
>>> + texturestorage_memory(2, texture, levels, internalFormat, width,
>>> height, 1,
>>> + memory, offset, "glTexureStorageMem2DEXT");
>>> }
>>> void GLAPIENTRY
>>> _mesa_TextureStorageMem2DMultisampleEXT(GLuint texture,
>>> GLsizei samples,
>>> GLenum internalFormat,
>>> GLsizei width,
>>> GLsizei height,
>>> GLboolean
>>> fixedSampleLocations,
>>> GLuint memory,
>>> GLuint64 offset)
>>> {
>>> -
>>> + texturestorage_memory_ms(2, texture, samples, internalFormat,
>>> width, height,
>>> + 1, fixedSampleLocations, memory, offset);
>>> }
>>> void GLAPIENTRY
>>> _mesa_TextureStorageMem3DEXT(GLuint texture,
>>> GLsizei levels,
>>> GLenum internalFormat,
>>> GLsizei width,
>>> GLsizei height,
>>> GLsizei depth,
>>> GLuint memory,
>>> GLuint64 offset)
>>> {
>>> -
>>> + texturestorage_memory(3, texture, levels, internalFormat, width,
>>> height,
>>> + depth, memory, offset,
>>> "glTextureStorageMem3DEXT");
>>> }
>>> void GLAPIENTRY
>>> _mesa_TextureStorageMem3DMultisampleEXT(GLuint texture,
>>> GLsizei samples,
>>> GLenum internalFormat,
>>> GLsizei width,
>>> GLsizei height,
>>> GLsizei depth,
>>> GLboolean
>>> fixedSampleLocations,
>>> GLuint memory,
>>> GLuint64 offset)
>>> {
>>> -
>>> + texturestorage_memory_ms(3, texture, samples, internalFormat,
>>> width, height,
>>> + depth, fixedSampleLocations, memory,
>>> offset);
>>> }
>>> void GLAPIENTRY
>>> _mesa_TexStorageMem1DEXT(GLenum target,
>>> GLsizei levels,
>>> GLenum internalFormat,
>>> GLsizei width,
>>> GLuint memory,
>>> GLuint64 offset)
>>> {
>>> -
>>> + texstorage_memory(1, target, levels, internalFormat, width, 1, 1,
>>> memory,
>>> + offset, "glTexStorageMem1DEXT");
>>> }
>>> void GLAPIENTRY
>>> _mesa_TextureStorageMem1DEXT(GLuint texture,
>>> GLsizei levels,
>>> GLenum internalFormat,
>>> GLsizei width,
>>> GLuint memory,
>>> GLuint64 offset)
>>> {
>>> -
>>> + texturestorage_memory(1, texture, levels, internalFormat, width,
>>> 1, 1,
>>> + memory, offset, "glTextureStorageMem1DEXT");
>>> }
>>> void GLAPIENTRY
>>> _mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
>>> {
>>> }
>>> void GLAPIENTRY
>>> _mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
>>> diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c
>>> index 7a61a4f478..e0930abe3f 100644
>>> --- a/src/mesa/main/texstorage.c
>>> +++ b/src/mesa/main/texstorage.c
>>> @@ -297,26 +297,28 @@ _mesa_AllocTextureStorage_sw(struct gl_context
>>> *ctx,
>>> /**
>>> * Do error checking for calls to glTexStorage1/2/3D().
>>> * If an error is found, record it with _mesa_error(), unless the
>>> target
>>> * is a proxy texture.
>>> * \return GL_TRUE if any error, GL_FALSE otherwise.
>>> */
>>> static GLboolean
>>> tex_storage_error_check(struct gl_context *ctx,
>>> struct gl_texture_object *texObj,
>>> + struct gl_memory_object *memObj,
>>> GLuint dims, GLenum target,
>>> GLsizei levels, GLenum internalformat,
>>> GLsizei width, GLsizei height, GLsizei depth,
>>> bool dsa)
>>> {
>>> - const char* suffix = dsa ? "ture" : "";
>>> + const char* suffix = dsa ? (memObj ? "tureMem" : "ture") :
>>> + (memObj ? "Mem" : "");
>>> /* Legal format checking has been moved to texstorage and
>>> texturestorage in
>>> * order to allow meta functions to use legacy formats. */
>>> /* size check */
>>> if (!_mesa_valid_tex_storage_dim(width, height, depth)) {
>>> _mesa_error(ctx, GL_INVALID_VALUE,
>>> "glTex%sStorage%uD(width, height or depth < 1)",
>>> suffix, dims);
>>> return GL_TRUE;
>>> @@ -382,32 +384,34 @@ tex_storage_error_check(struct gl_context *ctx,
>>> }
>>> /**
>>> * Helper that does the storage allocation for
>>> _mesa_TexStorage1/2/3D()
>>> * and _mesa_TextureStorage1/2/3D().
>>> */
>>> static ALWAYS_INLINE void
>>> texture_storage(struct gl_context *ctx, GLuint dims,
>>> struct gl_texture_object *texObj,
>>> - GLenum target, GLsizei levels,
>>> - GLenum internalformat, GLsizei width,
>>> - GLsizei height, GLsizei depth, bool dsa, bool no_error)
>>> + struct gl_memory_object *memObj, GLenum target,
>>> + GLsizei levels, GLenum internalformat, GLsizei width,
>>> + GLsizei height, GLsizei depth, GLuint64 offset, bool
>>> dsa,
>>> + bool no_error)
>>> {
>>> GLboolean sizeOK = GL_TRUE, dimensionsOK = GL_TRUE;
>>> mesa_format texFormat;
>>> - const char* suffix = dsa ? "ture" : "";
>>> + const char* suffix = dsa ? (memObj ? "tureMem" : "ture") :
>>> + (memObj ? "Mem" : "");
>>> assert(texObj);
>>> if (!no_error) {
>>> - if (tex_storage_error_check(ctx, texObj, dims, target, levels,
>>> + if (tex_storage_error_check(ctx, texObj, memObj, dims, target,
>>> levels,
>>> internalformat, width, height,
>>> depth, dsa)) {
>>> return; /* error was recorded */
>>> }
>>> }
>>> texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
>>> internalformat, GL_NONE,
>>> GL_NONE);
>>> if (!no_error) {
>>> /* check that width, height, depth are legal for the mipmap
>>> level */
>>> @@ -447,62 +451,74 @@ texture_storage(struct gl_context *ctx, GLuint
>>> dims,
>>> assert(levels > 0);
>>> assert(width > 0);
>>> assert(height > 0);
>>> assert(depth > 0);
>>> if (!initialize_texture_fields(ctx, texObj, levels, width,
>>> height, depth,
>>> internalformat, texFormat)) {
>>> return;
>>> }
>>> - /* Do actual texture memory allocation */
>>> - if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels,
>>> - width, height, depth)) {
>>> - /* Reset the texture images' info to zeros.
>>> - * Strictly speaking, we probably don't have to do this since
>>> - * generating GL_OUT_OF_MEMORY can leave things in an
>>> undefined
>>> - * state but this puts things in a consistent state.
>>> - */
>>> - clear_texture_fields(ctx, texObj);
>>> - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD",
>>> - suffix, dims);
>>> - return;
>>> + /* Setup the backing memory */
>>> + if (memObj) {
>>> + if (!ctx->Driver.SetTextureStorageForMemoryObject(ctx,
>>> texObj, memObj,
>>> + levels,
>>> + width,
>>> height, depth,
>>> + offset)) {
>>> +
>>> + clear_texture_fields(ctx, texObj);
>>> + return;
>>> + }
>>> + }
>>> + else {
>>> + if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels,
>>> + width, height, depth)) {
>>> + /* Reset the texture images' info to zeros.
>>> + * Strictly speaking, we probably don't have to do this
>>> since
>>> + * generating GL_OUT_OF_MEMORY can leave things in an
>>> undefined
>>> + * state but this puts things in a consistent state.
>>> + */
>>> + clear_texture_fields(ctx, texObj);
>>> + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD",
>>> + suffix, dims);
>>> + return;
>>> + }
>>> }
>>> _mesa_set_texture_view_state(ctx, texObj, target, levels);
>>> update_fbo_texture(ctx, texObj);
>>> }
>>> }
>>> static void
>>> texture_storage_error(struct gl_context *ctx, GLuint dims,
>>> struct gl_texture_object *texObj,
>>> GLenum target, GLsizei levels,
>>> GLenum internalformat, GLsizei width,
>>> GLsizei height, GLsizei depth, bool dsa)
>>> {
>>> - texture_storage(ctx, dims, texObj, target, levels,
>>> internalformat, width,
>>> - height, depth, dsa, false);
>>> + texture_storage(ctx, dims, texObj, NULL, target, levels,
>>> internalformat,
>>> + width, height, depth, dsa, 0, false);
>>> }
>>> static void
>>> texture_storage_no_error(struct gl_context *ctx, GLuint dims,
>>> struct gl_texture_object *texObj,
>>> GLenum target, GLsizei levels,
>>> GLenum internalformat, GLsizei width,
>>> GLsizei height, GLsizei depth, bool dsa)
>>> {
>>> - texture_storage(ctx, dims, texObj, target, levels,
>>> internalformat, width,
>>> - height, depth, dsa, true);
>>> + texture_storage(ctx, dims, texObj, NULL, target, levels,
>>> internalformat,
>>> + width, height, depth, dsa, 0, true);
>>> }
>>> /**
>>> * Helper used by _mesa_TexStorage1/2/3D().
>>> */
>>> static void
>>> texstorage_error(GLuint dims, GLenum target, GLsizei levels,
>>> GLenum internalformat, GLsizei width, GLsizei height,
>>> GLsizei depth, const char *caller)
>>> @@ -777,10 +793,26 @@ _mesa_TextureStorage3DEXT(GLuint texture,
>>> GLenum target, GLsizei levels,
>>> (void) target;
>>> (void) levels;
>>> (void) internalformat;
>>> (void) width;
>>> (void) height;
>>> (void) depth;
>>> _mesa_error(ctx, GL_INVALID_OPERATION,
>>> "glTextureStorage3DEXT not supported");
>>> }
>>> +
>>> +
>>> +void
>>> +_mesa_texture_storage_memory(struct gl_context *ctx, GLuint dims,
>>> + struct gl_texture_object *texObj,
>>> + struct gl_memory_object *memObj,
>>> + GLenum target, GLsizei levels,
>>> + GLenum internalformat, GLsizei width,
>>> + GLsizei height, GLsizei depth,
>>> + GLuint64 offset, bool dsa)
>>> +{
>>> + assert(memObj);
>>> +
>>> + texture_storage(ctx, dims, texObj, memObj, target, levels,
>>> internalformat,
>>> + width, height, depth, offset, dsa, false);
>>> +}
>>> diff --git a/src/mesa/main/texstorage.h b/src/mesa/main/texstorage.h
>>> index 66b77be4e1..f184dfd86e 100644
>>> --- a/src/mesa/main/texstorage.h
>>> +++ b/src/mesa/main/texstorage.h
>>> @@ -130,11 +130,20 @@ _mesa_TextureStorage3DEXT(GLuint texture,
>>> GLenum target, GLsizei levels,
>>> extern GLboolean
>>> _mesa_is_legal_tex_storage_format(const struct gl_context *ctx,
>>> GLenum internalformat);
>>> extern GLboolean
>>> _mesa_AllocTextureStorage_sw(struct gl_context *ctx,
>>> struct gl_texture_object *texObj,
>>> GLsizei levels, GLsizei width,
>>> GLsizei height, GLsizei depth);
>>> +extern void
>>> +_mesa_texture_storage_memory(struct gl_context *ctx, GLuint dims,
>>> + struct gl_texture_object *texObj,
>>> + struct gl_memory_object *memObj,
>>> + GLenum target, GLsizei levels,
>>> + GLenum internalformat, GLsizei width,
>>> + GLsizei height, GLsizei depth,
>>> + GLuint64 offset, bool dsa);
>>> +
>>> #endif /* TEXSTORAGE_H */
>>>
More information about the mesa-dev
mailing list