mesa/st: implement memory objects as a backend for texture storage

Instead of allocating memory to back a texture, use the provided memory
object.

v2: split off extension exposure logic
v3: de-duplicate code with st_AllocTextureStorage

Signed-off-by: Andres Rodriguez <andresx7@gmail.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
This commit is contained in:
Dave Airlie 2017-07-12 18:45:14 -04:00 committed by Timothy Arceri
parent 999653e398
commit 7683540029
2 changed files with 106 additions and 12 deletions

View file

@ -175,7 +175,7 @@ static GLboolean
st_bufferobj_data(struct gl_context *ctx,
GLenum target,
GLsizeiptrARB size,
const void * data,
const void *data,
GLenum usage,
GLbitfield storageFlags,
struct gl_buffer_object *obj)

View file

@ -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"
@ -2647,6 +2648,64 @@ st_finalize_texture(struct gl_context *ctx,
return GL_TRUE;
}
/**
* 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_from_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;
}
/**
* Allocate texture memory for a whole mipmap stack.
* Note: for multisample textures if the requested sample count is not
@ -2656,12 +2715,15 @@ static GLboolean
st_texture_storage(struct gl_context *ctx,
struct gl_texture_object *texObj,
GLsizei levels, GLsizei width,
GLsizei height, GLsizei depth)
GLsizei height, GLsizei depth,
struct gl_memory_object *memObj,
GLuint64 offset)
{
const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
struct gl_texture_image *texImage = texObj->Image[0][0];
struct st_context *st = st_context(ctx);
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, bindings;
uint16_t ptHeight, ptDepth, ptLayers;
@ -2705,15 +2767,31 @@ st_texture_storage(struct gl_context *ctx,
width, height, depth,
&ptWidth, &ptHeight, &ptDepth, &ptLayers);
stObj->pt = st_texture_create(st,
gl_target_to_pipe(texObj->Target),
fmt,
levels - 1,
ptWidth,
ptHeight,
ptDepth,
ptLayers, num_samples,
bindings);
if (smObj) {
stObj->pt = st_texture_create_from_memory(st,
smObj,
offset,
gl_target_to_pipe(texObj->Target),
fmt,
levels - 1,
ptWidth,
ptHeight,
ptDepth,
ptLayers, num_samples,
bindings);
}
else {
stObj->pt = st_texture_create(st,
gl_target_to_pipe(texObj->Target),
fmt,
levels - 1,
ptWidth,
ptHeight,
ptDepth,
ptLayers, num_samples,
bindings);
}
if (!stObj->pt)
return GL_FALSE;
@ -2748,7 +2826,8 @@ st_AllocTextureStorage(struct gl_context *ctx,
GLsizei height, GLsizei depth)
{
return st_texture_storage(ctx, texObj, levels,
width, height, depth);
width, height, depth,
NULL, 0);
}
@ -2972,6 +3051,18 @@ st_TexParameter(struct gl_context *ctx,
}
}
static GLboolean
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)
{
return st_texture_storage(ctx, texObj, levels,
width, height, depth,
memObj, offset);
}
static GLuint64
st_NewTextureHandle(struct gl_context *ctx, struct gl_texture_object *texObj,
@ -3094,4 +3185,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;
}