[virglrenderer-devel] [PATCH v2 1/2] vrend: extract functions from vrend_renderer_resource_create
Gert Wollny
gert.wollny at collabora.com
Tue Jun 12 10:55:40 UTC 2018
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 at collabora.com>
---
src/vrend_renderer.c | 280 +++++++++++++++++++++++--------------------
1 file changed, 151 insertions(+), 129 deletions(-)
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index d57247e..9a7412b 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -4599,10 +4599,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);
@@ -4613,17 +4759,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;
@@ -4669,125 +4807,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);
--
2.17.1
More information about the virglrenderer-devel
mailing list