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