st/mesa: shader image atoms must be before framebuffer update
[mesa.git] / src / mesa / state_tracker / st_atom_image.c
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 "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_cb_texture.h"
38 #include "st_debug.h"
39 #include "st_texture.h"
40 #include "st_context.h"
41 #include "st_atom.h"
42 #include "st_program.h"
43 #include "st_format.h"
44
45 static void
46 st_bind_images(struct st_context *st, struct gl_shader *shader,
47 unsigned shader_type)
48 {
49 unsigned i;
50 struct pipe_image_view images[MAX_IMAGE_UNIFORMS];
51 struct gl_program_constants *c;
52
53 if (!shader || !st->pipe->set_shader_images)
54 return;
55
56 c = &st->ctx->Const.Program[shader->Stage];
57
58 for (i = 0; i < shader->NumImages; i++) {
59 struct gl_image_unit *u = &st->ctx->ImageUnits[shader->ImageUnits[i]];
60 struct st_texture_object *stObj = st_texture_object(u->TexObj);
61 struct pipe_image_view *img = &images[i];
62
63 if (!stObj ||
64 !st_finalize_texture(st->ctx, st->pipe, u->TexObj) ||
65 !stObj->pt) {
66 memset(img, 0, sizeof(*img));
67 continue;
68 }
69
70 img->resource = stObj->pt;
71 img->format = st_mesa_format_to_pipe_format(st, u->_ActualFormat);
72 if (stObj->pt->target == PIPE_BUFFER) {
73 unsigned base, size;
74 unsigned f, n;
75 const struct util_format_description *desc
76 = util_format_description(img->format);
77
78 base = stObj->base.BufferOffset;
79 assert(base < stObj->pt->width0);
80 size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize);
81
82 f = (base / (desc->block.bits / 8)) * desc->block.width;
83 n = (size / (desc->block.bits / 8)) * desc->block.width;
84 assert(n > 0);
85 img->u.buf.first_element = f;
86 img->u.buf.last_element = f + (n - 1);
87 } else {
88 img->u.tex.level = u->Level + stObj->base.MinLevel;
89 if (stObj->pt->target == PIPE_TEXTURE_3D) {
90 if (u->Layered) {
91 img->u.tex.first_layer = 0;
92 img->u.tex.last_layer = u_minify(stObj->pt->depth0, img->u.tex.level) - 1;
93 } else {
94 img->u.tex.first_layer = u->_Layer;
95 img->u.tex.last_layer = u->_Layer;
96 }
97 } else {
98 img->u.tex.first_layer = u->_Layer + stObj->base.MinLayer;
99 img->u.tex.last_layer = u->_Layer + stObj->base.MinLayer;
100 if (u->Layered && img->resource->array_size > 1) {
101 if (stObj->base.Immutable)
102 img->u.tex.last_layer += stObj->base.NumLayers - 1;
103 else
104 img->u.tex.last_layer += img->resource->array_size - 1;
105 }
106 }
107 }
108 }
109 st->pipe->set_shader_images(st->pipe, shader_type, 0, shader->NumImages,
110 images);
111 /* clear out any stale shader images */
112 if (shader->NumImages < c->MaxImageUniforms)
113 st->pipe->set_shader_images(
114 st->pipe, shader_type,
115 shader->NumImages,
116 c->MaxImageUniforms - shader->NumImages,
117 NULL);
118 }
119
120 static void bind_vs_images(struct st_context *st)
121 {
122 struct gl_shader_program *prog =
123 st->ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
124
125 if (!prog)
126 return;
127
128 st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_VERTEX], PIPE_SHADER_VERTEX);
129 }
130
131 const struct st_tracked_state st_bind_vs_images = {
132 "st_bind_vs_images",
133 {
134 0,
135 ST_NEW_VERTEX_PROGRAM | ST_NEW_IMAGE_UNITS,
136 },
137 bind_vs_images
138 };
139
140 static void bind_fs_images(struct st_context *st)
141 {
142 struct gl_shader_program *prog =
143 st->ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT];
144
145 if (!prog)
146 return;
147
148 st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_FRAGMENT], PIPE_SHADER_FRAGMENT);
149 }
150
151 const struct st_tracked_state st_bind_fs_images = {
152 "st_bind_fs_images",
153 {
154 0,
155 ST_NEW_FRAGMENT_PROGRAM | ST_NEW_IMAGE_UNITS,
156 },
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)
166 return;
167
168 st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_GEOMETRY], PIPE_SHADER_GEOMETRY);
169 }
170
171 const struct st_tracked_state st_bind_gs_images = {
172 "st_bind_gs_images",
173 {
174 0,
175 ST_NEW_GEOMETRY_PROGRAM | ST_NEW_IMAGE_UNITS,
176 },
177 bind_gs_images
178 };
179
180 static void bind_tcs_images(struct st_context *st)
181 {
182 struct gl_shader_program *prog =
183 st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL];
184
185 if (!prog)
186 return;
187
188 st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_TESS_CTRL], PIPE_SHADER_TESS_CTRL);
189 }
190
191 const struct st_tracked_state st_bind_tcs_images = {
192 "st_bind_tcs_images",
193 {
194 0,
195 ST_NEW_TESSCTRL_PROGRAM | ST_NEW_IMAGE_UNITS,
196 },
197 bind_tcs_images
198 };
199
200 static void bind_tes_images(struct st_context *st)
201 {
202 struct gl_shader_program *prog =
203 st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
204
205 if (!prog)
206 return;
207
208 st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_TESS_EVAL], PIPE_SHADER_TESS_EVAL);
209 }
210
211 const struct st_tracked_state st_bind_tes_images = {
212 "st_bind_tes_images",
213 {
214 0,
215 ST_NEW_TESSEVAL_PROGRAM | ST_NEW_IMAGE_UNITS,
216 },
217 bind_tes_images
218 };
219
220 static void bind_cs_images(struct st_context *st)
221 {
222 struct gl_shader_program *prog =
223 st->ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
224
225 if (!prog)
226 return;
227
228 st_bind_images(st, prog->_LinkedShaders[MESA_SHADER_COMPUTE], PIPE_SHADER_COMPUTE);
229 }
230
231 const struct st_tracked_state st_bind_cs_images = {
232 "st_bind_cs_images",
233 {
234 0,
235 ST_NEW_COMPUTE_PROGRAM | ST_NEW_IMAGE_UNITS,
236 },
237 bind_cs_images
238 };