vrend: move GL blitter parameter list to a struct

Related: https://gitlab.freedesktop.org/virgl/virglrenderer/-/issues/125

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Reviewed-by: Corentin Noël <corentin.noel@collabora.com>.
macos/master
Gert Wollny 3 years ago
parent 4a5189267c
commit edaeae1261
  1. 51
      src/vrend_blitter.c
  2. 96
      src/vrend_renderer.c
  3. 19
      src/vrend_renderer.h

@ -702,11 +702,7 @@ static void vrend_set_vertex_param(GLuint prog_id)
void vrend_renderer_blit_gl(ASSERTED struct vrend_context *ctx, void vrend_renderer_blit_gl(ASSERTED struct vrend_context *ctx,
struct vrend_resource *src_res, struct vrend_resource *src_res,
struct vrend_resource *dst_res, struct vrend_resource *dst_res,
GLenum blit_views[2], struct vrend_blit_info *info)
const struct pipe_blit_info *info,
bool has_texture_srgb_decode,
bool has_srgb_write_control,
uint8_t swizzle[static 4])
{ {
struct vrend_blitter_ctx *blit_ctx = &vrend_blit_ctx; struct vrend_blitter_ctx *blit_ctx = &vrend_blit_ctx;
GLuint buffers; GLuint buffers;
@ -720,18 +716,18 @@ void vrend_renderer_blit_gl(ASSERTED struct vrend_context *ctx,
util_format_description(src_res->base.format); util_format_description(src_res->base.format);
const struct util_format_description *dst_desc = const struct util_format_description *dst_desc =
util_format_description(dst_res->base.format); util_format_description(dst_res->base.format);
const struct vrend_format_table *orig_src_entry = vrend_get_format_table_entry(info->src.format); const struct vrend_format_table *orig_src_entry = vrend_get_format_table_entry(info->b.src.format);
has_depth = util_format_has_depth(src_desc) && has_depth = util_format_has_depth(src_desc) &&
util_format_has_depth(dst_desc); util_format_has_depth(dst_desc);
has_stencil = util_format_has_stencil(src_desc) && has_stencil = util_format_has_stencil(src_desc) &&
util_format_has_stencil(dst_desc); util_format_has_stencil(dst_desc);
blit_depth = has_depth && (info->mask & PIPE_MASK_Z); blit_depth = has_depth && (info->b.mask & PIPE_MASK_Z);
blit_stencil = has_stencil && (info->mask & PIPE_MASK_S) & 0; blit_stencil = has_stencil && (info->b.mask & PIPE_MASK_S) & 0;
vrend_renderer_init_blit_ctx(blit_ctx); vrend_renderer_init_blit_ctx(blit_ctx);
blitter_set_points(blit_ctx, info, src_res, dst_res, &src0, &src1); blitter_set_points(blit_ctx, &info->b, src_res, dst_res, &src0, &src1);
prog_id = glCreateProgram(); prog_id = glCreateProgram();
glAttachShader(prog_id, blit_ctx->vs); glAttachShader(prog_id, blit_ctx->vs);
@ -741,11 +737,11 @@ void vrend_renderer_blit_gl(ASSERTED struct vrend_context *ctx,
src_res->base.nr_samples); src_res->base.nr_samples);
} else { } else {
VREND_DEBUG(dbg_blit, ctx, "BLIT: applying swizzle during blit: (%d %d %d %d)\n", VREND_DEBUG(dbg_blit, ctx, "BLIT: applying swizzle during blit: (%d %d %d %d)\n",
swizzle[0], swizzle[1], swizzle[2], swizzle[3]); info->swizzle[0], info->swizzle[1], info->swizzle[2], info->swizzle[3]);
fs_id = blit_get_frag_tex_col(blit_ctx, src_res->base.target, fs_id = blit_get_frag_tex_col(blit_ctx, src_res->base.target,
src_res->base.nr_samples, src_res->base.nr_samples,
orig_src_entry, orig_src_entry,
swizzle); info->swizzle);
} }
glAttachShader(prog_id, fs_id); glAttachShader(prog_id, fs_id);
@ -755,25 +751,27 @@ void vrend_renderer_blit_gl(ASSERTED struct vrend_context *ctx,
glUseProgram(prog_id); glUseProgram(prog_id);
glBindFramebuffer(GL_FRAMEBUFFER, blit_ctx->fb_id); glBindFramebuffer(GL_FRAMEBUFFER, blit_ctx->fb_id);
vrend_fb_bind_texture_id(dst_res, blit_views[1], 0, info->dst.level, info->dst.box.z, 0); vrend_fb_bind_texture_id(dst_res, info->dst_view, 0, info->b.dst.level, info->b.dst.box.z, 0);
buffers = GL_COLOR_ATTACHMENT0; buffers = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1, &buffers); glDrawBuffers(1, &buffers);
glBindTexture(src_res->target, blit_views[0]); glBindTexture(src_res->target, info->src_view);
vrend_set_tex_param(src_res, info, has_texture_srgb_decode); vrend_set_tex_param(src_res, &info->b, info->has_texture_srgb_decode);
vrend_set_vertex_param(prog_id); vrend_set_vertex_param(prog_id);
set_dsa_write_depth_keep_stencil(); set_dsa_write_depth_keep_stencil();
if (info->scissor_enable) { if (info->b.scissor_enable) {
glScissor(info->scissor.minx, info->scissor.miny, info->scissor.maxx - info->scissor.minx, info->scissor.maxy - info->scissor.miny); glScissor(info->b.scissor.minx, info->b.scissor.miny,
info->b.scissor.maxx - info->b.scissor.minx,
info->b.scissor.maxy - info->b.scissor.miny);
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
} else } else
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);
if (has_srgb_write_control) { if (info->has_srgb_write_control) {
if (util_format_is_srgb(info->dst.format) || util_format_is_srgb(info->src.format)) { if (util_format_is_srgb(info->b.dst.format) || util_format_is_srgb(info->b.src.format)) {
VREND_DEBUG(dbg_blit, ctx, "%s: Enable GL_FRAMEBUFFER_SRGB\n", __func__); VREND_DEBUG(dbg_blit, ctx, "%s: Enable GL_FRAMEBUFFER_SRGB\n", __func__);
glEnable(GL_FRAMEBUFFER_SRGB); glEnable(GL_FRAMEBUFFER_SRGB);
} else { } else {
@ -782,22 +780,23 @@ void vrend_renderer_blit_gl(ASSERTED struct vrend_context *ctx,
} }
} }
for (dst_z = 0; dst_z < info->dst.box.depth; dst_z++) { for (dst_z = 0; dst_z < info->b.dst.box.depth; dst_z++) {
float dst2src_scale = info->src.box.depth / (float)info->dst.box.depth; float dst2src_scale = info->b.src.box.depth / (float)info->b.dst.box.depth;
float dst_offset = ((info->src.box.depth - 1) - float dst_offset = ((info->b.src.box.depth - 1) -
(info->dst.box.depth - 1) * dst2src_scale) * 0.5; (info->b.dst.box.depth - 1) * dst2src_scale) * 0.5;
float src_z = (dst_z + dst_offset) * dst2src_scale; float src_z = (dst_z + dst_offset) * dst2src_scale;
uint32_t layer = (dst_res->target == GL_TEXTURE_CUBE_MAP || uint32_t layer = (dst_res->target == GL_TEXTURE_CUBE_MAP ||
dst_res->target == GL_TEXTURE_1D_ARRAY || dst_res->target == GL_TEXTURE_1D_ARRAY ||
dst_res->target == GL_TEXTURE_2D_ARRAY) ? info->dst.box.z : dst_z; dst_res->target == GL_TEXTURE_2D_ARRAY) ? info->b.dst.box.z : dst_z;
glBindFramebuffer(GL_FRAMEBUFFER, blit_ctx->fb_id); glBindFramebuffer(GL_FRAMEBUFFER, blit_ctx->fb_id);
vrend_fb_bind_texture_id(dst_res, blit_views[1], 0, info->dst.level, layer, 0); vrend_fb_bind_texture_id(dst_res, info->dst_view, 0, info->b.dst.level, layer, 0);
buffers = GL_COLOR_ATTACHMENT0; buffers = GL_COLOR_ATTACHMENT0;
glDrawBuffers(1, &buffers); glDrawBuffers(1, &buffers);
blitter_set_texcoords(blit_ctx, src_res, info->src.level, blitter_set_texcoords(blit_ctx, src_res, info->b.src.level,
info->src.box.z + src_z, 0, info->b.src.box.z + src_z, 0,
src0.x, src0.y, src1.x, src1.y); src0.x, src0.y, src1.x, src1.y);
glBufferData(GL_ARRAY_BUFFER, sizeof(blit_ctx->vertices), blit_ctx->vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(blit_ctx->vertices), blit_ctx->vertices, GL_STATIC_DRAW);

@ -9079,20 +9079,24 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
struct vrend_resource *dst_res, struct vrend_resource *dst_res,
const struct pipe_blit_info *info) const struct pipe_blit_info *info)
{ {
struct vrend_blit_info blit_info = {
.b = *info,
.src_view = src_res->id,
.dst_view = dst_res->id,
.needs_swizzle = false,
.can_fbo_blit = true,
.gl_filter = convert_mag_filter(info->filter),
.swizzle = {0, 1, 2, 3},
};
GLbitfield glmask = 0; GLbitfield glmask = 0;
int src_y1, src_y2, dst_y1, dst_y2;
GLenum filter;
int n_layers = 1, i; int n_layers = 1, i;
bool use_gl = false; bool use_gl = false;
bool needs_swizzle = false;
bool make_intermediate_copy = false; bool make_intermediate_copy = false;
GLuint intermediate_fbo = 0; GLuint intermediate_fbo = 0;
struct vrend_resource *intermediate_copy = 0; struct vrend_resource *intermediate_copy = 0;
GLuint blitter_views[2] = {src_res->id, dst_res->id};
filter = convert_mag_filter(info->filter);
/* if we can't make FBO's use the fallback path */ /* if we can't make FBO's use the fallback path */
if (!vrend_format_can_render(src_res->base.format) && if (!vrend_format_can_render(src_res->base.format) &&
!vrend_format_is_ds(src_res->base.format)) !vrend_format_is_ds(src_res->base.format))
@ -9123,25 +9127,25 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
(info->src.box.width != info->dst.box.width || (info->src.box.width != info->dst.box.width ||
info->src.box.height != info->dst.box.height)) { info->src.box.height != info->dst.box.height)) {
if (has_feature(feat_ms_scaled_blit)) if (has_feature(feat_ms_scaled_blit))
filter = GL_SCALED_RESOLVE_NICEST_EXT; blit_info.gl_filter = GL_SCALED_RESOLVE_NICEST_EXT;
else else
use_gl = true; use_gl = true;
} }
if (!dst_res->y_0_top) { if (!dst_res->y_0_top) {
dst_y1 = info->dst.box.y + info->dst.box.height; blit_info.dst_y1 = info->dst.box.y + info->dst.box.height;
dst_y2 = info->dst.box.y; blit_info.dst_y2 = info->dst.box.y;
} else { } else {
dst_y1 = dst_res->base.height0 - info->dst.box.y - info->dst.box.height; blit_info.dst_y1 = dst_res->base.height0 - info->dst.box.y - info->dst.box.height;
dst_y2 = dst_res->base.height0 - info->dst.box.y; blit_info.dst_y2 = dst_res->base.height0 - info->dst.box.y;
} }
if (!src_res->y_0_top) { if (!src_res->y_0_top) {
src_y1 = info->src.box.y + info->src.box.height; blit_info.src_y1 = info->src.box.y + info->src.box.height;
src_y2 = info->src.box.y; blit_info.src_y2 = info->src.box.y;
} else { } else {
src_y1 = src_res->base.height0 - info->src.box.y - info->src.box.height; blit_info.src_y1 = src_res->base.height0 - info->src.box.y - info->src.box.height;
src_y2 = src_res->base.height0 - info->src.box.y; blit_info.src_y2 = src_res->base.height0 - info->src.box.y;
} }
/* since upstream mesa change /* since upstream mesa change
@ -9170,13 +9174,15 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
(src_res->base.nr_samples > 0) && (src_res->base.nr_samples > 0) &&
(info->src.box.x != info->dst.box.x || (info->src.box.x != info->dst.box.x ||
info->src.box.width != info->dst.box.width || info->src.box.width != info->dst.box.width ||
dst_y1 != src_y1 || dst_y2 != src_y2 || blit_info.dst_y1 != blit_info.src_y1 ||
blit_info.dst_y2 != blit_info.src_y2 ||
info->src.format != info->dst.format)) info->src.format != info->dst.format))
) )
) { ) {
VREND_DEBUG(dbg_blit, ctx, "Use GL fallback because dst:ms:%d src:ms:%d (%d %d %d %d) -> (%d %d %d %d)\n", VREND_DEBUG(dbg_blit, ctx, "Use GL fallback because dst:ms:%d src:ms:%d (%d %d %d %d) -> (%d %d %d %d)\n",
dst_res->base.nr_samples, src_res->base.nr_samples, info->src.box.x, info->src.box.x + info->src.box.width, dst_res->base.nr_samples, src_res->base.nr_samples, info->src.box.x, info->src.box.x + info->src.box.width,
src_y1, src_y2, info->dst.box.x, info->dst.box.x + info->dst.box.width, dst_y1, dst_y2); blit_info.src_y1, blit_info.src_y2, info->dst.box.x, info->dst.box.x + info->dst.box.width,
blit_info.dst_y1, blit_info.dst_y2);
use_gl = true; use_gl = true;
} }
/* for 3D mipmapped blits - hand roll time */ /* for 3D mipmapped blits - hand roll time */
@ -9184,14 +9190,14 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
use_gl = true; use_gl = true;
else if (vrend_blit_needs_swizzle(info->dst.format, info->src.format)) { else if (vrend_blit_needs_swizzle(info->dst.format, info->src.format)) {
use_gl = true; use_gl = true;
needs_swizzle = true; blit_info.needs_swizzle = true;
} }
if ((src_res->base.format != info->src.format) && has_feature(feat_texture_view)) if ((src_res->base.format != info->src.format) && has_feature(feat_texture_view))
blitter_views[0] = vrend_make_view(src_res, info->src.format); blit_info.src_view = vrend_make_view(src_res, info->src.format);
if ((dst_res->base.format != info->dst.format) && has_feature(feat_texture_view)) if ((dst_res->base.format != info->dst.format) && has_feature(feat_texture_view))
blitter_views[1] = vrend_make_view(dst_res, info->dst.format); blit_info.dst_view = vrend_make_view(dst_res, info->dst.format);
/* Virgl's BGR* formats always use GL_RGBA8 internal format so texture views have no format /* Virgl's BGR* formats always use GL_RGBA8 internal format so texture views have no format
* conversion effects. Swizzling during blits is required instead. * conversion effects. Swizzling during blits is required instead.
@ -9213,24 +9219,24 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
if (vrend_format_is_bgra(dst_res->base.format) ^ vrend_format_is_bgra(info->dst.format)) if (vrend_format_is_bgra(dst_res->base.format) ^ vrend_format_is_bgra(info->dst.format))
needs_redblue_swizzle = !needs_redblue_swizzle; needs_redblue_swizzle = !needs_redblue_swizzle;
uint8_t blit_swizzle[4] = {0, 1, 2, 3}; if (blit_info.needs_swizzle && vrend_get_format_table_entry(dst_res->base.format)->flags & VIRGL_TEXTURE_NEED_SWIZZLE)
if (needs_swizzle && vrend_get_format_table_entry(dst_res->base.format)->flags & VIRGL_TEXTURE_NEED_SWIZZLE) memcpy(blit_info.swizzle, tex_conv_table[dst_res->base.format].swizzle, sizeof(blit_info.swizzle));
memcpy(blit_swizzle, tex_conv_table[dst_res->base.format].swizzle, sizeof(blit_swizzle));
if (needs_redblue_swizzle) { if (needs_redblue_swizzle) {
VREND_DEBUG(dbg_blit, ctx, "Applying red/blue swizzle during blit involving an external BGR* resource\n"); VREND_DEBUG(dbg_blit, ctx, "Applying red/blue swizzle during blit involving an external BGR* resource\n");
use_gl = true; use_gl = true;
uint8_t temp = blit_swizzle[0]; uint8_t temp = blit_info.swizzle[0];
blit_swizzle[0] = blit_swizzle[2]; blit_info.swizzle[0] = blit_info.swizzle[2];
blit_swizzle[2] = temp; blit_info.swizzle[2] = temp;
} }
if (use_gl) { if (use_gl) {
blit_info.has_texture_srgb_decode = has_feature(feat_texture_srgb_decode);
blit_info.has_srgb_write_control = has_feature(feat_srgb_write_control);
VREND_DEBUG(dbg_blit, ctx, "BLIT_INT: use GL fallback\n"); VREND_DEBUG(dbg_blit, ctx, "BLIT_INT: use GL fallback\n");
vrend_renderer_blit_gl(ctx, src_res, dst_res, blitter_views, info, vrend_renderer_blit_gl(ctx, src_res, dst_res, &blit_info);
has_feature(feat_texture_srgb_decode),
has_feature(feat_srgb_write_control),
blit_swizzle);
vrend_sync_make_current(ctx->sub->gl_context); vrend_sync_make_current(ctx->sub->gl_context);
goto cleanup; goto cleanup;
} }
@ -9265,9 +9271,9 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
((src_res->base.nr_samples > 0) && ((src_res->base.nr_samples > 0) &&
(src_res->base.nr_samples != dst_res->base.nr_samples)) && (src_res->base.nr_samples != dst_res->base.nr_samples)) &&
((info->src.box.x != info->dst.box.x) || ((info->src.box.x != info->dst.box.x) ||
(src_y1 != dst_y1) || (blit_info.src_y1 != blit_info.dst_y1) ||
(info->src.box.width != info->dst.box.width) || (info->src.box.width != info->dst.box.width) ||
(src_y2 != dst_y2))) { (blit_info.src_y2 != blit_info.dst_y2))) {
make_intermediate_copy = true; make_intermediate_copy = true;
@ -9315,7 +9321,7 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
n_layers = info->dst.box.depth; n_layers = info->dst.box.depth;
for (i = 0; i < n_layers; i++) { for (i = 0; i < n_layers; i++) {
glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[0]); glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[0]);
vrend_fb_bind_texture_id(src_res, blitter_views[0], 0, info->src.level, info->src.box.z + i, 0); vrend_fb_bind_texture_id(src_res, blit_info.src_view, 0, info->src.level, info->src.box.z + i, 0);
if (make_intermediate_copy) { if (make_intermediate_copy) {
int level_width = u_minify(src_res->base.width0, info->src.level); int level_width = u_minify(src_res->base.width0, info->src.level);
@ -9329,11 +9335,11 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
glBindFramebuffer(GL_READ_FRAMEBUFFER, ctx->sub->blit_fb_ids[0]); glBindFramebuffer(GL_READ_FRAMEBUFFER, ctx->sub->blit_fb_ids[0]);
glBlitFramebuffer(0, 0, level_width, level_height, glBlitFramebuffer(0, 0, level_width, level_height,
0, 0, level_width, level_height, 0, 0, level_width, level_height,
glmask, filter); glmask, blit_info.gl_filter);
} }
glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]); glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]);
vrend_fb_bind_texture_id(dst_res, blitter_views[1], 0, info->dst.level, info->dst.box.z + i, 0); vrend_fb_bind_texture_id(dst_res, blit_info.dst_view, 0, info->dst.level, info->dst.box.z + i, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]);
if (has_feature(feat_srgb_write_control)) { if (has_feature(feat_srgb_write_control)) {
@ -9347,14 +9353,14 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
glBindFramebuffer(GL_READ_FRAMEBUFFER, intermediate_fbo); glBindFramebuffer(GL_READ_FRAMEBUFFER, intermediate_fbo);
glBlitFramebuffer(info->src.box.x, glBlitFramebuffer(info->src.box.x,
src_y1, blit_info.src_y1,
info->src.box.x + info->src.box.width, info->src.box.x + info->src.box.width,
src_y2, blit_info.src_y2,
info->dst.box.x, info->dst.box.x,
dst_y1, blit_info.dst_y1,
info->dst.box.x + info->dst.box.width, info->dst.box.x + info->dst.box.width,
dst_y2, blit_info.dst_y2,
glmask, filter); glmask, blit_info.gl_filter);
} }
glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]); glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]);
@ -9389,11 +9395,11 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);
cleanup: cleanup:
if (blitter_views[0] != src_res->id) if (blit_info.src_view != src_res->id)
glDeleteTextures(1, &blitter_views[0]); glDeleteTextures(1, &blit_info.src_view);
if (blitter_views[1] != dst_res->id) if (blit_info.dst_view != dst_res->id)
glDeleteTextures(1, &blitter_views[1]); glDeleteTextures(1, &blit_info.dst_view);
} }
void vrend_renderer_blit(struct vrend_context *ctx, void vrend_renderer_blit(struct vrend_context *ctx,

@ -445,6 +445,19 @@ struct vrend_renderer_resource_info {
uint32_t stride; uint32_t stride;
}; };
struct vrend_blit_info {
const struct pipe_blit_info b;
GLuint src_view;
GLuint dst_view;
uint8_t swizzle[4];
int src_y1, src_y2, dst_y1, dst_y2;
GLenum gl_filter;
bool needs_swizzle;
bool can_fbo_blit;
bool has_texture_srgb_decode;
bool has_srgb_write_control;
};
void vrend_renderer_resource_get_info(struct pipe_resource *pres, void vrend_renderer_resource_get_info(struct pipe_resource *pres,
struct vrend_renderer_resource_info *info); struct vrend_renderer_resource_info *info);
@ -479,11 +492,7 @@ boolean format_is_copy_compatible(enum virgl_formats src, enum virgl_formats dst
void vrend_renderer_blit_gl(struct vrend_context *ctx, void vrend_renderer_blit_gl(struct vrend_context *ctx,
struct vrend_resource *src_res, struct vrend_resource *src_res,
struct vrend_resource *dst_res, struct vrend_resource *dst_res,
GLenum blit_views[2], struct vrend_blit_info *info);
const struct pipe_blit_info *info,
bool has_texture_srgb_decode,
bool has_srgb_write_control,
uint8_t swizzle[static 4]);
void vrend_blitter_fini(void); void vrend_blitter_fini(void);
void vrend_renderer_prepare_reset(void); void vrend_renderer_prepare_reset(void);

Loading…
Cancel
Save