mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 02:38:04 +02:00
svga: check shader size against max command buffer size
If the shader is too large, plug in a dummy shader. This patch also
reworks the existing dummy shader code.
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
(cherry picked from commit 97fdace6d7)
This commit is contained in:
parent
16c03a004d
commit
07d1e7f12f
2 changed files with 49 additions and 12 deletions
|
|
@ -889,6 +889,7 @@ typedef enum {
|
|||
} SVGAFifoCmdId;
|
||||
|
||||
#define SVGA_CMD_MAX_ARGS 64
|
||||
#define SVGA_CB_MAX_COMMAND_SIZE (32 * 1024) // 32 KB
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -76,12 +76,18 @@ search_fs_key(const struct svga_fragment_shader *fs,
|
|||
/**
|
||||
* If we fail to compile a fragment shader (because it uses too many
|
||||
* registers, for example) we'll use a dummy/fallback shader that
|
||||
* simply emits a constant color.
|
||||
* simply emits a constant color (red for debug, black for release).
|
||||
* We hit this with the Unigine/Heaven demo when Shaders = High.
|
||||
* With black, the demo still looks good.
|
||||
*/
|
||||
static const struct tgsi_token *
|
||||
get_dummy_fragment_shader(void)
|
||||
{
|
||||
static const float red[4] = { 1.0, 0.0, 0.0, 0.0 };
|
||||
#ifdef DEBUG
|
||||
static const float color[4] = { 1.0, 0.0, 0.0, 0.0 }; /* red */
|
||||
#else
|
||||
static const float color[4] = { 0.0, 0.0, 0.0, 0.0 }; /* black */
|
||||
#endif
|
||||
struct ureg_program *ureg;
|
||||
const struct tgsi_token *tokens;
|
||||
struct ureg_src src;
|
||||
|
|
@ -93,7 +99,7 @@ get_dummy_fragment_shader(void)
|
|||
return NULL;
|
||||
|
||||
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
|
||||
src = ureg_DECL_immediate(ureg, red, 4);
|
||||
src = ureg_DECL_immediate(ureg, color, 4);
|
||||
ureg_MOV(ureg, dst, src);
|
||||
ureg_END(ureg);
|
||||
|
||||
|
|
@ -105,6 +111,29 @@ get_dummy_fragment_shader(void)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace the given shader's instruction with a simple constant-color
|
||||
* shader. We use this when normal shader translation fails.
|
||||
*/
|
||||
static struct svga_shader_variant *
|
||||
get_compiled_dummy_shader(struct svga_fragment_shader *fs,
|
||||
const struct svga_fs_compile_key *key)
|
||||
{
|
||||
const struct tgsi_token *dummy = get_dummy_fragment_shader();
|
||||
struct svga_shader_variant *variant;
|
||||
|
||||
if (!dummy) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FREE((void *) fs->base.tokens);
|
||||
fs->base.tokens = dummy;
|
||||
|
||||
variant = svga_translate_fragment_program(fs, key);
|
||||
return variant;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translate TGSI shader into an svga shader variant.
|
||||
*/
|
||||
|
|
@ -119,17 +148,24 @@ compile_fs(struct svga_context *svga,
|
|||
|
||||
variant = svga_translate_fragment_program( fs, key );
|
||||
if (variant == NULL) {
|
||||
/* some problem during translation, try the dummy shader */
|
||||
const struct tgsi_token *dummy = get_dummy_fragment_shader();
|
||||
if (!dummy) {
|
||||
ret = PIPE_ERROR_OUT_OF_MEMORY;
|
||||
debug_printf("Failed to compile fragment shader,"
|
||||
" using dummy shader instead.\n");
|
||||
variant = get_compiled_dummy_shader(fs, key);
|
||||
if (!variant) {
|
||||
ret = PIPE_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
debug_printf("Failed to compile fragment shader, using dummy shader instead.\n");
|
||||
FREE((void *) fs->base.tokens);
|
||||
fs->base.tokens = dummy;
|
||||
variant = svga_translate_fragment_program(fs, key);
|
||||
if (variant == NULL) {
|
||||
}
|
||||
|
||||
if (variant->nr_tokens * sizeof(variant->tokens[0])
|
||||
+ sizeof(SVGA3dCmdDefineShader) + sizeof(SVGA3dCmdHeader)
|
||||
>= SVGA_CB_MAX_COMMAND_SIZE) {
|
||||
/* too big, use dummy shader */
|
||||
debug_printf("Shader too large (%lu bytes),"
|
||||
" using dummy shader instead.\n",
|
||||
(unsigned long ) variant->nr_tokens * sizeof(variant->tokens[0]));
|
||||
variant = get_compiled_dummy_shader(fs, key);
|
||||
if (!variant) {
|
||||
ret = PIPE_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue