diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index 1269464..f53da1e 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -416,6 +416,7 @@ struct vrend_shader { struct vrend_strarray glsl_strings; GLuint id; uint32_t uid; + bool is_compiled; struct vrend_shader_key key; struct list_head programs; }; @@ -1115,6 +1116,20 @@ static void vrend_destroy_shader_selector(struct vrend_shader_selector *sel) free(sel); } +static inline int conv_shader_type(int type) +{ + switch (type) { + case PIPE_SHADER_VERTEX: return GL_VERTEX_SHADER; + case PIPE_SHADER_FRAGMENT: return GL_FRAGMENT_SHADER; + case PIPE_SHADER_GEOMETRY: return GL_GEOMETRY_SHADER; + case PIPE_SHADER_TESS_CTRL: return GL_TESS_CONTROL_SHADER; + case PIPE_SHADER_TESS_EVAL: return GL_TESS_EVALUATION_SHADER; + case PIPE_SHADER_COMPUTE: return GL_COMPUTE_SHADER; + default: + return 0; + }; +} + static bool vrend_compile_shader(struct vrend_sub_context *sub_ctx, struct vrend_shader *shader) { @@ -1123,6 +1138,8 @@ static bool vrend_compile_shader(struct vrend_sub_context *sub_ctx, for (int i = 0; i < shader->glsl_strings.num_strings; i++) shader_parts[i] = shader->glsl_strings.strings[i].buf; + + shader->id = glCreateShader(conv_shader_type(shader->sel->type)); glShaderSource(shader->id, shader->glsl_strings.num_strings, shader_parts, NULL); glCompileShader(shader->id); glGetShaderiv(shader->id, GL_COMPILE_STATUS, ¶m); @@ -1130,11 +1147,13 @@ static bool vrend_compile_shader(struct vrend_sub_context *sub_ctx, char infolog[65536]; int len; glGetShaderInfoLog(shader->id, 65536, &len, infolog); + glDeleteShader(shader->id); 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; } + shader->is_compiled = true; return true; } @@ -3415,27 +3434,12 @@ static inline void vrend_fill_shader_key(struct vrend_sub_context *sub_ctx, } } -static inline int conv_shader_type(int type) -{ - switch (type) { - case PIPE_SHADER_VERTEX: return GL_VERTEX_SHADER; - case PIPE_SHADER_FRAGMENT: return GL_FRAGMENT_SHADER; - case PIPE_SHADER_GEOMETRY: return GL_GEOMETRY_SHADER; - case PIPE_SHADER_TESS_CTRL: return GL_TESS_CONTROL_SHADER; - case PIPE_SHADER_TESS_EVAL: return GL_TESS_EVALUATION_SHADER; - case PIPE_SHADER_COMPUTE: return GL_COMPUTE_SHADER; - default: - return 0; - }; -} - static int vrend_shader_create(struct vrend_context *ctx, struct vrend_shader *shader, struct vrend_shader_key *key) { static uint32_t uid; - shader->id = glCreateShader(conv_shader_type(shader->sel->type)); shader->uid = ++uid; if (shader->sel->tokens) { @@ -3443,26 +3447,14 @@ static int vrend_shader_create(struct vrend_context *ctx, shader->sel->req_local_mem, key, &shader->sel->sinfo, &shader->glsl_strings); if (!ret) { vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SHADER, shader->sel->type); - glDeleteShader(shader->id); return -1; } } else if (!ctx->shader_cfg.use_gles && shader->sel->type != TGSI_PROCESSOR_TESS_CTRL) { vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SHADER, shader->sel->type); - glDeleteShader(shader->id); return -1; } shader->key = *key; - if (1) {//shader->sel->type == PIPE_SHADER_FRAGMENT || shader->sel->type == PIPE_SHADER_GEOMETRY) { - bool ret; - - ret = vrend_compile_shader(ctx->sub, shader); - if (ret == false) { - glDeleteShader(shader->id); - strarray_free(&shader->glsl_strings, true); - return -1; - } - } return 0; } @@ -4473,7 +4465,6 @@ void vrend_inject_tcs(struct vrend_sub_context *sub_ctx, int vertices_per_patch) 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(sub_ctx, shader); } @@ -4535,6 +4526,23 @@ vrend_select_program(struct vrend_sub_context *sub_ctx, const struct pipe_draw_i sub_ctx->drawing = false; + for (uint i = 0; i < PIPE_SHADER_TYPES; i++) { + struct vrend_shader_selector *sel = shaders[i]; + if (!sel) + continue; + + struct vrend_shader *shader = sel->current; + if (shader && !shader->is_compiled) {//shader->sel->type == PIPE_SHADER_FRAGMENT || shader->sel->type == PIPE_SHADER_GEOMETRY) { + bool ret; + + ret = vrend_compile_shader(sub_ctx, shader); + if (ret == false) { + strarray_free(&shader->glsl_strings, true); + return -1; + } + } + } + if (!shaders[PIPE_SHADER_VERTEX]->current || !shaders[PIPE_SHADER_FRAGMENT]->current || (shaders[PIPE_SHADER_GEOMETRY] && !shaders[PIPE_SHADER_GEOMETRY]->current) || @@ -4879,9 +4887,15 @@ void vrend_launch_grid(struct vrend_context *ctx, 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); + vrend_printf( "failure to select compute shader variant: %s\n", ctx->debug_name); return; } + if (!sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current->is_compiled) { + if(!vrend_compile_shader(sub_ctx, sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current)) { + vrend_printf( "failure to compile compute shader variant: %s\n", ctx->debug_name); + return; + } + } 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) {