diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 677ee63..56934ed 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -591,6 +591,10 @@ struct pipe_blit_info boolean scissor_enable; struct pipe_scissor_state scissor; + + boolean render_condition_enable; /**< whether the blit should honor the + current render condition */ + boolean alpha_blend; /* dst.rgb = src.rgb * src.a + dst.rgb * (1 - src.a) */ }; diff --git a/src/virgl_protocol.h b/src/virgl_protocol.h index ca3142f..a2f1e81 100644 --- a/src/virgl_protocol.h +++ b/src/virgl_protocol.h @@ -388,6 +388,8 @@ enum virgl_context_cmd { #define VIRGL_CMD_BLIT_S0_MASK(x) (((x) & 0xff) << 0) #define VIRGL_CMD_BLIT_S0_FILTER(x) (((x) & 0x3) << 8) #define VIRGL_CMD_BLIT_S0_SCISSOR_ENABLE(x) (((x) & 0x1) << 10) +#define VIRGL_CMD_BLIT_S0_RENDER_CONDITION_ENABLE(x) (((x) & 0x1) << 11) +#define VIRGL_CMD_BLIT_S0_ALPHA_BLEND(x) (((x) & 0x1) << 12) #define VIRGL_CMD_BLIT_SCISSOR_MINX_MINY 2 #define VIRGL_CMD_BLIT_SCISSOR_MAXX_MAXY 3 #define VIRGL_CMD_BLIT_DST_RES_HANDLE 4 diff --git a/src/vrend_decode.c b/src/vrend_decode.c index 96b60f4..409cec7 100644 --- a/src/vrend_decode.c +++ b/src/vrend_decode.c @@ -875,6 +875,8 @@ static int vrend_decode_blit(struct vrend_decode_ctx *ctx, int length) info.mask = temp & 0xff; info.filter = (temp >> 8) & 0x3; info.scissor_enable = (temp >> 10) & 0x1; + info.render_condition_enable = (temp >> 11) & 0x1; + info.alpha_blend = (temp >> 12) & 0x1; temp = get_buf_entry(ctx, VIRGL_CMD_BLIT_SCISSOR_MINX_MINY); info.scissor.minx = temp & 0xffff; info.scissor.miny = (temp >> 16) & 0xffff; diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index a4a1642..64a2d78 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -367,6 +367,9 @@ struct vrend_sub_context { struct vrend_streamout_object *current_so; struct pipe_blend_color blend_color; + + uint32_t cond_render_q_id; + GLenum cond_render_gl_mode; }; struct vrend_context { @@ -397,6 +400,7 @@ struct vrend_context { }; static struct vrend_resource *vrend_renderer_ctx_res_lookup(struct vrend_context *ctx, int res_handle); +static void vrend_pause_render_condition(struct vrend_context *ctx, bool pause); static void vrend_update_viewport_state(struct vrend_context *ctx); static void vrend_update_scissor_state(struct vrend_context *ctx); static void vrend_destroy_query_object(void *obj_ptr); @@ -5571,7 +5575,13 @@ void vrend_renderer_blit(struct vrend_context *ctx, if (ctx->in_error) return; + if (info->render_condition_enable == false) + vrend_pause_render_condition(ctx, true); + vrend_renderer_blit_int(ctx, src_res, dst_res, info); + + if (info->render_condition_enable == false) + vrend_pause_render_condition(ctx, false); } int vrend_renderer_create_fence(int client_fence_id, uint32_t ctx_id) @@ -5874,6 +5884,18 @@ void vrend_get_query_result(struct vrend_context *ctx, uint32_t handle, list_addtail(&q->waiting_queries, &vrend_state.waiting_query_list); } +static void vrend_pause_render_condition(struct vrend_context *ctx, bool pause) +{ + if (pause) { + if (ctx->sub->cond_render_q_id) + glEndConditionalRenderNV(); + } else { + if (ctx->sub->cond_render_q_id) + glBeginConditionalRender(ctx->sub->cond_render_q_id, + ctx->sub->cond_render_gl_mode); + } +} + void vrend_render_condition(struct vrend_context *ctx, uint32_t handle, bool condition, @@ -5884,6 +5906,8 @@ void vrend_render_condition(struct vrend_context *ctx, if (handle == 0) { glEndConditionalRenderNV(); + ctx->sub->cond_render_q_id = 0; + ctx->sub->cond_render_gl_mode = 0; return; } @@ -5908,6 +5932,8 @@ void vrend_render_condition(struct vrend_context *ctx, fprintf(stderr, "unhandled condition %x\n", mode); } + ctx->sub->cond_render_q_id = q->id; + ctx->sub->cond_render_gl_mode = glmode; glBeginConditionalRender(q->id, glmode); }