1 /************************************************************************** 2 * 3 * Copyright 2014 Ilia Mirkin. All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 **************************************************************************/ 26 27 #include "main/imports.h" 28 #include "program/prog_parameter.h" 29 #include "program/prog_print.h" 30 #include "compiler/glsl/ir_uniform.h" 31 32 #include "pipe/p_context.h" 33 #include "pipe/p_defines.h" 34 #include "util/u_inlines.h" 35 #include "util/u_surface.h" 36 37 #include "st_debug.h" 38 #include "st_cb_bufferobjects.h" 39 #include "st_context.h" 40 #include "st_atom.h" 41 #include "st_program.h" 42 43 static void 44 st_bind_ssbos(struct st_context *st, struct gl_program *prog, 45 enum pipe_shader_type shader_type) 46 { 47 unsigned i; 48 struct pipe_shader_buffer buffers[MAX_SHADER_STORAGE_BUFFERS]; 49 struct gl_program_constants *c; 50 51 if (!prog || !st->pipe->set_shader_buffers) 52 return; 53 54 c = &st->ctx->Const.Program[prog->info.stage]; 55 56 for (i = 0; i < prog->info.num_ssbos; i++) { 57 struct gl_shader_storage_buffer_binding *binding; 58 struct st_buffer_object *st_obj; 59 struct pipe_shader_buffer *sb = &buffers[i]; 60 61 binding = &st->ctx->ShaderStorageBufferBindings[ 62 prog->sh.ShaderStorageBlocks[i]->Binding]; 63 st_obj = st_buffer_object(binding->BufferObject); 64 65 sb->buffer = st_obj->buffer; 66 67 if (sb->buffer) { 68 sb->buffer_offset = binding->Offset; 69 sb->buffer_size = sb->buffer->width0 - binding->Offset; 70 71 /* AutomaticSize is FALSE if the buffer was set with BindBufferRange. 72 * Take the minimum just to be sure. 73 */ 74 if (!binding->AutomaticSize) 75 sb->buffer_size = MIN2(sb->buffer_size, (unsigned) binding->Size); 76 } 77 else { 78 sb->buffer_offset = 0; 79 sb->buffer_size = 0; 80 } 81 } 82 st->pipe->set_shader_buffers(st->pipe, shader_type, c->MaxAtomicBuffers, 83 prog->info.num_ssbos, buffers); 84 /* clear out any stale shader buffers */ 85 if (prog->info.num_ssbos < c->MaxShaderStorageBlocks) 86 st->pipe->set_shader_buffers( 87 st->pipe, shader_type, 88 c->MaxAtomicBuffers + prog->info.num_ssbos, 89 c->MaxShaderStorageBlocks - prog->info.num_ssbos, 90 NULL); 91 } 92 93 static void bind_vs_ssbos(struct st_context *st) 94 { 95 struct gl_shader_program *prog = 96 st->ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; 97 98 if (!prog || !prog->_LinkedShaders[MESA_SHADER_VERTEX]) 99 return; 100 101 st_bind_ssbos(st, prog->_LinkedShaders[MESA_SHADER_VERTEX]->Program, 102 PIPE_SHADER_VERTEX); 103 } 104 105 const struct st_tracked_state st_bind_vs_ssbos = { 106 bind_vs_ssbos 107 }; 108 109 static void bind_fs_ssbos(struct st_context *st) 110 { 111 struct gl_shader_program *prog = 112 st->ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; 113 114 if (!prog || !prog->_LinkedShaders[MESA_SHADER_FRAGMENT]) 115 return; 116 117 st_bind_ssbos(st, prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program, 118 PIPE_SHADER_FRAGMENT); 119 } 120 121 const struct st_tracked_state st_bind_fs_ssbos = { 122 bind_fs_ssbos 123 }; 124 125 static void bind_gs_ssbos(struct st_context *st) 126 { 127 struct gl_shader_program *prog = 128 st->ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; 129 130 if (!prog || !prog->_LinkedShaders[MESA_SHADER_GEOMETRY]) 131 return; 132 133 st_bind_ssbos(st, prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program, 134 PIPE_SHADER_GEOMETRY); 135 } 136 137 const struct st_tracked_state st_bind_gs_ssbos = { 138 bind_gs_ssbos 139 }; 140 141 static void bind_tcs_ssbos(struct st_context *st) 142 { 143 struct gl_shader_program *prog = 144 st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; 145 146 if (!prog || !prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]) 147 return; 148 149 st_bind_ssbos(st, prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program, 150 PIPE_SHADER_TESS_CTRL); 151 } 152 153 const struct st_tracked_state st_bind_tcs_ssbos = { 154 bind_tcs_ssbos 155 }; 156 157 static void bind_tes_ssbos(struct st_context *st) 158 { 159 struct gl_shader_program *prog = 160 st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; 161 162 if (!prog || !prog->_LinkedShaders[MESA_SHADER_TESS_EVAL]) 163 return; 164 165 st_bind_ssbos(st, prog->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program, 166 PIPE_SHADER_TESS_EVAL); 167 } 168 169 const struct st_tracked_state st_bind_tes_ssbos = { 170 bind_tes_ssbos 171 }; 172 173 static void bind_cs_ssbos(struct st_context *st) 174 { 175 struct gl_shader_program *prog = 176 st->ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; 177 178 if (!prog || !prog->_LinkedShaders[MESA_SHADER_COMPUTE]) 179 return; 180 181 st_bind_ssbos(st, prog->_LinkedShaders[MESA_SHADER_COMPUTE]->Program, 182 PIPE_SHADER_COMPUTE); 183 } 184 185 const struct st_tracked_state st_bind_cs_ssbos = { 186 bind_cs_ssbos 187 }; 188