[Mesa-dev] [PATCH 06/23] mesa: hook up memoryobject tex(ture)storage api
Timothy Arceri
tarceri at itsqueeze.com
Fri Aug 4 09:10:15 UTC 2017
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.
>
>> +
>> + 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