shader: use string array handler to store current strings.

This uses the string array helpers to pass around the glsl strings
for the program.

This could be expanded on to provide more than 2 strings easily

Reviewed-By: Gert Wollny <gert.wollny@collabora.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
macos/master
Dave Airlie 6 years ago
parent fb71f03c99
commit dd06126de9
  1. 29
      src/vrend_renderer.c
  2. 74
      src/vrend_shader.c
  3. 18
      src/vrend_shader.h

@ -311,7 +311,7 @@ struct vrend_shader {
struct vrend_shader *next_variant; struct vrend_shader *next_variant;
struct vrend_shader_selector *sel; struct vrend_shader_selector *sel;
GLchar *glsl_prog; struct vrend_strarray glsl_strings;
GLuint id; GLuint id;
GLuint compiled_fs_id; GLuint compiled_fs_id;
struct vrend_shader_key key; struct vrend_shader_key key;
@ -823,7 +823,9 @@ vrend_so_target_reference(struct vrend_so_target **ptr, struct vrend_so_target *
static void vrend_shader_dump(struct vrend_shader *shader) static void vrend_shader_dump(struct vrend_shader *shader)
{ {
const char *prefix = pipe_shader_to_prefix(shader->sel->type); const char *prefix = pipe_shader_to_prefix(shader->sel->type);
vrend_printf("%s: %d GLSL:\n%s\n", prefix, shader->id, shader->glsl_prog); vrend_printf("%s: %d GLSL:\n", prefix, shader->id);
strarray_dump(&shader->glsl_strings);
vrend_printf("\n");
} }
static void vrend_shader_destroy(struct vrend_shader *shader) static void vrend_shader_destroy(struct vrend_shader *shader)
@ -835,7 +837,7 @@ static void vrend_shader_destroy(struct vrend_shader *shader)
} }
glDeleteShader(shader->id); glDeleteShader(shader->id);
free(shader->glsl_prog); strarray_free(&shader->glsl_strings, true);
free(shader); free(shader);
} }
@ -864,7 +866,11 @@ static bool vrend_compile_shader(struct vrend_context *ctx,
struct vrend_shader *shader) struct vrend_shader *shader)
{ {
GLint param; GLint param;
glShaderSource(shader->id, 1, (const char **)&shader->glsl_prog, NULL); const char *shader_parts[SHADER_MAX_STRINGS];
for (int i = 0; i < shader->glsl_strings.num_strings; i++)
shader_parts[i] = shader->glsl_strings.strings[i].buf;
glShaderSource(shader->id, shader->glsl_strings.num_strings, shader_parts, NULL);
glCompileShader(shader->id); glCompileShader(shader->id);
glGetShaderiv(shader->id, GL_COMPILE_STATUS, &param); glGetShaderiv(shader->id, GL_COMPILE_STATUS, &param);
if (param == GL_FALSE) { if (param == GL_FALSE) {
@ -1300,15 +1306,15 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_conte
bool ret; bool ret;
if (gs) if (gs)
vrend_patch_vertex_shader_interpolants(ctx, &ctx->shader_cfg, gs->glsl_prog, vrend_patch_vertex_shader_interpolants(ctx, &ctx->shader_cfg, &gs->glsl_strings,
&gs->sel->sinfo, &gs->sel->sinfo,
&fs->sel->sinfo, "gso", fs->key.flatshade); &fs->sel->sinfo, "gso", fs->key.flatshade);
else if (tes) else if (tes)
vrend_patch_vertex_shader_interpolants(ctx, &ctx->shader_cfg, tes->glsl_prog, vrend_patch_vertex_shader_interpolants(ctx, &ctx->shader_cfg, &tes->glsl_strings,
&tes->sel->sinfo, &tes->sel->sinfo,
&fs->sel->sinfo, "teo", fs->key.flatshade); &fs->sel->sinfo, "teo", fs->key.flatshade);
else else
vrend_patch_vertex_shader_interpolants(ctx, &ctx->shader_cfg, vs->glsl_prog, vrend_patch_vertex_shader_interpolants(ctx, &ctx->shader_cfg, &vs->glsl_strings,
&vs->sel->sinfo, &vs->sel->sinfo,
&fs->sel->sinfo, "vso", fs->key.flatshade); &fs->sel->sinfo, "vso", fs->key.flatshade);
ret = vrend_compile_shader(ctx, gs ? gs : (tes ? tes : vs)); ret = vrend_compile_shader(ctx, gs ? gs : (tes ? tes : vs));
@ -2937,9 +2943,9 @@ static int vrend_shader_create(struct vrend_context *ctx,
shader->id = glCreateShader(conv_shader_type(shader->sel->type)); shader->id = glCreateShader(conv_shader_type(shader->sel->type));
shader->compiled_fs_id = 0; shader->compiled_fs_id = 0;
shader->glsl_prog = vrend_convert_shader(ctx, &ctx->shader_cfg, shader->sel->tokens, bool ret = vrend_convert_shader(ctx, &ctx->shader_cfg, shader->sel->tokens,
shader->sel->req_local_mem, &key, &shader->sel->sinfo); shader->sel->req_local_mem, &key, &shader->sel->sinfo, &shader->glsl_strings);
if (!shader->glsl_prog) { if (!ret) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SHADER, 0); report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SHADER, 0);
glDeleteShader(shader->id); glDeleteShader(shader->id);
return -1; return -1;
@ -2951,7 +2957,7 @@ static int vrend_shader_create(struct vrend_context *ctx,
ret = vrend_compile_shader(ctx, shader); ret = vrend_compile_shader(ctx, shader);
if (ret == false) { if (ret == false) {
glDeleteShader(shader->id); glDeleteShader(shader->id);
free(shader->glsl_prog); strarray_free(&shader->glsl_strings, true);
return -1; return -1;
} }
} }
@ -2989,6 +2995,7 @@ static int vrend_shader_select(struct vrend_context *ctx,
shader = CALLOC_STRUCT(vrend_shader); shader = CALLOC_STRUCT(vrend_shader);
shader->sel = sel; shader->sel = sel;
list_inithead(&shader->programs); list_inithead(&shader->programs);
strarray_alloc(&shader->glsl_strings, SHADER_MAX_STRINGS);
r = vrend_shader_create(ctx, shader, key); r = vrend_shader_create(ctx, shader, key);
if (r) { if (r) {

@ -4956,15 +4956,15 @@ static boolean analyze_instruction(struct tgsi_iterate_context *iter,
return true; return true;
} }
char *vrend_convert_shader(struct vrend_context *rctx, bool vrend_convert_shader(struct vrend_context *rctx,
struct vrend_shader_cfg *cfg, struct vrend_shader_cfg *cfg,
const struct tgsi_token *tokens, const struct tgsi_token *tokens,
uint32_t req_local_mem, uint32_t req_local_mem,
struct vrend_shader_key *key, struct vrend_shader_key *key,
struct vrend_shader_info *sinfo) struct vrend_shader_info *sinfo,
struct vrend_strarray *shader)
{ {
struct dump_ctx ctx; struct dump_ctx ctx;
char *glsl_final = NULL;
boolean bret; boolean bret;
memset(&ctx, 0, sizeof(struct dump_ctx)); memset(&ctx, 0, sizeof(struct dump_ctx));
@ -4973,7 +4973,7 @@ char *vrend_convert_shader(struct vrend_context *rctx,
ctx.iter.iterate_instruction = analyze_instruction; ctx.iter.iterate_instruction = analyze_instruction;
bret = tgsi_iterate_shader(tokens, &ctx.iter); bret = tgsi_iterate_shader(tokens, &ctx.iter);
if (bret == false) if (bret == false)
return NULL; return false;
ctx.iter.prolog = prolog; ctx.iter.prolog = prolog;
ctx.iter.iterate_instruction = iter_instruction; ctx.iter.iterate_instruction = iter_instruction;
@ -5035,21 +5035,11 @@ char *vrend_convert_shader(struct vrend_context *rctx,
if (strbuf_get_error(&ctx.glsl_hdr)) if (strbuf_get_error(&ctx.glsl_hdr))
goto fail; goto fail;
glsl_final = malloc(strbuf_get_len(&ctx.glsl_hdr) + strbuf_get_len(&ctx.glsl_main) + 1);
if (!glsl_final)
goto fail;
bret = fill_interpolants(&ctx, sinfo); bret = fill_interpolants(&ctx, sinfo);
if (bret == false) if (bret == false)
goto fail; goto fail;
memcpy(glsl_final, ctx.glsl_hdr.buf, strbuf_get_len(&ctx.glsl_hdr));
memcpy(glsl_final + strbuf_get_len(&ctx.glsl_hdr), ctx.glsl_main.buf, strbuf_get_len(&ctx.glsl_main));
glsl_final[strbuf_get_len(&ctx.glsl_hdr) + strbuf_get_len(&ctx.glsl_main)] = '\0';
free(ctx.temp_ranges); free(ctx.temp_ranges);
strbuf_free(&ctx.glsl_main);
strbuf_free(&ctx.glsl_hdr);
sinfo->num_ucp = ctx.key->clip_plane_enable ? 8 : 0; sinfo->num_ucp = ctx.key->clip_plane_enable ? 8 : 0;
sinfo->has_pervertex_out = ctx.vs_has_pervertex; sinfo->has_pervertex_out = ctx.vs_has_pervertex;
sinfo->has_sample_input = ctx.has_sample_input; sinfo->has_sample_input = ctx.has_sample_input;
@ -5105,25 +5095,28 @@ char *vrend_convert_shader(struct vrend_context *rctx,
sinfo->image_arrays = ctx.image_arrays; sinfo->image_arrays = ctx.image_arrays;
sinfo->num_image_arrays = ctx.num_image_arrays; sinfo->num_image_arrays = ctx.num_image_arrays;
VREND_DEBUG(dbg_shader_glsl, rctx, "GLSL: %s\n", glsl_final); strarray_addstrbuf(shader, &ctx.glsl_hdr);
return glsl_final; strarray_addstrbuf(shader, &ctx.glsl_main);
VREND_DEBUG(dbg_shader_glsl, rctx, "GLSL:");
VREND_DEBUG_EXT(dbg_shader_glsl, rctx, strarray_dump(shader));
VREND_DEBUG(dbg_shader_glsl, rctx, "\n");
return true;
fail: fail:
strbuf_free(&ctx.glsl_main); strbuf_free(&ctx.glsl_main);
free(glsl_final);
strbuf_free(&ctx.glsl_hdr); strbuf_free(&ctx.glsl_hdr);
free(ctx.so_names); free(ctx.so_names);
free(ctx.temp_ranges); free(ctx.temp_ranges);
return NULL; return false;
} }
static void replace_interp(char *program, static void replace_interp(struct vrend_strarray *program,
const char *var_name, const char *var_name,
const char *pstring, const char *auxstring) const char *pstring, const char *auxstring)
{ {
char *ptr; char *ptr;
int mylen = strlen(INTERP_PREFIX) + strlen("out vec4 "); int mylen = strlen(INTERP_PREFIX) + strlen("out vec4 ");
ptr = strstr(program, var_name); ptr = strstr(program->strings[0].buf, var_name);
if (!ptr) if (!ptr)
return; return;
@ -5137,10 +5130,10 @@ static void replace_interp(char *program,
static const char *gpu_shader5_string = "#extension GL_ARB_gpu_shader5 : require\n"; static const char *gpu_shader5_string = "#extension GL_ARB_gpu_shader5 : require\n";
static void require_gpu_shader5(char *program) static void require_gpu_shader5(struct vrend_strarray *program)
{ {
/* the first line is the #version line */ /* the first line is the #version line */
char *ptr = strchr(program, '\n'); char *ptr = strchr(program->strings[0].buf, '\n');
if (!ptr) if (!ptr)
return; return;
ptr++; ptr++;
@ -5152,10 +5145,10 @@ static const char *gpu_shader5_and_msinterp_string =
"#extension GL_OES_gpu_shader5 : require\n" "#extension GL_OES_gpu_shader5 : require\n"
"#extension GL_OES_shader_multisample_interpolation : require\n"; "#extension GL_OES_shader_multisample_interpolation : require\n";
static void require_gpu_shader5_and_msinterp(char *program) static void require_gpu_shader5_and_msinterp(struct vrend_strarray *program)
{ {
/* the first line is the #version line */ /* the first line is the #version line */
char *ptr = strchr(program, '\n'); char *ptr = strchr(program->strings[0].buf, '\n');
if (!ptr) if (!ptr)
return; return;
ptr++; ptr++;
@ -5164,7 +5157,8 @@ static void require_gpu_shader5_and_msinterp(char *program)
} }
bool vrend_patch_vertex_shader_interpolants(struct vrend_context *rctx, bool vrend_patch_vertex_shader_interpolants(struct vrend_context *rctx,
struct vrend_shader_cfg *cfg, char *program, struct vrend_shader_cfg *cfg,
struct vrend_strarray *prog_strings,
struct vrend_shader_info *vs_info, struct vrend_shader_info *vs_info,
struct vrend_shader_info *fs_info, struct vrend_shader_info *fs_info,
const char *oprefix, bool flatshade) const char *oprefix, bool flatshade)
@ -5180,10 +5174,10 @@ bool vrend_patch_vertex_shader_interpolants(struct vrend_context *rctx,
if (fs_info->has_sample_input) { if (fs_info->has_sample_input) {
if (!cfg->use_gles && (cfg->glsl_version >= 320)) if (!cfg->use_gles && (cfg->glsl_version >= 320))
require_gpu_shader5(program); require_gpu_shader5(prog_strings);
if (cfg->use_gles && (cfg->glsl_version < 320)) if (cfg->use_gles && (cfg->glsl_version < 320))
require_gpu_shader5_and_msinterp(program); require_gpu_shader5_and_msinterp(prog_strings);
} }
for (i = 0; i < fs_info->num_interps; i++) { for (i = 0; i < fs_info->num_interps; i++) {
@ -5199,22 +5193,22 @@ bool vrend_patch_vertex_shader_interpolants(struct vrend_context *rctx,
/* color is a bit trickier */ /* color is a bit trickier */
if (fs_info->glsl_ver < 140) { if (fs_info->glsl_ver < 140) {
if (fs_info->interpinfo[i].semantic_index == 1) { if (fs_info->interpinfo[i].semantic_index == 1) {
replace_interp(program, "gl_FrontSecondaryColor", pstring, auxstring); replace_interp(prog_strings, "gl_FrontSecondaryColor", pstring, auxstring);
replace_interp(program, "gl_BackSecondaryColor", pstring, auxstring); replace_interp(prog_strings, "gl_BackSecondaryColor", pstring, auxstring);
} else { } else {
replace_interp(program, "gl_FrontColor", pstring, auxstring); replace_interp(prog_strings, "gl_FrontColor", pstring, auxstring);
replace_interp(program, "gl_BackColor", pstring, auxstring); replace_interp(prog_strings, "gl_BackColor", pstring, auxstring);
} }
} else { } else {
snprintf(glsl_name, 64, "ex_c%d", fs_info->interpinfo[i].semantic_index); snprintf(glsl_name, 64, "ex_c%d", fs_info->interpinfo[i].semantic_index);
replace_interp(program, glsl_name, pstring, auxstring); replace_interp(prog_strings, glsl_name, pstring, auxstring);
snprintf(glsl_name, 64, "ex_bc%d", fs_info->interpinfo[i].semantic_index); snprintf(glsl_name, 64, "ex_bc%d", fs_info->interpinfo[i].semantic_index);
replace_interp(program, glsl_name, pstring, auxstring); replace_interp(prog_strings, glsl_name, pstring, auxstring);
} }
break; break;
case TGSI_SEMANTIC_GENERIC: case TGSI_SEMANTIC_GENERIC:
snprintf(glsl_name, 64, "%s_g%d", oprefix, fs_info->interpinfo[i].semantic_index); snprintf(glsl_name, 64, "%s_g%d", oprefix, fs_info->interpinfo[i].semantic_index);
replace_interp(program, glsl_name, pstring, auxstring); replace_interp(prog_strings, glsl_name, pstring, auxstring);
break; break;
default: default:
vrend_printf("unhandled semantic: %x\n", fs_info->interpinfo[i].semantic_name); vrend_printf("unhandled semantic: %x\n", fs_info->interpinfo[i].semantic_name);
@ -5222,7 +5216,9 @@ bool vrend_patch_vertex_shader_interpolants(struct vrend_context *rctx,
} }
} }
VREND_DEBUG(dbg_shader_glsl, rctx, "GLSL: post interp: %s\n", program); VREND_DEBUG(dbg_shader_glsl, rctx, "GLSL:");
VREND_DEBUG_EXT(dbg_shader_glsl, rctx, strarray_dump(prog_strings));
VREND_DEBUG(dbg_shader_glsl, rctx, "\n");
return true; return true;
} }

@ -28,6 +28,7 @@
#include "pipe/p_state.h" #include "pipe/p_state.h"
#include "pipe/p_shader_tokens.h" #include "pipe/p_shader_tokens.h"
#include "vrend_strbuf.h"
/* need to store patching info for interpolation */ /* need to store patching info for interpolation */
struct vrend_interp_info { struct vrend_interp_info {
int semantic_name; int semantic_name;
@ -113,19 +114,22 @@ struct vrend_shader_cfg {
struct vrend_context; struct vrend_context;
#define SHADER_MAX_STRINGS 2
bool vrend_patch_vertex_shader_interpolants(struct vrend_context *rctx, bool vrend_patch_vertex_shader_interpolants(struct vrend_context *rctx,
struct vrend_shader_cfg *cfg, struct vrend_shader_cfg *cfg,
char *program, struct vrend_strarray *shader,
struct vrend_shader_info *vs_info, struct vrend_shader_info *vs_info,
struct vrend_shader_info *fs_info, struct vrend_shader_info *fs_info,
const char *oprefix, bool flatshade); const char *oprefix, bool flatshade);
char *vrend_convert_shader(struct vrend_context *rctx, bool vrend_convert_shader(struct vrend_context *rctx,
struct vrend_shader_cfg *cfg, struct vrend_shader_cfg *cfg,
const struct tgsi_token *tokens, const struct tgsi_token *tokens,
uint32_t req_local_mem, uint32_t req_local_mem,
struct vrend_shader_key *key, struct vrend_shader_key *key,
struct vrend_shader_info *sinfo); struct vrend_shader_info *sinfo,
struct vrend_strarray *shader);
const char *vrend_shader_samplertypeconv(bool use_gles, int sampler_type, int *is_shad); const char *vrend_shader_samplertypeconv(bool use_gles, int sampler_type, int *is_shad);

Loading…
Cancel
Save