|
|
|
@ -4388,86 +4388,22 @@ void vrend_inject_tcs(struct vrend_context *ctx, int vertices_per_patch) |
|
|
|
|
vrend_compile_shader(ctx, shader); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int vrend_draw_vbo(struct vrend_context *ctx, |
|
|
|
|
const struct pipe_draw_info *info, |
|
|
|
|
uint32_t cso, uint32_t indirect_handle, |
|
|
|
|
uint32_t indirect_draw_count_handle) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
bool new_program = false; |
|
|
|
|
struct vrend_resource *indirect_res = NULL; |
|
|
|
|
struct vrend_resource *indirect_params_res = NULL; |
|
|
|
|
|
|
|
|
|
if (ctx->in_error) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
if (info->instance_count && !has_feature(feat_draw_instance)) |
|
|
|
|
return EINVAL; |
|
|
|
|
|
|
|
|
|
if (info->start_instance && !has_feature(feat_base_instance)) |
|
|
|
|
return EINVAL; |
|
|
|
|
|
|
|
|
|
if (info->indirect.draw_count > 1 && !has_feature(feat_multi_draw_indirect)) |
|
|
|
|
return EINVAL; |
|
|
|
|
|
|
|
|
|
if (indirect_handle) { |
|
|
|
|
if (!has_feature(feat_indirect_draw)) |
|
|
|
|
return EINVAL; |
|
|
|
|
indirect_res = vrend_renderer_ctx_res_lookup(ctx, indirect_handle); |
|
|
|
|
if (!indirect_res) { |
|
|
|
|
vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, indirect_handle); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* this must be zero until we support the feature */ |
|
|
|
|
if (indirect_draw_count_handle) { |
|
|
|
|
if (!has_feature(feat_indirect_params)) |
|
|
|
|
return EINVAL; |
|
|
|
|
|
|
|
|
|
indirect_params_res = vrend_renderer_ctx_res_lookup(ctx, indirect_draw_count_handle); |
|
|
|
|
if (!indirect_params_res){ |
|
|
|
|
vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, indirect_draw_count_handle); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
|
|
if (ctx->sub->blend_state_dirty) |
|
|
|
|
vrend_patch_blend_state(ctx); |
|
|
|
|
|
|
|
|
|
// enable primitive-mode-dependent shader variants
|
|
|
|
|
if (ctx->sub->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 |
|
|
|
|
|| (int)info->mode == PIPE_PRIM_POINTS) |
|
|
|
|
ctx->sub->shader_dirty = true; |
|
|
|
|
|
|
|
|
|
ctx->sub->prim_mode = (int)info->mode; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ctx->sub->shader_dirty || ctx->sub->swizzle_output_rgb_to_bgr) { |
|
|
|
|
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 0; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// For some GPU, we'd like to use integer variable in generated GLSL if
|
|
|
|
@ -4500,7 +4436,7 @@ int vrend_draw_vbo(struct vrend_context *ctx, |
|
|
|
|
(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; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
same_prog = true; |
|
|
|
|
if (ctx->sub->shaders[PIPE_SHADER_VERTEX]->current->id != (GLuint)ctx->sub->prog_ids[PIPE_SHADER_VERTEX]) |
|
|
|
@ -4532,7 +4468,7 @@ int vrend_draw_vbo(struct vrend_context *ctx, |
|
|
|
|
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; |
|
|
|
|
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); |
|
|
|
@ -4559,7 +4495,81 @@ int vrend_draw_vbo(struct vrend_context *ctx, |
|
|
|
|
|
|
|
|
|
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, |
|
|
|
|
uint32_t indirect_draw_count_handle) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
bool new_program = false; |
|
|
|
|
struct vrend_resource *indirect_res = NULL; |
|
|
|
|
struct vrend_resource *indirect_params_res = NULL; |
|
|
|
|
|
|
|
|
|
if (ctx->in_error) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
if (info->instance_count && !has_feature(feat_draw_instance)) |
|
|
|
|
return EINVAL; |
|
|
|
|
|
|
|
|
|
if (info->start_instance && !has_feature(feat_base_instance)) |
|
|
|
|
return EINVAL; |
|
|
|
|
|
|
|
|
|
if (info->indirect.draw_count > 1 && !has_feature(feat_multi_draw_indirect)) |
|
|
|
|
return EINVAL; |
|
|
|
|
|
|
|
|
|
if (indirect_handle) { |
|
|
|
|
if (!has_feature(feat_indirect_draw)) |
|
|
|
|
return EINVAL; |
|
|
|
|
indirect_res = vrend_renderer_ctx_res_lookup(ctx, indirect_handle); |
|
|
|
|
if (!indirect_res) { |
|
|
|
|
vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, indirect_handle); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* this must be zero until we support the feature */ |
|
|
|
|
if (indirect_draw_count_handle) { |
|
|
|
|
if (!has_feature(feat_indirect_params)) |
|
|
|
|
return EINVAL; |
|
|
|
|
|
|
|
|
|
indirect_params_res = vrend_renderer_ctx_res_lookup(ctx, indirect_draw_count_handle); |
|
|
|
|
if (!indirect_params_res){ |
|
|
|
|
vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, indirect_draw_count_handle); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
|
|
if (ctx->sub->blend_state_dirty) |
|
|
|
|
vrend_patch_blend_state(ctx); |
|
|
|
|
|
|
|
|
|
// enable primitive-mode-dependent shader variants
|
|
|
|
|
if (ctx->sub->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 |
|
|
|
|
|| (int)info->mode == PIPE_PRIM_POINTS) |
|
|
|
|
ctx->sub->shader_dirty = true; |
|
|
|
|
|
|
|
|
|
ctx->sub->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 (!ctx->sub->prog) { |
|
|
|
|
vrend_printf("dropping rendering due to missing shaders: %s\n", ctx->debug_name); |
|
|
|
|
return 0; |
|
|
|
|