vrend: extract functions from vrend_renderer_resource_create

Two functions are extracted from vrend_renderer_resource_create to
make it possible to allocate a texture resource without adding too much
code duplication:

vrend_renderer_resource_copy_args:
   copies all required arguments from the args struct into the
   already allocated resource

vrend_renderer_resource_allocate_texture:
   Allocate a texture using the parameters in the given resource struct

v2: * instead of extracting the complete allocation also including buffers,
      only extract the parts that copy the parameters and allocate the texture
    * use latest upstream that also includes texture storage objects

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Tested-by: Jakob Bornecrantz <jakob@collabora.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
macos/master
Gert Wollny 7 years ago committed by Dave Airlie
parent 041c6f5473
commit 167e3ccbb9
  1. 280
      src/vrend_renderer.c

@ -4772,10 +4772,156 @@ static void vrend_create_buffer(struct vrend_resource *gr, uint32_t width)
gr->is_buffer = true;
}
static inline void
vrend_renderer_resource_copy_args(struct vrend_renderer_resource_create_args *args,
struct vrend_resource *gr)
{
assert(gr);
assert(args);
gr->handle = args->handle;
gr->base.width0 = args->width;
gr->base.height0 = args->height;
gr->base.depth0 = args->depth;
gr->base.format = args->format;
gr->base.target = args->target;
gr->base.last_level = args->last_level;
gr->base.nr_samples = args->nr_samples;
gr->base.array_size = args->array_size;
}
static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr)
{
uint level;
GLenum internalformat, glformat, gltype;
struct vrend_texture *gt = (struct vrend_texture *)gr;
struct pipe_resource *pr = &gr->base;
assert(pr->width0 > 0);
gr->target = tgsitargettogltarget(pr->target, pr->nr_samples);
/* ugly workaround for texture rectangle missing on GLES */
if (vrend_state.use_gles && gr->target == GL_TEXTURE_RECTANGLE_NV) {
/* for some guests this is the only usage of rect */
if (pr->width0 != 1 || pr->height0 != 1) {
report_gles_warn(NULL, GLES_WARN_TEXTURE_RECT, 0);
}
gr->target = GL_TEXTURE_2D;
}
/* fallback for 1D textures */
if (vrend_state.use_gles && gr->target == GL_TEXTURE_1D) {
gr->target = GL_TEXTURE_2D;
}
/* fallback for 1D array textures */
if (vrend_state.use_gles && gr->target == GL_TEXTURE_1D_ARRAY) {
gr->target = GL_TEXTURE_2D_ARRAY;
}
glGenTextures(1, &gr->id);
glBindTexture(gr->target, gr->id);
internalformat = tex_conv_table[pr->format].internalformat;
glformat = tex_conv_table[pr->format].glformat;
gltype = tex_conv_table[pr->format].gltype;
if (internalformat == 0) {
fprintf(stderr,"unknown format is %d\n", pr->format);
FREE(gt);
return EINVAL;
}
if (pr->nr_samples > 1) {
if (vrend_state.use_gles) {
if (gr->target == GL_TEXTURE_2D_MULTISAMPLE) {
glTexStorage2DMultisample(gr->target, pr->nr_samples,
internalformat, pr->width0, pr->height0,
GL_TRUE);
} else {
glTexStorage3DMultisample(gr->target, pr->nr_samples,
internalformat, pr->width0, pr->height0, pr->array_size,
GL_TRUE);
}
} else {
if (gr->target == GL_TEXTURE_2D_MULTISAMPLE) {
glTexImage2DMultisample(gr->target, pr->nr_samples,
internalformat, pr->width0, pr->height0,
GL_TRUE);
} else {
glTexImage3DMultisample(gr->target, pr->nr_samples,
internalformat, pr->width0, pr->height0, pr->array_size,
GL_TRUE);
}
}
} else if (gr->target == GL_TEXTURE_CUBE_MAP) {
int i;
if (vrend_state.have_texture_storage)
glTexStorage2D(GL_TEXTURE_CUBE_MAP, pr->last_level + 1, internalformat, pr->width0, pr->height0);
else {
for (i = 0; i < 6; i++) {
GLenum ctarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
for (level = 0; level <= pr->last_level; level++) {
unsigned mwidth = u_minify(pr->width0, level);
unsigned mheight = u_minify(pr->height0, level);
glTexImage2D(ctarget, level, internalformat, mwidth, mheight, 0, glformat,
gltype, NULL);
}
}
}
} else if (gr->target == GL_TEXTURE_3D ||
gr->target == GL_TEXTURE_2D_ARRAY ||
gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) {
if (vrend_state.have_texture_storage) {
unsigned depth_param = (gr->target == GL_TEXTURE_2D_ARRAY || gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) ?
pr->array_size : pr->depth0;
glTexStorage3D(gr->target, pr->last_level + 1, internalformat, pr->width0, pr->height0, depth_param);
} else {
for (level = 0; level <= pr->last_level; level++) {
unsigned depth_param = (gr->target == GL_TEXTURE_2D_ARRAY || gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) ?
pr->array_size : u_minify(pr->depth0, level);
unsigned mwidth = u_minify(pr->width0, level);
unsigned mheight = u_minify(pr->height0, level);
glTexImage3D(gr->target, level, internalformat, mwidth, mheight,
depth_param, 0, glformat, gltype, NULL);
}
}
} else if (gr->target == GL_TEXTURE_1D && vrend_state.use_gles) {
report_gles_missing_func(NULL, "glTexImage1D");
} else if (gr->target == GL_TEXTURE_1D) {
if (vrend_state.have_texture_storage) {
glTexStorage1D(gr->target, pr->last_level + 1, internalformat, pr->width0);
} else {
for (level = 0; level <= pr->last_level; level++) {
unsigned mwidth = u_minify(pr->width0, level);
glTexImage1D(gr->target, level, internalformat, mwidth, 0,
glformat, gltype, NULL);
}
}
} else {
if (vrend_state.have_texture_storage)
glTexStorage2D(gr->target, pr->last_level + 1, internalformat, pr->width0,
gr->target == GL_TEXTURE_1D_ARRAY ? pr->array_size : pr->height0);
else {
for (level = 0; level <= pr->last_level; level++) {
unsigned mwidth = u_minify(pr->width0, level);
unsigned mheight = u_minify(pr->height0, level);
glTexImage2D(gr->target, level, internalformat, mwidth,
gr->target == GL_TEXTURE_1D_ARRAY ? pr->array_size : mheight,
0, glformat, gltype, NULL);
}
}
}
gt->state.max_lod = -1;
gt->cur_swizzle_r = gt->cur_swizzle_g = gt->cur_swizzle_b = gt->cur_swizzle_a = -1;
return 0;
}
int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs)
{
struct vrend_resource *gr;
uint32_t level;
int ret;
ret = check_resource_valid(args);
@ -4786,17 +4932,9 @@ int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *a
if (!gr)
return ENOMEM;
gr->handle = args->handle;
vrend_renderer_resource_copy_args(args, gr);
gr->iov = iov;
gr->num_iovs = num_iovs;
gr->base.width0 = args->width;
gr->base.height0 = args->height;
gr->base.depth0 = args->depth;
gr->base.format = args->format;
gr->base.target = args->target;
gr->base.last_level = args->last_level;
gr->base.nr_samples = args->nr_samples;
gr->base.array_size = args->array_size;
if (args->flags & VIRGL_RESOURCE_Y_0_TOP)
gr->y_0_top = true;
@ -4842,125 +4980,9 @@ int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *a
}
vrend_create_buffer(gr, args->width);
} else {
struct vrend_texture *gt = (struct vrend_texture *)gr;
GLenum internalformat, glformat, gltype;
gr->target = tgsitargettogltarget(args->target, args->nr_samples);
/* ugly workaround for texture rectangle missing on GLES */
if (vrend_state.use_gles && gr->target == GL_TEXTURE_RECTANGLE_NV) {
/* for some guests this is the only usage of rect */
if (args->width != 1 || args->height != 1) {
report_gles_warn(NULL, GLES_WARN_TEXTURE_RECT, 0);
}
gr->target = GL_TEXTURE_2D;
}
/* fallback for 1D textures */
if (vrend_state.use_gles && gr->target == GL_TEXTURE_1D) {
gr->target = GL_TEXTURE_2D;
}
/* fallback for 1D array textures */
if (vrend_state.use_gles && gr->target == GL_TEXTURE_1D_ARRAY) {
gr->target = GL_TEXTURE_2D_ARRAY;
}
glGenTextures(1, &gr->id);
glBindTexture(gr->target, gr->id);
internalformat = tex_conv_table[args->format].internalformat;
glformat = tex_conv_table[args->format].glformat;
gltype = tex_conv_table[args->format].gltype;
if (internalformat == 0) {
fprintf(stderr,"unknown format is %d\n", args->format);
FREE(gr);
return EINVAL;
}
if (args->nr_samples > 1) {
if (vrend_state.use_gles || vrend_state.have_texture_storage) {
if (gr->target == GL_TEXTURE_2D_MULTISAMPLE) {
glTexStorage2DMultisample(gr->target, args->nr_samples,
internalformat, args->width, args->height,
GL_TRUE);
} else {
glTexStorage3DMultisample(gr->target, args->nr_samples,
internalformat, args->width, args->height, args->array_size,
GL_TRUE);
}
} else {
if (gr->target == GL_TEXTURE_2D_MULTISAMPLE) {
glTexImage2DMultisample(gr->target, args->nr_samples,
internalformat, args->width, args->height,
GL_TRUE);
} else {
glTexImage3DMultisample(gr->target, args->nr_samples,
internalformat, args->width, args->height, args->array_size,
GL_TRUE);
}
}
} else if (gr->target == GL_TEXTURE_CUBE_MAP) {
int i;
if (vrend_state.have_texture_storage)
glTexStorage2D(GL_TEXTURE_CUBE_MAP, args->last_level + 1, internalformat, args->width, args->height);
else {
for (i = 0; i < 6; i++) {
GLenum ctarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
for (level = 0; level <= args->last_level; level++) {
unsigned mwidth = u_minify(args->width, level);
unsigned mheight = u_minify(args->height, level);
glTexImage2D(ctarget, level, internalformat, mwidth, mheight, 0, glformat,
gltype, NULL);
}
}
}
} else if (gr->target == GL_TEXTURE_3D ||
gr->target == GL_TEXTURE_2D_ARRAY ||
gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) {
if (vrend_state.have_texture_storage) {
unsigned depth_param = (gr->target == GL_TEXTURE_2D_ARRAY || gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) ? args->array_size : args->depth;
glTexStorage3D(gr->target, args->last_level + 1, internalformat, args->width, args->height, depth_param);
} else {
for (level = 0; level <= args->last_level; level++) {
unsigned depth_param = (gr->target == GL_TEXTURE_2D_ARRAY || gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) ? args->array_size : u_minify(args->depth, level);
unsigned mwidth = u_minify(args->width, level);
unsigned mheight = u_minify(args->height, level);
glTexImage3D(gr->target, level, internalformat, mwidth, mheight, depth_param, 0,
glformat,
gltype, NULL);
}
}
} else if (gr->target == GL_TEXTURE_1D && vrend_state.use_gles) {
report_gles_missing_func(NULL, "glTexImage1D");
} else if (gr->target == GL_TEXTURE_1D) {
if (vrend_state.have_texture_storage) {
glTexStorage1D(gr->target, args->last_level + 1, internalformat, args->width);
} else {
for (level = 0; level <= args->last_level; level++) {
unsigned mwidth = u_minify(args->width, level);
glTexImage1D(gr->target, level, internalformat, mwidth, 0,
glformat,
gltype, NULL);
}
}
} else {
if (vrend_state.have_texture_storage)
glTexStorage2D(gr->target, args->last_level + 1, internalformat, args->width,
gr->target == GL_TEXTURE_1D_ARRAY ? args->array_size : args->height);
else {
for (level = 0; level <= args->last_level; level++) {
unsigned mwidth = u_minify(args->width, level);
unsigned mheight = u_minify(args->height, level);
glTexImage2D(gr->target, level, internalformat, mwidth, gr->target == GL_TEXTURE_1D_ARRAY ? args->array_size : mheight, 0, glformat,
gltype, NULL);
}
}
}
gt->state.max_lod = -1;
gt->cur_swizzle_r = gt->cur_swizzle_g = gt->cur_swizzle_b = gt->cur_swizzle_a = -1;
int r = vrend_renderer_resource_allocate_texture(gr);
if (r)
return r;
}
ret = vrend_resource_insert(gr, args->handle);

Loading…
Cancel
Save