vrend: extract method for shader update from vrend_draw_vbo

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
macos/master
Gert Wollny 4 years ago
parent 2b0e2f0729
commit 0be4be0c3b
  1. 214
      src/vrend_renderer.c

@ -4388,6 +4388,116 @@ void vrend_inject_tcs(struct vrend_context *ctx, int vertices_per_patch)
vrend_compile_shader(ctx, shader);
}
static bool
vrend_select_program(struct vrend_context *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 new_program = false;
ctx->sub->shader_dirty = false;
if (!ctx->sub->shaders[PIPE_SHADER_VERTEX] || !ctx->sub->shaders[PIPE_SHADER_FRAGMENT]) {
vrend_printf("dropping rendering due to missing shaders: %s\n", ctx->debug_name);
return false;
}
// For some GPU, we'd like to use integer variable in generated GLSL if
// the input buffers are integer formats. But we actually don't know the
// 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.
ctx->drawing = true;
vrend_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_VERTEX], &vs_dirty);
ctx->drawing = false;
if (ctx->sub->shaders[PIPE_SHADER_TESS_CTRL] && ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->tokens)
vrend_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_TESS_CTRL], &tcs_dirty);
else if (vrend_state.use_gles && ctx->sub->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_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_VERTEX], &vs_dirty);
}
if (ctx->sub->shaders[PIPE_SHADER_TESS_EVAL])
vrend_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_TESS_EVAL], &tes_dirty);
if (ctx->sub->shaders[PIPE_SHADER_GEOMETRY])
vrend_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_GEOMETRY], &gs_dirty);
vrend_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_FRAGMENT], &fs_dirty);
if (!ctx->sub->shaders[PIPE_SHADER_VERTEX]->current ||
!ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current ||
(ctx->sub->shaders[PIPE_SHADER_GEOMETRY] && !ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current) ||
(ctx->sub->shaders[PIPE_SHADER_TESS_CTRL] && !ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->current) ||
(ctx->sub->shaders[PIPE_SHADER_TESS_EVAL] && !ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->current)) {
vrend_printf( "failure to compile shader variants: %s\n", ctx->debug_name);
return false;
}
same_prog = true;
if (ctx->sub->shaders[PIPE_SHADER_VERTEX]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_VERTEX])
same_prog = false;
if (ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_FRAGMENT])
same_prog = false;
if (ctx->sub->shaders[PIPE_SHADER_GEOMETRY] && ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_GEOMETRY])
same_prog = false;
if (ctx->sub->prog && ctx->sub->prog->dual_src_linked != dual_src)
same_prog = false;
if (ctx->sub->shaders[PIPE_SHADER_TESS_CTRL] && ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_TESS_CTRL])
same_prog = false;
if (ctx->sub->shaders[PIPE_SHADER_TESS_EVAL] && ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_TESS_EVAL])
same_prog = false;
if (!same_prog) {
prog = lookup_shader_program(ctx,
ctx->sub->shaders[PIPE_SHADER_VERTEX]->current->id,
ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current->id,
ctx->sub->shaders[PIPE_SHADER_GEOMETRY] ? ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current->id : 0,
ctx->sub->shaders[PIPE_SHADER_TESS_CTRL] ? ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->current->id : 0,
ctx->sub->shaders[PIPE_SHADER_TESS_EVAL] ? ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->current->id : 0,
dual_src);
if (!prog) {
prog = add_shader_program(ctx,
ctx->sub->shaders[PIPE_SHADER_VERTEX]->current,
ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current,
ctx->sub->shaders[PIPE_SHADER_GEOMETRY] ? ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current : NULL,
ctx->sub->shaders[PIPE_SHADER_TESS_CTRL] ? ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->current : NULL,
ctx->sub->shaders[PIPE_SHADER_TESS_EVAL] ? ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->current : NULL);
if (!prog)
return false;
}
ctx->sub->last_shader_idx = ctx->sub->shaders[PIPE_SHADER_TESS_EVAL] ? PIPE_SHADER_TESS_EVAL : (ctx->sub->shaders[PIPE_SHADER_GEOMETRY] ? PIPE_SHADER_GEOMETRY : PIPE_SHADER_FRAGMENT);
} else
prog = ctx->sub->prog;
if (ctx->sub->prog != prog) {
new_program = true;
ctx->sub->prog_ids[PIPE_SHADER_VERTEX] = ctx->sub->shaders[PIPE_SHADER_VERTEX]->current->id;
ctx->sub->prog_ids[PIPE_SHADER_FRAGMENT] = ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current->id;
if (ctx->sub->shaders[PIPE_SHADER_GEOMETRY])
ctx->sub->prog_ids[PIPE_SHADER_GEOMETRY] = ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current->id;
if (ctx->sub->shaders[PIPE_SHADER_TESS_CTRL])
ctx->sub->prog_ids[PIPE_SHADER_TESS_CTRL] = ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->current->id;
if (ctx->sub->shaders[PIPE_SHADER_TESS_EVAL])
ctx->sub->prog_ids[PIPE_SHADER_TESS_EVAL] = ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->current->id;
ctx->sub->prog_ids[PIPE_SHADER_COMPUTE] = -1;
ctx->sub->prog = prog;
/* mark all constbufs and sampler views as dirty */
for (int stage = PIPE_SHADER_VERTEX; stage <= PIPE_SHADER_FRAGMENT; stage++) {
ctx->sub->const_bufs_dirty[stage] = ~0;
ctx->sub->sampler_views_dirty[stage] = ~0;
}
prog->ref_context = ctx->sub;
}
return new_program;
}
int vrend_draw_vbo(struct vrend_context *ctx,
const struct pipe_draw_info *info,
uint32_t cso, uint32_t indirect_handle,
@ -4457,109 +4567,9 @@ int vrend_draw_vbo(struct vrend_context *ctx,
ctx->sub->prim_mode = (int)info->mode;
}
if (ctx->sub->shader_dirty || ctx->sub->swizzle_output_rgb_to_bgr) {
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;
ctx->sub->shader_dirty = false;
if (ctx->sub->shader_dirty || ctx->sub->swizzle_output_rgb_to_bgr)
new_program = vrend_select_program(ctx, info);
if (!ctx->sub->shaders[PIPE_SHADER_VERTEX] || !ctx->sub->shaders[PIPE_SHADER_FRAGMENT]) {
vrend_printf("dropping rendering due to missing shaders: %s\n", ctx->debug_name);
return 0;
}
// For some GPU, we'd like to use integer variable in generated GLSL if
// the input buffers are integer formats. But we actually don't know the
// 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.
ctx->drawing = true;
vrend_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_VERTEX], &vs_dirty);
ctx->drawing = false;
if (ctx->sub->shaders[PIPE_SHADER_TESS_CTRL] && ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->tokens)
vrend_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_TESS_CTRL], &tcs_dirty);
else if (vrend_state.use_gles && ctx->sub->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_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_VERTEX], &vs_dirty);
}
if (ctx->sub->shaders[PIPE_SHADER_TESS_EVAL])
vrend_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_TESS_EVAL], &tes_dirty);
if (ctx->sub->shaders[PIPE_SHADER_GEOMETRY])
vrend_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_GEOMETRY], &gs_dirty);
vrend_shader_select(ctx, ctx->sub->shaders[PIPE_SHADER_FRAGMENT], &fs_dirty);
if (!ctx->sub->shaders[PIPE_SHADER_VERTEX]->current ||
!ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current ||
(ctx->sub->shaders[PIPE_SHADER_GEOMETRY] && !ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current) ||
(ctx->sub->shaders[PIPE_SHADER_TESS_CTRL] && !ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->current) ||
(ctx->sub->shaders[PIPE_SHADER_TESS_EVAL] && !ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->current)) {
vrend_printf( "failure to compile shader variants: %s\n", ctx->debug_name);
return 0;
}
same_prog = true;
if (ctx->sub->shaders[PIPE_SHADER_VERTEX]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_VERTEX])
same_prog = false;
if (ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_FRAGMENT])
same_prog = false;
if (ctx->sub->shaders[PIPE_SHADER_GEOMETRY] && ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_GEOMETRY])
same_prog = false;
if (ctx->sub->prog && ctx->sub->prog->dual_src_linked != dual_src)
same_prog = false;
if (ctx->sub->shaders[PIPE_SHADER_TESS_CTRL] && ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_TESS_CTRL])
same_prog = false;
if (ctx->sub->shaders[PIPE_SHADER_TESS_EVAL] && ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_TESS_EVAL])
same_prog = false;
if (!same_prog) {
prog = lookup_shader_program(ctx,
ctx->sub->shaders[PIPE_SHADER_VERTEX]->current->id,
ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current->id,
ctx->sub->shaders[PIPE_SHADER_GEOMETRY] ? ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current->id : 0,
ctx->sub->shaders[PIPE_SHADER_TESS_CTRL] ? ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->current->id : 0,
ctx->sub->shaders[PIPE_SHADER_TESS_EVAL] ? ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->current->id : 0,
dual_src);
if (!prog) {
prog = add_shader_program(ctx,
ctx->sub->shaders[PIPE_SHADER_VERTEX]->current,
ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current,
ctx->sub->shaders[PIPE_SHADER_GEOMETRY] ? ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current : NULL,
ctx->sub->shaders[PIPE_SHADER_TESS_CTRL] ? ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->current : NULL,
ctx->sub->shaders[PIPE_SHADER_TESS_EVAL] ? ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->current : NULL);
if (!prog)
return 0;
}
ctx->sub->last_shader_idx = ctx->sub->shaders[PIPE_SHADER_TESS_EVAL] ? PIPE_SHADER_TESS_EVAL : (ctx->sub->shaders[PIPE_SHADER_GEOMETRY] ? PIPE_SHADER_GEOMETRY : PIPE_SHADER_FRAGMENT);
} else
prog = ctx->sub->prog;
if (ctx->sub->prog != prog) {
new_program = true;
ctx->sub->prog_ids[PIPE_SHADER_VERTEX] = ctx->sub->shaders[PIPE_SHADER_VERTEX]->current->id;
ctx->sub->prog_ids[PIPE_SHADER_FRAGMENT] = ctx->sub->shaders[PIPE_SHADER_FRAGMENT]->current->id;
if (ctx->sub->shaders[PIPE_SHADER_GEOMETRY])
ctx->sub->prog_ids[PIPE_SHADER_GEOMETRY] = ctx->sub->shaders[PIPE_SHADER_GEOMETRY]->current->id;
if (ctx->sub->shaders[PIPE_SHADER_TESS_CTRL])
ctx->sub->prog_ids[PIPE_SHADER_TESS_CTRL] = ctx->sub->shaders[PIPE_SHADER_TESS_CTRL]->current->id;
if (ctx->sub->shaders[PIPE_SHADER_TESS_EVAL])
ctx->sub->prog_ids[PIPE_SHADER_TESS_EVAL] = ctx->sub->shaders[PIPE_SHADER_TESS_EVAL]->current->id;
ctx->sub->prog_ids[PIPE_SHADER_COMPUTE] = -1;
ctx->sub->prog = prog;
/* mark all constbufs and sampler views as dirty */
for (int stage = PIPE_SHADER_VERTEX; stage <= PIPE_SHADER_FRAGMENT; stage++) {
ctx->sub->const_bufs_dirty[stage] = ~0;
ctx->sub->sampler_views_dirty[stage] = ~0;
}
prog->ref_context = ctx->sub;
}
}
if (!ctx->sub->prog) {
vrend_printf("dropping rendering due to missing shaders: %s\n", ctx->debug_name);
return 0;

Loading…
Cancel
Save