1 /************************************************************************** 2 * 3 * Copyright 2016 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 "main/shaderimage.h" 29 #include "program/prog_parameter.h" 30 #include "program/prog_print.h" 31 #include "compiler/glsl/ir_uniform.h" 32 33 #include "pipe/p_context.h" 34 #include "pipe/p_defines.h" 35 #include "util/u_inlines.h" 36 #include "util/u_surface.h" 37 #include "cso_cache/cso_context.h" 38 39 #include "st_cb_texture.h" 40 #include "st_debug.h" 41 #include "st_texture.h" 42 #include "st_context.h" 43 #include "st_atom.h" 44 #include "st_program.h" 45 #include "st_format.h" 46 47 static void 48 st_bind_images(struct st_context *st, struct gl_program *prog, 49 enum pipe_shader_type shader_type) 50 { 51 unsigned i; 52 struct pipe_image_view images[MAX_IMAGE_UNIFORMS]; 53 struct gl_program_constants *c; 54 55 if (!prog || !st->pipe->set_shader_images) 56 return; 57 58 c = &st->ctx->Const.Program[prog->info.stage]; 59 60 for (i = 0; i < prog->info.num_images; i++) { 61 struct gl_image_unit *u = 62 &st->ctx->ImageUnits[prog->sh.ImageUnits[i]]; 63 struct st_texture_object *stObj = st_texture_object(u->TexObj); 64 struct pipe_image_view *img = &images[i]; 65 66 if (!_mesa_is_image_unit_valid(st->ctx, u) || 67 !st_finalize_texture(st->ctx, st->pipe, u->TexObj, 0) || 68 !stObj->pt) { 69 memset(img, 0, sizeof(*img)); 70 continue; 71 } 72 73 img->resource = stObj->pt; 74 img->format = st_mesa_format_to_pipe_format(st, u->_ActualFormat); 75 76 switch (u->Access) { 77 case GL_READ_ONLY: 78 img->access = PIPE_IMAGE_ACCESS_READ; 79 break; 80 case GL_WRITE_ONLY: 81 img->access = PIPE_IMAGE_ACCESS_WRITE; 82 break; 83 case GL_READ_WRITE: 84 img->access = PIPE_IMAGE_ACCESS_READ_WRITE; 85 break; 86 default: 87 unreachable("bad gl_image_unit::Access"); 88 } 89 90 if (stObj->pt->target == PIPE_BUFFER) { 91 unsigned base, size; 92 93 base = stObj->base.BufferOffset; 94 assert(base < stObj->pt->width0); 95 size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize); 96 97 img->u.buf.offset = base; 98 img->u.buf.size = size; 99 } else { 100 img->u.tex.level = u->Level + stObj->base.MinLevel; 101 if (stObj->pt->target == PIPE_TEXTURE_3D) { 102 if (u->Layered) { 103 img->u.tex.first_layer = 0; 104 img->u.tex.last_layer = u_minify(stObj->pt->depth0, img->u.tex.level) - 1; 105 } else { 106 img->u.tex.first_layer = u->_Layer; 107 img->u.tex.last_layer = u->_Layer; 108 } 109 } else { 110 img->u.tex.first_layer = u->_Layer + stObj->base.MinLayer; 111 img->u.tex.last_layer = u->_Layer + stObj->base.MinLayer; 112 if (u->Layered && img->resource->array_size > 1) { 113 if (stObj->base.Immutable) 114 img->u.tex.last_layer += stObj->base.NumLayers - 1; 115 else 116 img->u.tex.last_layer += img->resource->array_size - 1; 117 } 118 } 119 } 120 } 121 cso_set_shader_images(st->cso_context, shader_type, 0, 122 prog->info.num_images, images); 123 /* clear out any stale shader images */ 124 if (prog->info.num_images < c->MaxImageUniforms) 125 cso_set_shader_images( 126 st->cso_context, shader_type, prog->info.num_images, 127 c->MaxImageUniforms - prog->info.num_images, NULL); 128 } 129 130 static void bind_vs_images(struct st_context *st) 131 { 132 struct gl_shader_program *prog = 133 st->ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; 134 135 if (!prog || !prog->_LinkedShaders[MESA_SHADER_VERTEX]) 136 return; 137 138 st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_VERTEX]->Program, PIPE_SHADER_VERTEX); 139 } 140 141 const struct st_tracked_state st_bind_vs_images = { 142 bind_vs_images 143 }; 144 145 static void bind_fs_images(struct st_context *st) 146 { 147 struct gl_shader_program *prog = 148 st->ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; 149 150 if (!prog || !prog->_LinkedShaders[MESA_SHADER_FRAGMENT]) 151 return; 152 153 st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program, PIPE_SHADER_FRAGMENT); 154 } 155 156 const struct st_tracked_state st_bind_fs_images = { 157 bind_fs_images 158 }; 159 160 static void bind_gs_images(struct st_context *st) 161 { 162 struct gl_shader_program *prog = 163 st->ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; 164 165 if (!prog || !prog->_LinkedShaders[MESA_SHADER_GEOMETRY]) 166 return; 167 168 st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program, PIPE_SHADER_GEOMETRY); 169 } 170 171 const struct st_tracked_state st_bind_gs_images = { 172 bind_gs_images 173 }; 174 175 static void bind_tcs_images(struct st_context *st) 176 { 177 struct gl_shader_program *prog = 178 st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; 179 180 if (!prog || !prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]) 181 return; 182 183 st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program, PIPE_SHADER_TESS_CTRL); 184 } 185 186 const struct st_tracked_state st_bind_tcs_images = { 187 bind_tcs_images 188 }; 189 190 static void bind_tes_images(struct st_context *st) 191 { 192 struct gl_shader_program *prog = 193 st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; 194 195 if (!prog || !prog->_LinkedShaders[MESA_SHADER_TESS_EVAL]) 196 return; 197 198 st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program, PIPE_SHADER_TESS_EVAL); 199 } 200 201 const struct st_tracked_state st_bind_tes_images = { 202 bind_tes_images 203 }; 204 205 static void bind_cs_images(struct st_context *st) 206 { 207 struct gl_shader_program *prog = 208 st->ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; 209 210 if (!prog || !prog->_LinkedShaders[MESA_SHADER_COMPUTE]) 211 return; 212 213 st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_COMPUTE]->Program, PIPE_SHADER_COMPUTE); 214 } 215 216 const struct st_tracked_state st_bind_cs_images = { 217 bind_cs_images 218 }; 219