[Mesa-dev] [PATCH 08/19] mesa/st: implement memory objects as a backend for texture storage
Andres Rodriguez
andresx7 at gmail.com
Fri Jun 30 23:03:01 UTC 2017
From: Dave Airlie <airlied at redhat.com>
Instead of allocating memory to back a texture, use the provided memory
object.
Signed-off-by: Andres Rodriguez <andresx7 at gmail.com>
---
src/mesa/main/mtypes.h | 2 +
src/mesa/state_tracker/st_cb_texture.c | 123 +++++++++++++++++++++++++++++++++
src/mesa/state_tracker/st_extensions.c | 5 ++
3 files changed, 130 insertions(+)
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 8dcc1a8..463f444 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -4125,6 +4125,8 @@ struct gl_extensions
GLboolean EXT_framebuffer_sRGB;
GLboolean EXT_gpu_program_parameters;
GLboolean EXT_gpu_shader4;
+ GLboolean EXT_memory_object;
+ GLboolean EXT_memory_object_fd;
GLboolean EXT_packed_float;
GLboolean EXT_pixel_buffer_object;
GLboolean EXT_point_parameters;
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 9798321..063f6d6 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -53,6 +53,7 @@
#include "state_tracker/st_cb_flush.h"
#include "state_tracker/st_cb_texture.h"
#include "state_tracker/st_cb_bufferobjects.h"
+#include "state_tracker/st_cb_memoryobjects.h"
#include "state_tracker/st_format.h"
#include "state_tracker/st_pbo.h"
#include "state_tracker/st_texture.h"
@@ -2890,6 +2891,125 @@ st_TexParameter(struct gl_context *ctx,
}
}
+/**
+ * Allocate a new pipe_resource object
+ * width0, height0, depth0 are the dimensions of the level 0 image
+ * (the highest resolution). last_level indicates how many mipmap levels
+ * to allocate storage for. For non-mipmapped textures, this will be zero.
+ */
+static struct pipe_resource *
+st_texture_create_memory(struct st_context *st,
+ struct st_memory_object *memObj,
+ GLuint64 offset,
+ enum pipe_texture_target target,
+ enum pipe_format format,
+ GLuint last_level,
+ GLuint width0,
+ GLuint height0,
+ GLuint depth0,
+ GLuint layers,
+ GLuint nr_samples,
+ GLuint bind )
+{
+ struct pipe_resource pt, *newtex;
+ struct pipe_screen *screen = st->pipe->screen;
+
+ assert(target < PIPE_MAX_TEXTURE_TYPES);
+ assert(width0 > 0);
+ assert(height0 > 0);
+ assert(depth0 > 0);
+ if (target == PIPE_TEXTURE_CUBE)
+ assert(layers == 6);
+
+ DBG("%s target %d format %s last_level %d\n", __func__,
+ (int) target, util_format_name(format), last_level);
+
+ assert(format);
+ assert(screen->is_format_supported(screen, format, target, 0,
+ PIPE_BIND_SAMPLER_VIEW));
+
+ memset(&pt, 0, sizeof(pt));
+ pt.target = target;
+ pt.format = format;
+ pt.last_level = last_level;
+ pt.width0 = width0;
+ pt.height0 = height0;
+ pt.depth0 = depth0;
+ pt.array_size = layers;
+ pt.usage = PIPE_USAGE_DEFAULT;
+ pt.bind = bind;
+ /* only set this for OpenGL textures, not renderbuffers */
+ pt.flags = PIPE_RESOURCE_FLAG_TEXTURING_MORE_LIKELY;
+ pt.nr_samples = nr_samples;
+
+ newtex = screen->resource_from_memobj(screen, &pt, memObj->memory, offset);
+
+ assert(!newtex || pipe_is_referenced(&newtex->reference));
+
+ return newtex;
+}
+
+
+static bool
+st_SetTextureStorageForMemoryObject(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ struct gl_memory_object *memObj,
+ GLsizei levels, GLsizei width,
+ GLsizei height, GLsizei depth,
+ GLuint64 offset)
+{
+ struct st_context *st = st_context(ctx);
+ struct gl_texture_image *texImage = texObj->Image[0][0];
+ struct st_texture_object *stObj = st_texture_object(texObj);
+ struct st_memory_object *smObj = st_memory_object(memObj);
+ struct pipe_screen *screen = st->pipe->screen;
+ unsigned ptWidth;
+ uint16_t ptHeight, ptDepth, ptLayers;
+ GLuint bindings;
+ enum pipe_format fmt;
+ GLuint num_samples = texImage->NumSamples;
+
+ stObj->lastLevel = levels - 1;
+
+ fmt = st_mesa_format_to_pipe_format(st, texImage->TexFormat);
+
+ bindings = default_bindings(st, fmt);
+
+ /* Raise the sample count if the requested one is unsupported. */
+ if (num_samples > 1) {
+ GLboolean found = GL_FALSE;
+
+ for (; num_samples <= ctx->Const.MaxSamples; num_samples++) {
+ if (screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D,
+ num_samples,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ /* Update the sample count in gl_texture_image as well. */
+ texImage->NumSamples = num_samples;
+ found = GL_TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ return GL_FALSE;
+ }
+
+ st_gl_texture_dims_to_pipe_dims(texObj->Target,
+ width, height, depth,
+ &ptWidth, &ptHeight, &ptDepth, &ptLayers);
+ stObj->pt = st_texture_create_memory(st,
+ smObj,
+ offset,
+ gl_target_to_pipe(texObj->Target),
+ fmt,
+ levels - 1,
+ ptWidth,
+ ptHeight,
+ ptDepth,
+ ptLayers, num_samples,
+ bindings);
+ return stObj->pt ? GL_TRUE : GL_FALSE;
+}
static GLuint64
st_NewTextureHandle(struct gl_context *ctx, struct gl_texture_object *texObj,
@@ -3012,4 +3132,7 @@ st_init_texture_functions(struct dd_function_table *functions)
functions->NewImageHandle = st_NewImageHandle;
functions->DeleteImageHandle = st_DeleteImageHandle;
functions->MakeImageHandleResident = st_MakeImageHandleResident;
+
+ /* external object functions */
+ functions->SetTextureStorageForMemoryObject = st_SetTextureStorageForMemoryObject;
}
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 74193cc..6fd2fa0 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -1321,4 +1321,9 @@ void st_init_extensions(struct pipe_screen *screen,
extensions->ARB_texture_cube_map_array &&
extensions->ARB_texture_stencil8 &&
extensions->ARB_texture_multisample;
+
+ if (screen->memobj_create_from_handle) {
+ extensions->EXT_memory_object = GL_TRUE;
+ extensions->EXT_memory_object_fd = GL_TRUE;
+ }
}
--
2.9.3
More information about the mesa-dev
mailing list