[Mesa-dev] [PATCH 06/23] mesa: hook up memoryobject tex(ture)storage api
Samuel Pitoiset
samuel.pitoiset at gmail.com
Fri Aug 4 08:45:32 UTC 2017
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?
> +
> + 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