diff options
author | Icecream95 <[email protected]> | 2020-01-12 14:19:25 +1300 |
---|---|---|
committer | Alyssa Rosenzweig <[email protected]> | 2020-01-18 11:47:34 -0500 |
commit | d8a3501f1b2ef2d66091cc1e9c4ede3fb1b0da10 (patch) | |
tree | 7304d6aa4011b031f02fc06066323fe6f850bf2b | |
parent | bef716b56c6f50e8e448fd1cd677eca10140f24e (diff) |
panfrost: Dynamically allocate shader variants
This fixes a crash in LZDoom where over 16 shader variants are needed
for a few shaders in some maps, and should also save a few kilobytes
of RAM as most of the time only one or two variants of the 8 previously
allocated are actually needed.
Reviewed-by: Alyssa Rosenzweig <[email protected]>
-rw-r--r-- | src/gallium/drivers/panfrost/pan_context.c | 21 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_context.h | 5 |
2 files changed, 23 insertions, 3 deletions
diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index e44f8fc76d1..49716ab9bc4 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -1759,6 +1759,7 @@ panfrost_delete_shader_state( panfrost_bo_unreference(shader_state->bo); shader_state->bo = NULL; } + free(cso->variants); free(so); } @@ -1958,7 +1959,25 @@ panfrost_bind_shader_state( if (variant == -1) { /* No variant matched, so create a new one */ variant = variants->variant_count++; - assert(variants->variant_count < MAX_SHADER_VARIANTS); + + if (variants->variant_count > variants->variant_space) { + unsigned old_space = variants->variant_space; + + variants->variant_space *= 2; + if (variants->variant_space == 0) + variants->variant_space = 1; + + /* Arbitrary limit to stop runaway programs from + * creating an unbounded number of shader variants. */ + assert(variants->variant_space < 1024); + + unsigned msize = sizeof(struct panfrost_shader_state); + variants->variants = realloc(variants->variants, + variants->variant_space * msize); + + memset(&variants->variants[old_space], 0, + (variants->variant_space - old_space) * msize); + } struct panfrost_shader_state *v = &variants->variants[variant]; diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index ad0791bf06a..53ce9ec71df 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -199,7 +199,6 @@ struct panfrost_rasterizer { /* Variants bundle together to form the backing CSO, bundling multiple * shaders with varying emulated features baked in (alpha test * parameters, etc) */ -#define MAX_SHADER_VARIANTS 8 /* A shader state corresponds to the actual, current variant of the shader */ struct panfrost_shader_state { @@ -248,7 +247,9 @@ struct panfrost_shader_variants { struct pipe_compute_state cbase; }; - struct panfrost_shader_state variants[MAX_SHADER_VARIANTS]; + struct panfrost_shader_state *variants; + unsigned variant_space; + unsigned variant_count; /* The current active variant */ |