2 * Copyright © 2013 Intel Corporation
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:
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
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
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"
30 #include "util/ralloc.h"
32 #include "intel_fbo.h"
34 #include "brw_blorp.h"
35 #include "brw_meta_util.h"
36 #include "brw_context.h"
38 #include "brw_state.h"
40 #include "nir_builder.h"
42 #define FILE_DEBUG_FLAG DEBUG_BLORP
44 struct brw_blorp_const_color_prog_key
46 bool use_simd16_replicated_data
;
51 brw_blorp_params_get_clear_kernel(struct brw_context
*brw
,
52 struct brw_blorp_params
*params
,
53 bool use_replicated_data
)
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
;
59 if (brw_search_cache(&brw
->cache
, BRW_CACHE_BLORP_PROG
,
60 &blorp_key
, sizeof(blorp_key
),
61 ¶ms
->wm_prog_kernel
, ¶ms
->wm_prog_data
))
64 void *mem_ctx
= ralloc_context(NULL
);
67 nir_builder_init_simple_shader(&b
, NULL
, MESA_SHADER_FRAGMENT
, NULL
);
68 b
.shader
->info
.name
= ralloc_strdup(b
.shader
, "BLORP-clear");
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;
74 nir_variable
*frag_color
= nir_variable_create(b
.shader
, nir_var_shader_out
,
77 frag_color
->data
.location
= FRAG_RESULT_COLOR
;
79 nir_copy_var(&b
, frag_color
, u_color
);
81 struct brw_wm_prog_key wm_key
;
82 brw_blorp_init_wm_prog_key(&wm_key
);
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
);
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 ¶ms
->wm_prog_kernel
, ¶ms
->wm_prog_data
);
100 set_write_disables(const struct intel_renderbuffer
*irb
,
101 const GLubyte
*color_mask
, bool *color_write_disable
)
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.
108 const GLenum base_format
= irb
->Base
.Base
._BaseFormat
;
109 const int components
= _mesa_base_format_component_count(base_format
);
110 bool disables
= false;
112 assert(components
> 0);
114 for (int i
= 0; i
< components
; i
++) {
115 color_write_disable
[i
] = !color_mask
[i
];
116 disables
= disables
|| !color_mask
[i
];
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
)
127 struct gl_context
*ctx
= &brw
->ctx
;
128 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
129 mesa_format format
= irb
->mt
->format
;
131 struct brw_blorp_params params
;
132 brw_blorp_params_init(¶ms
);
134 if (!encode_srgb
&& _mesa_get_format_color_encoding(format
) == GL_SRGB
)
135 format
= _mesa_get_srgb_format_linear(format
);
137 brw_blorp_surface_info_init(brw
, ¶ms
.dst
, irb
->mt
, irb
->mt_level
,
138 layer
, format
, true);
140 /* Override the surface format according to the context's sRGB rules. */
141 params
.dst
.brw_surfaceformat
= brw
->render_target_format
[format
];
143 params
.x0
= fb
->_Xmin
;
144 params
.x1
= fb
->_Xmax
;
146 params
.y0
= fb
->_Ymin
;
147 params
.y1
= fb
->_Ymax
;
149 params
.y0
= rb
->Height
- fb
->_Ymax
;
150 params
.y1
= rb
->Height
- fb
->_Ymin
;
153 memcpy(¶ms
.wm_push_consts
.dst_x0
,
154 ctx
->Color
.ClearColor
.f
, sizeof(float) * 4);
156 bool use_simd16_replicated_data
= true;
158 /* From the SNB PRM (Vol4_Part1):
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."
164 if (irb
->mt
->tiling
== I915_TILING_NONE
)
165 use_simd16_replicated_data
= false;
167 /* Constant color writes ignore everyting in blend and color calculator
168 * state. This is not documented.
170 if (set_write_disables(irb
, ctx
->Color
.ColorMask
[buf
],
171 params
.color_write_disable
))
172 use_simd16_replicated_data
= false;
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(¶ms
.wm_push_consts
, 0xff, 4*sizeof(float));
179 params
.fast_clear_op
= GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE
;
181 brw_get_fast_clear_rect(brw
, fb
, irb
->mt
, ¶ms
.x0
, ¶ms
.y0
,
182 ¶ms
.x1
, ¶ms
.y1
);
184 brw_meta_get_buffer_rect(fb
, ¶ms
.x0
, ¶ms
.y0
,
185 ¶ms
.x1
, ¶ms
.y1
);
188 brw_blorp_params_get_clear_kernel(brw
, ¶ms
, use_simd16_replicated_data
);
190 const bool is_fast_clear
=
191 params
.fast_clear_op
== GEN7_PS_RENDER_TARGET_FAST_CLEAR_ENABLE
;
193 /* Record the clear color in the miptree so that it will be
194 * programmed in SURFACE_STATE by later rendering and resolve
197 const bool color_updated
= brw_meta_set_fast_clear_color(
198 brw
, irb
->mt
, &ctx
->Color
.ClearColor
);
200 /* If the buffer is already in INTEL_FAST_CLEAR_STATE_CLEAR, the clear
201 * is redundant and can be skipped.
203 if (!color_updated
&&
204 irb
->mt
->fast_clear_state
== INTEL_FAST_CLEAR_STATE_CLEAR
)
207 /* If the MCS buffer hasn't been allocated yet, we need to allocate
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.
221 const char *clear_type
;
224 else if (use_simd16_replicated_data
)
225 clear_type
= "replicated";
229 DBG("%s (%s) to mt %p level %d layer %d\n", __FUNCTION__
, clear_type
,
230 irb
->mt
, irb
->mt_level
, irb
->mt_layer
);
232 brw_blorp_exec(brw
, ¶ms
);
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
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.
245 assert(partial_clear
);
246 irb
->mt
->fast_clear_state
= INTEL_FAST_CLEAR_STATE_UNRESOLVED
;
255 brw_blorp_clear_color(struct brw_context
*brw
, struct gl_framebuffer
*fb
,
256 GLbitfield mask
, bool partial_clear
, bool encode_srgb
)
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
);
262 /* Only clear the buffers present in the provided mask */
263 if (((1 << fb
->_ColorDrawBufferIndexes
[buf
]) & mask
) == 0)
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.
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
)) {
287 unsigned layer
= irb
->mt_layer
;
288 if (!do_single_blorp_clear(brw
, fb
, rb
, buf
, partial_clear
,
293 irb
->need_downsample
= true;
300 brw_blorp_resolve_color(struct brw_context
*brw
, struct intel_mipmap_tree
*mt
)
302 DBG("%s to mt %p\n", __FUNCTION__
, mt
);
304 const mesa_format format
= _mesa_get_srgb_format_linear(mt
->format
);
306 struct brw_blorp_params params
;
307 brw_blorp_params_init(¶ms
);
309 brw_blorp_surface_info_init(brw
, ¶ms
.dst
, mt
,
310 0 /* level */, 0 /* layer */, format
, true);
312 brw_get_resolve_rect(brw
, mt
, ¶ms
.x0
, ¶ms
.y0
,
313 ¶ms
.x1
, ¶ms
.y1
);
315 if (intel_miptree_is_lossless_compressed(brw
, mt
))
316 params
.resolve_type
= GEN9_PS_RENDER_TARGET_RESOLVE_FULL
;
318 params
.resolve_type
= GEN7_PS_RENDER_TARGET_RESOLVE_ENABLE
;
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
326 brw_blorp_params_get_clear_kernel(brw
, ¶ms
, true);
328 brw_blorp_exec(brw
, ¶ms
);
329 mt
->fast_clear_state
= INTEL_FAST_CLEAR_STATE_RESOLVED
;