i965/blorp: Get rid of the blorp_prog_data_int() helper
[mesa.git] / src / mesa / drivers / dri / i965 / brw_blorp_clear.cpp
1 /*
2 * Copyright © 2013 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "main/teximage.h"
25 #include "main/blend.h"
26 #include "main/fbobject.h"
27 #include "main/renderbuffer.h"
28 #include "main/glformats.h"
29
30 #include "util/ralloc.h"
31
32 #include "intel_fbo.h"
33
34 #include "brw_blorp.h"
35 #include "brw_meta_util.h"
36 #include "brw_context.h"
37 #include "brw_eu.h"
38 #include "brw_state.h"
39
40 #include "nir_builder.h"
41
42 #define FILE_DEBUG_FLAG DEBUG_BLORP
43
44 struct brw_blorp_const_color_prog_key
45 {
46 bool use_simd16_replicated_data;
47 bool pad[3];
48 };
49
50 static void
51 brw_blorp_params_get_clear_kernel(struct brw_context *brw,
52 struct brw_blorp_params *params,
53 bool use_replicated_data)
54 {
55 struct brw_blorp_const_color_prog_key blorp_key;
56 memset(&blorp_key, 0, sizeof(blorp_key));
57 blorp_key.use_simd16_replicated_data = use_replicated_data;
58
59 if (brw_search_cache(&brw->cache, BRW_CACHE_BLORP_PROG,
60 &blorp_key, sizeof(blorp_key),
61 &params->wm_prog_kernel, &params->wm_prog_data))
62 return;
63
64 void *mem_ctx = ralloc_context(NULL);
65
66 nir_builder b;
67 nir_builder_init_simple_shader(&b, NULL, MESA_SHADER_FRAGMENT, NULL);
68 b.shader->info.name = ralloc_strdup(b.shader, "BLORP-clear");
69
70 nir_variable *u_color = nir_variable_create(b.shader, nir_var_uniform,
71 glsl_vec4_type(), "u_color");
72 u_color->data.location = 0;
73
74 nir_variable *frag_color = nir_variable_create(b.shader, nir_var_shader_out,
75 glsl_vec4_type(),
76 "gl_FragColor");
77 frag_color->data.location = FRAG_RESULT_COLOR;
78
79 nir_copy_var(&b, frag_color, u_color);
80
81 struct brw_wm_prog_key wm_key;
82 brw_blorp_init_wm_prog_key(&wm_key);
83
84 struct brw_blorp_prog_data prog_data;
85 unsigned program_size;
86 const unsigned *program =
87 brw_blorp_compile_nir_shader(brw, b.shader, &wm_key, use_replicated_data,
88 &prog_data, &program_size);
89
90 brw_upload_cache(&brw->cache, BRW_CACHE_BLORP_PROG,
91 &blorp_key, sizeof(blorp_key),
92 program, program_size,
93 &prog_data, sizeof(prog_data),
94 &params->wm_prog_kernel, &params->wm_prog_data);
95
96 ralloc_free(mem_ctx);
97 }
98
99 static bool
100 set_write_disables(const struct intel_renderbuffer *irb,
101 const GLubyte *color_mask, bool *color_write_disable)
102 {
103 /* Format information in the renderbuffer represents the requirements
104 * given by the client. There are cases where the backing miptree uses,
105 * for example, RGBA to represent RGBX. Since the client is only expecting
106 * RGB we can treat alpha as not used and write whatever we like into it.
107 */
108 const GLenum base_format = irb->Base.Base._BaseFormat;
109 const int components = _mesa_base_format_component_count(base_format);
110 bool disables = false;
111
112 assert(components > 0);
113
114 for (int i = 0; i < components; i++) {
115 color_write_disable[i] = !color_mask[i];
116 disables = disables || !color_mask[i];
117 }
118
119 return disables;
120 }
121
122 static bool
123 do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
124 struct gl_renderbuffer *rb, unsigned buf,
125 bool partial_clear, bool encode_srgb, unsigned layer)
126 {
127 struct gl_context *ctx = &brw->ctx;
128 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
129 mesa_format format = irb->mt->format;
130
131 struct brw_blorp_params params;
132 brw_blorp_params_init(&params);
133
134 if (!encode_srgb && _mesa_get_format_color_encoding(format) == GL_SRGB)
135 format = _mesa_get_srgb_format_linear(format);
136
137 brw_blorp_surface_info_init(brw, &params.dst, irb->mt, irb->mt_level,
138 layer, format, true);
139
140 /* Override the surface format according to the context's sRGB rules. */
141 params.dst.brw_surfaceformat = brw->render_target_format[format];
142
143 params.x0 = fb->_Xmin;
144 params.x1 = fb->_Xmax;
145 if (rb->Name != 0) {
146 params.y0 = fb->_Ymin;
147 params.y1 = fb->_Ymax;
148 } else {
149 params.y0 = rb->Height - fb->_Ymax;
150 params.y1 = rb->Height - fb->_Ymin;
151 }
152
153 memcpy(&params.wm_push_consts.dst_x0,
154 ctx->Color.ClearColor.f, sizeof(float) * 4);
155
156 bool use_simd16_replicated_data = true;
157
158 /* From the SNB PRM (Vol4_Part1):
159 *
160 * "Replicated data (Message Type = 111) is only supported when
161 * accessing tiled memory. Using this Message Type to access linear
162 * (untiled) memory is UNDEFINED."
163 */
164 if (irb->mt->tiling == I915_TILING_NONE)
165 use_simd16_replicated_data = false;
166
167 /* Constant color writes ignore everyting in blend and color calculator
168 * state. This is not documented.
169 */
170 if (set_write_disables(irb, ctx->Color.ColorMask[buf],
171 params.color_write_disable))
172 use_simd16_replicated_data = false;
173
174 if (irb->mt->fast_clear_state != INTEL_FAST_CLEAR_STATE_NO_MCS &&
175 !partial_clear && use_simd16_replicated_data &&
176 brw_is_color_fast_clear_compatible(brw, irb->mt,
177 &ctx->Color.ClearColor)) {
178 memset(&params.wm_push_consts, 0xff, 4*sizeof(float));
179 params.fast_clear_op = GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE;
180
181 brw_get_fast_clear_rect(brw, fb, irb->mt, &params.x0, &params.y0,
182 &params.x1, &params.y1);
183 } else {
184 brw_meta_get_buffer_rect(fb, &params.x0, &params.y0,
185 &params.x1, &params.y1);
186 }
187
188 brw_blorp_params_get_clear_kernel(brw, &params, use_simd16_replicated_data);
189
190 const bool is_fast_clear =
191 params.fast_clear_op == GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE;
192 if (is_fast_clear) {
193 /* Record the clear color in the miptree so that it will be
194 * programmed in SURFACE_STATE by later rendering and resolve
195 * operations.
196 */
197 const bool color_updated = brw_meta_set_fast_clear_color(
198 brw, irb->mt, &ctx->Color.ClearColor);
199
200 /* If the buffer is already in INTEL_FAST_CLEAR_STATE_CLEAR, the clear
201 * is redundant and can be skipped.
202 */
203 if (!color_updated &&
204 irb->mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR)
205 return true;
206
207 /* If the MCS buffer hasn't been allocated yet, we need to allocate
208 * it now.
209 */
210 if (!irb->mt->mcs_mt) {
211 if (!intel_miptree_alloc_non_msrt_mcs(brw, irb->mt)) {
212 /* MCS allocation failed--probably this will only happen in
213 * out-of-memory conditions. But in any case, try to recover
214 * by falling back to a non-blorp clear technique.
215 */
216 return false;
217 }
218 }
219 }
220
221 const char *clear_type;
222 if (is_fast_clear)
223 clear_type = "fast";
224 else if (use_simd16_replicated_data)
225 clear_type = "replicated";
226 else
227 clear_type = "slow";
228
229 DBG("%s (%s) to mt %p level %d layer %d\n", __FUNCTION__, clear_type,
230 irb->mt, irb->mt_level, irb->mt_layer);
231
232 brw_blorp_exec(brw, &params);
233
234 if (is_fast_clear) {
235 /* Now that the fast clear has occurred, put the buffer in
236 * INTEL_FAST_CLEAR_STATE_CLEAR so that we won't waste time doing
237 * redundant clears.
238 */
239 irb->mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_CLEAR;
240 } else if (intel_miptree_is_lossless_compressed(brw, irb->mt)) {
241 /* Compressed buffers can be cleared also using normal rep-clear. In
242 * such case they bahave such as if they were drawn using normal 3D
243 * render pipeline, and we simply mark the mcs as dirty.
244 */
245 assert(partial_clear);
246 irb->mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_UNRESOLVED;
247 }
248
249 return true;
250 }
251
252
253 extern "C" {
254 bool
255 brw_blorp_clear_color(struct brw_context *brw, struct gl_framebuffer *fb,
256 GLbitfield mask, bool partial_clear, bool encode_srgb)
257 {
258 for (unsigned buf = 0; buf < fb->_NumColorDrawBuffers; buf++) {
259 struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf];
260 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
261
262 /* Only clear the buffers present in the provided mask */
263 if (((1 << fb->_ColorDrawBufferIndexes[buf]) & mask) == 0)
264 continue;
265
266 /* If this is an ES2 context or GL_ARB_ES2_compatibility is supported,
267 * the framebuffer can be complete with some attachments missing. In
268 * this case the _ColorDrawBuffers pointer will be NULL.
269 */
270 if (rb == NULL)
271 continue;
272
273 if (fb->MaxNumLayers > 0) {
274 unsigned layer_multiplier =
275 (irb->mt->msaa_layout == INTEL_MSAA_LAYOUT_UMS ||
276 irb->mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) ?
277 irb->mt->num_samples : 1;
278 unsigned num_layers = irb->layer_count;
279 for (unsigned layer = 0; layer < num_layers; layer++) {
280 if (!do_single_blorp_clear(
281 brw, fb, rb, buf, partial_clear, encode_srgb,
282 irb->mt_layer + layer * layer_multiplier)) {
283 return false;
284 }
285 }
286 } else {
287 unsigned layer = irb->mt_layer;
288 if (!do_single_blorp_clear(brw, fb, rb, buf, partial_clear,
289 encode_srgb, layer))
290 return false;
291 }
292
293 irb->need_downsample = true;
294 }
295
296 return true;
297 }
298
299 void
300 brw_blorp_resolve_color(struct brw_context *brw, struct intel_mipmap_tree *mt)
301 {
302 DBG("%s to mt %p\n", __FUNCTION__, mt);
303
304 const mesa_format format = _mesa_get_srgb_format_linear(mt->format);
305
306 struct brw_blorp_params params;
307 brw_blorp_params_init(&params);
308
309 brw_blorp_surface_info_init(brw, &params.dst, mt,
310 0 /* level */, 0 /* layer */, format, true);
311
312 brw_get_resolve_rect(brw, mt, &params.x0, &params.y0,
313 &params.x1, &params.y1);
314
315 if (intel_miptree_is_lossless_compressed(brw, mt))
316 params.resolve_type = GEN9_PS_RENDER_TARGET_RESOLVE_FULL;
317 else
318 params.resolve_type = GEN7_PS_RENDER_TARGET_RESOLVE_ENABLE;
319
320 /* Note: there is no need to initialize push constants because it doesn't
321 * matter what data gets dispatched to the render target. However, we must
322 * ensure that the fragment shader delivers the data using the "replicated
323 * color" message.
324 */
325
326 brw_blorp_params_get_clear_kernel(brw, &params, true);
327
328 brw_blorp_exec(brw, &params);
329 mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED;
330 }
331
332 } /* extern "C" */