• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2009 Marek Olšák <maraeo@gmail.com>
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 /**
28  * @file
29  * Blitter utility to facilitate acceleration of the clear, clear_render_target,
30  * clear_depth_stencil, resource_copy_region, and blit functions.
31  *
32  * @author Marek Olšák
33  */
34 
35 #include "pipe/p_context.h"
36 #include "pipe/p_defines.h"
37 #include "util/u_inlines.h"
38 #include "pipe/p_shader_tokens.h"
39 #include "pipe/p_state.h"
40 
41 #include "util/format/u_format.h"
42 #include "util/u_memory.h"
43 #include "util/u_math.h"
44 #include "util/u_blitter.h"
45 #include "util/u_draw_quad.h"
46 #include "util/u_sampler.h"
47 #include "util/u_simple_shaders.h"
48 #include "util/u_surface.h"
49 #include "util/u_texture.h"
50 #include "util/u_upload_mgr.h"
51 
52 #define INVALID_PTR ((void*)~0)
53 
54 #define GET_CLEAR_BLEND_STATE_IDX(clear_buffers) \
55    ((clear_buffers) / PIPE_CLEAR_COLOR0)
56 
57 #define NUM_RESOLVE_FRAG_SHADERS 5 /* MSAA 2x, 4x, 8x, 16x, 32x */
58 #define GET_MSAA_RESOLVE_FS_IDX(nr_samples) (util_logbase2(nr_samples)-1)
59 
60 struct blitter_context_priv
61 {
62    struct blitter_context base;
63 
64    float vertices[4][2][4];   /**< {pos, color} or {pos, texcoord} */
65 
66    /* Templates for various state objects. */
67 
68    /* Constant state objects. */
69    /* Vertex shaders. */
70    void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/
71    void *vs_nogeneric;
72    void *vs_pos_only[4]; /**< Vertex shader which passes pos to the output
73                               for clear_buffer.*/
74    void *vs_layered; /**< Vertex shader which sets LAYER = INSTANCEID. */
75 
76    /* Fragment shaders. */
77    void *fs_empty;
78    void *fs_write_one_cbuf;
79    void *fs_clear_all_cbufs;
80 
81    /* FS which outputs a color from a texture where
82     * the 1st index indicates the texture type / destination type,
83     * the 2nd index is the PIPE_TEXTURE_* to be sampled,
84     * the 3rd index is 0 = use TEX, 1 = use TXF.
85     */
86    void *fs_texfetch_col[5][PIPE_MAX_TEXTURE_TYPES][2];
87 
88    /* FS which outputs a depth from a texture, where
89     * the 1st index is the PIPE_TEXTURE_* to be sampled,
90     * the 2nd index is 0 = use TEX, 1 = use TXF.
91     */
92    void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES][2];
93    void *fs_texfetch_depthstencil[PIPE_MAX_TEXTURE_TYPES][2];
94    void *fs_texfetch_stencil[PIPE_MAX_TEXTURE_TYPES][2];
95 
96    /* FS which outputs one sample from a multisample texture. */
97    void *fs_texfetch_col_msaa[5][PIPE_MAX_TEXTURE_TYPES];
98    void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES][2];
99    void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES][2];
100    void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES][2];
101 
102    /* FS which outputs an average of all samples. */
103    void *fs_resolve[PIPE_MAX_TEXTURE_TYPES][NUM_RESOLVE_FRAG_SHADERS][2];
104 
105    /* FS which unpacks color to ZS or packs ZS to color, matching
106     * the ZS format. See util_blitter_get_color_format_for_zs().
107     */
108    void *fs_pack_color_zs[TGSI_TEXTURE_COUNT][10];
109 
110    /* FS which is meant for replicating indevidual stencil-buffer bits */
111    void *fs_stencil_blit_fallback[2];
112 
113    /* Blend state. */
114    void *blend[PIPE_MASK_RGBA+1][2]; /**< blend state with writemask */
115    void *blend_clear[GET_CLEAR_BLEND_STATE_IDX(PIPE_CLEAR_COLOR)+1];
116 
117    /* Depth stencil alpha state. */
118    void *dsa_write_depth_stencil;
119    void *dsa_write_depth_keep_stencil;
120    void *dsa_keep_depth_stencil;
121    void *dsa_keep_depth_write_stencil;
122    void *dsa_replicate_stencil_bit[8];
123 
124    /* Vertex elements states. */
125    void *velem_state;
126    void *velem_state_readbuf[4]; /**< X, XY, XYZ, XYZW */
127 
128    /* Sampler state. */
129    void *sampler_state;
130    void *sampler_state_linear;
131    void *sampler_state_rect;
132    void *sampler_state_rect_linear;
133 
134    /* Rasterizer state. */
135    void *rs_state[2][2];  /**< [scissor][msaa] */
136    void *rs_discard_state;
137 
138    /* Destination surface dimensions. */
139    unsigned dst_width;
140    unsigned dst_height;
141 
142    void *custom_vs;
143 
144    bool has_geometry_shader;
145    bool has_tessellation;
146    bool has_layered;
147    bool has_stream_out;
148    bool has_stencil_export;
149    bool has_texture_multisample;
150    bool has_tex_lz;
151    bool has_txf_txq;
152    bool has_sample_shading;
153    bool cube_as_2darray;
154    bool has_texrect;
155    bool cached_all_shaders;
156 
157    /* The Draw module overrides these functions.
158     * Always create the blitter before Draw. */
159    void   (*bind_fs_state)(struct pipe_context *, void *);
160    void   (*delete_fs_state)(struct pipe_context *, void *);
161 };
162 
util_blitter_create(struct pipe_context * pipe)163 struct blitter_context *util_blitter_create(struct pipe_context *pipe)
164 {
165    struct blitter_context_priv *ctx;
166    struct pipe_blend_state blend;
167    struct pipe_depth_stencil_alpha_state dsa;
168    struct pipe_rasterizer_state rs_state;
169    struct pipe_sampler_state sampler_state;
170    struct pipe_vertex_element velem[2];
171    unsigned i, j;
172 
173    ctx = CALLOC_STRUCT(blitter_context_priv);
174    if (!ctx)
175       return NULL;
176 
177    ctx->base.pipe = pipe;
178    ctx->base.draw_rectangle = util_blitter_draw_rectangle;
179 
180    ctx->bind_fs_state = pipe->bind_fs_state;
181    ctx->delete_fs_state = pipe->delete_fs_state;
182 
183    /* init state objects for them to be considered invalid */
184    ctx->base.saved_blend_state = INVALID_PTR;
185    ctx->base.saved_dsa_state = INVALID_PTR;
186    ctx->base.saved_rs_state = INVALID_PTR;
187    ctx->base.saved_fs = INVALID_PTR;
188    ctx->base.saved_vs = INVALID_PTR;
189    ctx->base.saved_gs = INVALID_PTR;
190    ctx->base.saved_velem_state = INVALID_PTR;
191    ctx->base.saved_fb_state.nr_cbufs = ~0;
192    ctx->base.saved_num_sampler_views = ~0;
193    ctx->base.saved_num_sampler_states = ~0;
194    ctx->base.saved_num_so_targets = ~0;
195 
196    ctx->has_geometry_shader =
197       pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY,
198                                      PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0;
199 
200    ctx->has_tessellation =
201       pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_TESS_CTRL,
202                                      PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0;
203 
204    ctx->has_stream_out =
205       pipe->screen->get_param(pipe->screen,
206                               PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0;
207 
208    ctx->has_stencil_export =
209          pipe->screen->get_param(pipe->screen,
210                                  PIPE_CAP_SHADER_STENCIL_EXPORT);
211 
212    ctx->has_texture_multisample =
213       pipe->screen->get_param(pipe->screen, PIPE_CAP_TEXTURE_MULTISAMPLE);
214 
215    ctx->has_tex_lz = pipe->screen->get_param(pipe->screen,
216                                              PIPE_CAP_TGSI_TEX_TXF_LZ);
217    ctx->has_txf_txq = pipe->screen->get_param(pipe->screen,
218                                               PIPE_CAP_GLSL_FEATURE_LEVEL) >= 130;
219    ctx->has_sample_shading = pipe->screen->get_param(pipe->screen,
220                                                      PIPE_CAP_SAMPLE_SHADING);
221    ctx->cube_as_2darray = pipe->screen->get_param(pipe->screen,
222                                                   PIPE_CAP_SAMPLER_VIEW_TARGET);
223    ctx->has_texrect = pipe->screen->get_param(pipe->screen, PIPE_CAP_TEXRECT);
224 
225    /* blend state objects */
226    memset(&blend, 0, sizeof(blend));
227 
228    for (i = 0; i <= PIPE_MASK_RGBA; i++) {
229       for (j = 0; j < 2; j++) {
230          memset(&blend.rt[0], 0, sizeof(blend.rt[0]));
231          blend.rt[0].colormask = i;
232          if (j) {
233             blend.rt[0].blend_enable = 1;
234             blend.rt[0].rgb_func = PIPE_BLEND_ADD;
235             blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
236             blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
237             blend.rt[0].alpha_func = PIPE_BLEND_ADD;
238             blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
239             blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
240          }
241          ctx->blend[i][j] = pipe->create_blend_state(pipe, &blend);
242       }
243    }
244 
245    /* depth stencil alpha state objects */
246    memset(&dsa, 0, sizeof(dsa));
247    ctx->dsa_keep_depth_stencil =
248       pipe->create_depth_stencil_alpha_state(pipe, &dsa);
249 
250    dsa.depth_enabled = 1;
251    dsa.depth_writemask = 1;
252    dsa.depth_func = PIPE_FUNC_ALWAYS;
253    ctx->dsa_write_depth_keep_stencil =
254       pipe->create_depth_stencil_alpha_state(pipe, &dsa);
255 
256    dsa.stencil[0].enabled = 1;
257    dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
258    dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
259    dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
260    dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
261    dsa.stencil[0].valuemask = 0xff;
262    dsa.stencil[0].writemask = 0xff;
263    ctx->dsa_write_depth_stencil =
264       pipe->create_depth_stencil_alpha_state(pipe, &dsa);
265 
266    dsa.depth_enabled = 0;
267    dsa.depth_writemask = 0;
268    ctx->dsa_keep_depth_write_stencil =
269       pipe->create_depth_stencil_alpha_state(pipe, &dsa);
270 
271    /* sampler state */
272    memset(&sampler_state, 0, sizeof(sampler_state));
273    sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
274    sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
275    sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
276    sampler_state.unnormalized_coords = 0;
277    ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state);
278    if (ctx->has_texrect) {
279       sampler_state.unnormalized_coords = 1;
280       ctx->sampler_state_rect = pipe->create_sampler_state(pipe, &sampler_state);
281    }
282 
283    sampler_state.min_img_filter = PIPE_TEX_FILTER_LINEAR;
284    sampler_state.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
285    sampler_state.unnormalized_coords = 0;
286    ctx->sampler_state_linear = pipe->create_sampler_state(pipe, &sampler_state);
287    if (ctx->has_texrect) {
288       sampler_state.unnormalized_coords = 1;
289       ctx->sampler_state_rect_linear = pipe->create_sampler_state(pipe, &sampler_state);
290    }
291 
292    /* rasterizer state */
293    memset(&rs_state, 0, sizeof(rs_state));
294    rs_state.cull_face = PIPE_FACE_NONE;
295    rs_state.half_pixel_center = 1;
296    rs_state.bottom_edge_rule = 1;
297    rs_state.flatshade = 1;
298    rs_state.depth_clip_near = 1;
299    rs_state.depth_clip_far = 1;
300 
301    unsigned scissor, msaa;
302    for (scissor = 0; scissor < 2; scissor++) {
303       for (msaa = 0; msaa < 2; msaa++) {
304          rs_state.scissor = scissor;
305          rs_state.multisample = msaa;
306          ctx->rs_state[scissor][msaa] =
307             pipe->create_rasterizer_state(pipe, &rs_state);
308       }
309    }
310 
311    if (ctx->has_stream_out) {
312       rs_state.scissor = rs_state.multisample = 0;
313       rs_state.rasterizer_discard = 1;
314       ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state);
315    }
316 
317    ctx->base.cb_slot = 0; /* 0 for now */
318 
319    /* vertex elements states */
320    memset(&velem[0], 0, sizeof(velem[0]) * 2);
321    for (i = 0; i < 2; i++) {
322       velem[i].src_offset = i * 4 * sizeof(float);
323       velem[i].src_stride = 8 * sizeof(float);
324       velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
325       velem[i].vertex_buffer_index = 0;
326    }
327    ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
328 
329    if (ctx->has_stream_out) {
330       static enum pipe_format formats[4] = {
331          PIPE_FORMAT_R32_UINT,
332          PIPE_FORMAT_R32G32_UINT,
333          PIPE_FORMAT_R32G32B32_UINT,
334          PIPE_FORMAT_R32G32B32A32_UINT
335       };
336 
337       for (i = 0; i < 4; i++) {
338          velem[0].src_format = formats[i];
339          velem[0].vertex_buffer_index = 0;
340          velem[0].src_stride = 0;
341          ctx->velem_state_readbuf[i] =
342                pipe->create_vertex_elements_state(pipe, 1, &velem[0]);
343       }
344    }
345 
346    ctx->has_layered =
347       pipe->screen->get_param(pipe->screen, PIPE_CAP_VS_INSTANCEID) &&
348       pipe->screen->get_param(pipe->screen, PIPE_CAP_VS_LAYER_VIEWPORT);
349 
350    /* set invariant vertex coordinates */
351    for (i = 0; i < 4; i++) {
352       ctx->vertices[i][0][2] = 0; /*v.z*/
353       ctx->vertices[i][0][3] = 1; /*v.w*/
354    }
355 
356    return &ctx->base;
357 }
358 
util_blitter_get_noop_blend_state(struct blitter_context * blitter)359 void *util_blitter_get_noop_blend_state(struct blitter_context *blitter)
360 {
361    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
362 
363    return ctx->blend[0][0];
364 }
365 
util_blitter_get_noop_dsa_state(struct blitter_context * blitter)366 void *util_blitter_get_noop_dsa_state(struct blitter_context *blitter)
367 {
368    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
369 
370    return ctx->dsa_keep_depth_stencil;
371 }
372 
util_blitter_get_discard_rasterizer_state(struct blitter_context * blitter)373 void *util_blitter_get_discard_rasterizer_state(struct blitter_context *blitter)
374 {
375    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
376 
377    return ctx->rs_discard_state;
378 }
379 
bind_vs_pos_only(struct blitter_context_priv * ctx,unsigned num_so_channels)380 static void bind_vs_pos_only(struct blitter_context_priv *ctx,
381                              unsigned num_so_channels)
382 {
383    struct pipe_context *pipe = ctx->base.pipe;
384    int index = num_so_channels ? num_so_channels - 1 : 0;
385 
386    if (!ctx->vs_pos_only[index]) {
387       struct pipe_stream_output_info so;
388       static const enum tgsi_semantic semantic_names[] =
389          { TGSI_SEMANTIC_POSITION };
390       const unsigned semantic_indices[] = { 0 };
391 
392       memset(&so, 0, sizeof(so));
393       so.num_outputs = 1;
394       so.output[0].num_components = num_so_channels;
395       so.stride[0] = num_so_channels;
396 
397       ctx->vs_pos_only[index] =
398          util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names,
399                                                      semantic_indices, false,
400                                                      false, &so);
401    }
402 
403    pipe->bind_vs_state(pipe, ctx->vs_pos_only[index]);
404 }
405 
get_vs_passthrough_pos_generic(struct blitter_context * blitter)406 static void *get_vs_passthrough_pos_generic(struct blitter_context *blitter)
407 {
408    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
409    struct pipe_context *pipe = ctx->base.pipe;
410 
411    if (!ctx->vs) {
412       static const enum tgsi_semantic semantic_names[] =
413          { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC };
414       const unsigned semantic_indices[] = { 0, 0 };
415       ctx->vs =
416          util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
417                                              semantic_indices, false);
418    }
419    return ctx->vs;
420 }
421 
get_vs_passthrough_pos(struct blitter_context * blitter)422 static void *get_vs_passthrough_pos(struct blitter_context *blitter)
423 {
424    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
425    struct pipe_context *pipe = ctx->base.pipe;
426 
427    if (!ctx->vs_nogeneric) {
428       static const enum tgsi_semantic semantic_names[] =
429          { TGSI_SEMANTIC_POSITION };
430       const unsigned semantic_indices[] = { 0 };
431 
432       ctx->vs_nogeneric =
433          util_make_vertex_passthrough_shader(pipe, 1,
434                                              semantic_names,
435                                              semantic_indices, false);
436    }
437    return ctx->vs_nogeneric;
438 }
439 
get_vs_layered(struct blitter_context * blitter)440 static void *get_vs_layered(struct blitter_context *blitter)
441 {
442    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
443    struct pipe_context *pipe = ctx->base.pipe;
444 
445    if (!ctx->vs_layered) {
446       ctx->vs_layered = util_make_layered_clear_vertex_shader(pipe);
447    }
448    return ctx->vs_layered;
449 }
450 
bind_fs_empty(struct blitter_context_priv * ctx)451 static void bind_fs_empty(struct blitter_context_priv *ctx)
452 {
453    struct pipe_context *pipe = ctx->base.pipe;
454 
455    if (!ctx->fs_empty) {
456       assert(!ctx->cached_all_shaders);
457       ctx->fs_empty = util_make_empty_fragment_shader(pipe);
458    }
459 
460    ctx->bind_fs_state(pipe, ctx->fs_empty);
461 }
462 
bind_fs_write_one_cbuf(struct blitter_context_priv * ctx)463 static void bind_fs_write_one_cbuf(struct blitter_context_priv *ctx)
464 {
465    struct pipe_context *pipe = ctx->base.pipe;
466 
467    if (!ctx->fs_write_one_cbuf) {
468       assert(!ctx->cached_all_shaders);
469       ctx->fs_write_one_cbuf =
470          util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
471                                                TGSI_INTERPOLATE_CONSTANT, false);
472    }
473 
474    ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf);
475 }
476 
bind_fs_clear_all_cbufs(struct blitter_context_priv * ctx)477 static void bind_fs_clear_all_cbufs(struct blitter_context_priv *ctx)
478 {
479    struct pipe_context *pipe = ctx->base.pipe;
480 
481    if (!ctx->fs_clear_all_cbufs) {
482       assert(!ctx->cached_all_shaders);
483       ctx->fs_clear_all_cbufs = util_make_fs_clear_all_cbufs(pipe);
484    }
485 
486    ctx->bind_fs_state(pipe, ctx->fs_clear_all_cbufs);
487 }
488 
util_blitter_destroy(struct blitter_context * blitter)489 void util_blitter_destroy(struct blitter_context *blitter)
490 {
491    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
492    struct pipe_context *pipe = blitter->pipe;
493    unsigned i, j, f;
494 
495    for (i = 0; i <= PIPE_MASK_RGBA; i++)
496       for (j = 0; j < 2; j++)
497          pipe->delete_blend_state(pipe, ctx->blend[i][j]);
498 
499    for (i = 0; i < ARRAY_SIZE(ctx->blend_clear); i++) {
500       if (ctx->blend_clear[i])
501          pipe->delete_blend_state(pipe, ctx->blend_clear[i]);
502    }
503    pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
504    pipe->delete_depth_stencil_alpha_state(pipe,
505                                           ctx->dsa_write_depth_keep_stencil);
506    pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
507    pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
508 
509    for (i = 0; i < ARRAY_SIZE(ctx->dsa_replicate_stencil_bit); i++) {
510       if (ctx->dsa_replicate_stencil_bit[i])
511          pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_replicate_stencil_bit[i]);
512    }
513 
514    unsigned scissor, msaa;
515    for (scissor = 0; scissor < 2; scissor++) {
516       for (msaa = 0; msaa < 2; msaa++) {
517          pipe->delete_rasterizer_state(pipe, ctx->rs_state[scissor][msaa]);
518       }
519    }
520 
521    if (ctx->rs_discard_state)
522       pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state);
523    if (ctx->vs)
524       pipe->delete_vs_state(pipe, ctx->vs);
525    if (ctx->vs_nogeneric)
526       pipe->delete_vs_state(pipe, ctx->vs_nogeneric);
527    for (i = 0; i < 4; i++)
528       if (ctx->vs_pos_only[i])
529          pipe->delete_vs_state(pipe, ctx->vs_pos_only[i]);
530    if (ctx->vs_layered)
531       pipe->delete_vs_state(pipe, ctx->vs_layered);
532    pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
533    for (i = 0; i < 4; i++) {
534       if (ctx->velem_state_readbuf[i]) {
535          pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf[i]);
536       }
537    }
538 
539    for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
540       for (unsigned type = 0; type < ARRAY_SIZE(ctx->fs_texfetch_col); ++type) {
541          for (unsigned inst = 0; inst < 2; inst++) {
542             if (ctx->fs_texfetch_col[type][i][inst])
543                ctx->delete_fs_state(pipe, ctx->fs_texfetch_col[type][i][inst]);
544          }
545          if (ctx->fs_texfetch_col_msaa[type][i])
546             ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa[type][i]);
547       }
548 
549       for (unsigned inst = 0; inst < 2; inst++) {
550          if (ctx->fs_texfetch_depth[i][inst])
551             ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth[i][inst]);
552          if (ctx->fs_texfetch_depthstencil[i][inst])
553             ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i][inst]);
554          if (ctx->fs_texfetch_stencil[i][inst])
555             ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i][inst]);
556       }
557 
558       for (unsigned ss = 0; ss < 2; ss++) {
559          if (ctx->fs_texfetch_depth_msaa[i][ss])
560             ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth_msaa[i][ss]);
561          if (ctx->fs_texfetch_depthstencil_msaa[i][ss])
562             ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil_msaa[i][ss]);
563          if (ctx->fs_texfetch_stencil_msaa[i][ss])
564             ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil_msaa[i][ss]);
565       }
566 
567       for (j = 0; j< ARRAY_SIZE(ctx->fs_resolve[i]); j++)
568          for (f = 0; f < 2; f++)
569             if (ctx->fs_resolve[i][j][f])
570                ctx->delete_fs_state(pipe, ctx->fs_resolve[i][j][f]);
571    }
572 
573    for (i = 0; i < ARRAY_SIZE(ctx->fs_pack_color_zs); i++) {
574       for (j = 0; j < ARRAY_SIZE(ctx->fs_pack_color_zs[0]); j++) {
575          if (ctx->fs_pack_color_zs[i][j])
576             ctx->delete_fs_state(pipe, ctx->fs_pack_color_zs[i][j]);
577       }
578    }
579 
580    if (ctx->fs_empty)
581       ctx->delete_fs_state(pipe, ctx->fs_empty);
582    if (ctx->fs_write_one_cbuf)
583       ctx->delete_fs_state(pipe, ctx->fs_write_one_cbuf);
584    if (ctx->fs_clear_all_cbufs)
585       ctx->delete_fs_state(pipe, ctx->fs_clear_all_cbufs);
586 
587    for (i = 0; i < ARRAY_SIZE(ctx->fs_stencil_blit_fallback); ++i)
588       if (ctx->fs_stencil_blit_fallback[i])
589          ctx->delete_fs_state(pipe, ctx->fs_stencil_blit_fallback[i]);
590 
591    if (ctx->sampler_state_rect_linear)
592       pipe->delete_sampler_state(pipe, ctx->sampler_state_rect_linear);
593    if (ctx->sampler_state_rect)
594       pipe->delete_sampler_state(pipe, ctx->sampler_state_rect);
595    pipe->delete_sampler_state(pipe, ctx->sampler_state_linear);
596    pipe->delete_sampler_state(pipe, ctx->sampler_state);
597    FREE(ctx);
598 }
599 
util_blitter_set_texture_multisample(struct blitter_context * blitter,bool supported)600 void util_blitter_set_texture_multisample(struct blitter_context *blitter,
601                                           bool supported)
602 {
603    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
604 
605    ctx->has_texture_multisample = supported;
606 }
607 
util_blitter_set_running_flag(struct blitter_context * blitter)608 void util_blitter_set_running_flag(struct blitter_context *blitter)
609 {
610    if (blitter->running) {
611       _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", __LINE__);
612    }
613    blitter->running = true;
614 
615    blitter->pipe->set_active_query_state(blitter->pipe, false);
616 }
617 
util_blitter_unset_running_flag(struct blitter_context * blitter)618 void util_blitter_unset_running_flag(struct blitter_context *blitter)
619 {
620    if (!blitter->running) {
621       _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
622                     __LINE__);
623    }
624    blitter->running = false;
625 
626    blitter->pipe->set_active_query_state(blitter->pipe, true);
627 }
628 
blitter_check_saved_vertex_states(ASSERTED struct blitter_context_priv * ctx)629 static void blitter_check_saved_vertex_states(ASSERTED struct blitter_context_priv *ctx)
630 {
631    assert(ctx->base.saved_vs != INVALID_PTR);
632    assert(!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR);
633    assert(!ctx->has_tessellation || ctx->base.saved_tcs != INVALID_PTR);
634    assert(!ctx->has_tessellation || ctx->base.saved_tes != INVALID_PTR);
635    assert(!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0u);
636    assert(ctx->base.saved_rs_state != INVALID_PTR);
637 }
638 
util_blitter_restore_vertex_states(struct blitter_context * blitter)639 void util_blitter_restore_vertex_states(struct blitter_context *blitter)
640 {
641    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
642    struct pipe_context *pipe = ctx->base.pipe;
643    unsigned i;
644 
645    /* Vertex elements. */
646    if (ctx->base.saved_velem_state != INVALID_PTR) {
647       pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state);
648       ctx->base.saved_velem_state = INVALID_PTR;
649    }
650 
651    /* Vertex buffer. */
652    if (ctx->base.saved_num_vb) {
653       pipe->set_vertex_buffers(pipe, ctx->base.saved_num_vb,
654                                ctx->base.saved_vertex_buffers);
655       memset(ctx->base.saved_vertex_buffers, 0,
656              sizeof(ctx->base.saved_vertex_buffers[0]) * ctx->base.saved_num_vb);
657       ctx->base.saved_num_vb = 0;
658    }
659 
660    /* Vertex shader. */
661    pipe->bind_vs_state(pipe, ctx->base.saved_vs);
662    ctx->base.saved_vs = INVALID_PTR;
663 
664    /* Geometry shader. */
665    if (ctx->has_geometry_shader) {
666       pipe->bind_gs_state(pipe, ctx->base.saved_gs);
667       ctx->base.saved_gs = INVALID_PTR;
668    }
669 
670    if (ctx->has_tessellation) {
671       pipe->bind_tcs_state(pipe, ctx->base.saved_tcs);
672       pipe->bind_tes_state(pipe, ctx->base.saved_tes);
673       ctx->base.saved_tcs = INVALID_PTR;
674       ctx->base.saved_tes = INVALID_PTR;
675    }
676 
677    /* Stream outputs. */
678    if (ctx->has_stream_out) {
679       unsigned offsets[PIPE_MAX_SO_BUFFERS];
680       for (i = 0; i < ctx->base.saved_num_so_targets; i++)
681          offsets[i] = (unsigned)-1;
682       pipe->set_stream_output_targets(pipe,
683                                       ctx->base.saved_num_so_targets,
684                                       ctx->base.saved_so_targets, offsets);
685 
686       for (i = 0; i < ctx->base.saved_num_so_targets; i++)
687          pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL);
688 
689       ctx->base.saved_num_so_targets = ~0;
690    }
691 
692    /* Rasterizer. */
693    pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state);
694    ctx->base.saved_rs_state = INVALID_PTR;
695 }
696 
blitter_check_saved_fragment_states(ASSERTED struct blitter_context_priv * ctx)697 static void blitter_check_saved_fragment_states(ASSERTED struct blitter_context_priv *ctx)
698 {
699    assert(ctx->base.saved_fs != INVALID_PTR);
700    assert(ctx->base.saved_dsa_state != INVALID_PTR);
701    assert(ctx->base.saved_blend_state != INVALID_PTR);
702 }
703 
util_blitter_restore_fragment_states(struct blitter_context * blitter)704 void util_blitter_restore_fragment_states(struct blitter_context *blitter)
705 {
706    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
707    struct pipe_context *pipe = ctx->base.pipe;
708 
709    /* Fragment shader. */
710    ctx->bind_fs_state(pipe, ctx->base.saved_fs);
711    ctx->base.saved_fs = INVALID_PTR;
712 
713    /* Depth, stencil, alpha. */
714    pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state);
715    ctx->base.saved_dsa_state = INVALID_PTR;
716 
717    /* Blend state. */
718    pipe->bind_blend_state(pipe, ctx->base.saved_blend_state);
719    ctx->base.saved_blend_state = INVALID_PTR;
720 
721    /* Sample mask. */
722    if (ctx->base.is_sample_mask_saved) {
723       pipe->set_sample_mask(pipe, ctx->base.saved_sample_mask);
724       ctx->base.is_sample_mask_saved = false;
725    }
726 
727    if (ctx->base.saved_min_samples != ~0 && pipe->set_min_samples)
728       pipe->set_min_samples(pipe, ctx->base.saved_min_samples);
729    ctx->base.saved_min_samples = ~0;
730 
731    /* Miscellaneous states. */
732    /* XXX check whether these are saved and whether they need to be restored
733     * (depending on the operation) */
734    pipe->set_stencil_ref(pipe, ctx->base.saved_stencil_ref);
735 
736    if (!blitter->skip_viewport_restore)
737       pipe->set_viewport_states(pipe, 0, 1, &ctx->base.saved_viewport);
738 
739    if (blitter->saved_num_window_rectangles) {
740       pipe->set_window_rectangles(pipe,
741                                   blitter->saved_window_rectangles_include,
742                                   blitter->saved_num_window_rectangles,
743                                   blitter->saved_window_rectangles);
744    }
745 }
746 
blitter_check_saved_fb_state(ASSERTED struct blitter_context_priv * ctx)747 static void blitter_check_saved_fb_state(ASSERTED struct blitter_context_priv *ctx)
748 {
749    assert(ctx->base.saved_fb_state.nr_cbufs != (uint8_t) ~0);
750 }
751 
blitter_disable_render_cond(struct blitter_context_priv * ctx)752 static void blitter_disable_render_cond(struct blitter_context_priv *ctx)
753 {
754    struct pipe_context *pipe = ctx->base.pipe;
755 
756    if (ctx->base.saved_render_cond_query) {
757       pipe->render_condition(pipe, NULL, false, 0);
758    }
759 }
760 
util_blitter_restore_render_cond(struct blitter_context * blitter)761 void util_blitter_restore_render_cond(struct blitter_context *blitter)
762 {
763    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
764    struct pipe_context *pipe = ctx->base.pipe;
765 
766    if (ctx->base.saved_render_cond_query) {
767       pipe->render_condition(pipe, ctx->base.saved_render_cond_query,
768                              ctx->base.saved_render_cond_cond,
769                              ctx->base.saved_render_cond_mode);
770       ctx->base.saved_render_cond_query = NULL;
771    }
772 }
773 
util_blitter_restore_fb_state(struct blitter_context * blitter)774 void util_blitter_restore_fb_state(struct blitter_context *blitter)
775 {
776    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
777    struct pipe_context *pipe = ctx->base.pipe;
778 
779    pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state);
780    util_unreference_framebuffer_state(&ctx->base.saved_fb_state);
781 }
782 
blitter_check_saved_textures(ASSERTED struct blitter_context_priv * ctx)783 static void blitter_check_saved_textures(ASSERTED struct blitter_context_priv *ctx)
784 {
785    assert(ctx->base.saved_num_sampler_states != ~0u);
786    assert(ctx->base.saved_num_sampler_views != ~0u);
787 }
788 
util_blitter_restore_textures_internal(struct blitter_context * blitter,unsigned count)789 static void util_blitter_restore_textures_internal(struct blitter_context *blitter, unsigned count)
790 {
791    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
792    struct pipe_context *pipe = ctx->base.pipe;
793    unsigned i;
794 
795    /* Fragment sampler states. */
796    void *states[2] = {NULL};
797    assert(count <= ARRAY_SIZE(states));
798    if (ctx->base.saved_num_sampler_states)
799       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0,
800                                 ctx->base.saved_num_sampler_states,
801                                 ctx->base.saved_sampler_states);
802    else if (count)
803       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0,
804                                 count,
805                                 states);
806 
807    ctx->base.saved_num_sampler_states = ~0;
808 
809    /* Fragment sampler views. */
810    if (ctx->base.saved_num_sampler_views)
811       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0,
812                               ctx->base.saved_num_sampler_views, 0, true,
813                               ctx->base.saved_sampler_views);
814    else if (count)
815       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0,
816                               0, count, true,
817                               NULL);
818 
819    /* Just clear them to NULL because set_sampler_views(take_ownership = true). */
820    for (i = 0; i < ctx->base.saved_num_sampler_views; i++)
821       ctx->base.saved_sampler_views[i] = NULL;
822 
823    ctx->base.saved_num_sampler_views = ~0;
824 }
825 
util_blitter_restore_textures(struct blitter_context * blitter)826 void util_blitter_restore_textures(struct blitter_context *blitter)
827 {
828    util_blitter_restore_textures_internal(blitter, 0);
829 }
830 
util_blitter_restore_constant_buffer_state(struct blitter_context * blitter)831 void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter)
832 {
833    struct pipe_context *pipe = blitter->pipe;
834 
835    pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
836                              true, &blitter->saved_fs_constant_buffer);
837    blitter->saved_fs_constant_buffer.buffer = NULL;
838 }
839 
blitter_set_rectangle(struct blitter_context_priv * ctx,int x1,int y1,int x2,int y2,float depth)840 static void blitter_set_rectangle(struct blitter_context_priv *ctx,
841                                   int x1, int y1, int x2, int y2,
842                                   float depth)
843 {
844    /* set vertex positions */
845    ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/
846    ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/
847 
848    ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/
849    ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/
850 
851    ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/
852    ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/
853 
854    ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/
855    ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/
856 
857    for (unsigned i = 0; i < 4; ++i)
858       ctx->vertices[i][0][2] = depth;
859 
860    /* viewport */
861    struct pipe_viewport_state viewport;
862    viewport.scale[0] = 0.5f * ctx->dst_width;
863    viewport.scale[1] = 0.5f * ctx->dst_height;
864    viewport.scale[2] = 1.0f;
865    viewport.translate[0] = 0.5f * ctx->dst_width;
866    viewport.translate[1] = 0.5f * ctx->dst_height;
867    viewport.translate[2] = 0.0f;
868    viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;
869    viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;
870    viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;
871    viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;
872    ctx->base.pipe->set_viewport_states(ctx->base.pipe, 0, 1, &viewport);
873 }
874 
blitter_set_clear_color(struct blitter_context_priv * ctx,const float color[4])875 static void blitter_set_clear_color(struct blitter_context_priv *ctx,
876                                     const float color[4])
877 {
878    int i;
879 
880    if (color) {
881       for (i = 0; i < 4; i++)
882          memcpy(&ctx->vertices[i][1][0], color, sizeof(uint32_t) * 4);
883    } else {
884       for (i = 0; i < 4; i++)
885          memset(&ctx->vertices[i][1][0], 0, sizeof(uint32_t) * 4);
886    }
887 }
888 
get_texcoords(struct pipe_sampler_view * src,unsigned src_width0,unsigned src_height0,int x1,int y1,int x2,int y2,float layer,unsigned sample,bool uses_txf,union blitter_attrib * out)889 static void get_texcoords(struct pipe_sampler_view *src,
890                           unsigned src_width0, unsigned src_height0,
891                           int x1, int y1, int x2, int y2,
892                           float layer, unsigned sample,
893                           bool uses_txf, union blitter_attrib *out)
894 {
895    unsigned level = src->u.tex.first_level;
896    bool normalized = !uses_txf &&
897                         src->target != PIPE_TEXTURE_RECT &&
898                         src->texture->nr_samples <= 1;
899 
900    if (normalized) {
901       out->texcoord.x1 = x1 / (float)u_minify(src_width0,  level);
902       out->texcoord.y1 = y1 / (float)u_minify(src_height0, level);
903       out->texcoord.x2 = x2 / (float)u_minify(src_width0,  level);
904       out->texcoord.y2 = y2 / (float)u_minify(src_height0, level);
905    } else {
906       out->texcoord.x1 = x1;
907       out->texcoord.y1 = y1;
908       out->texcoord.x2 = x2;
909       out->texcoord.y2 = y2;
910    }
911 
912    out->texcoord.z = 0;
913    out->texcoord.w = 0;
914 
915    /* Set the layer. */
916    switch (src->target) {
917    case PIPE_TEXTURE_3D:
918       {
919          float r = layer;
920 
921          if (!uses_txf)
922             r /= u_minify(src->texture->depth0, src->u.tex.first_level);
923 
924          out->texcoord.z = r;
925       }
926       break;
927 
928    case PIPE_TEXTURE_1D_ARRAY:
929       out->texcoord.y1 = out->texcoord.y2 = layer;
930       break;
931 
932    case PIPE_TEXTURE_2D_ARRAY:
933       out->texcoord.z = layer;
934       out->texcoord.w = sample;
935       break;
936 
937    case PIPE_TEXTURE_CUBE_ARRAY:
938       out->texcoord.w = (unsigned)layer / 6;
939       break;
940 
941    case PIPE_TEXTURE_2D:
942       out->texcoord.w = sample;
943       break;
944 
945    default:;
946    }
947 }
948 
blitter_set_dst_dimensions(struct blitter_context_priv * ctx,unsigned width,unsigned height)949 static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
950                                        unsigned width, unsigned height)
951 {
952    ctx->dst_width = width;
953    ctx->dst_height = height;
954 }
955 
set_texcoords_in_vertices(const union blitter_attrib * attrib,float * out,unsigned stride)956 static void set_texcoords_in_vertices(const union blitter_attrib *attrib,
957                                       float *out, unsigned stride)
958 {
959    out[0] = attrib->texcoord.x1;
960    out[1] = attrib->texcoord.y1;
961    out += stride;
962    out[0] = attrib->texcoord.x2;
963    out[1] = attrib->texcoord.y1;
964    out += stride;
965    out[0] = attrib->texcoord.x2;
966    out[1] = attrib->texcoord.y2;
967    out += stride;
968    out[0] = attrib->texcoord.x1;
969    out[1] = attrib->texcoord.y2;
970 }
971 
blitter_get_fs_texfetch_col(struct blitter_context_priv * ctx,enum pipe_format src_format,enum pipe_format dst_format,enum pipe_texture_target target,unsigned src_nr_samples,unsigned dst_nr_samples,unsigned filter,bool use_txf)972 static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
973                                          enum pipe_format src_format,
974                                          enum pipe_format dst_format,
975                                          enum pipe_texture_target target,
976                                          unsigned src_nr_samples,
977                                          unsigned dst_nr_samples,
978                                          unsigned filter,
979                                          bool use_txf)
980 {
981    struct pipe_context *pipe = ctx->base.pipe;
982    enum tgsi_texture_type tgsi_tex =
983       util_pipe_tex_to_tgsi_tex(target, src_nr_samples);
984    enum tgsi_return_type stype;
985    enum tgsi_return_type dtype;
986    unsigned type;
987 
988    assert(target < PIPE_MAX_TEXTURE_TYPES);
989 
990    if (util_format_is_pure_uint(src_format)) {
991       stype = TGSI_RETURN_TYPE_UINT;
992       if (util_format_is_pure_uint(dst_format)) {
993          dtype = TGSI_RETURN_TYPE_UINT;
994          type = 0;
995       } else {
996          assert(util_format_is_pure_sint(dst_format));
997          dtype = TGSI_RETURN_TYPE_SINT;
998          type = 1;
999       }
1000    } else if (util_format_is_pure_sint(src_format)) {
1001       stype = TGSI_RETURN_TYPE_SINT;
1002       if (util_format_is_pure_sint(dst_format)) {
1003          dtype = TGSI_RETURN_TYPE_SINT;
1004          type = 2;
1005       } else {
1006          assert(util_format_is_pure_uint(dst_format));
1007          dtype = TGSI_RETURN_TYPE_UINT;
1008          type = 3;
1009       }
1010    } else {
1011       assert(!util_format_is_pure_uint(dst_format) &&
1012              !util_format_is_pure_sint(dst_format));
1013       dtype = stype = TGSI_RETURN_TYPE_FLOAT;
1014       type = 4;
1015    }
1016 
1017    if (src_nr_samples > 1) {
1018       void **shader;
1019 
1020       /* OpenGL requires that integer textures just copy 1 sample instead
1021        * of averaging.
1022        */
1023       if (dst_nr_samples <= 1 &&
1024           stype != TGSI_RETURN_TYPE_UINT &&
1025           stype != TGSI_RETURN_TYPE_SINT) {
1026          /* The destination has one sample, so we'll do color resolve. */
1027          unsigned index = GET_MSAA_RESOLVE_FS_IDX(src_nr_samples);
1028 
1029          assert(filter < 2);
1030 
1031          shader = &ctx->fs_resolve[target][index][filter];
1032 
1033          if (!*shader) {
1034             assert(!ctx->cached_all_shaders);
1035             if (filter == PIPE_TEX_FILTER_LINEAR) {
1036                *shader = util_make_fs_msaa_resolve_bilinear(pipe, tgsi_tex,
1037                                                    src_nr_samples, ctx->has_txf_txq);
1038             }
1039             else {
1040                *shader = util_make_fs_msaa_resolve(pipe, tgsi_tex,
1041                                                    src_nr_samples, ctx->has_txf_txq);
1042             }
1043          }
1044       }
1045       else {
1046          /* The destination has multiple samples, we'll do
1047           * an MSAA->MSAA copy.
1048           */
1049          shader = &ctx->fs_texfetch_col_msaa[type][target];
1050 
1051          /* Create the fragment shader on-demand. */
1052          if (!*shader) {
1053             assert(!ctx->cached_all_shaders);
1054             *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex, stype, dtype,
1055                                                    ctx->has_sample_shading,
1056                                                    ctx->has_txf_txq);
1057          }
1058       }
1059 
1060       return *shader;
1061    } else {
1062       void **shader;
1063 
1064       if (use_txf)
1065          shader = &ctx->fs_texfetch_col[type][target][1];
1066       else
1067          shader = &ctx->fs_texfetch_col[type][target][0];
1068 
1069       /* Create the fragment shader on-demand. */
1070       if (!*shader) {
1071          assert(!ctx->cached_all_shaders);
1072          *shader = util_make_fragment_tex_shader(pipe, tgsi_tex,
1073                                                  stype, dtype,
1074                                                  ctx->has_tex_lz, use_txf);
1075       }
1076 
1077       return *shader;
1078    }
1079 }
1080 
1081 static inline
blitter_get_fs_pack_color_zs(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned nr_samples,enum pipe_format zs_format,bool dst_is_color)1082 void *blitter_get_fs_pack_color_zs(struct blitter_context_priv *ctx,
1083                                    enum pipe_texture_target target,
1084                                    unsigned nr_samples,
1085                                    enum pipe_format zs_format,
1086                                    bool dst_is_color)
1087 {
1088    struct pipe_context *pipe = ctx->base.pipe;
1089    enum tgsi_texture_type tgsi_tex =
1090       util_pipe_tex_to_tgsi_tex(target, nr_samples);
1091    int format_index = zs_format == PIPE_FORMAT_Z24_UNORM_S8_UINT ? 0 :
1092                       zs_format == PIPE_FORMAT_S8_UINT_Z24_UNORM ? 1 :
1093                       zs_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ? 2 :
1094                       zs_format == PIPE_FORMAT_Z24X8_UNORM ? 3 :
1095                       zs_format == PIPE_FORMAT_X8Z24_UNORM ? 4 : -1;
1096 
1097    if (format_index == -1) {
1098       assert(0);
1099       return NULL;
1100    }
1101 
1102    /* The first 5 shaders pack ZS to color, the last 5 shaders unpack color
1103     * to ZS.
1104     */
1105    if (dst_is_color)
1106       format_index += 5;
1107 
1108    void **shader = &ctx->fs_pack_color_zs[tgsi_tex][format_index];
1109 
1110    /* Create the fragment shader on-demand. */
1111    if (!*shader) {
1112       assert(!ctx->cached_all_shaders);
1113       *shader = util_make_fs_pack_color_zs(pipe, tgsi_tex, zs_format,
1114                                            dst_is_color);
1115    }
1116    return *shader;
1117 }
1118 
1119 static inline
blitter_get_fs_texfetch_depth(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned src_samples,unsigned dst_samples,bool use_txf)1120 void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
1121                                     enum pipe_texture_target target,
1122                                     unsigned src_samples, unsigned dst_samples,
1123                                     bool use_txf)
1124 {
1125    struct pipe_context *pipe = ctx->base.pipe;
1126 
1127    assert(target < PIPE_MAX_TEXTURE_TYPES);
1128 
1129    if (src_samples > 1) {
1130       bool sample_shading = ctx->has_sample_shading && src_samples > 1 &&
1131                             src_samples == dst_samples;
1132       void **shader = &ctx->fs_texfetch_depth_msaa[target][sample_shading];
1133 
1134       /* Create the fragment shader on-demand. */
1135       if (!*shader) {
1136          enum tgsi_texture_type tgsi_tex;
1137          assert(!ctx->cached_all_shaders);
1138          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, src_samples);
1139          *shader = util_make_fs_blit_msaa_depth(pipe, tgsi_tex, sample_shading,
1140                                                 ctx->has_txf_txq);
1141       }
1142 
1143       return *shader;
1144    } else {
1145       void **shader;
1146 
1147       if (use_txf)
1148          shader = &ctx->fs_texfetch_depth[target][1];
1149       else
1150          shader = &ctx->fs_texfetch_depth[target][0];
1151 
1152       /* Create the fragment shader on-demand. */
1153       if (!*shader) {
1154          enum tgsi_texture_type tgsi_tex;
1155          assert(!ctx->cached_all_shaders);
1156          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1157          *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_Z, tgsi_tex,
1158                                         ctx->has_tex_lz, use_txf);
1159       }
1160 
1161       return *shader;
1162    }
1163 }
1164 
1165 static inline
blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned src_samples,unsigned dst_samples,bool use_txf)1166 void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
1167                                            enum pipe_texture_target target,
1168                                            unsigned src_samples,
1169                                            unsigned dst_samples, bool use_txf)
1170 {
1171    struct pipe_context *pipe = ctx->base.pipe;
1172 
1173    assert(target < PIPE_MAX_TEXTURE_TYPES);
1174 
1175    if (src_samples > 1) {
1176       bool sample_shading = ctx->has_sample_shading && src_samples > 1 &&
1177                             src_samples == dst_samples;
1178       void **shader = &ctx->fs_texfetch_depthstencil_msaa[target][sample_shading];
1179 
1180       /* Create the fragment shader on-demand. */
1181       if (!*shader) {
1182          enum tgsi_texture_type tgsi_tex;
1183          assert(!ctx->cached_all_shaders);
1184          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, src_samples);
1185          *shader = util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex,
1186                                                        sample_shading,
1187                                                        ctx->has_txf_txq);
1188       }
1189 
1190       return *shader;
1191    } else {
1192       void **shader;
1193 
1194       if (use_txf)
1195          shader = &ctx->fs_texfetch_depthstencil[target][1];
1196       else
1197          shader = &ctx->fs_texfetch_depthstencil[target][0];
1198 
1199       /* Create the fragment shader on-demand. */
1200       if (!*shader) {
1201          enum tgsi_texture_type tgsi_tex;
1202          assert(!ctx->cached_all_shaders);
1203          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1204          *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_ZS, tgsi_tex,
1205                                         ctx->has_tex_lz, use_txf);
1206       }
1207 
1208       return *shader;
1209    }
1210 }
1211 
1212 static inline
blitter_get_fs_texfetch_stencil(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned src_samples,unsigned dst_samples,bool use_txf)1213 void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
1214                                       enum pipe_texture_target target,
1215                                       unsigned src_samples, unsigned dst_samples,
1216                                       bool use_txf)
1217 {
1218    struct pipe_context *pipe = ctx->base.pipe;
1219 
1220    assert(target < PIPE_MAX_TEXTURE_TYPES);
1221 
1222    if (src_samples > 1) {
1223       bool sample_shading = ctx->has_sample_shading && src_samples > 1 &&
1224                             src_samples == dst_samples;
1225       void **shader = &ctx->fs_texfetch_stencil_msaa[target][sample_shading];
1226 
1227       /* Create the fragment shader on-demand. */
1228       if (!*shader) {
1229          enum tgsi_texture_type tgsi_tex;
1230          assert(!ctx->cached_all_shaders);
1231          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, src_samples);
1232          *shader = util_make_fs_blit_msaa_stencil(pipe, tgsi_tex,
1233                                                   sample_shading,
1234                                                   ctx->has_txf_txq);
1235       }
1236 
1237       return *shader;
1238    } else {
1239       void **shader;
1240 
1241       if (use_txf)
1242          shader = &ctx->fs_texfetch_stencil[target][1];
1243       else
1244          shader = &ctx->fs_texfetch_stencil[target][0];
1245 
1246       /* Create the fragment shader on-demand. */
1247       if (!*shader) {
1248          enum tgsi_texture_type tgsi_tex;
1249          assert(!ctx->cached_all_shaders);
1250          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1251          *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_S, tgsi_tex,
1252                                         ctx->has_tex_lz, use_txf);
1253       }
1254 
1255       return *shader;
1256    }
1257 }
1258 
1259 
1260 /**
1261  * Generate and save all fragment shaders that we will ever need for
1262  * blitting.  Drivers which use the 'draw' fallbacks will typically use
1263  * this to make sure we generate/use shaders that don't go through the
1264  * draw module's wrapper functions.
1265  */
util_blitter_cache_all_shaders(struct blitter_context * blitter)1266 void util_blitter_cache_all_shaders(struct blitter_context *blitter)
1267 {
1268    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1269    struct pipe_context *pipe = blitter->pipe;
1270    struct pipe_screen *screen = pipe->screen;
1271    unsigned samples, j, f, target, max_samples, use_txf;
1272    bool has_arraytex, has_cubearraytex;
1273 
1274    max_samples = ctx->has_texture_multisample ? 2 : 1;
1275    has_arraytex = screen->get_param(screen,
1276                                     PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) != 0;
1277    has_cubearraytex = screen->get_param(screen,
1278                                     PIPE_CAP_CUBE_MAP_ARRAY) != 0;
1279 
1280    /* It only matters if i <= 1 or > 1. */
1281    for (samples = 1; samples <= max_samples; samples++) {
1282       for (target = PIPE_TEXTURE_1D; target < PIPE_MAX_TEXTURE_TYPES; target++) {
1283          for (use_txf = 0; use_txf <= ctx->has_txf_txq; use_txf++) {
1284             if (!has_arraytex &&
1285                 (target == PIPE_TEXTURE_1D_ARRAY ||
1286                  target == PIPE_TEXTURE_2D_ARRAY)) {
1287                continue;
1288             }
1289             if (!has_cubearraytex &&
1290                 (target == PIPE_TEXTURE_CUBE_ARRAY))
1291                continue;
1292             if (!ctx->has_texrect &&
1293                 (target == PIPE_TEXTURE_RECT))
1294                continue;
1295 
1296             if (samples > 1 &&
1297                 (target != PIPE_TEXTURE_2D &&
1298                  target != PIPE_TEXTURE_2D_ARRAY))
1299                continue;
1300 
1301             if (samples > 1 && use_txf)
1302                continue; /* TXF is the only option, use_txf has no effect */
1303 
1304             /* If samples == 1, the shaders read one texel. If samples >= 1,
1305              * they read one sample.
1306              */
1307             blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT,
1308                                         PIPE_FORMAT_R32_FLOAT, target,
1309                                         samples, samples, 0, use_txf);
1310             blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1311                                         PIPE_FORMAT_R32_UINT, target,
1312                                         samples, samples, 0, use_txf);
1313             blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1314                                         PIPE_FORMAT_R32_SINT, target,
1315                                         samples, samples, 0, use_txf);
1316             blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1317                                         PIPE_FORMAT_R32_SINT, target,
1318                                         samples, samples, 0, use_txf);
1319             blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1320                                         PIPE_FORMAT_R32_UINT, target,
1321                                         samples, samples, 0, use_txf);
1322             blitter_get_fs_texfetch_depth(ctx, target, samples, samples, use_txf);
1323             if (ctx->has_stencil_export) {
1324                blitter_get_fs_texfetch_depthstencil(ctx, target, samples, samples, use_txf);
1325                blitter_get_fs_texfetch_stencil(ctx, target, samples, samples, use_txf);
1326             }
1327 
1328             if (samples == 2) {
1329                blitter_get_fs_texfetch_depth(ctx, target, samples, 1, use_txf);
1330                if (ctx->has_stencil_export) {
1331                   blitter_get_fs_texfetch_depthstencil(ctx, target, samples, 1, use_txf);
1332                   blitter_get_fs_texfetch_stencil(ctx, target, samples, 1, use_txf);
1333                }
1334             }
1335 
1336             if (samples == 1)
1337                continue;
1338 
1339             /* MSAA resolve shaders. */
1340             for (j = 2; j < 32; j++) {
1341                if (!screen->is_format_supported(screen, PIPE_FORMAT_R32_FLOAT,
1342                                                 target, j, j,
1343                                                 PIPE_BIND_SAMPLER_VIEW)) {
1344                   continue;
1345                }
1346 
1347                for (f = 0; f < 2; f++) {
1348                   if (f != PIPE_TEX_FILTER_NEAREST && use_txf)
1349                      continue;
1350 
1351                   blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT,
1352                                               PIPE_FORMAT_R32_FLOAT, target,
1353                                               j, 1, f, use_txf);
1354                   blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1355                                               PIPE_FORMAT_R32_UINT, target,
1356                                               j, 1, f, use_txf);
1357                   blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1358                                               PIPE_FORMAT_R32_SINT, target,
1359                                               j, 1, f, use_txf);
1360                }
1361             }
1362          }
1363       }
1364    }
1365 
1366    ctx->fs_empty = util_make_empty_fragment_shader(pipe);
1367 
1368    ctx->fs_write_one_cbuf =
1369       util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
1370                                             TGSI_INTERPOLATE_CONSTANT, false);
1371 
1372    ctx->fs_clear_all_cbufs = util_make_fs_clear_all_cbufs(pipe);
1373 
1374    ctx->cached_all_shaders = true;
1375 }
1376 
blitter_set_common_draw_rect_state(struct blitter_context_priv * ctx,bool scissor,bool msaa)1377 static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx,
1378                                                bool scissor, bool msaa)
1379 {
1380    struct pipe_context *pipe = ctx->base.pipe;
1381 
1382    if (ctx->base.saved_num_window_rectangles)
1383       pipe->set_window_rectangles(pipe, false, 0, NULL);
1384 
1385    pipe->bind_rasterizer_state(pipe, ctx->rs_state[scissor][msaa]);
1386 
1387    if (ctx->has_geometry_shader)
1388       pipe->bind_gs_state(pipe, NULL);
1389    if (ctx->has_tessellation) {
1390       pipe->bind_tcs_state(pipe, NULL);
1391       pipe->bind_tes_state(pipe, NULL);
1392    }
1393    if (ctx->has_stream_out)
1394       pipe->set_stream_output_targets(pipe, 0, NULL, NULL);
1395 }
1396 
blitter_draw(struct blitter_context_priv * ctx,void * vertex_elements_cso,blitter_get_vs_func get_vs,int x1,int y1,int x2,int y2,float depth,unsigned num_instances)1397 static void blitter_draw(struct blitter_context_priv *ctx,
1398                          void *vertex_elements_cso,
1399                          blitter_get_vs_func get_vs,
1400                          int x1, int y1, int x2, int y2, float depth,
1401                          unsigned num_instances)
1402 {
1403    struct pipe_context *pipe = ctx->base.pipe;
1404    struct pipe_vertex_buffer vb = {0};
1405 
1406    blitter_set_rectangle(ctx, x1, y1, x2, y2, depth);
1407 
1408    u_upload_data(pipe->stream_uploader, 0, sizeof(ctx->vertices), 4, ctx->vertices,
1409                  &vb.buffer_offset, &vb.buffer.resource);
1410    if (!vb.buffer.resource)
1411       return;
1412    u_upload_unmap(pipe->stream_uploader);
1413 
1414    pipe->bind_vertex_elements_state(pipe, vertex_elements_cso);
1415    pipe->set_vertex_buffers(pipe, 1, &vb);
1416    pipe->bind_vs_state(pipe, get_vs(&ctx->base));
1417 
1418    if (ctx->base.use_index_buffer) {
1419       /* Note that for V3D,
1420        * dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_* require
1421        * that the last vert of the two tris be the same.
1422        */
1423       static uint8_t indices[6] = { 0, 1, 2, 0, 3, 2 };
1424       util_draw_elements_instanced(pipe, indices, 1, 0,
1425                                    MESA_PRIM_TRIANGLES, 0, 6,
1426                                    0, num_instances);
1427    } else {
1428       util_draw_arrays_instanced(pipe, MESA_PRIM_TRIANGLE_FAN, 0, 4,
1429                                  0, num_instances);
1430    }
1431 }
1432 
util_blitter_draw_rectangle(struct blitter_context * blitter,void * vertex_elements_cso,blitter_get_vs_func get_vs,int x1,int y1,int x2,int y2,float depth,unsigned num_instances,enum blitter_attrib_type type,const union blitter_attrib * attrib)1433 void util_blitter_draw_rectangle(struct blitter_context *blitter,
1434                                  void *vertex_elements_cso,
1435                                  blitter_get_vs_func get_vs,
1436                                  int x1, int y1, int x2, int y2,
1437                                  float depth, unsigned num_instances,
1438                                  enum blitter_attrib_type type,
1439                                  const union blitter_attrib *attrib)
1440 {
1441    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1442    unsigned i;
1443 
1444    switch (type) {
1445       case UTIL_BLITTER_ATTRIB_COLOR:
1446          blitter_set_clear_color(ctx, attrib->color);
1447          break;
1448 
1449       case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
1450          for (i = 0; i < 4; i++) {
1451             ctx->vertices[i][1][2] = attrib->texcoord.z;
1452             ctx->vertices[i][1][3] = attrib->texcoord.w;
1453          }
1454          set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8);
1455          break;
1456       case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
1457          /* We clean-up the ZW components, just in case we used before XYZW,
1458           * to avoid feeding in the shader with wrong values (like on the lod)
1459           */
1460          for (i = 0; i < 4; i++) {
1461             ctx->vertices[i][1][2] = 0;
1462             ctx->vertices[i][1][3] = 0;
1463          }
1464          set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8);
1465          break;
1466 
1467       default:;
1468    }
1469 
1470    blitter_draw(ctx, vertex_elements_cso, get_vs, x1, y1, x2, y2, depth,
1471                 num_instances);
1472 }
1473 
get_clear_blend_state(struct blitter_context_priv * ctx,unsigned clear_buffers)1474 static void *get_clear_blend_state(struct blitter_context_priv *ctx,
1475                                    unsigned clear_buffers)
1476 {
1477    struct pipe_context *pipe = ctx->base.pipe;
1478    int index;
1479 
1480    clear_buffers &= PIPE_CLEAR_COLOR;
1481 
1482    /* Return an existing blend state. */
1483    if (!clear_buffers)
1484       return ctx->blend[0][0];
1485 
1486    index = GET_CLEAR_BLEND_STATE_IDX(clear_buffers);
1487 
1488    if (ctx->blend_clear[index])
1489       return ctx->blend_clear[index];
1490 
1491    /* Create a new one. */
1492    {
1493       struct pipe_blend_state blend = {0};
1494       unsigned i;
1495 
1496       blend.independent_blend_enable = 1;
1497 
1498       for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
1499          if (clear_buffers & (PIPE_CLEAR_COLOR0 << i)) {
1500             blend.rt[i].colormask = PIPE_MASK_RGBA;
1501             blend.max_rt = i;
1502          }
1503       }
1504 
1505       ctx->blend_clear[index] = pipe->create_blend_state(pipe, &blend);
1506    }
1507    return ctx->blend_clear[index];
1508 }
1509 
util_blitter_common_clear_setup(struct blitter_context * blitter,unsigned width,unsigned height,unsigned clear_buffers,void * custom_blend,void * custom_dsa)1510 void util_blitter_common_clear_setup(struct blitter_context *blitter,
1511                                      unsigned width, unsigned height,
1512                                      unsigned clear_buffers,
1513                                      void *custom_blend, void *custom_dsa)
1514 {
1515    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1516    struct pipe_context *pipe = ctx->base.pipe;
1517 
1518    util_blitter_set_running_flag(blitter);
1519    blitter_check_saved_vertex_states(ctx);
1520    blitter_check_saved_fragment_states(ctx);
1521    blitter_disable_render_cond(ctx);
1522 
1523    /* bind states */
1524    if (custom_blend) {
1525       pipe->bind_blend_state(pipe, custom_blend);
1526    } else {
1527       pipe->bind_blend_state(pipe, get_clear_blend_state(ctx, clear_buffers));
1528    }
1529 
1530    if (custom_dsa) {
1531       pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa);
1532    } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
1533       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
1534    } else if (clear_buffers & PIPE_CLEAR_DEPTH) {
1535       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
1536    } else if (clear_buffers & PIPE_CLEAR_STENCIL) {
1537       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
1538    } else {
1539       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1540    }
1541 
1542    pipe->set_sample_mask(pipe, ~0);
1543    if (pipe->set_min_samples)
1544       pipe->set_min_samples(pipe, 1);
1545    blitter_set_dst_dimensions(ctx, width, height);
1546 }
1547 
util_blitter_clear_custom(struct blitter_context * blitter,unsigned width,unsigned height,unsigned num_layers,unsigned clear_buffers,const union pipe_color_union * color,double depth,unsigned stencil,void * custom_blend,void * custom_dsa,bool msaa)1548 static void util_blitter_clear_custom(struct blitter_context *blitter,
1549                                       unsigned width, unsigned height,
1550                                       unsigned num_layers,
1551                                       unsigned clear_buffers,
1552                                       const union pipe_color_union *color,
1553                                       double depth, unsigned stencil,
1554                                       void *custom_blend, void *custom_dsa,
1555                                       bool msaa)
1556 {
1557    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1558    struct pipe_context *pipe = ctx->base.pipe;
1559    struct pipe_stencil_ref sr = { { 0 } };
1560 
1561    assert(ctx->has_layered || num_layers <= 1);
1562 
1563    util_blitter_common_clear_setup(blitter, width, height, clear_buffers,
1564                                    custom_blend, custom_dsa);
1565 
1566    sr.ref_value[0] = stencil & 0xff;
1567    pipe->set_stencil_ref(pipe, sr);
1568 
1569    bool pass_generic = (clear_buffers & PIPE_CLEAR_COLOR) != 0;
1570    enum blitter_attrib_type type = UTIL_BLITTER_ATTRIB_NONE;
1571 
1572    if (pass_generic) {
1573       struct pipe_constant_buffer cb = {
1574          .user_buffer = color->f,
1575          .buffer_size = 4 * sizeof(float),
1576       };
1577       pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
1578                                 false, &cb);
1579       bind_fs_clear_all_cbufs(ctx);
1580    } else {
1581       bind_fs_empty(ctx);
1582    }
1583 
1584    if (num_layers > 1 && ctx->has_layered) {
1585       blitter_get_vs_func get_vs = get_vs_layered;
1586 
1587       blitter_set_common_draw_rect_state(ctx, false, msaa);
1588       blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
1589                               0, 0, width, height,
1590                               (float) depth, num_layers, type, NULL);
1591    } else {
1592       blitter_get_vs_func get_vs;
1593 
1594       if (pass_generic)
1595          get_vs = get_vs_passthrough_pos_generic;
1596       else
1597          get_vs = get_vs_passthrough_pos;
1598 
1599       blitter_set_common_draw_rect_state(ctx, false, msaa);
1600       blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
1601                               0, 0, width, height,
1602                               (float) depth, 1, type, NULL);
1603    }
1604 
1605    util_blitter_restore_vertex_states(blitter);
1606    util_blitter_restore_fragment_states(blitter);
1607    util_blitter_restore_constant_buffer_state(blitter);
1608    util_blitter_restore_render_cond(blitter);
1609    util_blitter_unset_running_flag(blitter);
1610 }
1611 
util_blitter_clear(struct blitter_context * blitter,unsigned width,unsigned height,unsigned num_layers,unsigned clear_buffers,const union pipe_color_union * color,double depth,unsigned stencil,bool msaa)1612 void util_blitter_clear(struct blitter_context *blitter,
1613                         unsigned width, unsigned height, unsigned num_layers,
1614                         unsigned clear_buffers,
1615                         const union pipe_color_union *color,
1616                         double depth, unsigned stencil,
1617                         bool msaa)
1618 {
1619    util_blitter_clear_custom(blitter, width, height, num_layers,
1620                              clear_buffers, color, depth, stencil,
1621                              NULL, NULL, msaa);
1622 }
1623 
util_blitter_custom_clear_depth(struct blitter_context * blitter,unsigned width,unsigned height,double depth,void * custom_dsa)1624 void util_blitter_custom_clear_depth(struct blitter_context *blitter,
1625                                      unsigned width, unsigned height,
1626                                      double depth, void *custom_dsa)
1627 {
1628    static const union pipe_color_union color;
1629    util_blitter_clear_custom(blitter, width, height, 0, 0, &color, depth, 0,
1630                              NULL, custom_dsa, false);
1631 }
1632 
util_blitter_default_dst_texture(struct pipe_surface * dst_templ,struct pipe_resource * dst,unsigned dstlevel,unsigned dstz)1633 void util_blitter_default_dst_texture(struct pipe_surface *dst_templ,
1634                                       struct pipe_resource *dst,
1635                                       unsigned dstlevel,
1636                                       unsigned dstz)
1637 {
1638    memset(dst_templ, 0, sizeof(*dst_templ));
1639    dst_templ->format = util_format_linear(dst->format);
1640    dst_templ->u.tex.level = dstlevel;
1641    dst_templ->u.tex.first_layer = dstz;
1642    dst_templ->u.tex.last_layer = dstz;
1643 }
1644 
1645 static struct pipe_surface *
util_blitter_get_next_surface_layer(struct pipe_context * pipe,struct pipe_surface * surf)1646 util_blitter_get_next_surface_layer(struct pipe_context *pipe,
1647                                     struct pipe_surface *surf)
1648 {
1649    struct pipe_surface dst_templ;
1650 
1651    memset(&dst_templ, 0, sizeof(dst_templ));
1652    dst_templ.format = surf->format;
1653    dst_templ.u.tex.level = surf->u.tex.level;
1654    dst_templ.u.tex.first_layer = surf->u.tex.first_layer + 1;
1655    dst_templ.u.tex.last_layer = surf->u.tex.last_layer + 1;
1656 
1657    return pipe->create_surface(pipe, surf->texture, &dst_templ);
1658 }
1659 
util_blitter_default_src_texture(struct blitter_context * blitter,struct pipe_sampler_view * src_templ,struct pipe_resource * src,unsigned srclevel)1660 void util_blitter_default_src_texture(struct blitter_context *blitter,
1661                                       struct pipe_sampler_view *src_templ,
1662                                       struct pipe_resource *src,
1663                                       unsigned srclevel)
1664 {
1665    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1666 
1667    memset(src_templ, 0, sizeof(*src_templ));
1668 
1669    if (ctx->cube_as_2darray &&
1670        (src->target == PIPE_TEXTURE_CUBE ||
1671         src->target == PIPE_TEXTURE_CUBE_ARRAY))
1672       src_templ->target = PIPE_TEXTURE_2D_ARRAY;
1673    else
1674       src_templ->target = src->target;
1675 
1676    src_templ->format = util_format_linear(src->format);
1677    src_templ->u.tex.first_level = srclevel;
1678    src_templ->u.tex.last_level = srclevel;
1679    src_templ->u.tex.first_layer = 0;
1680    src_templ->u.tex.last_layer =
1681       src->target == PIPE_TEXTURE_3D ? u_minify(src->depth0, srclevel) - 1
1682                                      : (unsigned)(src->array_size - 1);
1683    src_templ->swizzle_r = PIPE_SWIZZLE_X;
1684    src_templ->swizzle_g = PIPE_SWIZZLE_Y;
1685    src_templ->swizzle_b = PIPE_SWIZZLE_Z;
1686    src_templ->swizzle_a = PIPE_SWIZZLE_W;
1687 }
1688 
is_blit_generic_supported(struct blitter_context * blitter,const struct pipe_resource * dst,enum pipe_format dst_format,const struct pipe_resource * src,enum pipe_format src_format,unsigned mask)1689 static bool is_blit_generic_supported(struct blitter_context *blitter,
1690                                       const struct pipe_resource *dst,
1691                                       enum pipe_format dst_format,
1692                                       const struct pipe_resource *src,
1693                                       enum pipe_format src_format,
1694                                       unsigned mask)
1695 {
1696    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1697    struct pipe_screen *screen = ctx->base.pipe->screen;
1698 
1699    if (dst) {
1700       unsigned bind;
1701       const struct util_format_description *desc =
1702             util_format_description(dst_format);
1703       bool dst_has_stencil = util_format_has_stencil(desc);
1704 
1705       /* Stencil export must be supported for stencil copy. */
1706       if ((mask & PIPE_MASK_S) && dst_has_stencil &&
1707           !ctx->has_stencil_export) {
1708          return false;
1709       }
1710 
1711       if (dst_has_stencil || util_format_has_depth(desc))
1712          bind = PIPE_BIND_DEPTH_STENCIL;
1713       else
1714          bind = PIPE_BIND_RENDER_TARGET;
1715 
1716       if (!screen->is_format_supported(screen, dst_format, dst->target,
1717                                        dst->nr_samples, dst->nr_storage_samples,
1718                                        bind)) {
1719          return false;
1720       }
1721    }
1722 
1723    if (src) {
1724       if (src->nr_samples > 1 && !ctx->has_texture_multisample) {
1725          return false;
1726       }
1727 
1728       if (!screen->is_format_supported(screen, src_format, src->target,
1729                                        src->nr_samples, src->nr_storage_samples,
1730                                        PIPE_BIND_SAMPLER_VIEW)) {
1731          return false;
1732       }
1733 
1734       /* Check stencil sampler support for stencil copy. */
1735       if (mask & PIPE_MASK_S) {
1736          if (util_format_has_stencil(util_format_description(src_format))) {
1737             enum pipe_format stencil_format =
1738                util_format_stencil_only(src_format);
1739             assert(stencil_format != PIPE_FORMAT_NONE);
1740 
1741             if (stencil_format != src_format &&
1742                 !screen->is_format_supported(screen, stencil_format,
1743                                              src->target, src->nr_samples,
1744                                              src->nr_storage_samples,
1745                                              PIPE_BIND_SAMPLER_VIEW)) {
1746                return false;
1747             }
1748          }
1749       }
1750    }
1751 
1752    return true;
1753 }
1754 
util_blitter_is_copy_supported(struct blitter_context * blitter,const struct pipe_resource * dst,const struct pipe_resource * src)1755 bool util_blitter_is_copy_supported(struct blitter_context *blitter,
1756                                     const struct pipe_resource *dst,
1757                                     const struct pipe_resource *src)
1758 {
1759    return is_blit_generic_supported(blitter, dst, dst->format,
1760                                     src, src->format, PIPE_MASK_RGBAZS);
1761 }
1762 
util_blitter_is_blit_supported(struct blitter_context * blitter,const struct pipe_blit_info * info)1763 bool util_blitter_is_blit_supported(struct blitter_context *blitter,
1764                                     const struct pipe_blit_info *info)
1765 {
1766    return is_blit_generic_supported(blitter,
1767                                     info->dst.resource, info->dst.format,
1768                                     info->src.resource, info->src.format,
1769                                     info->mask);
1770 }
1771 
util_blitter_copy_texture(struct blitter_context * blitter,struct pipe_resource * dst,unsigned dst_level,unsigned dstx,unsigned dsty,unsigned dstz,struct pipe_resource * src,unsigned src_level,const struct pipe_box * srcbox)1772 void util_blitter_copy_texture(struct blitter_context *blitter,
1773                                struct pipe_resource *dst,
1774                                unsigned dst_level,
1775                                unsigned dstx, unsigned dsty, unsigned dstz,
1776                                struct pipe_resource *src,
1777                                unsigned src_level,
1778                                const struct pipe_box *srcbox)
1779 {
1780    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1781    struct pipe_context *pipe = ctx->base.pipe;
1782    struct pipe_surface *dst_view, dst_templ;
1783    struct pipe_sampler_view src_templ, *src_view;
1784    struct pipe_box dstbox;
1785 
1786    assert(dst && src);
1787    assert(src->target < PIPE_MAX_TEXTURE_TYPES);
1788 
1789    u_box_3d(dstx, dsty, dstz, abs(srcbox->width), abs(srcbox->height),
1790             abs(srcbox->depth), &dstbox);
1791 
1792    /* Initialize the surface. */
1793    util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz);
1794    dst_view = pipe->create_surface(pipe, dst, &dst_templ);
1795 
1796    /* Initialize the sampler view. */
1797    util_blitter_default_src_texture(blitter, &src_templ, src, src_level);
1798    src_view = pipe->create_sampler_view(pipe, src, &src_templ);
1799 
1800    /* Copy. */
1801    util_blitter_blit_generic(blitter, dst_view, &dstbox,
1802                              src_view, srcbox, src->width0, src->height0,
1803                              PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
1804                              false, false, 0);
1805 
1806    pipe_surface_reference(&dst_view, NULL);
1807    pipe_sampler_view_reference(&src_view, NULL);
1808 }
1809 
1810 static void
blitter_draw_tex(struct blitter_context_priv * ctx,int dst_x1,int dst_y1,int dst_x2,int dst_y2,struct pipe_sampler_view * src,unsigned src_width0,unsigned src_height0,int src_x1,int src_y1,int src_x2,int src_y2,float layer,unsigned sample,bool uses_txf,enum blitter_attrib_type type)1811 blitter_draw_tex(struct blitter_context_priv *ctx,
1812                  int dst_x1, int dst_y1, int dst_x2, int dst_y2,
1813                  struct pipe_sampler_view *src,
1814                  unsigned src_width0, unsigned src_height0,
1815                  int src_x1, int src_y1, int src_x2, int src_y2,
1816                  float layer, unsigned sample,
1817                  bool uses_txf, enum blitter_attrib_type type)
1818 {
1819    union blitter_attrib coord;
1820    blitter_get_vs_func get_vs = get_vs_passthrough_pos_generic;
1821 
1822    get_texcoords(src, src_width0, src_height0,
1823                  src_x1, src_y1, src_x2, src_y2, layer, sample,
1824                  uses_txf, &coord);
1825 
1826    if (src->target == PIPE_TEXTURE_CUBE ||
1827        src->target == PIPE_TEXTURE_CUBE_ARRAY) {
1828       float face_coord[4][2];
1829 
1830       set_texcoords_in_vertices(&coord, &face_coord[0][0], 2);
1831       util_map_texcoords2d_onto_cubemap((unsigned)layer % 6,
1832                                         /* pointer, stride in floats */
1833                                         &face_coord[0][0], 2,
1834                                         &ctx->vertices[0][1][0], 8,
1835                                         false);
1836       for (unsigned i = 0; i < 4; i++)
1837          ctx->vertices[i][1][3] = coord.texcoord.w;
1838 
1839       /* Cubemaps don't use draw_rectangle. */
1840       blitter_draw(ctx, ctx->velem_state, get_vs,
1841                    dst_x1, dst_y1, dst_x2, dst_y2, 0, 1);
1842    } else {
1843       ctx->base.draw_rectangle(&ctx->base, ctx->velem_state, get_vs,
1844                                dst_x1, dst_y1, dst_x2, dst_y2,
1845                                0, 1, type, &coord);
1846    }
1847 }
1848 
do_blits(struct blitter_context_priv * ctx,struct pipe_surface * dst,const struct pipe_box * dstbox,struct pipe_sampler_view * src,unsigned src_width0,unsigned src_height0,const struct pipe_box * srcbox,bool is_zsbuf,bool uses_txf,bool sample0_only,unsigned dst_sample)1849 static void do_blits(struct blitter_context_priv *ctx,
1850                      struct pipe_surface *dst,
1851                      const struct pipe_box *dstbox,
1852                      struct pipe_sampler_view *src,
1853                      unsigned src_width0,
1854                      unsigned src_height0,
1855                      const struct pipe_box *srcbox,
1856                      bool is_zsbuf,
1857                      bool uses_txf, bool sample0_only,
1858                      unsigned dst_sample)
1859 {
1860    struct pipe_context *pipe = ctx->base.pipe;
1861    unsigned src_samples = src->texture->nr_samples;
1862    unsigned dst_samples = dst->texture->nr_samples;
1863    bool sample_shading = ctx->has_sample_shading && src_samples > 1 &&
1864                          src_samples == dst_samples && !sample0_only;
1865    enum pipe_texture_target src_target = src->target;
1866    struct pipe_framebuffer_state fb_state = {0};
1867 
1868    /* Initialize framebuffer state. */
1869    fb_state.width = dst->width;
1870    fb_state.height = dst->height;
1871    fb_state.nr_cbufs = is_zsbuf ? 0 : 1;
1872 
1873    blitter_set_dst_dimensions(ctx, fb_state.width, fb_state.height);
1874 
1875    if ((src_target == PIPE_TEXTURE_1D ||
1876         src_target == PIPE_TEXTURE_2D ||
1877         src_target == PIPE_TEXTURE_RECT) &&
1878        (src_samples <= 1 || sample_shading)) {
1879       /* Set framebuffer state. */
1880       if (is_zsbuf) {
1881          fb_state.zsbuf = dst;
1882       } else {
1883          fb_state.cbufs[0] = dst;
1884       }
1885       pipe->set_framebuffer_state(pipe, &fb_state);
1886 
1887       /* Draw. */
1888       pipe->set_sample_mask(pipe, dst_sample ? BITFIELD_BIT(dst_sample - 1) : ~0);
1889       if (pipe->set_min_samples)
1890          pipe->set_min_samples(pipe, sample_shading ? dst_samples : 1);
1891       blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1892                        dstbox->x + dstbox->width,
1893                        dstbox->y + dstbox->height,
1894                        src, src_width0, src_height0, srcbox->x, srcbox->y,
1895                        srcbox->x + srcbox->width, srcbox->y + srcbox->height,
1896                        0, 0, uses_txf, UTIL_BLITTER_ATTRIB_TEXCOORD_XY);
1897    } else {
1898       /* Draw the quad with the generic codepath. */
1899       int dst_z;
1900       for (dst_z = 0; dst_z < dstbox->depth; dst_z++) {
1901          struct pipe_surface *old;
1902          bool flipped = (srcbox->depth < 0);
1903          float depth_center_offset = 0.0;
1904          int src_depth = abs(srcbox->depth);
1905          float src_z_step = src_depth / (float)dstbox->depth;
1906 
1907          /* Scale Z properly if the blit is scaled.
1908           *
1909           * When downscaling, we want the coordinates centered, so that
1910           * mipmapping works for 3D textures. For example, when generating
1911           * a 4x4x4 level, this wouldn't average the pixels:
1912           *
1913           *   src Z:  0 1 2 3 4 5 6 7
1914           *   dst Z:  0   1   2   3
1915           *
1916           * Because the pixels are not centered below the pixels of the higher
1917           * level. Therefore, we want this:
1918           *   src Z:  0 1 2 3 4 5 6 7
1919           *   dst Z:   0   1   2   3
1920           *
1921           * This calculation is taken from the radv driver.
1922           */
1923          if (src_target == PIPE_TEXTURE_3D)
1924             depth_center_offset = 0.5 / dstbox->depth * src_depth;
1925 
1926          if (flipped) {
1927             src_z_step *= - 1;
1928             depth_center_offset *= -1;
1929          }
1930 
1931          float src_z = dst_z * src_z_step + depth_center_offset;
1932 
1933          /* Set framebuffer state. */
1934          if (is_zsbuf) {
1935             fb_state.zsbuf = dst;
1936          } else {
1937             fb_state.cbufs[0] = dst;
1938          }
1939          pipe->set_framebuffer_state(pipe, &fb_state);
1940 
1941          /* See if we need to blit a multisample or singlesample buffer. */
1942          if (sample0_only || (src_samples == dst_samples && dst_samples > 1)) {
1943             /* MSAA copy. */
1944             unsigned i, max_sample = sample0_only ? 0 : dst_samples - 1;
1945 
1946             if (sample_shading) {
1947                assert(dst_sample == 0);
1948                pipe->set_sample_mask(pipe, ~0);
1949                if (pipe->set_min_samples)
1950                   pipe->set_min_samples(pipe, max_sample);
1951                blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1952                                 dstbox->x + dstbox->width,
1953                                 dstbox->y + dstbox->height,
1954                                 src, src_width0, src_height0,
1955                                 srcbox->x, srcbox->y,
1956                                 srcbox->x + srcbox->width,
1957                                 srcbox->y + srcbox->height,
1958                                 srcbox->z + src_z, 0, uses_txf,
1959                                 UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
1960             } else {
1961                if (pipe->set_min_samples)
1962                   pipe->set_min_samples(pipe, 1);
1963 
1964                for (i = 0; i <= max_sample; i++) {
1965                   pipe->set_sample_mask(pipe, 1 << i);
1966                   blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1967                                    dstbox->x + dstbox->width,
1968                                    dstbox->y + dstbox->height,
1969                                    src, src_width0, src_height0,
1970                                    srcbox->x, srcbox->y,
1971                                    srcbox->x + srcbox->width,
1972                                    srcbox->y + srcbox->height,
1973                                    srcbox->z + src_z, i, uses_txf,
1974                                    UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
1975                }
1976             }
1977          } else {
1978             /* Normal copy, MSAA upsampling, or MSAA resolve. */
1979             pipe->set_sample_mask(pipe, dst_sample ? BITFIELD_BIT(dst_sample - 1) : ~0);
1980             if (pipe->set_min_samples)
1981                pipe->set_min_samples(pipe, 1);
1982             blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1983                              dstbox->x + dstbox->width,
1984                              dstbox->y + dstbox->height,
1985                              src, src_width0, src_height0,
1986                              srcbox->x, srcbox->y,
1987                              srcbox->x + srcbox->width,
1988                              srcbox->y + srcbox->height,
1989                              srcbox->z + src_z, 0, uses_txf,
1990                              UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
1991          }
1992 
1993          /* Get the next surface or (if this is the last iteration)
1994           * just unreference the last one. */
1995          old = dst;
1996          if (dst_z < dstbox->depth-1) {
1997             dst = util_blitter_get_next_surface_layer(ctx->base.pipe, dst);
1998          }
1999          if (dst_z) {
2000             pipe_surface_reference(&old, NULL);
2001          }
2002       }
2003    }
2004 }
2005 
util_blitter_blit_generic(struct blitter_context * blitter,struct pipe_surface * dst,const struct pipe_box * dstbox,struct pipe_sampler_view * src,const struct pipe_box * srcbox,unsigned src_width0,unsigned src_height0,unsigned mask,unsigned filter,const struct pipe_scissor_state * scissor,bool alpha_blend,bool sample0_only,unsigned dst_sample)2006 void util_blitter_blit_generic(struct blitter_context *blitter,
2007                                struct pipe_surface *dst,
2008                                const struct pipe_box *dstbox,
2009                                struct pipe_sampler_view *src,
2010                                const struct pipe_box *srcbox,
2011                                unsigned src_width0, unsigned src_height0,
2012                                unsigned mask, unsigned filter,
2013                                const struct pipe_scissor_state *scissor,
2014                                bool alpha_blend, bool sample0_only,
2015                                unsigned dst_sample)
2016 {
2017    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2018    struct pipe_context *pipe = ctx->base.pipe;
2019    enum pipe_texture_target src_target = src->target;
2020    unsigned src_samples = src->texture->nr_samples;
2021    unsigned dst_samples = dst->texture->nr_samples;
2022    void *sampler_state;
2023    const struct util_format_description *src_desc =
2024          util_format_description(src->format);
2025    const struct util_format_description *dst_desc =
2026          util_format_description(dst->format);
2027 
2028    bool src_has_color = src_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
2029    bool src_has_depth = util_format_has_depth(src_desc);
2030    bool src_has_stencil = util_format_has_stencil(src_desc);
2031 
2032    bool dst_has_color = mask & PIPE_MASK_RGBA &&
2033                         dst_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
2034    bool dst_has_depth = mask & PIPE_MASK_Z &&
2035                         util_format_has_depth(dst_desc);
2036    bool dst_has_stencil = ctx->has_stencil_export &&
2037                           mask & PIPE_MASK_S &&
2038                           util_format_has_stencil(dst_desc);
2039 
2040    /* Return if there is nothing to do. */
2041    if (!dst_has_color && !dst_has_depth && !dst_has_stencil) {
2042       return;
2043    }
2044 
2045    bool is_scaled = dstbox->width != abs(srcbox->width) ||
2046                     dstbox->height != abs(srcbox->height) ||
2047                     dstbox->depth != abs(srcbox->depth);
2048 
2049    if (src_has_stencil || !is_scaled)
2050       filter = PIPE_TEX_FILTER_NEAREST;
2051 
2052    bool use_txf = false;
2053 
2054    /* Don't support scaled blits. The TXF shader uses F2I for rounding. */
2055    if (ctx->has_txf_txq &&
2056        !is_scaled &&
2057        filter == PIPE_TEX_FILTER_NEAREST &&
2058        src->target != PIPE_TEXTURE_CUBE &&
2059        src->target != PIPE_TEXTURE_CUBE_ARRAY) {
2060       int src_width = u_minify(src_width0, src->u.tex.first_level);
2061       int src_height = u_minify(src_height0, src->u.tex.first_level);
2062       int src_depth = src->u.tex.last_layer + 1;
2063       struct pipe_box box = *srcbox;
2064 
2065       /* Eliminate negative width/height/depth. */
2066       if (box.width < 0) {
2067          box.x += box.width;
2068          box.width *= -1;
2069       }
2070       if (box.height < 0) {
2071          box.y += box.height;
2072          box.height *= -1;
2073       }
2074       if (box.depth < 0) {
2075          box.z += box.depth;
2076          box.depth *= -1;
2077       }
2078 
2079       /* See if srcbox is in bounds. TXF doesn't clamp the coordinates. */
2080       use_txf =
2081          box.x >= 0 && box.x < src_width &&
2082          box.y >= 0 && box.y < src_height &&
2083          box.z >= 0 && box.z < src_depth &&
2084          box.x + box.width > 0 && box.x + box.width <= src_width &&
2085          box.y + box.height > 0 && box.y + box.height <= src_height &&
2086          box.z + box.depth > 0 && box.z + box.depth <= src_depth;
2087    }
2088 
2089    /* Check whether the states are properly saved. */
2090    util_blitter_set_running_flag(blitter);
2091    blitter_check_saved_vertex_states(ctx);
2092    blitter_check_saved_fragment_states(ctx);
2093    blitter_check_saved_textures(ctx);
2094    blitter_check_saved_fb_state(ctx);
2095    blitter_disable_render_cond(ctx);
2096 
2097    /* Blend, DSA, fragment shader. */
2098    if (dst_has_depth && dst_has_stencil) {
2099       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2100       pipe->bind_depth_stencil_alpha_state(pipe,
2101                                            ctx->dsa_write_depth_stencil);
2102       if (src_has_color) {
2103          assert(use_txf);
2104          ctx->bind_fs_state(pipe,
2105             blitter_get_fs_pack_color_zs(ctx, src_target,
2106                                          src_samples, dst->format, false));
2107       } else {
2108          ctx->bind_fs_state(pipe,
2109             blitter_get_fs_texfetch_depthstencil(ctx, src_target, src_samples,
2110                                                  dst_samples, use_txf));
2111       }
2112    } else if (dst_has_depth) {
2113       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2114       pipe->bind_depth_stencil_alpha_state(pipe,
2115                                            ctx->dsa_write_depth_keep_stencil);
2116       if (src_has_color &&
2117           (src->format == PIPE_FORMAT_R32_UINT ||
2118            src->format == PIPE_FORMAT_R32G32_UINT)) {
2119          assert(use_txf);
2120          ctx->bind_fs_state(pipe,
2121             blitter_get_fs_pack_color_zs(ctx, src_target,
2122                                          src_samples, dst->format, false));
2123       } else {
2124          ctx->bind_fs_state(pipe,
2125             blitter_get_fs_texfetch_depth(ctx, src_target, src_samples,
2126                                           dst_samples, use_txf));
2127       }
2128    } else if (dst_has_stencil) {
2129       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2130       pipe->bind_depth_stencil_alpha_state(pipe,
2131                                            ctx->dsa_keep_depth_write_stencil);
2132 
2133       assert(src_has_stencil); /* unpacking from color is unsupported */
2134       ctx->bind_fs_state(pipe,
2135          blitter_get_fs_texfetch_stencil(ctx, src_target, src_samples,
2136                                          dst_samples, use_txf));
2137    } else {
2138       unsigned colormask = mask & PIPE_MASK_RGBA;
2139 
2140       pipe->bind_blend_state(pipe, ctx->blend[colormask][alpha_blend]);
2141       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2142 
2143       if (src_has_depth &&
2144           (dst->format == PIPE_FORMAT_R32_UINT ||
2145            dst->format == PIPE_FORMAT_R32G32_UINT)) {
2146          assert(use_txf);
2147          ctx->bind_fs_state(pipe,
2148             blitter_get_fs_pack_color_zs(ctx, src_target,
2149                                          src_samples, src->format, true));
2150       } else {
2151          ctx->bind_fs_state(pipe,
2152             blitter_get_fs_texfetch_col(ctx, src->format, dst->format, src_target,
2153                                         src_samples, dst_samples, filter,
2154                                         use_txf));
2155       }
2156    }
2157 
2158    /* Set the linear filter only for scaled color non-MSAA blits. */
2159    if (filter == PIPE_TEX_FILTER_LINEAR) {
2160       if (src_target == PIPE_TEXTURE_RECT && ctx->has_texrect) {
2161          sampler_state = ctx->sampler_state_rect_linear;
2162       } else {
2163          sampler_state = ctx->sampler_state_linear;
2164       }
2165    } else {
2166       if (src_target == PIPE_TEXTURE_RECT && ctx->has_texrect) {
2167          sampler_state = ctx->sampler_state_rect;
2168       } else {
2169          sampler_state = ctx->sampler_state;
2170       }
2171    }
2172 
2173    /* Set samplers. */
2174    unsigned count = 0;
2175    if (src_has_depth && src_has_stencil &&
2176        (dst_has_color || (dst_has_depth && dst_has_stencil))) {
2177       /* Setup two samplers, one for depth and the other one for stencil. */
2178       struct pipe_sampler_view templ;
2179       struct pipe_sampler_view *views[2];
2180       void *samplers[2] = {sampler_state, sampler_state};
2181 
2182       templ = *src;
2183       templ.format = util_format_stencil_only(templ.format);
2184       assert(templ.format != PIPE_FORMAT_NONE);
2185 
2186       views[0] = src;
2187       views[1] = pipe->create_sampler_view(pipe, src->texture, &templ);
2188 
2189       count = 2;
2190       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 2, 0, false, views);
2191       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 2, samplers);
2192 
2193       pipe_sampler_view_reference(&views[1], NULL);
2194    } else if (src_has_stencil && dst_has_stencil) {
2195       /* Set a stencil-only sampler view for it not to sample depth instead. */
2196       struct pipe_sampler_view templ;
2197       struct pipe_sampler_view *view;
2198 
2199       templ = *src;
2200       templ.format = util_format_stencil_only(templ.format);
2201       assert(templ.format != PIPE_FORMAT_NONE);
2202 
2203       view = pipe->create_sampler_view(pipe, src->texture, &templ);
2204 
2205       count = 1;
2206       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &view);
2207       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2208                                 0, 1, &sampler_state);
2209 
2210       pipe_sampler_view_reference(&view, NULL);
2211    } else {
2212       count = 1;
2213       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src);
2214       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2215                                 0, 1, &sampler_state);
2216    }
2217 
2218    if (scissor) {
2219       pipe->set_scissor_states(pipe, 0, 1, scissor);
2220    }
2221 
2222    blitter_set_common_draw_rect_state(ctx, scissor != NULL, dst_samples > 1);
2223 
2224    do_blits(ctx, dst, dstbox, src, src_width0, src_height0,
2225             srcbox, dst_has_depth || dst_has_stencil, use_txf, sample0_only,
2226             dst_sample);
2227 
2228    util_blitter_restore_vertex_states(blitter);
2229    util_blitter_restore_fragment_states(blitter);
2230    util_blitter_restore_textures_internal(blitter, count);
2231    util_blitter_restore_fb_state(blitter);
2232    if (scissor) {
2233       pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor);
2234    }
2235    util_blitter_restore_render_cond(blitter);
2236    util_blitter_unset_running_flag(blitter);
2237 }
2238 
2239 void
util_blitter_blit(struct blitter_context * blitter,const struct pipe_blit_info * info)2240 util_blitter_blit(struct blitter_context *blitter,
2241                   const struct pipe_blit_info *info)
2242 {
2243    struct pipe_resource *dst = info->dst.resource;
2244    struct pipe_resource *src = info->src.resource;
2245    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2246    struct pipe_context *pipe = ctx->base.pipe;
2247    struct pipe_surface *dst_view, dst_templ;
2248    struct pipe_sampler_view src_templ, *src_view;
2249 
2250    /* Initialize the surface. */
2251    util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level,
2252                                     info->dst.box.z);
2253    dst_templ.format = info->dst.format;
2254    dst_view = pipe->create_surface(pipe, dst, &dst_templ);
2255 
2256    /* Initialize the sampler view. */
2257    util_blitter_default_src_texture(blitter, &src_templ, src, info->src.level);
2258    src_templ.format = info->src.format;
2259    src_view = pipe->create_sampler_view(pipe, src, &src_templ);
2260 
2261    /* Copy. */
2262    util_blitter_blit_generic(blitter, dst_view, &info->dst.box,
2263                              src_view, &info->src.box, src->width0, src->height0,
2264                              info->mask, info->filter,
2265                              info->scissor_enable ? &info->scissor : NULL,
2266                              info->alpha_blend, info->sample0_only,
2267                              info->dst_sample);
2268 
2269    pipe_surface_reference(&dst_view, NULL);
2270    pipe_sampler_view_reference(&src_view, NULL);
2271 }
2272 
util_blitter_generate_mipmap(struct blitter_context * blitter,struct pipe_resource * tex,enum pipe_format format,unsigned base_level,unsigned last_level,unsigned first_layer,unsigned last_layer)2273 void util_blitter_generate_mipmap(struct blitter_context *blitter,
2274                                   struct pipe_resource *tex,
2275                                   enum pipe_format format,
2276                                   unsigned base_level, unsigned last_level,
2277                                   unsigned first_layer, unsigned last_layer)
2278 {
2279    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2280    struct pipe_context *pipe = ctx->base.pipe;
2281    struct pipe_surface dst_templ, *dst_view;
2282    struct pipe_sampler_view src_templ, *src_view;
2283    bool is_depth;
2284    void *sampler_state;
2285    const struct util_format_description *desc =
2286          util_format_description(format);
2287    unsigned src_level;
2288    unsigned target = tex->target;
2289 
2290    if (ctx->cube_as_2darray &&
2291        (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY))
2292       target = PIPE_TEXTURE_2D_ARRAY;
2293 
2294    assert(tex->nr_samples <= 1);
2295    /* Disallow stencil formats without depth. */
2296    assert(!util_format_has_stencil(desc) || util_format_has_depth(desc));
2297 
2298    is_depth = desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS;
2299 
2300    /* Check whether the states are properly saved. */
2301    util_blitter_set_running_flag(blitter);
2302    blitter_check_saved_vertex_states(ctx);
2303    blitter_check_saved_fragment_states(ctx);
2304    blitter_check_saved_textures(ctx);
2305    blitter_check_saved_fb_state(ctx);
2306    blitter_disable_render_cond(ctx);
2307 
2308    /* Set states. */
2309    if (is_depth) {
2310       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2311       pipe->bind_depth_stencil_alpha_state(pipe,
2312                                            ctx->dsa_write_depth_keep_stencil);
2313       ctx->bind_fs_state(pipe,
2314                          blitter_get_fs_texfetch_depth(ctx, target, 1, 1, false));
2315    } else {
2316       pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2317       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2318       ctx->bind_fs_state(pipe,
2319             blitter_get_fs_texfetch_col(ctx, tex->format, tex->format, target,
2320                                         1, 1, PIPE_TEX_FILTER_LINEAR, false));
2321    }
2322 
2323    if (target == PIPE_TEXTURE_RECT) {
2324       sampler_state = ctx->sampler_state_rect_linear;
2325    } else {
2326       sampler_state = ctx->sampler_state_linear;
2327    }
2328    pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2329                              0, 1, &sampler_state);
2330 
2331    blitter_set_common_draw_rect_state(ctx, false, false);
2332 
2333    for (src_level = base_level; src_level < last_level; src_level++) {
2334       struct pipe_box dstbox = {0}, srcbox = {0};
2335       unsigned dst_level = src_level + 1;
2336 
2337       dstbox.width = u_minify(tex->width0, dst_level);
2338       dstbox.height = u_minify(tex->height0, dst_level);
2339 
2340       srcbox.width = u_minify(tex->width0, src_level);
2341       srcbox.height = u_minify(tex->height0, src_level);
2342 
2343       if (target == PIPE_TEXTURE_3D) {
2344          dstbox.depth = util_num_layers(tex, dst_level);
2345          srcbox.depth = util_num_layers(tex, src_level);
2346       } else {
2347          dstbox.z = srcbox.z = first_layer;
2348          dstbox.depth = srcbox.depth = last_layer - first_layer + 1;
2349       }
2350 
2351       /* Initialize the surface. */
2352       util_blitter_default_dst_texture(&dst_templ, tex, dst_level,
2353                                        first_layer);
2354       dst_templ.format = format;
2355       dst_view = pipe->create_surface(pipe, tex, &dst_templ);
2356 
2357       /* Initialize the sampler view. */
2358       util_blitter_default_src_texture(blitter, &src_templ, tex, src_level);
2359       src_templ.format = format;
2360       src_view = pipe->create_sampler_view(pipe, tex, &src_templ);
2361 
2362       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src_view);
2363 
2364       do_blits(ctx, dst_view, &dstbox, src_view, tex->width0, tex->height0,
2365                &srcbox, is_depth, false, false, 0);
2366 
2367       pipe_surface_reference(&dst_view, NULL);
2368       pipe_sampler_view_reference(&src_view, NULL);
2369    }
2370 
2371    util_blitter_restore_vertex_states(blitter);
2372    util_blitter_restore_fragment_states(blitter);
2373    util_blitter_restore_textures_internal(blitter, 1);
2374    util_blitter_restore_fb_state(blitter);
2375    util_blitter_restore_render_cond(blitter);
2376    util_blitter_unset_running_flag(blitter);
2377 }
2378 
2379 /* Clear a region of a color surface to a constant value. */
util_blitter_clear_render_target(struct blitter_context * blitter,struct pipe_surface * dstsurf,const union pipe_color_union * color,unsigned dstx,unsigned dsty,unsigned width,unsigned height)2380 void util_blitter_clear_render_target(struct blitter_context *blitter,
2381                                       struct pipe_surface *dstsurf,
2382                                       const union pipe_color_union *color,
2383                                       unsigned dstx, unsigned dsty,
2384                                       unsigned width, unsigned height)
2385 {
2386    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2387    struct pipe_context *pipe = ctx->base.pipe;
2388    struct pipe_framebuffer_state fb_state = { 0 };
2389    bool msaa;
2390    unsigned num_layers;
2391    blitter_get_vs_func get_vs;
2392 
2393    assert(dstsurf->texture);
2394    if (!dstsurf->texture)
2395       return;
2396 
2397    /* check the saved state */
2398    util_blitter_set_running_flag(blitter);
2399    blitter_check_saved_vertex_states(ctx);
2400    blitter_check_saved_fragment_states(ctx);
2401    blitter_check_saved_fb_state(ctx);
2402    blitter_disable_render_cond(ctx);
2403 
2404    /* bind states */
2405    pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2406    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2407    bind_fs_write_one_cbuf(ctx);
2408 
2409    /* set a framebuffer state */
2410    fb_state.width = dstsurf->width;
2411    fb_state.height = dstsurf->height;
2412    fb_state.nr_cbufs = 1;
2413    fb_state.cbufs[0] = dstsurf;
2414    fb_state.zsbuf = NULL;
2415    fb_state.resolve = NULL;
2416    pipe->set_framebuffer_state(pipe, &fb_state);
2417    pipe->set_sample_mask(pipe, ~0);
2418    if (pipe->set_min_samples)
2419       pipe->set_min_samples(pipe, 1);
2420    msaa = util_framebuffer_get_num_samples(&fb_state) > 1;
2421 
2422    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2423    blitter_set_common_draw_rect_state(ctx, false, msaa);
2424 
2425    union blitter_attrib attrib;
2426    memcpy(attrib.color, color->ui, sizeof(color->ui));
2427 
2428    num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
2429 
2430    if (num_layers > 1 && ctx->has_layered) {
2431       get_vs = get_vs_layered;
2432    } else {
2433       get_vs = get_vs_passthrough_pos_generic;
2434       num_layers = 1;
2435    }
2436 
2437    blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
2438                            dstx, dsty, dstx+width, dsty+height, 0,
2439                            num_layers, UTIL_BLITTER_ATTRIB_COLOR, &attrib);
2440 
2441    util_blitter_restore_vertex_states(blitter);
2442    util_blitter_restore_fragment_states(blitter);
2443    util_blitter_restore_fb_state(blitter);
2444    util_blitter_restore_render_cond(blitter);
2445    util_blitter_unset_running_flag(blitter);
2446 }
2447 
2448 /* Clear a region of a depth stencil surface. */
util_blitter_clear_depth_stencil(struct blitter_context * blitter,struct pipe_surface * dstsurf,unsigned clear_flags,double depth,unsigned stencil,unsigned dstx,unsigned dsty,unsigned width,unsigned height)2449 void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
2450                                       struct pipe_surface *dstsurf,
2451                                       unsigned clear_flags,
2452                                       double depth,
2453                                       unsigned stencil,
2454                                       unsigned dstx, unsigned dsty,
2455                                       unsigned width, unsigned height)
2456 {
2457    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2458    struct pipe_context *pipe = ctx->base.pipe;
2459    struct pipe_framebuffer_state fb_state = { 0 };
2460    struct pipe_stencil_ref sr = { { 0 } };
2461    unsigned num_layers;
2462 
2463    assert(dstsurf->texture);
2464    if (!dstsurf->texture)
2465       return;
2466 
2467    /* check the saved state */
2468    util_blitter_set_running_flag(blitter);
2469    blitter_check_saved_vertex_states(ctx);
2470    blitter_check_saved_fragment_states(ctx);
2471    blitter_check_saved_fb_state(ctx);
2472    blitter_disable_render_cond(ctx);
2473 
2474    /* bind states */
2475    pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2476    if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
2477       sr.ref_value[0] = stencil & 0xff;
2478       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
2479       pipe->set_stencil_ref(pipe, sr);
2480    }
2481    else if (clear_flags & PIPE_CLEAR_DEPTH) {
2482       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
2483    }
2484    else if (clear_flags & PIPE_CLEAR_STENCIL) {
2485       sr.ref_value[0] = stencil & 0xff;
2486       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
2487       pipe->set_stencil_ref(pipe, sr);
2488    }
2489    else
2490       /* hmm that should be illegal probably, or make it a no-op somewhere */
2491       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2492 
2493    bind_fs_empty(ctx);
2494 
2495    /* set a framebuffer state */
2496    fb_state.width = dstsurf->width;
2497    fb_state.height = dstsurf->height;
2498    fb_state.nr_cbufs = 0;
2499    fb_state.cbufs[0] = NULL;
2500    fb_state.zsbuf = dstsurf;
2501    fb_state.resolve = NULL;
2502    pipe->set_framebuffer_state(pipe, &fb_state);
2503    pipe->set_sample_mask(pipe, ~0);
2504    if (pipe->set_min_samples)
2505       pipe->set_min_samples(pipe, 1);
2506 
2507    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2508 
2509    num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
2510    if (num_layers > 1 && ctx->has_layered) {
2511       blitter_set_common_draw_rect_state(ctx, false, false);
2512       blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_layered,
2513                               dstx, dsty, dstx+width, dsty+height, depth,
2514                               num_layers, UTIL_BLITTER_ATTRIB_NONE, NULL);
2515    } else {
2516       blitter_set_common_draw_rect_state(ctx, false, false);
2517       blitter->draw_rectangle(blitter, ctx->velem_state,
2518                               get_vs_passthrough_pos,
2519                               dstx, dsty, dstx+width, dsty+height, depth, 1,
2520                               UTIL_BLITTER_ATTRIB_NONE, NULL);
2521    }
2522 
2523    util_blitter_restore_vertex_states(blitter);
2524    util_blitter_restore_fragment_states(blitter);
2525    util_blitter_restore_fb_state(blitter);
2526    util_blitter_restore_render_cond(blitter);
2527    util_blitter_unset_running_flag(blitter);
2528 }
2529 
2530 /* draw a rectangle across a region using a custom dsa stage - for r600g */
util_blitter_custom_depth_stencil(struct blitter_context * blitter,struct pipe_surface * zsurf,struct pipe_surface * cbsurf,unsigned sample_mask,void * dsa_stage,float depth)2531 void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
2532                                        struct pipe_surface *zsurf,
2533                                        struct pipe_surface *cbsurf,
2534                                        unsigned sample_mask,
2535                                        void *dsa_stage, float depth)
2536 {
2537    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2538    struct pipe_context *pipe = ctx->base.pipe;
2539    struct pipe_framebuffer_state fb_state = { 0 };
2540 
2541    assert(zsurf->texture);
2542    if (!zsurf->texture)
2543       return;
2544 
2545    /* check the saved state */
2546    util_blitter_set_running_flag(blitter);
2547    blitter_check_saved_vertex_states(ctx);
2548    blitter_check_saved_fragment_states(ctx);
2549    blitter_check_saved_fb_state(ctx);
2550    blitter_disable_render_cond(ctx);
2551 
2552    /* bind states */
2553    pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA][0] :
2554                                          ctx->blend[0][0]);
2555    pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
2556    if (cbsurf)
2557       bind_fs_write_one_cbuf(ctx);
2558    else
2559       bind_fs_empty(ctx);
2560 
2561    /* set a framebuffer state */
2562    fb_state.width = zsurf->width;
2563    fb_state.height = zsurf->height;
2564    fb_state.nr_cbufs = 1;
2565    if (cbsurf) {
2566       fb_state.cbufs[0] = cbsurf;
2567       fb_state.nr_cbufs = 1;
2568    } else {
2569       fb_state.cbufs[0] = NULL;
2570       fb_state.nr_cbufs = 0;
2571    }
2572    fb_state.zsbuf = zsurf;
2573    fb_state.resolve = NULL;
2574    pipe->set_framebuffer_state(pipe, &fb_state);
2575    pipe->set_sample_mask(pipe, sample_mask);
2576    if (pipe->set_min_samples)
2577       pipe->set_min_samples(pipe, 1);
2578 
2579    blitter_set_common_draw_rect_state(ctx, false,
2580       util_framebuffer_get_num_samples(&fb_state) > 1);
2581    blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height);
2582    blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2583                            0, 0, zsurf->width, zsurf->height, depth,
2584                            1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2585 
2586    util_blitter_restore_vertex_states(blitter);
2587    util_blitter_restore_fragment_states(blitter);
2588    util_blitter_restore_fb_state(blitter);
2589    util_blitter_restore_render_cond(blitter);
2590    util_blitter_unset_running_flag(blitter);
2591 }
2592 
util_blitter_clear_buffer(struct blitter_context * blitter,struct pipe_resource * dst,unsigned offset,unsigned size,unsigned num_channels,const union pipe_color_union * clear_value)2593 void util_blitter_clear_buffer(struct blitter_context *blitter,
2594                                struct pipe_resource *dst,
2595                                unsigned offset, unsigned size,
2596                                unsigned num_channels,
2597                                const union pipe_color_union *clear_value)
2598 {
2599    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2600    struct pipe_context *pipe = ctx->base.pipe;
2601    struct pipe_vertex_buffer vb = {0};
2602    struct pipe_stream_output_target *so_target = NULL;
2603    unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
2604 
2605    assert(num_channels >= 1);
2606    assert(num_channels <= 4);
2607 
2608    /* IMPORTANT:  DON'T DO ANY BOUNDS CHECKING HERE!
2609     *
2610     * R600 uses this to initialize texture resources, so width0 might not be
2611     * what you think it is.
2612     */
2613 
2614    /* Streamout is required. */
2615    if (!ctx->has_stream_out) {
2616       assert(!"Streamout unsupported in util_blitter_clear_buffer()");
2617       return;
2618    }
2619 
2620    /* Some alignment is required. */
2621    if (offset % 4 != 0 || size % 4 != 0) {
2622       assert(!"Bad alignment in util_blitter_clear_buffer()");
2623       return;
2624    }
2625 
2626    u_upload_data(pipe->stream_uploader, 0, num_channels*4, 4, clear_value,
2627                  &vb.buffer_offset, &vb.buffer.resource);
2628    if (!vb.buffer.resource)
2629       goto out;
2630 
2631    util_blitter_set_running_flag(blitter);
2632    blitter_check_saved_vertex_states(ctx);
2633    blitter_disable_render_cond(ctx);
2634 
2635    pipe->bind_vertex_elements_state(pipe,
2636                                     ctx->velem_state_readbuf[num_channels-1]);
2637    pipe->set_vertex_buffers(pipe, 1, &vb);
2638    bind_vs_pos_only(ctx, num_channels);
2639 
2640    if (ctx->has_geometry_shader)
2641       pipe->bind_gs_state(pipe, NULL);
2642    if (ctx->has_tessellation) {
2643       pipe->bind_tcs_state(pipe, NULL);
2644       pipe->bind_tes_state(pipe, NULL);
2645    }
2646    pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
2647 
2648    so_target = pipe->create_stream_output_target(pipe, dst, offset, size);
2649    pipe->set_stream_output_targets(pipe, 1, &so_target, offsets);
2650 
2651    util_draw_arrays(pipe, MESA_PRIM_POINTS, 0, size / 4);
2652 
2653 out:
2654    util_blitter_restore_vertex_states(blitter);
2655    util_blitter_restore_render_cond(blitter);
2656    util_blitter_unset_running_flag(blitter);
2657    pipe_so_target_reference(&so_target, NULL);
2658 }
2659 
2660 /* probably radeon specific */
util_blitter_custom_resolve_color(struct blitter_context * blitter,struct pipe_resource * dst,unsigned dst_level,unsigned dst_layer,struct pipe_resource * src,unsigned src_layer,unsigned sample_mask,void * custom_blend,enum pipe_format format)2661 void util_blitter_custom_resolve_color(struct blitter_context *blitter,
2662                                        struct pipe_resource *dst,
2663                                        unsigned dst_level,
2664                                        unsigned dst_layer,
2665                                        struct pipe_resource *src,
2666                                        unsigned src_layer,
2667                                        unsigned sample_mask,
2668                                        void *custom_blend,
2669                                        enum pipe_format format)
2670 {
2671    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2672    struct pipe_context *pipe = ctx->base.pipe;
2673    struct pipe_framebuffer_state fb_state = { 0 };
2674    struct pipe_surface *srcsurf, *dstsurf, surf_tmpl;
2675 
2676    util_blitter_set_running_flag(blitter);
2677    blitter_check_saved_vertex_states(ctx);
2678    blitter_check_saved_fragment_states(ctx);
2679    blitter_disable_render_cond(ctx);
2680 
2681    /* bind states */
2682    pipe->bind_blend_state(pipe, custom_blend);
2683    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2684    bind_fs_write_one_cbuf(ctx);
2685    pipe->set_sample_mask(pipe, sample_mask);
2686    if (pipe->set_min_samples)
2687       pipe->set_min_samples(pipe, 1);
2688 
2689    memset(&surf_tmpl, 0, sizeof(surf_tmpl));
2690    surf_tmpl.format = format;
2691    surf_tmpl.u.tex.level = dst_level;
2692    surf_tmpl.u.tex.first_layer = dst_layer;
2693    surf_tmpl.u.tex.last_layer = dst_layer;
2694 
2695    dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl);
2696 
2697    surf_tmpl.u.tex.level = 0;
2698    surf_tmpl.u.tex.first_layer = src_layer;
2699    surf_tmpl.u.tex.last_layer = src_layer;
2700 
2701    srcsurf = pipe->create_surface(pipe, src, &surf_tmpl);
2702 
2703    /* set a framebuffer state */
2704    fb_state.width = src->width0;
2705    fb_state.height = src->height0;
2706    fb_state.nr_cbufs = 2;
2707    fb_state.cbufs[0] = srcsurf;
2708    fb_state.cbufs[1] = dstsurf;
2709    fb_state.zsbuf = NULL;
2710    fb_state.resolve = NULL;
2711    pipe->set_framebuffer_state(pipe, &fb_state);
2712 
2713    blitter_set_common_draw_rect_state(ctx, false,
2714       util_framebuffer_get_num_samples(&fb_state) > 1);
2715    blitter_set_dst_dimensions(ctx, src->width0, src->height0);
2716    blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2717                            0, 0, src->width0, src->height0,
2718                            0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2719    util_blitter_restore_fb_state(blitter);
2720    util_blitter_restore_vertex_states(blitter);
2721    util_blitter_restore_fragment_states(blitter);
2722    util_blitter_restore_render_cond(blitter);
2723    util_blitter_unset_running_flag(blitter);
2724 
2725    pipe_surface_reference(&srcsurf, NULL);
2726    pipe_surface_reference(&dstsurf, NULL);
2727 }
2728 
util_blitter_custom_color(struct blitter_context * blitter,struct pipe_surface * dstsurf,void * custom_blend)2729 void util_blitter_custom_color(struct blitter_context *blitter,
2730                                struct pipe_surface *dstsurf,
2731                                void *custom_blend)
2732 {
2733    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2734    struct pipe_context *pipe = ctx->base.pipe;
2735    struct pipe_framebuffer_state fb_state = { 0 };
2736 
2737    assert(dstsurf->texture);
2738    if (!dstsurf->texture)
2739       return;
2740 
2741    /* check the saved state */
2742    util_blitter_set_running_flag(blitter);
2743    blitter_check_saved_vertex_states(ctx);
2744    blitter_check_saved_fragment_states(ctx);
2745    blitter_check_saved_fb_state(ctx);
2746    blitter_disable_render_cond(ctx);
2747 
2748    /* bind states */
2749    pipe->bind_blend_state(pipe, custom_blend ? custom_blend
2750                                              : ctx->blend[PIPE_MASK_RGBA][0]);
2751    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2752    bind_fs_write_one_cbuf(ctx);
2753 
2754    /* set a framebuffer state */
2755    fb_state.width = dstsurf->width;
2756    fb_state.height = dstsurf->height;
2757    fb_state.nr_cbufs = 1;
2758    fb_state.cbufs[0] = dstsurf;
2759    fb_state.zsbuf = NULL;
2760    fb_state.resolve = NULL;
2761    pipe->set_framebuffer_state(pipe, &fb_state);
2762    pipe->set_sample_mask(pipe, ~0);
2763    if (pipe->set_min_samples)
2764       pipe->set_min_samples(pipe, 1);
2765 
2766    blitter_set_common_draw_rect_state(ctx, false,
2767       util_framebuffer_get_num_samples(&fb_state) > 1);
2768    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2769    blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2770                            0, 0, dstsurf->width, dstsurf->height,
2771                            0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2772 
2773    util_blitter_restore_vertex_states(blitter);
2774    util_blitter_restore_fragment_states(blitter);
2775    util_blitter_restore_fb_state(blitter);
2776    util_blitter_restore_render_cond(blitter);
2777    util_blitter_unset_running_flag(blitter);
2778 }
2779 
get_custom_vs(struct blitter_context * blitter)2780 static void *get_custom_vs(struct blitter_context *blitter)
2781 {
2782    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2783 
2784    return ctx->custom_vs;
2785 }
2786 
2787 /**
2788  * Performs a custom blit to the destination surface, using the VS and FS
2789  * provided.
2790  *
2791  * Used by vc4 for the 8-bit linear-to-tiled blit.
2792  */
util_blitter_custom_shader(struct blitter_context * blitter,struct pipe_surface * dstsurf,void * custom_vs,void * custom_fs)2793 void util_blitter_custom_shader(struct blitter_context *blitter,
2794                                 struct pipe_surface *dstsurf,
2795                                 void *custom_vs, void *custom_fs)
2796 {
2797    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2798    struct pipe_context *pipe = ctx->base.pipe;
2799    struct pipe_framebuffer_state fb_state = { 0 };
2800 
2801    ctx->custom_vs = custom_vs;
2802 
2803    assert(dstsurf->texture);
2804    if (!dstsurf->texture)
2805       return;
2806 
2807    /* check the saved state */
2808    util_blitter_set_running_flag(blitter);
2809    blitter_check_saved_vertex_states(ctx);
2810    blitter_check_saved_fragment_states(ctx);
2811    blitter_check_saved_fb_state(ctx);
2812    blitter_disable_render_cond(ctx);
2813 
2814    /* bind states */
2815    pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2816    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2817    pipe->bind_fs_state(pipe, custom_fs);
2818 
2819    /* set a framebuffer state */
2820    fb_state.width = dstsurf->width;
2821    fb_state.height = dstsurf->height;
2822    fb_state.nr_cbufs = 1;
2823    fb_state.cbufs[0] = dstsurf;
2824    fb_state.resolve = NULL;
2825    pipe->set_framebuffer_state(pipe, &fb_state);
2826    pipe->set_sample_mask(pipe, ~0);
2827    if (pipe->set_min_samples)
2828       pipe->set_min_samples(pipe, 1);
2829 
2830    blitter_set_common_draw_rect_state(ctx, false,
2831       util_framebuffer_get_num_samples(&fb_state) > 1);
2832    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2833    blitter->draw_rectangle(blitter, ctx->velem_state, get_custom_vs,
2834                            0, 0, dstsurf->width, dstsurf->height,
2835                            0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2836 
2837    util_blitter_restore_vertex_states(blitter);
2838    util_blitter_restore_fragment_states(blitter);
2839    util_blitter_restore_fb_state(blitter);
2840    util_blitter_restore_render_cond(blitter);
2841    util_blitter_unset_running_flag(blitter);
2842 }
2843 
2844 static void *
get_stencil_blit_fallback_fs(struct blitter_context_priv * ctx,bool msaa_src)2845 get_stencil_blit_fallback_fs(struct blitter_context_priv *ctx, bool msaa_src)
2846 {
2847    if (!ctx->fs_stencil_blit_fallback[msaa_src]) {
2848       ctx->fs_stencil_blit_fallback[msaa_src] =
2849          util_make_fs_stencil_blit(ctx->base.pipe, msaa_src, ctx->has_txf_txq);
2850    }
2851 
2852    return ctx->fs_stencil_blit_fallback[msaa_src];
2853 }
2854 
2855 static void *
get_stencil_blit_fallback_dsa(struct blitter_context_priv * ctx,unsigned i)2856 get_stencil_blit_fallback_dsa(struct blitter_context_priv *ctx, unsigned i)
2857 {
2858    assert(i < ARRAY_SIZE(ctx->dsa_replicate_stencil_bit));
2859    if (!ctx->dsa_replicate_stencil_bit[i]) {
2860       struct pipe_depth_stencil_alpha_state dsa = { 0 };
2861       dsa.depth_func = PIPE_FUNC_ALWAYS;
2862       dsa.stencil[0].enabled = 1;
2863       dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
2864       dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
2865       dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
2866       dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
2867       dsa.stencil[0].valuemask = 0xff;
2868       dsa.stencil[0].writemask = 1u << i;
2869 
2870       ctx->dsa_replicate_stencil_bit[i] =
2871          ctx->base.pipe->create_depth_stencil_alpha_state(ctx->base.pipe, &dsa);
2872    }
2873    return ctx->dsa_replicate_stencil_bit[i];
2874 }
2875 
2876 /**
2877  * Performs a series of draws to implement stencil blits texture without
2878  * requiring stencil writes, updating a single bit per pixel at the time.
2879  */
2880 void
util_blitter_stencil_fallback(struct blitter_context * blitter,struct pipe_resource * dst,unsigned dst_level,const struct pipe_box * dstbox,struct pipe_resource * src,unsigned src_level,const struct pipe_box * srcbox,const struct pipe_scissor_state * scissor)2881 util_blitter_stencil_fallback(struct blitter_context *blitter,
2882                               struct pipe_resource *dst,
2883                               unsigned dst_level,
2884                               const struct pipe_box *dstbox,
2885                               struct pipe_resource *src,
2886                               unsigned src_level,
2887                               const struct pipe_box *srcbox,
2888                               const struct pipe_scissor_state *scissor)
2889 {
2890    struct blitter_context_priv *ctx = (struct blitter_context_priv *)blitter;
2891    struct pipe_context *pipe = ctx->base.pipe;
2892 
2893    /* check the saved state */
2894    util_blitter_set_running_flag(blitter);
2895    blitter_check_saved_vertex_states(ctx);
2896    blitter_check_saved_fragment_states(ctx);
2897    blitter_check_saved_fb_state(ctx);
2898    blitter_disable_render_cond(ctx);
2899 
2900    /* Initialize the surface. */
2901    struct pipe_surface *dst_view, dst_templ;
2902    util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstbox->z);
2903    dst_view = pipe->create_surface(pipe, dst, &dst_templ);
2904 
2905    /* Initialize the sampler view. */
2906    struct pipe_sampler_view src_templ, *src_view;
2907    util_blitter_default_src_texture(blitter, &src_templ, src, src_level);
2908    src_templ.format = util_format_stencil_only(src_templ.format);
2909    src_view = pipe->create_sampler_view(pipe, src, &src_templ);
2910 
2911    /* bind states */
2912    pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2913    pipe->bind_fs_state(pipe,
2914       get_stencil_blit_fallback_fs(ctx, src->nr_samples > 1));
2915 
2916    /* set a framebuffer state */
2917    struct pipe_framebuffer_state fb_state = { 0 };
2918    fb_state.width = dstbox->x + dstbox->width;
2919    fb_state.height = dstbox->y + dstbox->height;
2920    fb_state.zsbuf = dst_view;
2921    fb_state.resolve = NULL;
2922    pipe->set_framebuffer_state(pipe, &fb_state);
2923    pipe->set_sample_mask(pipe, ~0);
2924    if (pipe->set_min_samples)
2925       pipe->set_min_samples(pipe, 1);
2926 
2927    blitter_set_common_draw_rect_state(ctx, scissor != NULL,
2928       util_framebuffer_get_num_samples(&fb_state) > 1);
2929    blitter_set_dst_dimensions(ctx, dst_view->width, dst_view->height);
2930 
2931    if (scissor) {
2932       pipe->clear_depth_stencil(pipe, dst_view, PIPE_CLEAR_STENCIL, 0.0, 0,
2933                                 MAX2(dstbox->x, scissor->minx),
2934                                 MAX2(dstbox->y, scissor->miny),
2935                                 MIN2(dstbox->x + dstbox->width, scissor->maxx) - dstbox->x,
2936                                 MIN2(dstbox->y + dstbox->height, scissor->maxy) - dstbox->y,
2937                                 true);
2938       pipe->set_scissor_states(pipe, 0, 1, scissor);
2939    } else {
2940       pipe->clear_depth_stencil(pipe, dst_view, PIPE_CLEAR_STENCIL, 0.0, 0,
2941                                 dstbox->x, dstbox->y,
2942                                 dstbox->width, dstbox->height,
2943                                 true);
2944    }
2945 
2946    pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src_view);
2947    pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &ctx->sampler_state);
2948 
2949    unsigned stencil_bits =
2950       util_format_get_component_bits(dst->format,
2951                                      UTIL_FORMAT_COLORSPACE_ZS, 1);
2952 
2953    struct pipe_stencil_ref sr = { { (1u << stencil_bits) - 1 } };
2954    pipe->set_stencil_ref(pipe, sr);
2955 
2956    union blitter_attrib coord;
2957    get_texcoords(src_view, src->width0, src->height0,
2958                  srcbox->x, srcbox->y,
2959                  srcbox->x + srcbox->width, srcbox->y + srcbox->height,
2960                  srcbox->z, 0, true,
2961                  &coord);
2962 
2963    for (int i = 0; i < stencil_bits; ++i) {
2964       uint32_t mask = 1 << i;
2965       struct pipe_constant_buffer cb = {
2966          .user_buffer = &mask,
2967          .buffer_size = sizeof(mask),
2968       };
2969       pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
2970                                 false, &cb);
2971 
2972       pipe->bind_depth_stencil_alpha_state(pipe,
2973          get_stencil_blit_fallback_dsa(ctx, i));
2974 
2975       blitter->draw_rectangle(blitter, ctx->velem_state,
2976                               get_vs_passthrough_pos_generic,
2977                               dstbox->x, dstbox->y,
2978                               dstbox->x + dstbox->width,
2979                               dstbox->y + dstbox->height,
2980                               0, 1,
2981                               UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW,
2982                               &coord);
2983    }
2984 
2985    if (scissor)
2986       pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor);
2987 
2988    util_blitter_restore_vertex_states(blitter);
2989    util_blitter_restore_fragment_states(blitter);
2990    util_blitter_restore_textures_internal(blitter, 1);
2991    util_blitter_restore_fb_state(blitter);
2992    util_blitter_restore_render_cond(blitter);
2993    util_blitter_restore_constant_buffer_state(blitter);
2994    util_blitter_unset_running_flag(blitter);
2995 
2996    pipe_surface_reference(&dst_view, NULL);
2997    pipe_sampler_view_reference(&src_view, NULL);
2998 }
2999