diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index a8d2e33aa5a9e6ef3e1d04d0c768aaaa273b9d5c..7b25c3c3e0ef78975ea1a9a636c41c98ab295eef 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -663,6 +663,7 @@ struct vrend_sub_context { int prim_mode; bool drawing; + struct vrend_context *parent; }; struct vrend_untyped_resource { @@ -722,22 +723,22 @@ 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_update_viewport_state(struct vrend_sub_context *sub_ctx); +static void vrend_update_scissor_state(struct vrend_sub_context *sub_ctx); static void vrend_destroy_query_object(void *obj_ptr); static void vrend_finish_context_switch(struct vrend_context *ctx); -static void vrend_patch_blend_state(struct vrend_context *ctx); -static void vrend_update_frontface_state(struct vrend_context *ctx); +static void vrend_patch_blend_state(struct vrend_sub_context *sub_ctx); +static void vrend_update_frontface_state(struct vrend_sub_context *ctx); static void vrender_get_glsl_version(int *glsl_version); static void vrend_destroy_program(struct vrend_linked_shader_program *ent); -static void vrend_apply_sampler_state(struct vrend_context *ctx, +static void vrend_apply_sampler_state(struct vrend_sub_context *sub_ctx, struct vrend_resource *res, uint32_t shader_type, int id, int sampler_id, struct vrend_sampler_view *tview); static GLenum tgsitargettogltarget(const enum pipe_texture_target target, int nr_samples); -void vrend_update_stencil_state(struct vrend_context *ctx); +void vrend_update_stencil_state(struct vrend_sub_context *sub_ctx); static struct vrend_format_table tex_conv_table[VIRGL_FORMAT_MAX_EXTENDED]; @@ -1086,7 +1087,7 @@ static void vrend_destroy_shader_selector(struct vrend_shader_selector *sel) free(sel); } -static bool vrend_compile_shader(struct vrend_context *ctx, +static bool vrend_compile_shader(struct vrend_sub_context *sub_ctx, struct vrend_shader *shader) { GLint param; @@ -1101,7 +1102,7 @@ static bool vrend_compile_shader(struct vrend_context *ctx, char infolog[65536]; int len; glGetShaderInfoLog(shader->id, 65536, &len, infolog); - vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SHADER, 0); + vrend_report_context_error(sub_ctx->parent, VIRGL_ERROR_CTX_ILLEGAL_SHADER, 0); vrend_printf("shader failed to compile\n%s\n", infolog); vrend_shader_dump(shader); return false; @@ -1184,11 +1185,11 @@ static bool vrend_is_timer_query(GLenum gltype) gltype == GL_TIME_ELAPSED; } -static void vrend_use_program(struct vrend_context *ctx, GLuint program_id) +static void vrend_use_program(struct vrend_sub_context *sub_ctx, GLuint program_id) { - if (ctx->sub->program_id != program_id) { + if (sub_ctx->program_id != program_id) { glUseProgram(program_id); - ctx->sub->program_id = program_id; + sub_ctx->program_id = program_id; } } @@ -1231,10 +1232,10 @@ static void vrend_alpha_test_enable(struct vrend_context *ctx, bool alpha_test_e } } -static void vrend_stencil_test_enable(struct vrend_context *ctx, bool stencil_test_enable) +static void vrend_stencil_test_enable(struct vrend_sub_context *sub_ctx, bool stencil_test_enable) { - if (ctx->sub->stencil_test_enabled != stencil_test_enable) { - ctx->sub->stencil_test_enabled = stencil_test_enable; + if (sub_ctx->stencil_test_enabled != stencil_test_enable) { + sub_ctx->stencil_test_enabled = stencil_test_enable; if (stencil_test_enable) glEnable(GL_STENCIL_TEST); else @@ -1290,7 +1291,7 @@ static char *get_skip_str(int *skip_val) return start_skip; } -static void set_stream_out_varyings(MAYBE_UNUSED struct vrend_context *ctx, +static void set_stream_out_varyings(MAYBE_UNUSED struct vrend_sub_context *sub_ctx, int prog_id, struct vrend_shader_info *sinfo) { @@ -1305,7 +1306,7 @@ static void set_stream_out_varyings(MAYBE_UNUSED struct vrend_context *ctx, if (!so->num_outputs) return; - VREND_DEBUG_EXT(dbg_shader_streamout, ctx, dump_stream_out(so)); + VREND_DEBUG_EXT(dbg_shader_streamout, sub_ctx->parent, dump_stream_out(so)); for (i = 0; i < so->num_outputs; i++) { if (last_buffer != so->output[i].output_buffer) { @@ -1531,7 +1532,7 @@ static struct vrend_linked_shader_program *add_cs_shader_program(struct vrend_co sprog->id = prog_id; list_addtail(&sprog->head, &ctx->sub->cs_programs); - vrend_use_program(ctx, prog_id); + vrend_use_program(ctx->sub, prog_id); bind_sampler_locs(sprog, PIPE_SHADER_COMPUTE, 0); bind_ubo_locs(sprog, PIPE_SHADER_COMPUTE, 0); @@ -1541,7 +1542,7 @@ static struct vrend_linked_shader_program *add_cs_shader_program(struct vrend_co return sprog; } -static struct vrend_linked_shader_program *add_shader_program(struct vrend_context *ctx, +static struct vrend_linked_shader_program *add_shader_program(struct vrend_sub_context *sub_ctx, struct vrend_shader *vs, struct vrend_shader *fs, struct vrend_shader *gs, @@ -1568,20 +1569,20 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_conte if (gs) { if (gs->id > 0) glAttachShader(prog_id, gs->id); - set_stream_out_varyings(ctx, prog_id, &gs->sel->sinfo); + set_stream_out_varyings(sub_ctx, prog_id, &gs->sel->sinfo); } else if (tes) - set_stream_out_varyings(ctx, prog_id, &tes->sel->sinfo); + set_stream_out_varyings(sub_ctx, prog_id, &tes->sel->sinfo); else - set_stream_out_varyings(ctx, prog_id, &vs->sel->sinfo); + set_stream_out_varyings(sub_ctx, prog_id, &vs->sel->sinfo); glAttachShader(prog_id, fs->id); if (fs->sel->sinfo.num_outputs > 1) { - if (util_blend_state_is_dual(&ctx->sub->blend_state, 0)) { + if (util_blend_state_is_dual(&sub_ctx->blend_state, 0)) { if (has_feature(feat_dual_src_blend)) { glBindFragDataLocationIndexed(prog_id, 0, 0, "fsout_c0"); glBindFragDataLocationIndexed(prog_id, 0, 1, "fsout_c1"); } else { - vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_DUAL_SRC_BLEND, 0); + vrend_report_context_error(sub_ctx->parent, VIRGL_ERROR_CTX_ILLEGAL_DUAL_SRC_BLEND, 0); } sprog->dual_src_linked = true; } else { @@ -1612,7 +1613,7 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_conte glGetProgramInfoLog(prog_id, 65536, &len, infolog); vrend_printf("got error linking\n%s\n", infolog); /* dump shaders */ - vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SHADER, 0); + vrend_report_context_error(sub_ctx->parent, VIRGL_ERROR_CTX_ILLEGAL_SHADER, 0); vrend_shader_dump(vs); if (gs) vrend_shader_dump(gs); @@ -1643,7 +1644,7 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_conte last_shader = tes ? PIPE_SHADER_TESS_EVAL : (gs ? PIPE_SHADER_GEOMETRY : PIPE_SHADER_FRAGMENT); sprog->id = prog_id; - list_addtail(&sprog->head, &ctx->sub->gl_programs[vs->id & VREND_PROGRAM_NQUEUE_MASK]); + list_addtail(&sprog->head, &sub_ctx->gl_programs[vs->id & VREND_PROGRAM_NQUEUE_MASK]); if (fs->key.pstipple_tex) sprog->fs_stipple_loc = glGetUniformLocation(prog_id, "pstipple_sampler"); @@ -1655,7 +1656,7 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_conte sprog->fs_alpha_ref_val_loc = -1; sprog->vs_ws_adjust_loc = glGetUniformLocation(prog_id, "winsys_adjust_y"); - vrend_use_program(ctx, prog_id); + vrend_use_program(sub_ctx, prog_id); int next_ubo_id = 0, next_sampler_id = 0; for (id = PIPE_SHADER_VERTEX; id <= last_shader; id++) { @@ -1705,7 +1706,7 @@ static struct vrend_linked_shader_program *lookup_cs_shader_program(struct vrend return NULL; } -static struct vrend_linked_shader_program *lookup_shader_program(struct vrend_context *ctx, +static struct vrend_linked_shader_program *lookup_shader_program(struct vrend_sub_context *sub_ctx, GLuint vs_id, GLuint fs_id, GLuint gs_id, @@ -1718,7 +1719,7 @@ static struct vrend_linked_shader_program *lookup_shader_program(struct vrend_co struct vrend_linked_shader_program *ent; - struct list_head *programs = &ctx->sub->gl_programs[vs_id & VREND_PROGRAM_NQUEUE_MASK]; + struct list_head *programs = &sub_ctx->gl_programs[vs_id & VREND_PROGRAM_NQUEUE_MASK]; LIST_FOR_EACH_ENTRY(ent, programs, head) { if (likely(ent->vs_fs_key != vs_fs_key)) continue; @@ -1732,9 +1733,10 @@ static struct vrend_linked_shader_program *lookup_shader_program(struct vrend_co ent->ss[PIPE_SHADER_TESS_EVAL]->id != tes_id) continue; /* put the entry in front */ - list_del(&ent->head); - list_add(&ent->head, programs); - + if (programs->next != &ent->head) { + list_del(&ent->head); + list_add(&ent->head, programs); + } return ent; } @@ -2371,9 +2373,9 @@ static void vrend_hw_set_zsurf_texture(struct vrend_context *ctx) } } -static void vrend_hw_set_color_surface(struct vrend_context *ctx, int index) +static void vrend_hw_set_color_surface(struct vrend_sub_context *sub_ctx, int index) { - struct vrend_surface *surf = ctx->sub->surf[index]; + struct vrend_surface *surf = sub_ctx->surf[index]; if (!surf) { GLenum attachment = GL_COLOR_ATTACHMENT0 + index; @@ -2381,15 +2383,15 @@ static void vrend_hw_set_color_surface(struct vrend_context *ctx, int index) glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, 0, 0); } else { - uint32_t first_layer = ctx->sub->surf[index]->val1 & 0xffff; - uint32_t last_layer = (ctx->sub->surf[index]->val1 >> 16) & 0xffff; + uint32_t first_layer = sub_ctx->surf[index]->val1 & 0xffff; + uint32_t last_layer = (sub_ctx->surf[index]->val1 >> 16) & 0xffff; vrend_fb_bind_texture_id(surf->texture, surf->id, index, surf->val0, first_layer != last_layer ? 0xffffffff : first_layer); } } -static void vrend_hw_emit_framebuffer_state(struct vrend_context *ctx) +static void vrend_hw_emit_framebuffer_state(struct vrend_sub_context *sub_ctx) { static const GLenum buffers[8] = { GL_COLOR_ATTACHMENT0, @@ -2402,19 +2404,19 @@ static void vrend_hw_emit_framebuffer_state(struct vrend_context *ctx) GL_COLOR_ATTACHMENT7, }; - if (ctx->sub->nr_cbufs == 0) { + if (sub_ctx->nr_cbufs == 0) { glReadBuffer(GL_NONE); if (has_feature(feat_srgb_write_control)) { glDisable(GL_FRAMEBUFFER_SRGB_EXT); - ctx->sub->framebuffer_srgb_enabled = false; + sub_ctx->framebuffer_srgb_enabled = false; } } else if (has_feature(feat_srgb_write_control)) { struct vrend_surface *surf = NULL; bool use_srgb = false; int i; - for (i = 0; i < ctx->sub->nr_cbufs; i++) { - if (ctx->sub->surf[i]) { - surf = ctx->sub->surf[i]; + for (i = 0; i < sub_ctx->nr_cbufs; i++) { + if (sub_ctx->surf[i]) { + surf = sub_ctx->surf[i]; if (util_format_is_srgb(surf->format)) { use_srgb = true; } @@ -2425,25 +2427,25 @@ static void vrend_hw_emit_framebuffer_state(struct vrend_context *ctx) } else { glDisable(GL_FRAMEBUFFER_SRGB_EXT); } - ctx->sub->framebuffer_srgb_enabled = use_srgb; + sub_ctx->framebuffer_srgb_enabled = use_srgb; } if (vrend_state.use_gles && - vrend_get_tweak_is_active(&ctx->sub->tweaks, virgl_tweak_gles_brga_apply_dest_swizzle)) { - ctx->sub->swizzle_output_rgb_to_bgr = 0; - for (int i = 0; i < ctx->sub->nr_cbufs; i++) { - if (ctx->sub->surf[i]) { - struct vrend_surface *surf = ctx->sub->surf[i]; + vrend_get_tweak_is_active(&sub_ctx->tweaks, virgl_tweak_gles_brga_apply_dest_swizzle)) { + sub_ctx->swizzle_output_rgb_to_bgr = 0; + for (int i = 0; i < sub_ctx->nr_cbufs; i++) { + if (sub_ctx->surf[i]) { + struct vrend_surface *surf = sub_ctx->surf[i]; if (surf->texture->base.bind & VIRGL_BIND_PREFER_EMULATED_BGRA) { - VREND_DEBUG(dbg_tweak, ctx, "Swizzled BGRA output for 0x%x (%s)\n", i, util_format_name(surf->format)); - ctx->sub->swizzle_output_rgb_to_bgr |= 1 << i; + VREND_DEBUG(dbg_tweak, sub_ctx->parent, "Swizzled BGRA output for 0x%x (%s)\n", i, util_format_name(surf->format)); + sub_ctx->swizzle_output_rgb_to_bgr |= 1 << i; } } } } - glDrawBuffers(ctx->sub->nr_cbufs, buffers); + glDrawBuffers(sub_ctx->nr_cbufs, buffers); } void vrend_set_framebuffer_state(struct vrend_context *ctx, @@ -2457,10 +2459,12 @@ void vrend_set_framebuffer_state(struct vrend_context *ctx, GLint new_height = -1; bool new_ibf = false; - glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->fb_id); + struct vrend_sub_context *sub_ctx = ctx->sub; + + glBindFramebuffer(GL_FRAMEBUFFER, sub_ctx->fb_id); if (zsurf_handle) { - zsurf = vrend_object_lookup(ctx->sub->object_hash, zsurf_handle, VIRGL_OBJECT_SURFACE); + zsurf = vrend_object_lookup(sub_ctx->object_hash, zsurf_handle, VIRGL_OBJECT_SURFACE); if (!zsurf) { vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SURFACE, zsurf_handle); return; @@ -2468,18 +2472,18 @@ void vrend_set_framebuffer_state(struct vrend_context *ctx, } else zsurf = NULL; - if (ctx->sub->zsurf != zsurf) { - vrend_surface_reference(&ctx->sub->zsurf, zsurf); + if (sub_ctx->zsurf != zsurf) { + vrend_surface_reference(&sub_ctx->zsurf, zsurf); vrend_hw_set_zsurf_texture(ctx); } - old_num = ctx->sub->nr_cbufs; - ctx->sub->nr_cbufs = nr_cbufs; - ctx->sub->old_nr_cbufs = old_num; + old_num = sub_ctx->nr_cbufs; + sub_ctx->nr_cbufs = nr_cbufs; + sub_ctx->old_nr_cbufs = old_num; for (i = 0; i < (int)nr_cbufs; i++) { if (surf_handle[i] != 0) { - surf = vrend_object_lookup(ctx->sub->object_hash, surf_handle[i], VIRGL_OBJECT_SURFACE); + surf = vrend_object_lookup(sub_ctx->object_hash, surf_handle[i], VIRGL_OBJECT_SURFACE); if (!surf) { vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SURFACE, surf_handle[i]); return; @@ -2487,32 +2491,32 @@ void vrend_set_framebuffer_state(struct vrend_context *ctx, } else surf = NULL; - if (ctx->sub->surf[i] != surf) { - vrend_surface_reference(&ctx->sub->surf[i], surf); - vrend_hw_set_color_surface(ctx, i); + if (sub_ctx->surf[i] != surf) { + vrend_surface_reference(&sub_ctx->surf[i], surf); + vrend_hw_set_color_surface(sub_ctx, i); } } - if (old_num > ctx->sub->nr_cbufs) { - for (i = ctx->sub->nr_cbufs; i < old_num; i++) { - vrend_surface_reference(&ctx->sub->surf[i], NULL); - vrend_hw_set_color_surface(ctx, i); + if (old_num > sub_ctx->nr_cbufs) { + for (i = sub_ctx->nr_cbufs; i < old_num; i++) { + vrend_surface_reference(&sub_ctx->surf[i], NULL); + vrend_hw_set_color_surface(sub_ctx, i); } } /* find a buffer to set fb_height from */ - if (ctx->sub->nr_cbufs == 0 && !ctx->sub->zsurf) { + if (sub_ctx->nr_cbufs == 0 && !sub_ctx->zsurf) { new_height = 0; new_ibf = false; - } else if (ctx->sub->nr_cbufs == 0) { - new_height = u_minify(ctx->sub->zsurf->texture->base.height0, ctx->sub->zsurf->val0); - new_ibf = ctx->sub->zsurf->texture->y_0_top ? true : false; + } else if (sub_ctx->nr_cbufs == 0) { + new_height = u_minify(sub_ctx->zsurf->texture->base.height0, sub_ctx->zsurf->val0); + new_ibf = sub_ctx->zsurf->texture->y_0_top ? true : false; } else { surf = NULL; - for (i = 0; i < ctx->sub->nr_cbufs; i++) { - if (ctx->sub->surf[i]) { - surf = ctx->sub->surf[i]; + for (i = 0; i < sub_ctx->nr_cbufs; i++) { + if (sub_ctx->surf[i]) { + surf = sub_ctx->surf[i]; break; } } @@ -2525,23 +2529,23 @@ void vrend_set_framebuffer_state(struct vrend_context *ctx, } if (new_height != -1) { - if (ctx->sub->fb_height != (uint32_t)new_height || ctx->sub->inverted_fbo_content != new_ibf) { - ctx->sub->fb_height = new_height; - ctx->sub->inverted_fbo_content = new_ibf; - ctx->sub->viewport_state_dirty = (1 << 0); + if (sub_ctx->fb_height != (uint32_t)new_height || sub_ctx->inverted_fbo_content != new_ibf) { + sub_ctx->fb_height = new_height; + sub_ctx->inverted_fbo_content = new_ibf; + sub_ctx->viewport_state_dirty = (1 << 0); } } - vrend_hw_emit_framebuffer_state(ctx); + vrend_hw_emit_framebuffer_state(sub_ctx); - if (ctx->sub->nr_cbufs > 0 || ctx->sub->zsurf) { + if (sub_ctx->nr_cbufs > 0 || sub_ctx->zsurf) { status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) vrend_printf("failed to complete framebuffer 0x%x %s\n", status, ctx->debug_name); } - ctx->sub->shader_dirty = true; - ctx->sub->blend_state_dirty = true; + sub_ctx->shader_dirty = true; + sub_ctx->blend_state_dirty = true; } void vrend_set_framebuffer_state_no_attach(UNUSED struct vrend_context *ctx, @@ -3401,7 +3405,7 @@ static int vrend_shader_create(struct vrend_context *ctx, if (1) {//shader->sel->type == PIPE_SHADER_FRAGMENT || shader->sel->type == PIPE_SHADER_GEOMETRY) { bool ret; - ret = vrend_compile_shader(ctx, shader); + ret = vrend_compile_shader(ctx->sub, shader); if (ret == false) { glDeleteShader(shader->id); strarray_free(&shader->glsl_strings, true); @@ -3411,7 +3415,7 @@ static int vrend_shader_create(struct vrend_context *ctx, return 0; } -static int vrend_shader_select(struct vrend_context *ctx, +static int vrend_shader_select(struct vrend_sub_context *sub_ctx, struct vrend_shader_selector *sel, bool *dirty) { @@ -3420,7 +3424,7 @@ static int vrend_shader_select(struct vrend_context *ctx, int r; memset(&key, 0, sizeof(key)); - vrend_fill_shader_key(ctx->sub, sel, &key); + vrend_fill_shader_key(sub_ctx, sel, &key); if (sel->current && !memcmp(&sel->current->key, &key, sizeof(key))) return 0; @@ -3444,7 +3448,7 @@ static int vrend_shader_select(struct vrend_context *ctx, list_inithead(&shader->programs); strarray_alloc(&shader->glsl_strings, SHADER_MAX_STRINGS); - r = vrend_shader_create(ctx, shader, &key); + r = vrend_shader_create(sub_ctx->parent, shader, &key); if (r) { sel->current = NULL; FREE(shader); @@ -3485,7 +3489,7 @@ static int vrend_finish_shader(struct vrend_context *ctx, sel->tokens = tgsi_dup_tokens(tokens); - r = vrend_shader_select(ctx, sel, NULL); + r = vrend_shader_select(ctx->sub, sel, NULL); if (r) { return EINVAL; } @@ -3526,12 +3530,14 @@ int vrend_create_shader(struct vrend_context *ctx, else if (((offlen + 3) / 4) > pkt_length) long_shader = true; + struct vrend_sub_context *sub_ctx = ctx->sub; + /* if we have an in progress one - don't allow a new shader of that type or a different handle. */ - if (ctx->sub->long_shader_in_progress_handle[type]) { + if (sub_ctx->long_shader_in_progress_handle[type]) { if (new_shader == true) return EINVAL; - if (handle != ctx->sub->long_shader_in_progress_handle[type]) + if (handle != sub_ctx->long_shader_in_progress_handle[type]) return EINVAL; } @@ -3549,11 +3555,11 @@ int vrend_create_shader(struct vrend_context *ctx, } memcpy(sel->tmp_buf, shd_text, pkt_length * 4); sel->buf_offset = pkt_length * 4; - ctx->sub->long_shader_in_progress_handle[type] = handle; + sub_ctx->long_shader_in_progress_handle[type] = handle; } else finished = true; } else { - sel = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_SHADER); + sel = vrend_object_lookup(sub_ctx->object_hash, handle, VIRGL_OBJECT_SHADER); if (!sel) { vrend_printf( "got continuation without original shader %d\n", handle); ret = EINVAL; @@ -3625,7 +3631,7 @@ int vrend_create_shader(struct vrend_context *ctx, sel->tmp_buf = NULL; } free(tokens); - ctx->sub->long_shader_in_progress_handle[type] = 0; + sub_ctx->long_shader_in_progress_handle[type] = 0; } if (new_shader) { @@ -3655,31 +3661,33 @@ void vrend_bind_shader(struct vrend_context *ctx, if (type > PIPE_SHADER_COMPUTE) return; + struct vrend_sub_context *sub_ctx = ctx->sub; + if (handle == 0) { if (type == PIPE_SHADER_COMPUTE) - ctx->sub->cs_shader_dirty = true; + sub_ctx->cs_shader_dirty = true; else - ctx->sub->shader_dirty = true; - vrend_shader_state_reference(&ctx->sub->shaders[type], NULL); + sub_ctx->shader_dirty = true; + vrend_shader_state_reference(&sub_ctx->shaders[type], NULL); return; } - sel = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_SHADER); + sel = vrend_object_lookup(sub_ctx->object_hash, handle, VIRGL_OBJECT_SHADER); if (!sel) return; if (sel->type != type) return; - if (ctx->sub->shaders[sel->type] != sel) { + if (sub_ctx->shaders[sel->type] != sel) { if (type == PIPE_SHADER_COMPUTE) - ctx->sub->cs_shader_dirty = true; + sub_ctx->cs_shader_dirty = true; else - ctx->sub->shader_dirty = true; - ctx->sub->prog_ids[sel->type] = 0; + sub_ctx->shader_dirty = true; + sub_ctx->prog_ids[sel->type] = 0; } - vrend_shader_state_reference(&ctx->sub->shaders[sel->type], sel); + vrend_shader_state_reference(&sub_ctx->shaders[sel->type], sel); } void vrend_clear(struct vrend_context *ctx, @@ -3688,6 +3696,7 @@ void vrend_clear(struct vrend_context *ctx, double depth, unsigned stencil) { GLbitfield bits = 0; + struct vrend_sub_context *sub_ctx = ctx->sub; if (ctx->in_error) return; @@ -3695,20 +3704,20 @@ void vrend_clear(struct vrend_context *ctx, if (ctx->ctx_switch_pending) vrend_finish_context_switch(ctx); - vrend_update_frontface_state(ctx); - if (ctx->sub->stencil_state_dirty) - vrend_update_stencil_state(ctx); - if (ctx->sub->scissor_state_dirty) - vrend_update_scissor_state(ctx); - if (ctx->sub->viewport_state_dirty) - vrend_update_viewport_state(ctx); + vrend_update_frontface_state(sub_ctx); + if (sub_ctx->stencil_state_dirty) + vrend_update_stencil_state(sub_ctx); + if (sub_ctx->scissor_state_dirty) + vrend_update_scissor_state(sub_ctx); + if (sub_ctx->viewport_state_dirty) + vrend_update_viewport_state(sub_ctx); - vrend_use_program(ctx, 0); + vrend_use_program(sub_ctx, 0); glDisable(GL_SCISSOR_TEST); if (buffers & PIPE_CLEAR_COLOR) { - if (ctx->sub->nr_cbufs && ctx->sub->surf[0] && vrend_format_is_emulated_alpha(ctx->sub->surf[0]->format)) { + if (sub_ctx->nr_cbufs && sub_ctx->surf[0] && vrend_format_is_emulated_alpha(sub_ctx->surf[0]->format)) { glClearColor(color->f[3], 0.0, 0.0, 0.0); } else { glClearColor(color->f[0], color->f[1], color->f[2], color->f[3]); @@ -3717,7 +3726,7 @@ void vrend_clear(struct vrend_context *ctx, /* This function implements Gallium's full clear callback (st->pipe->clear) on the host. This callback requires no color component be masked. We must unmask all components before calling glClear* and restore the previous colormask afterwards, as Gallium expects. */ - if (ctx->sub->hw_blend_state.independent_blend_enable && + if (sub_ctx->hw_blend_state.independent_blend_enable && has_feature(feat_indep_blend)) { int i; for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) @@ -3745,24 +3754,24 @@ void vrend_clear(struct vrend_context *ctx, glClearStencil(stencil); } - if (ctx->sub->hw_rs_state.rasterizer_discard) + if (sub_ctx->hw_rs_state.rasterizer_discard) glDisable(GL_RASTERIZER_DISCARD); if (buffers & PIPE_CLEAR_COLOR) { uint32_t mask = 0; int i; - for (i = 0; i < ctx->sub->nr_cbufs; i++) { - if (ctx->sub->surf[i]) + for (i = 0; i < sub_ctx->nr_cbufs; i++) { + if (sub_ctx->surf[i]) mask |= (1 << i); } if (mask != (buffers >> 2)) { mask = buffers >> 2; while (mask) { i = u_bit_scan(&mask); - if (i < PIPE_MAX_COLOR_BUFS && ctx->sub->surf[i] && util_format_is_pure_uint(ctx->sub->surf[i] && ctx->sub->surf[i]->format)) + if (i < PIPE_MAX_COLOR_BUFS && sub_ctx->surf[i] && util_format_is_pure_uint(sub_ctx->surf[i] && sub_ctx->surf[i]->format)) glClearBufferuiv(GL_COLOR, i, (GLuint *)color); - else if (i < PIPE_MAX_COLOR_BUFS && ctx->sub->surf[i] && util_format_is_pure_sint(ctx->sub->surf[i] && ctx->sub->surf[i]->format)) + else if (i < PIPE_MAX_COLOR_BUFS && sub_ctx->surf[i] && util_format_is_pure_sint(sub_ctx->surf[i] && sub_ctx->surf[i]->format)) glClearBufferiv(GL_COLOR, i, (GLint *)color); else @@ -3785,40 +3794,40 @@ void vrend_clear(struct vrend_context *ctx, * get here is because the guest cleared all those states but gallium * didn't forward them before calling the clear command */ - if (ctx->sub->hw_rs_state.rasterizer_discard) + if (sub_ctx->hw_rs_state.rasterizer_discard) glEnable(GL_RASTERIZER_DISCARD); if (buffers & PIPE_CLEAR_DEPTH) { - if (!ctx->sub->dsa_state.depth.writemask) + if (!sub_ctx->dsa_state.depth.writemask) glDepthMask(GL_FALSE); } /* Restore previous stencil buffer write masks for both front and back faces */ if (buffers & PIPE_CLEAR_STENCIL) { - glStencilMaskSeparate(GL_FRONT, ctx->sub->dsa_state.stencil[0].writemask); - glStencilMaskSeparate(GL_BACK, ctx->sub->dsa_state.stencil[1].writemask); + glStencilMaskSeparate(GL_FRONT, sub_ctx->dsa_state.stencil[0].writemask); + glStencilMaskSeparate(GL_BACK, sub_ctx->dsa_state.stencil[1].writemask); } /* Restore previous colormask */ if (buffers & PIPE_CLEAR_COLOR) { - if (ctx->sub->hw_blend_state.independent_blend_enable && + if (sub_ctx->hw_blend_state.independent_blend_enable && has_feature(feat_indep_blend)) { int i; for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { - struct pipe_blend_state *blend = &ctx->sub->hw_blend_state; + struct pipe_blend_state *blend = &sub_ctx->hw_blend_state; glColorMaskIndexedEXT(i, blend->rt[i].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE, blend->rt[i].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE, blend->rt[i].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE, blend->rt[i].colormask & PIPE_MASK_A ? GL_TRUE : GL_FALSE); } } else { - glColorMask(ctx->sub->hw_blend_state.rt[0].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE, - ctx->sub->hw_blend_state.rt[0].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE, - ctx->sub->hw_blend_state.rt[0].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE, - ctx->sub->hw_blend_state.rt[0].colormask & PIPE_MASK_A ? GL_TRUE : GL_FALSE); + glColorMask(sub_ctx->hw_blend_state.rt[0].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE, + sub_ctx->hw_blend_state.rt[0].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE, + sub_ctx->hw_blend_state.rt[0].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE, + sub_ctx->hw_blend_state.rt[0].colormask & PIPE_MASK_A ? GL_TRUE : GL_FALSE); } } - if (ctx->sub->hw_rs_state.scissor) + if (sub_ctx->hw_rs_state.scissor) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); @@ -3856,20 +3865,20 @@ void vrend_clear_texture(struct vrend_context* ctx, } } -static void vrend_update_scissor_state(struct vrend_context *ctx) +static void vrend_update_scissor_state(struct vrend_sub_context *sub_ctx) { struct pipe_scissor_state *ss; GLint y; GLuint idx; - unsigned mask = ctx->sub->scissor_state_dirty; + unsigned mask = sub_ctx->scissor_state_dirty; while (mask) { idx = u_bit_scan(&mask); if (idx >= PIPE_MAX_VIEWPORTS) { - vrend_report_buffer_error(ctx, 0); + vrend_report_buffer_error(sub_ctx->parent, 0); break; } - ss = &ctx->sub->ss[idx]; + ss = &sub_ctx->ss[idx]; y = ss->miny; if (idx > 0 && has_feature(feat_viewport_array)) @@ -3877,39 +3886,39 @@ static void vrend_update_scissor_state(struct vrend_context *ctx) else glScissor(ss->minx, y, ss->maxx - ss->minx, ss->maxy - ss->miny); } - ctx->sub->scissor_state_dirty = 0; + sub_ctx->scissor_state_dirty = 0; } -static void vrend_update_viewport_state(struct vrend_context *ctx) +static void vrend_update_viewport_state(struct vrend_sub_context *sub_ctx) { GLint cy; - unsigned mask = ctx->sub->viewport_state_dirty; + unsigned mask = sub_ctx->viewport_state_dirty; int idx; while (mask) { idx = u_bit_scan(&mask); - if (ctx->sub->viewport_is_negative) - cy = ctx->sub->vps[idx].cur_y - ctx->sub->vps[idx].height; + if (sub_ctx->viewport_is_negative) + cy = sub_ctx->vps[idx].cur_y - sub_ctx->vps[idx].height; else - cy = ctx->sub->vps[idx].cur_y; + cy = sub_ctx->vps[idx].cur_y; if (idx > 0 && has_feature(feat_viewport_array)) - glViewportIndexedf(idx, ctx->sub->vps[idx].cur_x, cy, ctx->sub->vps[idx].width, ctx->sub->vps[idx].height); + glViewportIndexedf(idx, sub_ctx->vps[idx].cur_x, cy, sub_ctx->vps[idx].width, sub_ctx->vps[idx].height); else - glViewport(ctx->sub->vps[idx].cur_x, cy, ctx->sub->vps[idx].width, ctx->sub->vps[idx].height); + glViewport(sub_ctx->vps[idx].cur_x, cy, sub_ctx->vps[idx].width, sub_ctx->vps[idx].height); if (idx && has_feature(feat_viewport_array)) if (vrend_state.use_gles) { - glDepthRangeIndexedfOES(idx, ctx->sub->vps[idx].near_val, ctx->sub->vps[idx].far_val); + glDepthRangeIndexedfOES(idx, sub_ctx->vps[idx].near_val, sub_ctx->vps[idx].far_val); } else - glDepthRangeIndexed(idx, ctx->sub->vps[idx].near_val, ctx->sub->vps[idx].far_val); + glDepthRangeIndexed(idx, sub_ctx->vps[idx].near_val, sub_ctx->vps[idx].far_val); else if (vrend_state.use_gles) - glDepthRangefOES(ctx->sub->vps[idx].near_val, ctx->sub->vps[idx].far_val); + glDepthRangefOES(sub_ctx->vps[idx].near_val, sub_ctx->vps[idx].far_val); else - glDepthRange(ctx->sub->vps[idx].near_val, ctx->sub->vps[idx].far_val); + glDepthRange(sub_ctx->vps[idx].near_val, sub_ctx->vps[idx].far_val); } - ctx->sub->viewport_state_dirty = 0; + sub_ctx->viewport_state_dirty = 0; } static GLenum get_gs_xfb_mode(GLenum mode) @@ -4121,27 +4130,33 @@ static void vrend_draw_bind_vertex_binding(struct vrend_context *ctx, } } -static int vrend_draw_bind_samplers_shader(struct vrend_context *ctx, +static int vrend_draw_bind_samplers_shader(struct vrend_sub_context *sub_ctx, int shader_type, int next_sampler_id) { int index = 0; - uint32_t dirty = ctx->sub->sampler_views_dirty[shader_type]; + uint32_t dirty = sub_ctx->sampler_views_dirty[shader_type]; + + uint32_t mask = sub_ctx->prog->samplers_used_mask[shader_type]; + + struct vrend_shader_view *sviews = &sub_ctx->views[shader_type]; - uint32_t mask = ctx->sub->prog->samplers_used_mask[shader_type]; while (mask) { int i = u_bit_scan(&mask); - struct vrend_sampler_view *tview = ctx->sub->views[shader_type].views[i]; - if (dirty & (1 << i) && tview) { - if (ctx->sub->prog->shadow_samp_mask[shader_type] & (1 << i)) { - glUniform4f(ctx->sub->prog->shadow_samp_mask_locs[shader_type][index], + if (!(dirty & (1 << i))) + continue; + + struct vrend_sampler_view *tview = sviews->views[i]; + if (tview) { + if (sub_ctx->prog->shadow_samp_mask[shader_type] & (1 << i)) { + glUniform4f(sub_ctx->prog->shadow_samp_mask_locs[shader_type][index], (tview->gl_swizzle[0] == GL_ZERO || tview->gl_swizzle[0] == GL_ONE) ? 0.0 : 1.0, (tview->gl_swizzle[1] == GL_ZERO || tview->gl_swizzle[1] == GL_ONE) ? 0.0 : 1.0, (tview->gl_swizzle[2] == GL_ZERO || tview->gl_swizzle[2] == GL_ONE) ? 0.0 : 1.0, (tview->gl_swizzle[3] == GL_ZERO || tview->gl_swizzle[3] == GL_ONE) ? 0.0 : 1.0); - glUniform4f(ctx->sub->prog->shadow_samp_add_locs[shader_type][index], + glUniform4f(sub_ctx->prog->shadow_samp_add_locs[shader_type][index], tview->gl_swizzle[0] == GL_ONE ? 1.0 : 0.0, tview->gl_swizzle[1] == GL_ONE ? 1.0 : 0.0, tview->gl_swizzle[2] == GL_ONE ? 1.0 : 0.0, @@ -4149,7 +4164,7 @@ static int vrend_draw_bind_samplers_shader(struct vrend_context *ctx, } if (tview->texture) { - GLuint id; + GLuint id = tview->id; struct vrend_resource *texture = tview->texture; GLenum target = tview->target; @@ -4158,17 +4173,16 @@ static int vrend_draw_bind_samplers_shader(struct vrend_context *ctx, if (has_bit(tview->texture->storage_bits, VREND_STORAGE_GL_BUFFER)) { id = texture->tbo_tex_id; target = GL_TEXTURE_BUFFER; - } else - id = tview->id; + } glActiveTexture(GL_TEXTURE0 + next_sampler_id); glBindTexture(target, id); - if (ctx->sub->views[shader_type].old_ids[i] != id || - ctx->sub->sampler_views_dirty[shader_type] & (1 << i)) { - vrend_apply_sampler_state(ctx, texture, shader_type, i, + if (sviews->old_ids[i] != id || + sub_ctx->sampler_views_dirty[shader_type] & (1 << i)) { + vrend_apply_sampler_state(sub_ctx, texture, shader_type, i, next_sampler_id, tview); - ctx->sub->views[shader_type].old_ids[i] = id; + sviews->old_ids[i] = id; } dirty &= ~(1 << i); } @@ -4176,12 +4190,12 @@ static int vrend_draw_bind_samplers_shader(struct vrend_context *ctx, next_sampler_id++; index++; } - ctx->sub->sampler_views_dirty[shader_type] = dirty; + sub_ctx->sampler_views_dirty[shader_type] = dirty; return next_sampler_id; } -static int vrend_draw_bind_ubo_shader(struct vrend_context *ctx, +static int vrend_draw_bind_ubo_shader(struct vrend_sub_context *sub_ctx, int shader_type, int next_ubo_id) { uint32_t mask, dirty, update; @@ -4191,9 +4205,9 @@ static int vrend_draw_bind_ubo_shader(struct vrend_context *ctx, if (!has_feature(feat_ubo)) return next_ubo_id; - mask = ctx->sub->prog->ubo_used_mask[shader_type]; - dirty = ctx->sub->const_bufs_dirty[shader_type]; - update = dirty & ctx->sub->const_bufs_used_mask[shader_type]; + mask = sub_ctx->prog->ubo_used_mask[shader_type]; + dirty = sub_ctx->const_bufs_dirty[shader_type]; + update = dirty & sub_ctx->const_bufs_used_mask[shader_type]; if (!update) return next_ubo_id + util_bitcount(mask); @@ -4204,7 +4218,7 @@ static int vrend_draw_bind_ubo_shader(struct vrend_context *ctx, if (update & (1 << i)) { /* The cbs array is indexed using the gallium uniform buffer index */ - cb = &ctx->sub->cbs[shader_type][i]; + cb = &sub_ctx->cbs[shader_type][i]; res = (struct vrend_resource *)cb->buffer; glBindBufferRange(GL_UNIFORM_BUFFER, next_ubo_id, res->id, @@ -4213,26 +4227,26 @@ static int vrend_draw_bind_ubo_shader(struct vrend_context *ctx, } next_ubo_id++; } - ctx->sub->const_bufs_dirty[shader_type] = dirty; + sub_ctx->const_bufs_dirty[shader_type] = dirty; return next_ubo_id; } -static void vrend_draw_bind_const_shader(struct vrend_context *ctx, +static void vrend_draw_bind_const_shader(struct vrend_sub_context *sub_ctx, int shader_type, bool new_program) { - if (ctx->sub->consts[shader_type].consts && - ctx->sub->shaders[shader_type] && - (ctx->sub->prog->const_location[shader_type] != -1) && - (ctx->sub->const_dirty[shader_type] || new_program)) { - glUniform4uiv(ctx->sub->prog->const_location[shader_type], - ctx->sub->shaders[shader_type]->sinfo.num_consts, - ctx->sub->consts[shader_type].consts); - ctx->sub->const_dirty[shader_type] = false; + if (sub_ctx->consts[shader_type].consts && + sub_ctx->shaders[shader_type] && + (sub_ctx->prog->const_location[shader_type] != -1) && + (sub_ctx->const_dirty[shader_type] || new_program)) { + glUniform4uiv(sub_ctx->prog->const_location[shader_type], + sub_ctx->shaders[shader_type]->sinfo.num_consts, + sub_ctx->consts[shader_type].consts); + sub_ctx->const_dirty[shader_type] = false; } } -static void vrend_draw_bind_ssbo_shader(struct vrend_context *ctx, int shader_type) +static void vrend_draw_bind_ssbo_shader(struct vrend_sub_context *sub_ctx, int shader_type) { uint32_t mask; struct vrend_ssbo *ssbo; @@ -4242,30 +4256,30 @@ static void vrend_draw_bind_ssbo_shader(struct vrend_context *ctx, int shader_ty if (!has_feature(feat_ssbo)) return; - if (!ctx->sub->prog->ssbo_locs[shader_type]) + if (!sub_ctx->prog->ssbo_locs[shader_type]) return; - if (!ctx->sub->ssbo_used_mask[shader_type]) + if (!sub_ctx->ssbo_used_mask[shader_type]) return; - mask = ctx->sub->ssbo_used_mask[shader_type]; + mask = sub_ctx->ssbo_used_mask[shader_type]; while (mask) { i = u_bit_scan(&mask); - ssbo = &ctx->sub->ssbo[shader_type][i]; + ssbo = &sub_ctx->ssbo[shader_type][i]; res = (struct vrend_resource *)ssbo->res; glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, res->id, ssbo->buffer_offset, ssbo->buffer_size); - if (ctx->sub->prog->ssbo_locs[shader_type][i] != GL_INVALID_INDEX) { + if (sub_ctx->prog->ssbo_locs[shader_type][i] != GL_INVALID_INDEX) { if (!vrend_state.use_gles) - glShaderStorageBlockBinding(ctx->sub->prog->id, ctx->sub->prog->ssbo_locs[shader_type][i], i); + glShaderStorageBlockBinding(sub_ctx->prog->id, sub_ctx->prog->ssbo_locs[shader_type][i], i); else debug_printf("glShaderStorageBlockBinding not supported on gles \n"); } } } -static void vrend_draw_bind_abo_shader(struct vrend_context *ctx) +static void vrend_draw_bind_abo_shader(struct vrend_sub_context *sub_ctx) { uint32_t mask; struct vrend_abo *abo; @@ -4275,18 +4289,18 @@ static void vrend_draw_bind_abo_shader(struct vrend_context *ctx) if (!has_feature(feat_atomic_counters)) return; - mask = ctx->sub->abo_used_mask; + mask = sub_ctx->abo_used_mask; while (mask) { i = u_bit_scan(&mask); - abo = &ctx->sub->abo[i]; + abo = &sub_ctx->abo[i]; res = (struct vrend_resource *)abo->res; glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, i, res->id, abo->buffer_offset, abo->buffer_size); } } -static void vrend_draw_bind_images_shader(struct vrend_context *ctx, int shader_type) +static void vrend_draw_bind_images_shader(struct vrend_sub_context *sub_ctx, int shader_type) { GLenum access; GLboolean layered; @@ -4294,22 +4308,22 @@ static void vrend_draw_bind_images_shader(struct vrend_context *ctx, int shader_ uint32_t mask, tex_id, level, first_layer; - if (!ctx->sub->images_used_mask[shader_type]) + if (!sub_ctx->images_used_mask[shader_type]) return; - if (!ctx->sub->prog->img_locs[shader_type]) + if (!sub_ctx->prog->img_locs[shader_type]) return; if (!has_feature(feat_images)) return; - mask = ctx->sub->images_used_mask[shader_type]; + mask = sub_ctx->images_used_mask[shader_type]; while (mask) { unsigned i = u_bit_scan(&mask); - if (!(ctx->sub->prog->images_used_mask[shader_type] & (1 << i))) + if (!(sub_ctx->prog->images_used_mask[shader_type] & (1 << i))) continue; - iview = &ctx->sub->image_views[shader_type][i]; + iview = &sub_ctx->image_views[shader_type][i]; tex_id = iview->texture->id; if (has_bit(iview->texture->storage_bits, VREND_STORAGE_GL_BUFFER)) { if (!iview->texture->tbo_tex_id) @@ -4335,7 +4349,7 @@ static void vrend_draw_bind_images_shader(struct vrend_context *ctx, int shader_ } if (!vrend_state.use_gles) - glUniform1i(ctx->sub->prog->img_locs[shader_type][i], i); + glUniform1i(sub_ctx->prog->img_locs[shader_type][i], i); switch (iview->access) { case PIPE_IMAGE_ACCESS_READ: @@ -4356,33 +4370,33 @@ static void vrend_draw_bind_images_shader(struct vrend_context *ctx, int shader_ } } -static void vrend_draw_bind_objects(struct vrend_context *ctx, bool new_program) +static void vrend_draw_bind_objects(struct vrend_sub_context *sub_ctx, bool new_program) { int next_ubo_id = 0, next_sampler_id = 0; - for (int shader_type = PIPE_SHADER_VERTEX; shader_type <= ctx->sub->last_shader_idx; shader_type++) { - next_ubo_id = vrend_draw_bind_ubo_shader(ctx, shader_type, next_ubo_id); - vrend_draw_bind_const_shader(ctx, shader_type, new_program); - next_sampler_id = vrend_draw_bind_samplers_shader(ctx, shader_type, + for (int shader_type = PIPE_SHADER_VERTEX; shader_type <= sub_ctx->last_shader_idx; shader_type++) { + next_ubo_id = vrend_draw_bind_ubo_shader(sub_ctx, shader_type, next_ubo_id); + vrend_draw_bind_const_shader(sub_ctx, shader_type, new_program); + next_sampler_id = vrend_draw_bind_samplers_shader(sub_ctx, shader_type, next_sampler_id); - vrend_draw_bind_images_shader(ctx, shader_type); - vrend_draw_bind_ssbo_shader(ctx, shader_type); + vrend_draw_bind_images_shader(sub_ctx, shader_type); + vrend_draw_bind_ssbo_shader(sub_ctx, shader_type); } - vrend_draw_bind_abo_shader(ctx); + vrend_draw_bind_abo_shader(sub_ctx); - if (vrend_state.use_core_profile && ctx->sub->prog->fs_stipple_loc != -1) { + if (vrend_state.use_core_profile && sub_ctx->prog->fs_stipple_loc != -1) { glActiveTexture(GL_TEXTURE0 + next_sampler_id); - glBindTexture(GL_TEXTURE_2D, ctx->pstipple_tex_id); - glUniform1i(ctx->sub->prog->fs_stipple_loc, next_sampler_id); + glBindTexture(GL_TEXTURE_2D, sub_ctx->parent->pstipple_tex_id); + glUniform1i(sub_ctx->prog->fs_stipple_loc, next_sampler_id); } - if (vrend_state.use_core_profile && ctx->sub->prog->fs_alpha_ref_val_loc != -1) { - glUniform1f(ctx->sub->prog->fs_alpha_ref_val_loc, ctx->sub->dsa_state.alpha.ref_value); + if (vrend_state.use_core_profile && sub_ctx->prog->fs_alpha_ref_val_loc != -1) { + glUniform1f(sub_ctx->prog->fs_alpha_ref_val_loc, sub_ctx->dsa_state.alpha.ref_value); } } static -void vrend_inject_tcs(struct vrend_context *ctx, int vertices_per_patch) +void vrend_inject_tcs(struct vrend_sub_context *sub_ctx, int vertices_per_patch) { struct pipe_stream_output_info so_info; @@ -4391,45 +4405,42 @@ void vrend_inject_tcs(struct vrend_context *ctx, int vertices_per_patch) false, PIPE_SHADER_TESS_CTRL); struct vrend_shader *shader; shader = CALLOC_STRUCT(vrend_shader); - vrend_fill_shader_key(ctx->sub, sel, &shader->key); + vrend_fill_shader_key(sub_ctx, sel, &shader->key); shader->sel = sel; list_inithead(&shader->programs); strarray_alloc(&shader->glsl_strings, SHADER_MAX_STRINGS); - vrend_shader_create_passthrough_tcs(ctx, &ctx->shader_cfg, - ctx->sub->shaders[PIPE_SHADER_VERTEX]->tokens, + vrend_shader_create_passthrough_tcs(sub_ctx->parent, &sub_ctx->parent->shader_cfg, + sub_ctx->shaders[PIPE_SHADER_VERTEX]->tokens, &shader->key, vrend_state.tess_factors, &sel->sinfo, &shader->glsl_strings, vertices_per_patch); // Need to add inject the selected shader to the shader selector and then the code below // can continue sel->tokens = NULL; sel->current = shader; - ctx->sub->shaders[PIPE_SHADER_TESS_CTRL] = sel; - ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->num_shaders = 1; + sub_ctx->shaders[PIPE_SHADER_TESS_CTRL] = sel; + sub_ctx->shaders[PIPE_SHADER_TESS_CTRL]->num_shaders = 1; shader->id = glCreateShader(conv_shader_type(shader->sel->type)); - vrend_compile_shader(ctx, shader); + vrend_compile_shader(sub_ctx, shader); } static bool -vrend_select_program(struct vrend_context *ctx, const struct pipe_draw_info *info) +vrend_select_program(struct vrend_sub_context *sub_ctx, const struct pipe_draw_info *info) { struct vrend_linked_shader_program *prog; bool fs_dirty, vs_dirty, gs_dirty, tcs_dirty, tes_dirty; - bool dual_src = util_blend_state_is_dual(&ctx->sub->blend_state, 0); - bool same_prog; - + bool dual_src = util_blend_state_is_dual(&sub_ctx->blend_state, 0); bool new_program = false; - struct vrend_sub_context *sub = ctx->sub; - struct vrend_shader_selector **shaders = sub->shaders; + struct vrend_shader_selector **shaders = sub_ctx->shaders; - sub->shader_dirty = false; + sub_ctx->shader_dirty = false; if (!shaders[PIPE_SHADER_VERTEX] || !shaders[PIPE_SHADER_FRAGMENT]) { - vrend_printf("dropping rendering due to missing shaders: %s\n", ctx->debug_name); + vrend_printf("dropping rendering due to missing shaders: %s\n", sub_ctx->parent->debug_name); return false; } @@ -4438,31 +4449,31 @@ vrend_select_program(struct vrend_context *ctx, const struct pipe_draw_info *inf // buffer formats when the shader is created, we only know it here. // Set it to true so the underlying code knows to use the buffer formats // now. - sub->drawing = true; - vrend_shader_select(ctx, shaders[PIPE_SHADER_VERTEX], &vs_dirty); - sub->drawing = false; + sub_ctx->drawing = true; + vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_VERTEX], &vs_dirty); + sub_ctx->drawing = false; if (shaders[PIPE_SHADER_TESS_CTRL] && shaders[PIPE_SHADER_TESS_CTRL]->tokens) - vrend_shader_select(ctx, shaders[PIPE_SHADER_TESS_CTRL], &tcs_dirty); + vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_TESS_CTRL], &tcs_dirty); else if (vrend_state.use_gles && shaders[PIPE_SHADER_TESS_EVAL]) { - VREND_DEBUG(dbg_shader, ctx, "Need to inject a TCS\n"); - vrend_inject_tcs(ctx, info->vertices_per_patch); + VREND_DEBUG(dbg_shader, sub_ctx->parent, "Need to inject a TCS\n"); + vrend_inject_tcs(sub_ctx, info->vertices_per_patch); - vrend_shader_select(ctx, shaders[PIPE_SHADER_VERTEX], &vs_dirty); + vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_VERTEX], &vs_dirty); } if (shaders[PIPE_SHADER_TESS_EVAL]) - vrend_shader_select(ctx, shaders[PIPE_SHADER_TESS_EVAL], &tes_dirty); + vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_TESS_EVAL], &tes_dirty); if (shaders[PIPE_SHADER_GEOMETRY]) - vrend_shader_select(ctx, shaders[PIPE_SHADER_GEOMETRY], &gs_dirty); - vrend_shader_select(ctx, shaders[PIPE_SHADER_FRAGMENT], &fs_dirty); + vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_GEOMETRY], &gs_dirty); + vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_FRAGMENT], &fs_dirty); if (!shaders[PIPE_SHADER_VERTEX]->current || !shaders[PIPE_SHADER_FRAGMENT]->current || (shaders[PIPE_SHADER_GEOMETRY] && !shaders[PIPE_SHADER_GEOMETRY]->current) || (shaders[PIPE_SHADER_TESS_CTRL] && !shaders[PIPE_SHADER_TESS_CTRL]->current) || (shaders[PIPE_SHADER_TESS_EVAL] && !shaders[PIPE_SHADER_TESS_EVAL]->current)) { - vrend_printf( "failure to compile shader variants: %s\n", ctx->debug_name); + vrend_printf( "failure to compile shader variants: %s\n", sub_ctx->parent->debug_name); return false; } @@ -4472,53 +4483,47 @@ vrend_select_program(struct vrend_context *ctx, const struct pipe_draw_info *inf GLuint tcs_id = shaders[PIPE_SHADER_TESS_CTRL] ? shaders[PIPE_SHADER_TESS_CTRL]->current->id : 0; GLuint tes_id = shaders[PIPE_SHADER_TESS_EVAL] ? shaders[PIPE_SHADER_TESS_EVAL]->current->id : 0; - same_prog = true; - if (vs_id != sub->prog_ids[PIPE_SHADER_VERTEX]) - same_prog = false; - if (fs_id != sub->prog_ids[PIPE_SHADER_FRAGMENT]) - same_prog = false; - if (gs_id != sub->prog_ids[PIPE_SHADER_GEOMETRY]) - same_prog = false; - if (sub->prog && sub->prog->dual_src_linked != dual_src) - same_prog = false; - if (tcs_id != sub->prog_ids[PIPE_SHADER_TESS_CTRL]) - same_prog = false; - if (tes_id != sub->prog_ids[PIPE_SHADER_TESS_EVAL]) - same_prog = false; + bool same_prog = sub_ctx->prog && + vs_id == sub_ctx->prog_ids[PIPE_SHADER_VERTEX] && + fs_id == sub_ctx->prog_ids[PIPE_SHADER_FRAGMENT] && + gs_id == sub_ctx->prog_ids[PIPE_SHADER_GEOMETRY] && + tcs_id == sub_ctx->prog_ids[PIPE_SHADER_TESS_CTRL] && + tes_id == sub_ctx->prog_ids[PIPE_SHADER_TESS_EVAL] && + sub_ctx->prog->dual_src_linked == dual_src; if (!same_prog) { - prog = lookup_shader_program(ctx, vs_id, fs_id, gs_id, tcs_id, tes_id, dual_src); + prog = lookup_shader_program(sub_ctx, vs_id, fs_id, gs_id, tcs_id, tes_id, dual_src); if (!prog) { - prog = add_shader_program(ctx, - sub->shaders[PIPE_SHADER_VERTEX]->current, - sub->shaders[PIPE_SHADER_FRAGMENT]->current, - gs_id ? sub->shaders[PIPE_SHADER_GEOMETRY]->current : NULL, - tcs_id ? sub->shaders[PIPE_SHADER_TESS_CTRL]->current : NULL, - tes_id ? sub->shaders[PIPE_SHADER_TESS_EVAL]->current : NULL); + prog = add_shader_program(sub_ctx, + sub_ctx->shaders[PIPE_SHADER_VERTEX]->current, + sub_ctx->shaders[PIPE_SHADER_FRAGMENT]->current, + gs_id ? sub_ctx->shaders[PIPE_SHADER_GEOMETRY]->current : NULL, + tcs_id ? sub_ctx->shaders[PIPE_SHADER_TESS_CTRL]->current : NULL, + tes_id ? sub_ctx->shaders[PIPE_SHADER_TESS_EVAL]->current : NULL); if (!prog) return false; } - sub->last_shader_idx = sub->shaders[PIPE_SHADER_TESS_EVAL] ? PIPE_SHADER_TESS_EVAL : (sub->shaders[PIPE_SHADER_GEOMETRY] ? PIPE_SHADER_GEOMETRY : PIPE_SHADER_FRAGMENT); + sub_ctx->last_shader_idx = sub_ctx->shaders[PIPE_SHADER_TESS_EVAL] ? PIPE_SHADER_TESS_EVAL : (sub_ctx->shaders[PIPE_SHADER_GEOMETRY] ? PIPE_SHADER_GEOMETRY : PIPE_SHADER_FRAGMENT); } else - prog = sub->prog; - if (sub->prog != prog) { + prog = sub_ctx->prog; + if (sub_ctx->prog != prog) { new_program = true; - sub->prog_ids[PIPE_SHADER_VERTEX] = vs_id; - sub->prog_ids[PIPE_SHADER_FRAGMENT] = fs_id; - sub->prog_ids[PIPE_SHADER_GEOMETRY] = gs_id; - sub->prog_ids[PIPE_SHADER_TESS_CTRL] = tcs_id; - sub->prog_ids[PIPE_SHADER_TESS_EVAL] = tes_id; - sub->prog_ids[PIPE_SHADER_COMPUTE] = 0; - sub->prog = prog; + sub_ctx->prog_ids[PIPE_SHADER_VERTEX] = vs_id; + sub_ctx->prog_ids[PIPE_SHADER_FRAGMENT] = fs_id; + sub_ctx->prog_ids[PIPE_SHADER_GEOMETRY] = gs_id; + sub_ctx->prog_ids[PIPE_SHADER_TESS_CTRL] = tcs_id; + sub_ctx->prog_ids[PIPE_SHADER_TESS_EVAL] = tes_id; + sub_ctx->prog_ids[PIPE_SHADER_COMPUTE] = 0; + sub_ctx->prog = prog; /* mark all constbufs and sampler views as dirty */ for (int stage = PIPE_SHADER_VERTEX; stage <= PIPE_SHADER_FRAGMENT; stage++) { - sub->const_bufs_dirty[stage] = ~0; - sub->sampler_views_dirty[stage] = ~0; + sub_ctx->const_bufs_dirty[stage] = ~0; + sub_ctx->sampler_views_dirty[stage] = ~0; } - prog->ref_context = sub; + prog->ref_context = sub_ctx; } return new_program; } @@ -4532,6 +4537,7 @@ int vrend_draw_vbo(struct vrend_context *ctx, bool new_program = false; struct vrend_resource *indirect_res = NULL; struct vrend_resource *indirect_params_res = NULL; + struct vrend_sub_context *sub_ctx = ctx->sub; if (ctx->in_error) return 0; @@ -4570,73 +4576,63 @@ int vrend_draw_vbo(struct vrend_context *ctx, if (ctx->ctx_switch_pending) vrend_finish_context_switch(ctx); - vrend_update_frontface_state(ctx); + vrend_update_frontface_state(sub_ctx); if (ctx->sub->stencil_state_dirty) - vrend_update_stencil_state(ctx); + vrend_update_stencil_state(sub_ctx); if (ctx->sub->scissor_state_dirty) - vrend_update_scissor_state(ctx); + vrend_update_scissor_state(sub_ctx); if (ctx->sub->viewport_state_dirty) - vrend_update_viewport_state(ctx); + vrend_update_viewport_state(sub_ctx); if (ctx->sub->blend_state_dirty) - vrend_patch_blend_state(ctx); + vrend_patch_blend_state(sub_ctx); // enable primitive-mode-dependent shader variants - if (ctx->sub->prim_mode != (int)info->mode) { + if (sub_ctx->prim_mode != (int)info->mode) { // Only refresh shader program when switching in/out of GL_POINTS primitive mode - if (ctx->sub->prim_mode == PIPE_PRIM_POINTS + if (sub_ctx->prim_mode == PIPE_PRIM_POINTS || (int)info->mode == PIPE_PRIM_POINTS) - ctx->sub->shader_dirty = true; + sub_ctx->shader_dirty = true; - ctx->sub->prim_mode = (int)info->mode; + sub_ctx->prim_mode = (int)info->mode; } - if (ctx->sub->shader_dirty || ctx->sub->swizzle_output_rgb_to_bgr) - new_program = vrend_select_program(ctx, info); + if (sub_ctx->shader_dirty || sub_ctx->swizzle_output_rgb_to_bgr) + new_program = vrend_select_program(sub_ctx, info); - if (!ctx->sub->prog) { + if (!sub_ctx->prog) { vrend_printf("dropping rendering due to missing shaders: %s\n", ctx->debug_name); return 0; } - vrend_use_program(ctx, ctx->sub->prog->id); + vrend_use_program(sub_ctx, sub_ctx->prog->id); - vrend_draw_bind_objects(ctx, new_program); + vrend_draw_bind_objects(sub_ctx, new_program); - if (!ctx->sub->ve) { + if (!sub_ctx->ve) { vrend_printf("illegal VE setup - skipping renderering\n"); return 0; } - float viewport_neg_val = ctx->sub->viewport_is_negative ? -1.0 : 1.0; - if (ctx->sub->prog->viewport_neg_val != viewport_neg_val) { - glUniform1f(ctx->sub->prog->vs_ws_adjust_loc, viewport_neg_val); - ctx->sub->prog->viewport_neg_val = viewport_neg_val; + float viewport_neg_val = sub_ctx->viewport_is_negative ? -1.0 : 1.0; + if (sub_ctx->prog->viewport_neg_val != viewport_neg_val) { + glUniform1f(sub_ctx->prog->vs_ws_adjust_loc, viewport_neg_val); + sub_ctx->prog->viewport_neg_val = viewport_neg_val; } - if (ctx->sub->rs_state.clip_plane_enable) { + if (sub_ctx->rs_state.clip_plane_enable) { for (i = 0 ; i < 8; i++) { - glUniform4fv(ctx->sub->prog->clip_locs[i], 1, (const GLfloat *)&ctx->sub->ucp_state.ucp[i]); + glUniform4fv(sub_ctx->prog->clip_locs[i], 1, (const GLfloat *)&sub_ctx->ucp_state.ucp[i]); } } if (has_feature(feat_gles31_vertex_attrib_binding)) - vrend_draw_bind_vertex_binding(ctx, ctx->sub->ve); + vrend_draw_bind_vertex_binding(ctx, sub_ctx->ve); else - vrend_draw_bind_vertex_legacy(ctx, ctx->sub->ve); - - for (i = 0 ; i < ctx->sub->prog->ss[PIPE_SHADER_VERTEX]->sel->sinfo.num_inputs; i++) { - struct vrend_vertex_element_array *va = ctx->sub->ve; - struct vrend_vertex_element *ve = &va->elements[i]; - int vbo_index = ve->base.vertex_buffer_index; - if (!ctx->sub->vbo[vbo_index].base.buffer) { - vrend_printf( "VBO missing vertex buffer\n"); - return 0; - } - } + vrend_draw_bind_vertex_legacy(ctx, sub_ctx->ve); if (info->indexed) { - struct vrend_resource *res = (struct vrend_resource *)ctx->sub->ib.buffer; + struct vrend_resource *res = (struct vrend_resource *)sub_ctx->ib.buffer; if (!res) { vrend_printf( "VBO missing indexed array buffer\n"); return 0; @@ -4645,19 +4641,19 @@ int vrend_draw_vbo(struct vrend_context *ctx, } else glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - if (ctx->sub->current_so) { - if (ctx->sub->current_so->xfb_state == XFB_STATE_STARTED_NEED_BEGIN) { - if (ctx->sub->shaders[PIPE_SHADER_GEOMETRY]) - glBeginTransformFeedback(get_gs_xfb_mode(ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->sinfo.gs_out_prim)); - else if (ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]) - glBeginTransformFeedback(get_tess_xfb_mode(ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->sinfo.tes_prim, - ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->sinfo.tes_point_mode)); + if (sub_ctx->current_so) { + if (sub_ctx->current_so->xfb_state == XFB_STATE_STARTED_NEED_BEGIN) { + if (sub_ctx->shaders[PIPE_SHADER_GEOMETRY]) + glBeginTransformFeedback(get_gs_xfb_mode(sub_ctx->shaders[PIPE_SHADER_GEOMETRY]->sinfo.gs_out_prim)); + else if (sub_ctx->shaders[PIPE_SHADER_TESS_EVAL]) + glBeginTransformFeedback(get_tess_xfb_mode(sub_ctx->shaders[PIPE_SHADER_TESS_EVAL]->sinfo.tes_prim, + sub_ctx->shaders[PIPE_SHADER_TESS_EVAL]->sinfo.tes_point_mode)); else glBeginTransformFeedback(get_xfb_mode(info->mode)); - ctx->sub->current_so->xfb_state = XFB_STATE_STARTED; - } else if (ctx->sub->current_so->xfb_state == XFB_STATE_PAUSED) { + sub_ctx->current_so->xfb_state = XFB_STATE_STARTED; + } else if (sub_ctx->current_so->xfb_state == XFB_STATE_PAUSED) { glResumeTransformFeedback(); - ctx->sub->current_so->xfb_state = XFB_STATE_STARTED; + sub_ctx->current_so->xfb_state = XFB_STATE_STARTED; } } @@ -4675,16 +4671,16 @@ int vrend_draw_vbo(struct vrend_context *ctx, if (has_feature(feat_indirect_draw)) { GLint buf = indirect_res ? indirect_res->id : 0; - if (ctx->sub->draw_indirect_buffer != buf) { + if (sub_ctx->draw_indirect_buffer != buf) { glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buf); - ctx->sub->draw_indirect_buffer = buf; + sub_ctx->draw_indirect_buffer = buf; } if (has_feature(feat_indirect_params)) { GLint buf = indirect_params_res ? indirect_params_res->id : 0; - if (ctx->sub->draw_indirect_params_buffer != buf) { + if (sub_ctx->draw_indirect_params_buffer != buf) { glBindBuffer(GL_PARAMETER_BUFFER_ARB, buf); - ctx->sub->draw_indirect_params_buffer = buf; + sub_ctx->draw_indirect_params_buffer = buf; } } } @@ -4697,9 +4693,9 @@ int vrend_draw_vbo(struct vrend_context *ctx, * accept those blend equations. * When we transmit the blend mode through alpha_src_factor, alpha_dst_factor is always 0. */ - uint32_t blend_mask_shader = ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->sinfo.fs_blend_equation_advanced; - uint32_t blend_mode = ctx->sub->blend_state.rt[0].alpha_src_factor; - uint32_t alpha_dst_factor = ctx->sub->blend_state.rt[0].alpha_dst_factor; + uint32_t blend_mask_shader = sub_ctx->shaders[PIPE_SHADER_FRAGMENT]->sinfo.fs_blend_equation_advanced; + uint32_t blend_mode = sub_ctx->blend_state.rt[0].alpha_src_factor; + uint32_t alpha_dst_factor = sub_ctx->blend_state.rt[0].alpha_dst_factor; bool use_advanced_blending = !has_feature(feat_framebuffer_fetch) && has_feature(feat_blend_equation_advanced) && blend_mask_shader != 0 && @@ -4734,7 +4730,7 @@ int vrend_draw_vbo(struct vrend_context *ctx, } else { GLenum elsz; GLenum mode = info->mode; - switch (ctx->sub->ib.index_size) { + switch (sub_ctx->ib.index_size) { case 1: elsz = GL_UNSIGNED_BYTE; break; @@ -4757,17 +4753,17 @@ int vrend_draw_vbo(struct vrend_context *ctx, glDrawElementsIndirect(mode, elsz, (GLvoid const *)(unsigned long)info->indirect.offset); } else if (info->index_bias) { if (info->instance_count > 1) - glDrawElementsInstancedBaseVertex(mode, info->count, elsz, (void *)(unsigned long)ctx->sub->ib.offset, info->instance_count, info->index_bias); + glDrawElementsInstancedBaseVertex(mode, info->count, elsz, (void *)(unsigned long)sub_ctx->ib.offset, info->instance_count, info->index_bias); else if (info->min_index != 0 || info->max_index != (unsigned)-1) - glDrawRangeElementsBaseVertex(mode, info->min_index, info->max_index, info->count, elsz, (void *)(unsigned long)ctx->sub->ib.offset, info->index_bias); + glDrawRangeElementsBaseVertex(mode, info->min_index, info->max_index, info->count, elsz, (void *)(unsigned long)sub_ctx->ib.offset, info->index_bias); else - glDrawElementsBaseVertex(mode, info->count, elsz, (void *)(unsigned long)ctx->sub->ib.offset, info->index_bias); + glDrawElementsBaseVertex(mode, info->count, elsz, (void *)(unsigned long)sub_ctx->ib.offset, info->index_bias); } else if (info->instance_count > 1) { - glDrawElementsInstancedARB(mode, info->count, elsz, (void *)(unsigned long)ctx->sub->ib.offset, info->instance_count); + glDrawElementsInstancedARB(mode, info->count, elsz, (void *)(unsigned long)sub_ctx->ib.offset, info->instance_count); } else if (info->min_index != 0 || info->max_index != (unsigned)-1) - glDrawRangeElements(mode, info->min_index, info->max_index, info->count, elsz, (void *)(unsigned long)ctx->sub->ib.offset); + glDrawRangeElements(mode, info->min_index, info->max_index, info->count, elsz, (void *)(unsigned long)sub_ctx->ib.offset); else - glDrawElements(mode, info->count, elsz, (void *)(unsigned long)ctx->sub->ib.offset); + glDrawElements(mode, info->count, elsz, (void *)(unsigned long)sub_ctx->ib.offset); } if (info->primitive_restart) { @@ -4780,10 +4776,10 @@ int vrend_draw_vbo(struct vrend_context *ctx, } } - if (ctx->sub->current_so && has_feature(feat_transform_feedback2)) { - if (ctx->sub->current_so->xfb_state == XFB_STATE_STARTED) { + if (sub_ctx->current_so && has_feature(feat_transform_feedback2)) { + if (sub_ctx->current_so->xfb_state == XFB_STATE_STARTED) { glPauseTransformFeedback(); - ctx->sub->current_so->xfb_state = XFB_STATE_PAUSED; + sub_ctx->current_so->xfb_state = XFB_STATE_PAUSED; } } return 0; @@ -4801,56 +4797,58 @@ void vrend_launch_grid(struct vrend_context *ctx, if (!has_feature(feat_compute_shader)) return; - if (ctx->sub->cs_shader_dirty) { + struct vrend_sub_context *sub_ctx = ctx->sub; + + if (sub_ctx->cs_shader_dirty) { struct vrend_linked_shader_program *prog; bool cs_dirty; - ctx->sub->cs_shader_dirty = false; + sub_ctx->cs_shader_dirty = false; - if (!ctx->sub->shaders[PIPE_SHADER_COMPUTE]) { + if (!sub_ctx->shaders[PIPE_SHADER_COMPUTE]) { vrend_printf("dropping rendering due to missing shaders: %s\n", ctx->debug_name); return; } - vrend_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_COMPUTE], &cs_dirty); - if (!ctx->sub->shaders[PIPE_SHADER_COMPUTE]->current) { + vrend_shader_select(sub_ctx, sub_ctx->shaders[PIPE_SHADER_COMPUTE], &cs_dirty); + if (!sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current) { vrend_printf( "failure to compile shader variants: %s\n", ctx->debug_name); return; } - if (ctx->sub->shaders[PIPE_SHADER_COMPUTE]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_COMPUTE]) { - prog = lookup_cs_shader_program(ctx, ctx->sub->shaders[PIPE_SHADER_COMPUTE]->current->id); + if (sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current->id != (GLuint)sub_ctx->prog_ids[PIPE_SHADER_COMPUTE]) { + prog = lookup_cs_shader_program(ctx, sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current->id); if (!prog) { - prog = add_cs_shader_program(ctx, ctx->sub->shaders[PIPE_SHADER_COMPUTE]->current); + prog = add_cs_shader_program(ctx, sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current); if (!prog) return; } } else - prog = ctx->sub->prog; + prog = sub_ctx->prog; - if (ctx->sub->prog != prog) { + if (sub_ctx->prog != prog) { new_program = true; - ctx->sub->prog_ids[PIPE_SHADER_VERTEX] = 0; - ctx->sub->prog_ids[PIPE_SHADER_COMPUTE] = ctx->sub->shaders[PIPE_SHADER_COMPUTE]->current->id; - ctx->sub->prog = prog; - prog->ref_context = ctx->sub; + sub_ctx->prog_ids[PIPE_SHADER_VERTEX] = 0; + sub_ctx->prog_ids[PIPE_SHADER_COMPUTE] = sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current->id; + sub_ctx->prog = prog; + prog->ref_context = sub_ctx; } - ctx->sub->shader_dirty = true; + sub_ctx->shader_dirty = true; } - if (!ctx->sub->prog) { + if (!sub_ctx->prog) { vrend_printf("%s: Skipping compute shader execution due to missing shaders: %s\n", __func__, ctx->debug_name); return; } - vrend_use_program(ctx, ctx->sub->prog->id); + vrend_use_program(sub_ctx, sub_ctx->prog->id); - vrend_draw_bind_ubo_shader(ctx, PIPE_SHADER_COMPUTE, 0); - vrend_draw_bind_const_shader(ctx, PIPE_SHADER_COMPUTE, new_program); - vrend_draw_bind_samplers_shader(ctx, PIPE_SHADER_COMPUTE, 0); - vrend_draw_bind_images_shader(ctx, PIPE_SHADER_COMPUTE); - vrend_draw_bind_ssbo_shader(ctx, PIPE_SHADER_COMPUTE); - vrend_draw_bind_abo_shader(ctx); + vrend_draw_bind_ubo_shader(sub_ctx, PIPE_SHADER_COMPUTE, 0); + vrend_draw_bind_const_shader(sub_ctx, PIPE_SHADER_COMPUTE, new_program); + vrend_draw_bind_samplers_shader(sub_ctx, PIPE_SHADER_COMPUTE, 0); + vrend_draw_bind_images_shader(sub_ctx, PIPE_SHADER_COMPUTE); + vrend_draw_bind_ssbo_shader(sub_ctx, PIPE_SHADER_COMPUTE); + vrend_draw_bind_abo_shader(sub_ctx); if (indirect_handle) { indirect_res = vrend_renderer_ctx_res_lookup(ctx, indirect_handle); @@ -5003,15 +5001,15 @@ static inline bool is_const_blend(int blend_factor) blend_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA); } -static void vrend_hw_emit_blend(struct vrend_context *ctx, struct pipe_blend_state *state) +static void vrend_hw_emit_blend(struct vrend_sub_context *sub_ctx, struct pipe_blend_state *state) { - if (state->logicop_enable != ctx->sub->hw_blend_state.logicop_enable) { - ctx->sub->hw_blend_state.logicop_enable = state->logicop_enable; + if (state->logicop_enable != sub_ctx->hw_blend_state.logicop_enable) { + sub_ctx->hw_blend_state.logicop_enable = state->logicop_enable; if (vrend_state.use_gles) { if (can_emulate_logicop(state->logicop_func)) - ctx->sub->shader_dirty = true; + sub_ctx->shader_dirty = true; else - report_gles_warn(ctx, GLES_WARN_LOGIC_OP); + report_gles_warn(sub_ctx->parent, GLES_WARN_LOGIC_OP); } else if (state->logicop_enable) { glEnable(GL_COLOR_LOGIC_OP); glLogicOp(translate_logicop(state->logicop_func)); @@ -5029,7 +5027,7 @@ static void vrend_hw_emit_blend(struct vrend_context *ctx, struct pipe_blend_sta for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { if (state->rt[i].blend_enable) { - bool dual_src = util_blend_state_is_dual(&ctx->sub->blend_state, i); + bool dual_src = util_blend_state_is_dual(&sub_ctx->blend_state, i); if (dual_src && !has_feature(feat_dual_src_blend)) { vrend_printf( "dual src blend requested but not supported for rt %d\n", i); continue; @@ -5045,8 +5043,8 @@ static void vrend_hw_emit_blend(struct vrend_context *ctx, struct pipe_blend_sta } else glDisableIndexedEXT(GL_BLEND, i); - if (state->rt[i].colormask != ctx->sub->hw_blend_state.rt[i].colormask) { - ctx->sub->hw_blend_state.rt[i].colormask = state->rt[i].colormask; + if (state->rt[i].colormask != sub_ctx->hw_blend_state.rt[i].colormask) { + sub_ctx->hw_blend_state.rt[i].colormask = state->rt[i].colormask; glColorMaskIndexedEXT(i, state->rt[i].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE, state->rt[i].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE, state->rt[i].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE, @@ -5055,7 +5053,7 @@ static void vrend_hw_emit_blend(struct vrend_context *ctx, struct pipe_blend_sta } } else { if (state->rt[0].blend_enable) { - bool dual_src = util_blend_state_is_dual(&ctx->sub->blend_state, 0); + bool dual_src = util_blend_state_is_dual(&sub_ctx->blend_state, 0); if (dual_src && !has_feature(feat_dual_src_blend)) { vrend_printf( "dual src blend requested but not supported for rt 0\n"); } @@ -5070,19 +5068,19 @@ static void vrend_hw_emit_blend(struct vrend_context *ctx, struct pipe_blend_sta else glDisable(GL_BLEND); - if (state->rt[0].colormask != ctx->sub->hw_blend_state.rt[0].colormask || - (ctx->sub->hw_blend_state.independent_blend_enable && + if (state->rt[0].colormask != sub_ctx->hw_blend_state.rt[0].colormask || + (sub_ctx->hw_blend_state.independent_blend_enable && !state->independent_blend_enable)) { int i; for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - ctx->sub->hw_blend_state.rt[i].colormask = state->rt[i].colormask; + sub_ctx->hw_blend_state.rt[i].colormask = state->rt[i].colormask; glColorMask(state->rt[0].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE, state->rt[0].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE, state->rt[0].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE, state->rt[0].colormask & PIPE_MASK_A ? GL_TRUE : GL_FALSE); } } - ctx->sub->hw_blend_state.independent_blend_enable = state->independent_blend_enable; + sub_ctx->hw_blend_state.independent_blend_enable = state->independent_blend_enable; if (has_feature(feat_multisample)) { if (state->alpha_to_coverage) @@ -5109,22 +5107,22 @@ static void vrend_hw_emit_blend(struct vrend_context *ctx, struct pipe_blend_sta b) patching colormask/blendcolor/blendfactors for A8/A16 format emulation using GL_R8/GL_R16. */ -static void vrend_patch_blend_state(struct vrend_context *ctx) +static void vrend_patch_blend_state(struct vrend_sub_context *sub_ctx) { - struct pipe_blend_state new_state = ctx->sub->blend_state; - struct pipe_blend_state *state = &ctx->sub->blend_state; + struct pipe_blend_state new_state = sub_ctx->blend_state; + struct pipe_blend_state *state = &sub_ctx->blend_state; bool swizzle_blend_color = false; - struct pipe_blend_color blend_color = ctx->sub->blend_color; + struct pipe_blend_color blend_color = sub_ctx->blend_color; int i; - if (ctx->sub->nr_cbufs == 0) { - ctx->sub->blend_state_dirty = false; + if (sub_ctx->nr_cbufs == 0) { + sub_ctx->blend_state_dirty = false; return; } for (i = 0; i < (state->independent_blend_enable ? PIPE_MAX_COLOR_BUFS : 1); i++) { - if (i < ctx->sub->nr_cbufs && ctx->sub->surf[i]) { - if (vrend_format_is_emulated_alpha(ctx->sub->surf[i]->format)) { + if (i < sub_ctx->nr_cbufs && sub_ctx->surf[i]) { + if (vrend_format_is_emulated_alpha(sub_ctx->surf[i]->format)) { if (state->rt[i].blend_enable) { new_state.rt[i].rgb_src_factor = conv_a8_blend(state->rt[i].alpha_src_factor); new_state.rt[i].rgb_dst_factor = conv_a8_blend(state->rt[i].alpha_dst_factor); @@ -5138,7 +5136,7 @@ static void vrend_patch_blend_state(struct vrend_context *ctx) is_const_blend(new_state.rt[i].rgb_dst_factor)) { swizzle_blend_color = true; } - } else if (!util_format_has_alpha(ctx->sub->surf[i]->format)) { + } else if (!util_format_has_alpha(sub_ctx->surf[i]->format)) { if (!(is_dst_blend(state->rt[i].rgb_src_factor) || is_dst_blend(state->rt[i].rgb_dst_factor) || is_dst_blend(state->rt[i].alpha_src_factor) || @@ -5152,7 +5150,7 @@ static void vrend_patch_blend_state(struct vrend_context *ctx) } } - vrend_hw_emit_blend(ctx, &new_state); + vrend_hw_emit_blend(sub_ctx, &new_state); if (swizzle_blend_color) { blend_color.color[0] = blend_color.color[3]; @@ -5166,7 +5164,7 @@ static void vrend_patch_blend_state(struct vrend_context *ctx) blend_color.color[2], blend_color.color[3]); - ctx->sub->blend_state_dirty = false; + sub_ctx->blend_state_dirty = false; } void vrend_object_bind_blend(struct vrend_context *ctx, @@ -5244,41 +5242,41 @@ void vrend_object_bind_dsa(struct vrend_context *ctx, vrend_hw_emit_dsa(ctx); } -static void vrend_update_frontface_state(struct vrend_context *ctx) +static void vrend_update_frontface_state(struct vrend_sub_context *sub_ctx) { - struct pipe_rasterizer_state *state = &ctx->sub->rs_state; + struct pipe_rasterizer_state *state = &sub_ctx->rs_state; int front_ccw = state->front_ccw; - front_ccw ^= (ctx->sub->inverted_fbo_content ? 0 : 1); + front_ccw ^= (sub_ctx->inverted_fbo_content ? 0 : 1); if (front_ccw) glFrontFace(GL_CCW); else glFrontFace(GL_CW); } -void vrend_update_stencil_state(struct vrend_context *ctx) +void vrend_update_stencil_state(struct vrend_sub_context *sub_ctx) { - struct pipe_depth_stencil_alpha_state *state = ctx->sub->dsa; + struct pipe_depth_stencil_alpha_state *state = sub_ctx->dsa; int i; if (!state) return; if (!state->stencil[1].enabled) { if (state->stencil[0].enabled) { - vrend_stencil_test_enable(ctx, true); + vrend_stencil_test_enable(sub_ctx, true); glStencilOp(translate_stencil_op(state->stencil[0].fail_op), translate_stencil_op(state->stencil[0].zfail_op), translate_stencil_op(state->stencil[0].zpass_op)); glStencilFunc(GL_NEVER + state->stencil[0].func, - ctx->sub->stencil_refs[0], + sub_ctx->stencil_refs[0], state->stencil[0].valuemask); glStencilMask(state->stencil[0].writemask); } else - vrend_stencil_test_enable(ctx, false); + vrend_stencil_test_enable(sub_ctx, false); } else { - vrend_stencil_test_enable(ctx, true); + vrend_stencil_test_enable(sub_ctx, true); for (i = 0; i < 2; i++) { GLenum face = (i == 1) ? GL_BACK : GL_FRONT; @@ -5288,12 +5286,12 @@ void vrend_update_stencil_state(struct vrend_context *ctx) translate_stencil_op(state->stencil[i].zpass_op)); glStencilFuncSeparate(face, GL_NEVER + state->stencil[i].func, - ctx->sub->stencil_refs[i], + sub_ctx->stencil_refs[i], state->stencil[i].valuemask); glStencilMaskSeparate(face, state->stencil[i].writemask); } } - ctx->sub->stencil_state_dirty = false; + sub_ctx->stencil_state_dirty = false; } static inline GLenum translate_fill(uint32_t mode) @@ -5655,7 +5653,7 @@ static bool get_swizzled_border_color(enum virgl_formats fmt, return false; } -static void vrend_apply_sampler_state(struct vrend_context *ctx, +static void vrend_apply_sampler_state(struct vrend_sub_context *sub_ctx, struct vrend_resource *res, uint32_t shader_type, int id, @@ -5663,7 +5661,7 @@ static void vrend_apply_sampler_state(struct vrend_context *ctx, struct vrend_sampler_view *tview) { struct vrend_texture *tex = (struct vrend_texture *)res; - struct vrend_sampler_state *vstate = ctx->sub->sampler_state[shader_type][id]; + struct vrend_sampler_state *vstate = sub_ctx->sampler_state[shader_type][id]; struct pipe_sampler_state *state = &vstate->base; bool set_all = false; GLenum target = tex->base.target; @@ -5728,7 +5726,7 @@ static void vrend_apply_sampler_state(struct vrend_context *ctx, if (tex->state.lod_bias != state->lod_bias || set_all) { if (vrend_state.use_gles) { if (state->lod_bias) - report_gles_warn(ctx, GLES_WARN_LOD_BIAS); + report_gles_warn(sub_ctx->parent, GLES_WARN_LOD_BIAS); } else { glTexParameterf(target, GL_TEXTURE_LOD_BIAS, state->lod_bias); } @@ -7416,7 +7414,7 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx, uint32_t layer_stride = info->layer_stride; if (ctx) - vrend_use_program(ctx, 0); + vrend_use_program(ctx->sub, 0); else glUseProgram(0); @@ -7510,7 +7508,7 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx, if (ctx) { vrend_depth_test_enable(ctx, false); vrend_alpha_test_enable(ctx, false); - vrend_stencil_test_enable(ctx, false); + vrend_stencil_test_enable(ctx->sub, false); } else { glDisable(GL_DEPTH_TEST); glDisable(GL_ALPHA_TEST); @@ -7752,7 +7750,7 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx, GLint old_fbo; if (ctx) - vrend_use_program(ctx, 0); + vrend_use_program(ctx->sub, 0); else glUseProgram(0); @@ -10574,6 +10572,7 @@ void vrend_renderer_create_sub_ctx(struct vrend_context *ctx, int sub_ctx_id) ctx_params.major_ver = vrend_state.gl_major_ver; ctx_params.minor_ver = vrend_state.gl_minor_ver; sub->gl_context = vrend_clicbs->create_gl_context(0, &ctx_params); + sub->parent = ctx; vrend_clicbs->make_current(sub->gl_context); /* enable if vrend_renderer_init function has done it as well */