diff options
author | Samuel Iglesias Gonsalvez <[email protected]> | 2015-04-22 16:58:45 +0200 |
---|---|---|
committer | Samuel Iglesias Gonsalvez <[email protected]> | 2015-09-25 08:39:22 +0200 |
commit | 138e4ae8aee3c13e83c732ba0f6d705e8001050c (patch) | |
tree | 6ccefadede4cda09c02886314170fc8024b301b7 /src/glsl/linker.cpp | |
parent | a7b4ab45d08d8469daefb9f2af34ad6860b9fc3b (diff) |
glsl: number of active shader storage blocks must be within allowed limits
Notice that we should differentiate between shader storage blocks and
uniform blocks, since they have different limits.
Signed-off-by: Samuel Iglesias Gonsalvez <[email protected]>
Reviewed-by: Jordan Justen <[email protected]>
Reviewed-by: Kristian Høgsberg <[email protected]>
Diffstat (limited to 'src/glsl/linker.cpp')
-rw-r--r-- | src/glsl/linker.cpp | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index c0520be4f15..9be957a3f80 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -2799,6 +2799,8 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog) unsigned blocks[MESA_SHADER_STAGES] = {0}; unsigned total_uniform_blocks = 0; + unsigned shader_blocks[MESA_SHADER_STAGES] = {0}; + unsigned total_shader_storage_blocks = 0; for (unsigned i = 0; i < prog->NumUniformBlocks; i++) { if (prog->UniformBlocks[i].UniformBufferSize > ctx->Const.MaxUniformBlockSize) { @@ -2810,8 +2812,15 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog) for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) { if (prog->UniformBlockStageIndex[j][i] != -1) { - blocks[j]++; - total_uniform_blocks++; + struct gl_shader *sh = prog->_LinkedShaders[j]; + int stage_index = prog->UniformBlockStageIndex[j][i]; + if (sh && sh->UniformBlocks[stage_index].IsShaderStorage) { + shader_blocks[j]++; + total_shader_storage_blocks++; + } else { + blocks[j]++; + total_uniform_blocks++; + } } } @@ -2832,6 +2841,24 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog) } } } + + if (total_shader_storage_blocks > ctx->Const.MaxCombinedShaderStorageBlocks) { + linker_error(prog, "Too many combined shader storage blocks (%d/%d)\n", + total_shader_storage_blocks, + ctx->Const.MaxCombinedShaderStorageBlocks); + } else { + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + const unsigned max_shader_storage_blocks = + ctx->Const.Program[i].MaxShaderStorageBlocks; + if (shader_blocks[i] > max_shader_storage_blocks) { + linker_error(prog, "Too many %s shader storage blocks (%d/%d)\n", + _mesa_shader_stage_to_string(i), + shader_blocks[i], + max_shader_storage_blocks); + break; + } + } + } } } @@ -2886,6 +2913,7 @@ check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog) { unsigned total_image_units = 0; unsigned fragment_outputs = 0; + unsigned total_shader_storage_blocks = 0; if (!ctx->Extensions.ARB_shader_image_load_store) return; @@ -2901,6 +2929,12 @@ check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog) total_image_units += sh->NumImages; + for (unsigned j = 0; j < prog->NumUniformBlocks; j++) { + int stage_index = prog->UniformBlockStageIndex[i][j]; + if (stage_index != -1 && sh->UniformBlocks[stage_index].IsShaderStorage) + total_shader_storage_blocks++; + } + if (i == MESA_SHADER_FRAGMENT) { foreach_in_list(ir_instruction, node, sh->ir) { ir_variable *var = node->as_variable(); @@ -2914,9 +2948,10 @@ check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog) if (total_image_units > ctx->Const.MaxCombinedImageUniforms) linker_error(prog, "Too many combined image uniforms\n"); - if (total_image_units + fragment_outputs > + if (total_image_units + fragment_outputs + total_shader_storage_blocks > ctx->Const.MaxCombinedShaderOutputResources) - linker_error(prog, "Too many combined image uniforms and fragment outputs\n"); + linker_error(prog, "Too many combined image uniforms, shader storage " + " buffers and fragment outputs\n"); } |