aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIcecream95 <[email protected]>2020-01-12 14:19:25 +1300
committerAlyssa Rosenzweig <[email protected]>2020-01-18 11:47:34 -0500
commitd8a3501f1b2ef2d66091cc1e9c4ede3fb1b0da10 (patch)
tree7304d6aa4011b031f02fc06066323fe6f850bf2b
parentbef716b56c6f50e8e448fd1cd677eca10140f24e (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.c21
-rw-r--r--src/gallium/drivers/panfrost/pan_context.h5
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 */