shader: add string buffer wrapper and use for glsl strings.

This converts the current string tracking code to using strbuf.

The indent code and tracking for the main + header strings is moved
over.

Now we know the string lengths this also optimises the concatentation.

Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
macos/master
Dave Airlie 6 years ago
parent e56000111e
commit f7e0ec0873
  1. 75
      src/vrend_shader.c

@ -34,6 +34,8 @@
#include "vrend_shader.h" #include "vrend_shader.h"
#include "vrend_debug.h" #include "vrend_debug.h"
#include "vrend_strbuf.h"
/* start convert of tgsi to glsl */ /* start convert of tgsi to glsl */
#define INTERP_PREFIX " " #define INTERP_PREFIX " "
@ -129,8 +131,8 @@ struct dump_ctx {
struct tgsi_shader_info info; struct tgsi_shader_info info;
int prog_type; int prog_type;
int size; int size;
char *glsl_main; struct vrend_strbuf glsl_main;
char *glsl_hdr; struct vrend_strbuf glsl_hdr;
uint instno; uint instno;
uint32_t num_interps; uint32_t num_interps;
@ -202,7 +204,6 @@ struct dump_ctx {
int gs_num_invocations; int gs_num_invocations;
struct vrend_shader_key *key; struct vrend_shader_key *key;
int indent_level;
int num_in_clip_dist; int num_in_clip_dist;
int num_clip_dist; int num_clip_dist;
int glsl_ver_required; int glsl_ver_required;
@ -490,32 +491,25 @@ static void require_glsl_ver(struct dump_ctx *ctx, int glsl_ver)
ctx->glsl_ver_required = glsl_ver; ctx->glsl_ver_required = glsl_ver;
} }
static char *strcat_realloc(char *str, const char *catstr) static bool add_str_to_glsl_main(struct dump_ctx *ctx, const char *buf)
{ {
char *new = realloc(str, strlen(str) + strlen(catstr) + 1); strbuf_append(&ctx->glsl_main, buf);
if (!new) { return !strbuf_get_error(&ctx->glsl_main);
free(str);
return NULL;
}
strcat(new, catstr);
return new;
} }
static bool add_str_to_glsl_main(struct dump_ctx *ctx, const char *buf) static bool emit_buf(struct dump_ctx *ctx, const char *buf)
{ {
ctx->glsl_main = strcat_realloc(ctx->glsl_main, buf); return add_str_to_glsl_main(ctx, buf);
return ctx->glsl_main ? true : false;
} }
static bool emit_buf(struct dump_ctx *ctx, const char *buf) static void indent_buf(struct dump_ctx *ctx)
{ {
int i; return strbuf_indent(&ctx->glsl_main);
for (i = 0; i < ctx->indent_level; i++) {
if (!add_str_to_glsl_main(ctx, "\t"))
return false;
} }
return add_str_to_glsl_main(ctx, buf); static void outdent_buf(struct dump_ctx *ctx)
{
return strbuf_outdent(&ctx->glsl_main);
} }
#define EMIT_BUF_WITH_RET(ctx, buf) do { \ #define EMIT_BUF_WITH_RET(ctx, buf) do { \
@ -525,8 +519,8 @@ static bool emit_buf(struct dump_ctx *ctx, const char *buf)
static bool add_str_to_glsl_hdr(struct dump_ctx *ctx, const char *buf) static bool add_str_to_glsl_hdr(struct dump_ctx *ctx, const char *buf)
{ {
ctx->glsl_hdr = strcat_realloc(ctx->glsl_hdr, buf); strbuf_append(&ctx->glsl_hdr, buf);
return ctx->glsl_hdr ? true : false; return !strbuf_get_error(&ctx->glsl_hdr);
} }
static bool emit_hdr(struct dump_ctx *ctx, const char *buf) static bool emit_hdr(struct dump_ctx *ctx, const char *buf)
@ -3451,17 +3445,17 @@ iter_instruction(struct tgsi_iterate_context *iter,
case TGSI_OPCODE_UIF: case TGSI_OPCODE_UIF:
snprintf(buf, 255, "if (any(bvec4(%s))) {\n", srcs[0]); snprintf(buf, 255, "if (any(bvec4(%s))) {\n", srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
ctx->indent_level++; indent_buf(ctx);
break; break;
case TGSI_OPCODE_ELSE: case TGSI_OPCODE_ELSE:
snprintf(buf, 255, "} else {\n"); snprintf(buf, 255, "} else {\n");
ctx->indent_level--; outdent_buf(ctx);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
ctx->indent_level++; indent_buf(ctx);
break; break;
case TGSI_OPCODE_ENDIF: case TGSI_OPCODE_ENDIF:
snprintf(buf, 255, "}\n"); snprintf(buf, 255, "}\n");
ctx->indent_level--; outdent_buf(ctx);
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
case TGSI_OPCODE_KILL: case TGSI_OPCODE_KILL:
@ -3828,10 +3822,10 @@ iter_instruction(struct tgsi_iterate_context *iter,
case TGSI_OPCODE_BGNLOOP: case TGSI_OPCODE_BGNLOOP:
snprintf(buf, 255, "do {\n"); snprintf(buf, 255, "do {\n");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
ctx->indent_level++; indent_buf(ctx);
break; break;
case TGSI_OPCODE_ENDLOOP: case TGSI_OPCODE_ENDLOOP:
ctx->indent_level--; outdent_buf(ctx);
snprintf(buf, 255, "} while(true);\n"); snprintf(buf, 255, "} while(true);\n");
EMIT_BUF_WITH_RET(ctx, buf); EMIT_BUF_WITH_RET(ctx, buf);
break; break;
@ -5061,43 +5055,38 @@ char *vrend_convert_shader(struct vrend_context *rctx,
if (ctx.info.indirect_files & (1 << TGSI_FILE_SAMPLER)) if (ctx.info.indirect_files & (1 << TGSI_FILE_SAMPLER))
ctx.shader_req_bits |= SHADER_REQ_GPU_SHADER5; ctx.shader_req_bits |= SHADER_REQ_GPU_SHADER5;
ctx.glsl_main = malloc(4096); if (!strbuf_alloc(&ctx.glsl_main, 4096))
if (!ctx.glsl_main)
goto fail; goto fail;
ctx.glsl_main[0] = '\0';
bret = tgsi_iterate_shader(tokens, &ctx.iter); bret = tgsi_iterate_shader(tokens, &ctx.iter);
if (bret == false) if (bret == false)
goto fail; goto fail;
ctx.glsl_hdr = malloc(1024); if (!strbuf_alloc(&ctx.glsl_hdr, 1024))
if (!ctx.glsl_hdr)
goto fail; goto fail;
ctx.glsl_hdr[0] = '\0';
if (!emit_header(&ctx)) if (!emit_header(&ctx))
goto fail; goto fail;
if (!emit_ios(&ctx)) if (!emit_ios(&ctx))
goto fail; goto fail;
glsl_final = malloc(strlen(ctx.glsl_hdr) + strlen(ctx.glsl_main) + 1); glsl_final = malloc(strbuf_get_len(&ctx.glsl_hdr) + strbuf_get_len(&ctx.glsl_main) + 1);
if (!glsl_final) if (!glsl_final)
goto fail; goto fail;
glsl_final[0] = '\0';
bret = fill_interpolants(&ctx, sinfo); bret = fill_interpolants(&ctx, sinfo);
if (bret == false) if (bret == false)
goto fail; goto fail;
strcat(glsl_final, ctx.glsl_hdr); memcpy(glsl_final, ctx.glsl_hdr.buf, strbuf_get_len(&ctx.glsl_hdr));
strcat(glsl_final, ctx.glsl_main); 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';
VREND_DEBUG(dbg_shader_glsl, rctx, "GLSL: %s\n", glsl_final); VREND_DEBUG(dbg_shader_glsl, rctx, "GLSL: %s\n", glsl_final);
free(ctx.temp_ranges); free(ctx.temp_ranges);
free(ctx.glsl_main); strbuf_free(&ctx.glsl_main);
free(ctx.glsl_hdr); 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;
@ -5151,9 +5140,9 @@ char *vrend_convert_shader(struct vrend_context *rctx,
sinfo->num_image_arrays = ctx.num_image_arrays; sinfo->num_image_arrays = ctx.num_image_arrays;
return glsl_final; return glsl_final;
fail: fail:
free(ctx.glsl_main); strbuf_free(&ctx.glsl_main);
free(glsl_final); free(glsl_final);
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 NULL;

Loading…
Cancel
Save