1 /**************************************************************************
2  *
3  * Copyright 2007 VMware, Inc.
4  * All Rights Reserved.
5  * Copyright 2009 VMware, Inc.  All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sub license, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice (including the
16  * next paragraph) shall be included in all copies or substantial portions
17  * of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26  *
27  **************************************************************************/
28 
29  /*
30   * Authors:
31   *   Keith Whitwell <keithw@vmware.com>
32   *   Brian Paul
33   *   Michel Dänzer
34   */
35 
36 #include "main/errors.h"
37 #include "main/glheader.h"
38 #include "main/accum.h"
39 #include "main/formats.h"
40 #include "main/framebuffer.h"
41 #include "main/macros.h"
42 #include "main/glformats.h"
43 #include "program/prog_instruction.h"
44 #include "st_context.h"
45 #include "st_atom.h"
46 #include "st_cb_bitmap.h"
47 #include "st_cb_clear.h"
48 #include "st_cb_fbo.h"
49 #include "st_draw.h"
50 #include "st_format.h"
51 #include "st_nir.h"
52 #include "st_program.h"
53 #include "st_util.h"
54 
55 #include "pipe/p_context.h"
56 #include "pipe/p_shader_tokens.h"
57 #include "pipe/p_state.h"
58 #include "pipe/p_defines.h"
59 #include "util/format/u_format.h"
60 #include "util/u_inlines.h"
61 #include "util/u_simple_shaders.h"
62 
63 #include "cso_cache/cso_context.h"
64 
65 
66 /**
67  * Do per-context initialization for glClear.
68  */
69 void
st_init_clear(struct st_context * st)70 st_init_clear(struct st_context *st)
71 {
72    memset(&st->clear, 0, sizeof(st->clear));
73 
74    st->clear.raster.half_pixel_center = 1;
75    st->clear.raster.bottom_edge_rule = 1;
76    st->clear.raster.depth_clip_near = 1;
77    st->clear.raster.depth_clip_far = 1;
78 }
79 
80 
81 /**
82  * Free per-context state for glClear.
83  */
84 void
st_destroy_clear(struct st_context * st)85 st_destroy_clear(struct st_context *st)
86 {
87    if (st->clear.fs) {
88       st->pipe->delete_fs_state(st->pipe, st->clear.fs);
89       st->clear.fs = NULL;
90    }
91    if (st->clear.vs) {
92       st->pipe->delete_vs_state(st->pipe, st->clear.vs);
93       st->clear.vs = NULL;
94    }
95    if (st->clear.vs_layered) {
96       st->pipe->delete_vs_state(st->pipe, st->clear.vs_layered);
97       st->clear.vs_layered = NULL;
98    }
99    if (st->clear.gs_layered) {
100       st->pipe->delete_gs_state(st->pipe, st->clear.gs_layered);
101       st->clear.gs_layered = NULL;
102    }
103 }
104 
105 
106 /**
107  * Helper function to set the fragment shaders.
108  */
109 static inline void
set_fragment_shader(struct st_context * st)110 set_fragment_shader(struct st_context *st)
111 {
112    struct pipe_screen *pscreen = st->pipe->screen;
113    bool use_nir = PIPE_SHADER_IR_NIR ==
114       pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX,
115                                 PIPE_SHADER_CAP_PREFERRED_IR);
116 
117    if (!st->clear.fs) {
118       if (use_nir) {
119          unsigned inputs[] = { VARYING_SLOT_VAR0 };
120          unsigned outputs[] = { FRAG_RESULT_COLOR };
121          unsigned interpolation[] = { INTERP_MODE_FLAT };
122          st->clear.fs = st_nir_make_passthrough_shader(st, "clear FS",
123                                                        MESA_SHADER_FRAGMENT,
124                                                        1, inputs, outputs,
125                                                        interpolation, 0);
126       } else {
127          st->clear.fs =
128             util_make_fragment_passthrough_shader(st->pipe,
129                                                   TGSI_SEMANTIC_GENERIC,
130                                                   TGSI_INTERPOLATE_CONSTANT,
131                                                   TRUE);
132       }
133    }
134 
135    cso_set_fragment_shader_handle(st->cso_context, st->clear.fs);
136 }
137 
138 
139 static void *
make_nir_clear_vertex_shader(struct st_context * st,bool layered)140 make_nir_clear_vertex_shader(struct st_context *st, bool layered)
141 {
142    const char *shader_name = layered ? "layered clear VS" : "clear VS";
143    unsigned inputs[] = {
144       VERT_ATTRIB_POS,
145       VERT_ATTRIB_GENERIC0,
146       SYSTEM_VALUE_INSTANCE_ID,
147    };
148    unsigned outputs[] = {
149       VARYING_SLOT_POS,
150       VARYING_SLOT_VAR0,
151       VARYING_SLOT_LAYER
152    };
153 
154    return st_nir_make_passthrough_shader(st, shader_name, MESA_SHADER_VERTEX,
155                                          layered ? 3 : 2, inputs, outputs,
156                                          NULL, (1 << 2));
157 }
158 
159 
160 /**
161  * Helper function to set the vertex shader.
162  */
163 static inline void
set_vertex_shader(struct st_context * st)164 set_vertex_shader(struct st_context *st)
165 {
166    struct pipe_screen *pscreen = st->pipe->screen;
167    bool use_nir = PIPE_SHADER_IR_NIR ==
168       pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX,
169                                 PIPE_SHADER_CAP_PREFERRED_IR);
170 
171    /* vertex shader - still required to provide the linkage between
172     * fragment shader input semantics and vertex_element/buffers.
173     */
174    if (!st->clear.vs)
175    {
176       if (use_nir) {
177          st->clear.vs = make_nir_clear_vertex_shader(st, false);
178       } else {
179          const enum tgsi_semantic semantic_names[] = {
180             TGSI_SEMANTIC_POSITION,
181             TGSI_SEMANTIC_GENERIC
182          };
183          const uint semantic_indexes[] = { 0, 0 };
184          st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2,
185                                                             semantic_names,
186                                                             semantic_indexes,
187                                                             FALSE);
188       }
189    }
190 
191    cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
192    cso_set_geometry_shader_handle(st->cso_context, NULL);
193 }
194 
195 
196 static void
set_vertex_shader_layered(struct st_context * st)197 set_vertex_shader_layered(struct st_context *st)
198 {
199    struct pipe_context *pipe = st->pipe;
200    struct pipe_screen *pscreen = pipe->screen;
201    bool use_nir = PIPE_SHADER_IR_NIR ==
202       pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX,
203                                 PIPE_SHADER_CAP_PREFERRED_IR);
204 
205    if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID)) {
206       assert(!"Got layered clear, but VS instancing is unsupported");
207       set_vertex_shader(st);
208       return;
209    }
210 
211    if (!st->clear.vs_layered) {
212       bool vs_layer =
213          pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT);
214       if (vs_layer) {
215          st->clear.vs_layered =
216             use_nir ? make_nir_clear_vertex_shader(st, true)
217                     : util_make_layered_clear_vertex_shader(pipe);
218       } else {
219          st->clear.vs_layered = util_make_layered_clear_helper_vertex_shader(pipe);
220          st->clear.gs_layered = util_make_layered_clear_geometry_shader(pipe);
221       }
222    }
223 
224    cso_set_vertex_shader_handle(st->cso_context, st->clear.vs_layered);
225    cso_set_geometry_shader_handle(st->cso_context, st->clear.gs_layered);
226 }
227 
228 
229 /**
230  * Do glClear by drawing a quadrilateral.
231  * The vertices of the quad will be computed from the
232  * ctx->DrawBuffer->_X/Ymin/max fields.
233  */
234 static void
clear_with_quad(struct gl_context * ctx,unsigned clear_buffers)235 clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
236 {
237    struct st_context *st = st_context(ctx);
238    struct cso_context *cso = st->cso_context;
239    const struct gl_framebuffer *fb = ctx->DrawBuffer;
240    const GLfloat fb_width = (GLfloat) fb->Width;
241    const GLfloat fb_height = (GLfloat) fb->Height;
242 
243    _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer);
244 
245    const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin / fb_width * 2.0f - 1.0f;
246    const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
247    const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
248    const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
249    unsigned num_layers = st->state.fb_num_layers;
250 
251    /*
252    printf("%s %s%s%s %f,%f %f,%f\n", __func__,
253 	  color ? "color, " : "",
254 	  depth ? "depth, " : "",
255 	  stencil ? "stencil" : "",
256 	  x0, y0,
257 	  x1, y1);
258    */
259 
260    cso_save_state(cso, (CSO_BIT_BLEND |
261                         CSO_BIT_STENCIL_REF |
262                         CSO_BIT_DEPTH_STENCIL_ALPHA |
263                         CSO_BIT_RASTERIZER |
264                         CSO_BIT_SAMPLE_MASK |
265                         CSO_BIT_MIN_SAMPLES |
266                         CSO_BIT_VIEWPORT |
267                         CSO_BIT_STREAM_OUTPUTS |
268                         CSO_BIT_VERTEX_ELEMENTS |
269                         CSO_BIT_AUX_VERTEX_BUFFER_SLOT |
270                         (st->active_queries ? CSO_BIT_PAUSE_QUERIES : 0) |
271                         CSO_BITS_ALL_SHADERS));
272 
273    /* blend state: RGBA masking */
274    {
275       struct pipe_blend_state blend;
276       memset(&blend, 0, sizeof(blend));
277       if (clear_buffers & PIPE_CLEAR_COLOR) {
278          int num_buffers = ctx->Extensions.EXT_draw_buffers2 ?
279                            ctx->DrawBuffer->_NumColorDrawBuffers : 1;
280          int i;
281 
282          blend.independent_blend_enable = num_buffers > 1;
283          blend.max_rt = num_buffers - 1;
284 
285          for (i = 0; i < num_buffers; i++) {
286             if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i)))
287                continue;
288 
289             blend.rt[i].colormask = GET_COLORMASK(ctx->Color.ColorMask, i);
290          }
291 
292          if (ctx->Color.DitherFlag)
293             blend.dither = 1;
294       }
295       cso_set_blend(cso, &blend);
296    }
297 
298    /* depth_stencil state: always pass/set to ref value */
299    {
300       struct pipe_depth_stencil_alpha_state depth_stencil;
301       memset(&depth_stencil, 0, sizeof(depth_stencil));
302       if (clear_buffers & PIPE_CLEAR_DEPTH) {
303          depth_stencil.depth.enabled = 1;
304          depth_stencil.depth.writemask = 1;
305          depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
306       }
307 
308       if (clear_buffers & PIPE_CLEAR_STENCIL) {
309          struct pipe_stencil_ref stencil_ref;
310          memset(&stencil_ref, 0, sizeof(stencil_ref));
311          depth_stencil.stencil[0].enabled = 1;
312          depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS;
313          depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
314          depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
315          depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
316          depth_stencil.stencil[0].valuemask = 0xff;
317          depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
318          stencil_ref.ref_value[0] = ctx->Stencil.Clear;
319          cso_set_stencil_ref(cso, &stencil_ref);
320       }
321 
322       cso_set_depth_stencil_alpha(cso, &depth_stencil);
323    }
324 
325    st->util_velems.count = 2;
326    cso_set_vertex_elements(cso, &st->util_velems);
327 
328    cso_set_stream_outputs(cso, 0, NULL, NULL);
329    cso_set_sample_mask(cso, ~0);
330    cso_set_min_samples(cso, 1);
331    st->clear.raster.multisample = st->state.fb_num_samples > 1;
332    cso_set_rasterizer(cso, &st->clear.raster);
333 
334    /* viewport state: viewport matching window dims */
335    cso_set_viewport_dims(st->cso_context, fb_width, fb_height,
336                          st_fb_orientation(fb) == Y_0_TOP);
337 
338    set_fragment_shader(st);
339    cso_set_tessctrl_shader_handle(cso, NULL);
340    cso_set_tesseval_shader_handle(cso, NULL);
341 
342    if (num_layers > 1)
343       set_vertex_shader_layered(st);
344    else
345       set_vertex_shader(st);
346 
347    /* draw quad matching scissor rect.
348     *
349     * Note: if we're only clearing depth/stencil we still setup vertices
350     * with color, but they'll be ignored.
351     *
352     * We can't translate the clear color to the colorbuffer format,
353     * because different colorbuffers may have different formats.
354     */
355    if (!st_draw_quad(st, x0, y0, x1, y1,
356                      ctx->Depth.Clear * 2.0f - 1.0f,
357                      0.0f, 0.0f, 0.0f, 0.0f,
358                      (const float *) &ctx->Color.ClearColor.f,
359                      num_layers)) {
360       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear");
361    }
362 
363    /* Restore pipe state */
364    cso_restore_state(cso);
365 }
366 
367 
368 /**
369  * Return if the scissor must be enabled during the clear.
370  */
371 static inline GLboolean
is_scissor_enabled(struct gl_context * ctx,struct gl_renderbuffer * rb)372 is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
373 {
374    const struct gl_scissor_rect *scissor = &ctx->Scissor.ScissorArray[0];
375 
376    return (ctx->Scissor.EnableFlags & 1) &&
377           (scissor->X > 0 ||
378            scissor->Y > 0 ||
379            scissor->X + scissor->Width < (int)rb->Width ||
380            scissor->Y + scissor->Height < (int)rb->Height);
381 }
382 
383 /**
384  * Return if window rectangles must be enabled during the clear.
385  */
386 static inline bool
is_window_rectangle_enabled(struct gl_context * ctx)387 is_window_rectangle_enabled(struct gl_context *ctx)
388 {
389    if (ctx->DrawBuffer == ctx->WinSysDrawBuffer)
390       return false;
391    return ctx->Scissor.NumWindowRects > 0 ||
392       ctx->Scissor.WindowRectMode == GL_INCLUSIVE_EXT;
393 }
394 
395 
396 /**
397  * Return if all of the stencil bits are masked.
398  */
399 static inline GLboolean
is_stencil_disabled(struct gl_context * ctx,struct gl_renderbuffer * rb)400 is_stencil_disabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
401 {
402    const GLuint stencilMax = 0xff;
403 
404    assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
405    return (ctx->Stencil.WriteMask[0] & stencilMax) == 0;
406 }
407 
408 
409 /**
410  * Return if any of the stencil bits are masked.
411  */
412 static inline GLboolean
is_stencil_masked(struct gl_context * ctx,struct gl_renderbuffer * rb)413 is_stencil_masked(struct gl_context *ctx, struct gl_renderbuffer *rb)
414 {
415    const GLuint stencilMax = 0xff;
416 
417    assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
418    return (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
419 }
420 
421 
422 /**
423  * Called via ctx->Driver.Clear()
424  */
425 static void
st_Clear(struct gl_context * ctx,GLbitfield mask)426 st_Clear(struct gl_context *ctx, GLbitfield mask)
427 {
428    struct st_context *st = st_context(ctx);
429    struct gl_renderbuffer *depthRb
430       = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
431    struct gl_renderbuffer *stencilRb
432       = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
433    GLbitfield quad_buffers = 0x0;
434    GLbitfield clear_buffers = 0x0;
435    bool have_scissor_buffers = false;
436    GLuint i;
437 
438    st_flush_bitmap_cache(st);
439    st_invalidate_readpix_cache(st);
440 
441    /* This makes sure the pipe has the latest scissor, etc values */
442    st_validate_state(st, ST_PIPELINE_CLEAR);
443 
444    if (mask & BUFFER_BITS_COLOR) {
445       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
446          gl_buffer_index b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
447 
448          if (b != BUFFER_NONE && mask & (1 << b)) {
449             struct gl_renderbuffer *rb
450                = ctx->DrawBuffer->Attachment[b].Renderbuffer;
451             struct st_renderbuffer *strb = st_renderbuffer(rb);
452             int colormask_index = ctx->Extensions.EXT_draw_buffers2 ? i : 0;
453 
454             if (!strb || !strb->surface)
455                continue;
456 
457             unsigned colormask =
458                GET_COLORMASK(ctx->Color.ColorMask, colormask_index);
459 
460             if (!colormask)
461                continue;
462 
463             unsigned surf_colormask =
464                util_format_colormask(util_format_description(strb->surface->format));
465 
466             bool scissor = is_scissor_enabled(ctx, rb);
467             if ((scissor && !st->can_scissor_clear) ||
468                 is_window_rectangle_enabled(ctx) ||
469                 ((colormask & surf_colormask) != surf_colormask))
470                quad_buffers |= PIPE_CLEAR_COLOR0 << i;
471             else
472                clear_buffers |= PIPE_CLEAR_COLOR0 << i;
473             have_scissor_buffers |= scissor && st->can_scissor_clear;
474          }
475       }
476    }
477 
478    if (mask & BUFFER_BIT_DEPTH) {
479       struct st_renderbuffer *strb = st_renderbuffer(depthRb);
480 
481       if (strb->surface && ctx->Depth.Mask) {
482          if (is_scissor_enabled(ctx, depthRb) ||
483              is_window_rectangle_enabled(ctx))
484             quad_buffers |= PIPE_CLEAR_DEPTH;
485          else
486             clear_buffers |= PIPE_CLEAR_DEPTH;
487       }
488    }
489    if (mask & BUFFER_BIT_STENCIL) {
490       struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
491 
492       if (strb->surface && !is_stencil_disabled(ctx, stencilRb)) {
493          if (is_scissor_enabled(ctx, stencilRb) ||
494              is_window_rectangle_enabled(ctx) ||
495              is_stencil_masked(ctx, stencilRb))
496             quad_buffers |= PIPE_CLEAR_STENCIL;
497          else
498             clear_buffers |= PIPE_CLEAR_STENCIL;
499       }
500    }
501 
502    /* Always clear depth and stencil together.
503     * This can only happen when the stencil writemask is not a full mask.
504     */
505    if (quad_buffers & PIPE_CLEAR_DEPTHSTENCIL &&
506        clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
507       quad_buffers |= clear_buffers & PIPE_CLEAR_DEPTHSTENCIL;
508       clear_buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
509    }
510 
511    /* Only use quad-based clearing for the renderbuffers which cannot
512     * use pipe->clear. We want to always use pipe->clear for the other
513     * renderbuffers, because it's likely to be faster.
514     */
515    if (clear_buffers) {
516       const struct gl_scissor_rect *scissor = &ctx->Scissor.ScissorArray[0];
517       struct pipe_scissor_state scissor_state = {
518          .minx = MAX2(scissor->X, 0),
519          .miny = MAX2(scissor->Y, 0),
520          .maxx = MAX2(scissor->X + scissor->Width, 0),
521          .maxy = MAX2(scissor->Y + scissor->Height, 0),
522 
523       };
524 
525       /* Now invert Y if needed.
526        * Gallium drivers use the convention Y=0=top for surfaces.
527        */
528       if (st->state.fb_orientation == Y_0_TOP) {
529          const struct gl_framebuffer *fb = ctx->DrawBuffer;
530          /* use intermediate variables to avoid uint underflow */
531          GLint miny, maxy;
532          miny = fb->Height - scissor_state.maxy;
533          maxy = fb->Height - scissor_state.miny;
534          scissor_state.miny = MAX2(miny, 0);
535          scissor_state.maxy = MAX2(maxy, 0);
536       }
537       /* We can't translate the clear color to the colorbuffer format,
538        * because different colorbuffers may have different formats.
539        */
540       st->pipe->clear(st->pipe, clear_buffers, have_scissor_buffers ? &scissor_state : NULL,
541                       (union pipe_color_union*)&ctx->Color.ClearColor,
542                       ctx->Depth.Clear, ctx->Stencil.Clear);
543    }
544    if (quad_buffers) {
545       clear_with_quad(ctx, quad_buffers);
546    }
547    if (mask & BUFFER_BIT_ACCUM)
548       _mesa_clear_accum_buffer(ctx);
549 }
550 
551 
552 void
st_init_clear_functions(struct dd_function_table * functions)553 st_init_clear_functions(struct dd_function_table *functions)
554 {
555    functions->Clear = st_Clear;
556 }
557