xref: /aosp_15_r20/external/mesa3d/src/gallium/auxiliary/util/u_blitter.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /**************************************************************************
2  *
3  * Copyright 2009 Marek Olšák <[email protected]>
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, NULL);
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       for (unsigned i = 0; i < 4; i++)
1836          ctx->vertices[i][1][3] = coord.texcoord.w;
1837 
1838       /* Cubemaps don't use draw_rectangle. */
1839       blitter_draw(ctx, ctx->velem_state, get_vs,
1840                    dst_x1, dst_y1, dst_x2, dst_y2, 0, 1);
1841    } else {
1842       ctx->base.draw_rectangle(&ctx->base, ctx->velem_state, get_vs,
1843                                dst_x1, dst_y1, dst_x2, dst_y2,
1844                                0, 1, type, &coord);
1845    }
1846 }
1847 
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)1848 static void do_blits(struct blitter_context_priv *ctx,
1849                      struct pipe_surface *dst,
1850                      const struct pipe_box *dstbox,
1851                      struct pipe_sampler_view *src,
1852                      unsigned src_width0,
1853                      unsigned src_height0,
1854                      const struct pipe_box *srcbox,
1855                      bool is_zsbuf,
1856                      bool uses_txf, bool sample0_only,
1857                      unsigned dst_sample)
1858 {
1859    struct pipe_context *pipe = ctx->base.pipe;
1860    unsigned src_samples = src->texture->nr_samples;
1861    unsigned dst_samples = dst->texture->nr_samples;
1862    bool sample_shading = ctx->has_sample_shading && src_samples > 1 &&
1863                          src_samples == dst_samples && !sample0_only;
1864    enum pipe_texture_target src_target = src->target;
1865    struct pipe_framebuffer_state fb_state = {0};
1866 
1867    /* Initialize framebuffer state. */
1868    fb_state.width = dst->width;
1869    fb_state.height = dst->height;
1870    fb_state.nr_cbufs = is_zsbuf ? 0 : 1;
1871 
1872    blitter_set_dst_dimensions(ctx, fb_state.width, fb_state.height);
1873 
1874    if ((src_target == PIPE_TEXTURE_1D ||
1875         src_target == PIPE_TEXTURE_2D ||
1876         src_target == PIPE_TEXTURE_RECT) &&
1877        (src_samples <= 1 || sample_shading)) {
1878       /* Set framebuffer state. */
1879       if (is_zsbuf) {
1880          fb_state.zsbuf = dst;
1881       } else {
1882          fb_state.cbufs[0] = dst;
1883       }
1884       pipe->set_framebuffer_state(pipe, &fb_state);
1885 
1886       /* Draw. */
1887       pipe->set_sample_mask(pipe, dst_sample ? BITFIELD_BIT(dst_sample - 1) : ~0);
1888       if (pipe->set_min_samples)
1889          pipe->set_min_samples(pipe, sample_shading ? dst_samples : 1);
1890       blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1891                        dstbox->x + dstbox->width,
1892                        dstbox->y + dstbox->height,
1893                        src, src_width0, src_height0, srcbox->x, srcbox->y,
1894                        srcbox->x + srcbox->width, srcbox->y + srcbox->height,
1895                        0, 0, uses_txf, UTIL_BLITTER_ATTRIB_TEXCOORD_XY);
1896    } else {
1897       /* Draw the quad with the generic codepath. */
1898       int dst_z;
1899       for (dst_z = 0; dst_z < dstbox->depth; dst_z++) {
1900          struct pipe_surface *old;
1901          bool flipped = (srcbox->depth < 0);
1902          float depth_center_offset = 0.0;
1903          int src_depth = abs(srcbox->depth);
1904          float src_z_step = src_depth / (float)dstbox->depth;
1905 
1906          /* Scale Z properly if the blit is scaled.
1907           *
1908           * When downscaling, we want the coordinates centered, so that
1909           * mipmapping works for 3D textures. For example, when generating
1910           * a 4x4x4 level, this wouldn't average the pixels:
1911           *
1912           *   src Z:  0 1 2 3 4 5 6 7
1913           *   dst Z:  0   1   2   3
1914           *
1915           * Because the pixels are not centered below the pixels of the higher
1916           * level. Therefore, we want this:
1917           *   src Z:  0 1 2 3 4 5 6 7
1918           *   dst Z:   0   1   2   3
1919           *
1920           * This calculation is taken from the radv driver.
1921           */
1922          if (src_target == PIPE_TEXTURE_3D)
1923             depth_center_offset = 0.5 / dstbox->depth * src_depth;
1924 
1925          if (flipped) {
1926             src_z_step *= - 1;
1927             depth_center_offset *= -1;
1928          }
1929 
1930          float src_z = dst_z * src_z_step + depth_center_offset;
1931 
1932          /* Set framebuffer state. */
1933          if (is_zsbuf) {
1934             fb_state.zsbuf = dst;
1935          } else {
1936             fb_state.cbufs[0] = dst;
1937          }
1938          pipe->set_framebuffer_state(pipe, &fb_state);
1939 
1940          /* See if we need to blit a multisample or singlesample buffer. */
1941          if (sample0_only || (src_samples == dst_samples && dst_samples > 1)) {
1942             /* MSAA copy. */
1943             unsigned i, max_sample = sample0_only ? 0 : dst_samples - 1;
1944 
1945             if (sample_shading) {
1946                assert(dst_sample == 0);
1947                pipe->set_sample_mask(pipe, ~0);
1948                if (pipe->set_min_samples)
1949                   pipe->set_min_samples(pipe, max_sample);
1950                blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1951                                 dstbox->x + dstbox->width,
1952                                 dstbox->y + dstbox->height,
1953                                 src, src_width0, src_height0,
1954                                 srcbox->x, srcbox->y,
1955                                 srcbox->x + srcbox->width,
1956                                 srcbox->y + srcbox->height,
1957                                 srcbox->z + src_z, 0, uses_txf,
1958                                 UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
1959             } else {
1960                if (pipe->set_min_samples)
1961                   pipe->set_min_samples(pipe, 1);
1962 
1963                for (i = 0; i <= max_sample; i++) {
1964                   pipe->set_sample_mask(pipe, 1 << i);
1965                   blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1966                                    dstbox->x + dstbox->width,
1967                                    dstbox->y + dstbox->height,
1968                                    src, src_width0, src_height0,
1969                                    srcbox->x, srcbox->y,
1970                                    srcbox->x + srcbox->width,
1971                                    srcbox->y + srcbox->height,
1972                                    srcbox->z + src_z, i, uses_txf,
1973                                    UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
1974                }
1975             }
1976          } else {
1977             /* Normal copy, MSAA upsampling, or MSAA resolve. */
1978             pipe->set_sample_mask(pipe, dst_sample ? BITFIELD_BIT(dst_sample - 1) : ~0);
1979             if (pipe->set_min_samples)
1980                pipe->set_min_samples(pipe, 1);
1981             blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1982                              dstbox->x + dstbox->width,
1983                              dstbox->y + dstbox->height,
1984                              src, src_width0, src_height0,
1985                              srcbox->x, srcbox->y,
1986                              srcbox->x + srcbox->width,
1987                              srcbox->y + srcbox->height,
1988                              srcbox->z + src_z, 0, uses_txf,
1989                              UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
1990          }
1991 
1992          /* Get the next surface or (if this is the last iteration)
1993           * just unreference the last one. */
1994          old = dst;
1995          if (dst_z < dstbox->depth-1) {
1996             dst = util_blitter_get_next_surface_layer(ctx->base.pipe, dst);
1997          }
1998          if (dst_z) {
1999             pipe_surface_reference(&old, NULL);
2000          }
2001       }
2002    }
2003 }
2004 
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,void * fs_override)2005 void util_blitter_blit_generic(struct blitter_context *blitter,
2006                                struct pipe_surface *dst,
2007                                const struct pipe_box *dstbox,
2008                                struct pipe_sampler_view *src,
2009                                const struct pipe_box *srcbox,
2010                                unsigned src_width0, unsigned src_height0,
2011                                unsigned mask, unsigned filter,
2012                                const struct pipe_scissor_state *scissor,
2013                                bool alpha_blend, bool sample0_only,
2014                                unsigned dst_sample,
2015                                void *fs_override)
2016 {
2017    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2018    unsigned count = 0;
2019    struct pipe_context *pipe = ctx->base.pipe;
2020    enum pipe_texture_target src_target = src->target;
2021    unsigned src_samples = src->texture->nr_samples;
2022    unsigned dst_samples = dst->texture->nr_samples;
2023    void *sampler_state;
2024    const struct util_format_description *src_desc =
2025          util_format_description(src->format);
2026    const struct util_format_description *dst_desc =
2027          util_format_description(dst->format);
2028 
2029    bool src_has_color = src_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
2030    bool src_has_depth = util_format_has_depth(src_desc);
2031    bool src_has_stencil = util_format_has_stencil(src_desc);
2032 
2033    bool dst_has_color = mask & PIPE_MASK_RGBA &&
2034                         dst_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
2035    bool dst_has_depth = mask & PIPE_MASK_Z &&
2036                         util_format_has_depth(dst_desc);
2037    bool dst_has_stencil = ctx->has_stencil_export &&
2038                           mask & PIPE_MASK_S &&
2039                           util_format_has_stencil(dst_desc);
2040 
2041    /* Return if there is nothing to do. */
2042    if (!dst_has_color && !dst_has_depth && !dst_has_stencil) {
2043       goto out;
2044    }
2045 
2046    bool is_scaled = dstbox->width != abs(srcbox->width) ||
2047                     dstbox->height != abs(srcbox->height) ||
2048                     dstbox->depth != abs(srcbox->depth);
2049 
2050    if (src_has_stencil || !is_scaled)
2051       filter = PIPE_TEX_FILTER_NEAREST;
2052 
2053    bool use_txf = false;
2054 
2055    /* Don't support scaled blits. The TXF shader uses F2I for rounding. */
2056    if (ctx->has_txf_txq &&
2057        !is_scaled &&
2058        filter == PIPE_TEX_FILTER_NEAREST &&
2059        src->target != PIPE_TEXTURE_CUBE &&
2060        src->target != PIPE_TEXTURE_CUBE_ARRAY) {
2061       int src_width = u_minify(src_width0, src->u.tex.first_level);
2062       int src_height = u_minify(src_height0, src->u.tex.first_level);
2063       int src_depth = src->u.tex.last_layer + 1;
2064       struct pipe_box box = *srcbox;
2065 
2066       /* Eliminate negative width/height/depth. */
2067       if (box.width < 0) {
2068          box.x += box.width;
2069          box.width *= -1;
2070       }
2071       if (box.height < 0) {
2072          box.y += box.height;
2073          box.height *= -1;
2074       }
2075       if (box.depth < 0) {
2076          box.z += box.depth;
2077          box.depth *= -1;
2078       }
2079 
2080       /* See if srcbox is in bounds. TXF doesn't clamp the coordinates. */
2081       use_txf =
2082          box.x >= 0 && box.x < src_width &&
2083          box.y >= 0 && box.y < src_height &&
2084          box.z >= 0 && box.z < src_depth &&
2085          box.x + box.width > 0 && box.x + box.width <= src_width &&
2086          box.y + box.height > 0 && box.y + box.height <= src_height &&
2087          box.z + box.depth > 0 && box.z + box.depth <= src_depth;
2088    }
2089 
2090    /* Check whether the states are properly saved. */
2091    util_blitter_set_running_flag(blitter);
2092    blitter_check_saved_vertex_states(ctx);
2093    blitter_check_saved_fragment_states(ctx);
2094    blitter_check_saved_textures(ctx);
2095    blitter_check_saved_fb_state(ctx);
2096    blitter_disable_render_cond(ctx);
2097 
2098    void *fs = fs_override;
2099 
2100    /* Blend, DSA, fragment shader. */
2101    if (dst_has_depth && dst_has_stencil) {
2102       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2103       pipe->bind_depth_stencil_alpha_state(pipe,
2104                                            ctx->dsa_write_depth_stencil);
2105 
2106       if (!fs) {
2107          if (src_has_color) {
2108             assert(use_txf);
2109             fs = blitter_get_fs_pack_color_zs(ctx, src_target,
2110                                               src_samples, dst->format, false);
2111          } else {
2112             fs = blitter_get_fs_texfetch_depthstencil(ctx, src_target,
2113                                                       src_samples, dst_samples,
2114                                                       use_txf);
2115          }
2116       }
2117    } else if (dst_has_depth) {
2118       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2119       pipe->bind_depth_stencil_alpha_state(pipe,
2120                                            ctx->dsa_write_depth_keep_stencil);
2121       if (!fs) {
2122          if (src_has_color &&
2123              (src->format == PIPE_FORMAT_R32_UINT ||
2124               src->format == PIPE_FORMAT_R32G32_UINT)) {
2125             assert(use_txf);
2126             fs = blitter_get_fs_pack_color_zs(ctx, src_target, src_samples,
2127                                               dst->format, false);
2128          } else {
2129             fs = blitter_get_fs_texfetch_depth(ctx, src_target, src_samples,
2130                                                dst_samples, use_txf);
2131          }
2132       }
2133    } else if (dst_has_stencil) {
2134       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2135       pipe->bind_depth_stencil_alpha_state(pipe,
2136                                            ctx->dsa_keep_depth_write_stencil);
2137 
2138       assert(src_has_stencil); /* unpacking from color is unsupported */
2139       if (!fs) {
2140          fs = blitter_get_fs_texfetch_stencil(ctx, src_target, src_samples,
2141                                               dst_samples, use_txf);
2142       }
2143    } else {
2144       unsigned colormask = mask & PIPE_MASK_RGBA;
2145 
2146       pipe->bind_blend_state(pipe, ctx->blend[colormask][alpha_blend]);
2147       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2148 
2149       if (!fs) {
2150          if (src_has_depth &&
2151              (dst->format == PIPE_FORMAT_R32_UINT ||
2152               dst->format == PIPE_FORMAT_R32G32_UINT)) {
2153             assert(use_txf);
2154             fs = blitter_get_fs_pack_color_zs(ctx, src_target, src_samples,
2155                                               src->format, true);
2156          } else {
2157             fs = blitter_get_fs_texfetch_col(ctx, src->format, dst->format,
2158                                              src_target, src_samples,
2159                                              dst_samples, filter, use_txf);
2160          }
2161       }
2162    }
2163 
2164    ctx->bind_fs_state(pipe, fs);
2165 
2166    /* Set the linear filter only for scaled color non-MSAA blits. */
2167    if (filter == PIPE_TEX_FILTER_LINEAR) {
2168       if (src_target == PIPE_TEXTURE_RECT && ctx->has_texrect) {
2169          sampler_state = ctx->sampler_state_rect_linear;
2170       } else {
2171          sampler_state = ctx->sampler_state_linear;
2172       }
2173    } else {
2174       if (src_target == PIPE_TEXTURE_RECT && ctx->has_texrect) {
2175          sampler_state = ctx->sampler_state_rect;
2176       } else {
2177          sampler_state = ctx->sampler_state;
2178       }
2179    }
2180 
2181    /* Set samplers. */
2182    if (src_has_depth && src_has_stencil &&
2183        (dst_has_color || (dst_has_depth && dst_has_stencil))) {
2184       /* Setup two samplers, one for depth and the other one for stencil. */
2185       struct pipe_sampler_view templ;
2186       struct pipe_sampler_view *views[2];
2187       void *samplers[2] = {sampler_state, sampler_state};
2188 
2189       templ = *src;
2190       templ.format = util_format_stencil_only(templ.format);
2191       assert(templ.format != PIPE_FORMAT_NONE);
2192 
2193       views[0] = src;
2194       views[1] = pipe->create_sampler_view(pipe, src->texture, &templ);
2195 
2196       count = 2;
2197       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 2, 0, false, views);
2198       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 2, samplers);
2199 
2200       pipe_sampler_view_reference(&views[1], NULL);
2201    } else if (src_has_stencil && dst_has_stencil) {
2202       /* Set a stencil-only sampler view for it not to sample depth instead. */
2203       struct pipe_sampler_view templ;
2204       struct pipe_sampler_view *view;
2205 
2206       templ = *src;
2207       templ.format = util_format_stencil_only(templ.format);
2208       assert(templ.format != PIPE_FORMAT_NONE);
2209 
2210       view = pipe->create_sampler_view(pipe, src->texture, &templ);
2211 
2212       count = 1;
2213       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &view);
2214       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2215                                 0, 1, &sampler_state);
2216 
2217       pipe_sampler_view_reference(&view, NULL);
2218    } else {
2219       count = 1;
2220       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src);
2221       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2222                                 0, 1, &sampler_state);
2223    }
2224 
2225    if (scissor) {
2226       pipe->set_scissor_states(pipe, 0, 1, scissor);
2227    }
2228 
2229    blitter_set_common_draw_rect_state(ctx, scissor != NULL, dst_samples > 1);
2230 
2231    do_blits(ctx, dst, dstbox, src, src_width0, src_height0,
2232             srcbox, dst_has_depth || dst_has_stencil, use_txf, sample0_only,
2233             dst_sample);
2234    util_blitter_unset_running_flag(blitter);
2235 out:
2236    util_blitter_restore_vertex_states(blitter);
2237    util_blitter_restore_fragment_states(blitter);
2238    util_blitter_restore_textures_internal(blitter, count);
2239    util_blitter_restore_fb_state(blitter);
2240    if (scissor) {
2241       pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor);
2242    }
2243    util_blitter_restore_render_cond(blitter);
2244 }
2245 
2246 void
util_blitter_blit(struct blitter_context * blitter,const struct pipe_blit_info * info,void * fs_override)2247 util_blitter_blit(struct blitter_context *blitter,
2248                   const struct pipe_blit_info *info,
2249                   void *fs_override)
2250 {
2251    struct pipe_resource *dst = info->dst.resource;
2252    struct pipe_resource *src = info->src.resource;
2253    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2254    struct pipe_context *pipe = ctx->base.pipe;
2255    struct pipe_surface *dst_view, dst_templ;
2256    struct pipe_sampler_view src_templ, *src_view;
2257 
2258    /* Initialize the surface. */
2259    util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level,
2260                                     info->dst.box.z);
2261    dst_templ.format = info->dst.format;
2262    dst_view = pipe->create_surface(pipe, dst, &dst_templ);
2263 
2264    /* Initialize the sampler view. */
2265    util_blitter_default_src_texture(blitter, &src_templ, src, info->src.level);
2266    src_templ.format = info->src.format;
2267    src_view = pipe->create_sampler_view(pipe, src, &src_templ);
2268 
2269    /* Copy. */
2270    util_blitter_blit_generic(blitter, dst_view, &info->dst.box,
2271                              src_view, &info->src.box, src->width0, src->height0,
2272                              info->mask, info->filter,
2273                              info->scissor_enable ? &info->scissor : NULL,
2274                              info->alpha_blend, info->sample0_only,
2275                              info->dst_sample, fs_override);
2276 
2277    pipe_surface_reference(&dst_view, NULL);
2278    pipe_sampler_view_reference(&src_view, NULL);
2279 }
2280 
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)2281 void util_blitter_generate_mipmap(struct blitter_context *blitter,
2282                                   struct pipe_resource *tex,
2283                                   enum pipe_format format,
2284                                   unsigned base_level, unsigned last_level,
2285                                   unsigned first_layer, unsigned last_layer)
2286 {
2287    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2288    struct pipe_context *pipe = ctx->base.pipe;
2289    struct pipe_surface dst_templ, *dst_view;
2290    struct pipe_sampler_view src_templ, *src_view;
2291    bool is_depth;
2292    void *sampler_state;
2293    const struct util_format_description *desc =
2294          util_format_description(format);
2295    unsigned src_level;
2296    unsigned target = tex->target;
2297 
2298    if (ctx->cube_as_2darray &&
2299        (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY))
2300       target = PIPE_TEXTURE_2D_ARRAY;
2301 
2302    assert(tex->nr_samples <= 1);
2303    /* Disallow stencil formats without depth. */
2304    assert(!util_format_has_stencil(desc) || util_format_has_depth(desc));
2305 
2306    is_depth = desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS;
2307 
2308    /* Check whether the states are properly saved. */
2309    util_blitter_set_running_flag(blitter);
2310    blitter_check_saved_vertex_states(ctx);
2311    blitter_check_saved_fragment_states(ctx);
2312    blitter_check_saved_textures(ctx);
2313    blitter_check_saved_fb_state(ctx);
2314    blitter_disable_render_cond(ctx);
2315 
2316    /* Set states. */
2317    if (is_depth) {
2318       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2319       pipe->bind_depth_stencil_alpha_state(pipe,
2320                                            ctx->dsa_write_depth_keep_stencil);
2321       ctx->bind_fs_state(pipe,
2322                          blitter_get_fs_texfetch_depth(ctx, target, 1, 1, false));
2323    } else {
2324       pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2325       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2326       ctx->bind_fs_state(pipe,
2327             blitter_get_fs_texfetch_col(ctx, tex->format, tex->format, target,
2328                                         1, 1, PIPE_TEX_FILTER_LINEAR, false));
2329    }
2330 
2331    if (target == PIPE_TEXTURE_RECT) {
2332       sampler_state = ctx->sampler_state_rect_linear;
2333    } else {
2334       sampler_state = ctx->sampler_state_linear;
2335    }
2336    pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2337                              0, 1, &sampler_state);
2338 
2339    blitter_set_common_draw_rect_state(ctx, false, false);
2340 
2341    for (src_level = base_level; src_level < last_level; src_level++) {
2342       struct pipe_box dstbox = {0}, srcbox = {0};
2343       unsigned dst_level = src_level + 1;
2344 
2345       dstbox.width = u_minify(tex->width0, dst_level);
2346       dstbox.height = u_minify(tex->height0, dst_level);
2347 
2348       srcbox.width = u_minify(tex->width0, src_level);
2349       srcbox.height = u_minify(tex->height0, src_level);
2350 
2351       if (target == PIPE_TEXTURE_3D) {
2352          dstbox.depth = util_num_layers(tex, dst_level);
2353          srcbox.depth = util_num_layers(tex, src_level);
2354       } else {
2355          dstbox.z = srcbox.z = first_layer;
2356          dstbox.depth = srcbox.depth = last_layer - first_layer + 1;
2357       }
2358 
2359       /* Initialize the surface. */
2360       util_blitter_default_dst_texture(&dst_templ, tex, dst_level,
2361                                        first_layer);
2362       dst_templ.format = format;
2363       dst_view = pipe->create_surface(pipe, tex, &dst_templ);
2364 
2365       /* Initialize the sampler view. */
2366       util_blitter_default_src_texture(blitter, &src_templ, tex, src_level);
2367       src_templ.format = format;
2368       src_view = pipe->create_sampler_view(pipe, tex, &src_templ);
2369 
2370       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src_view);
2371 
2372       do_blits(ctx, dst_view, &dstbox, src_view, tex->width0, tex->height0,
2373                &srcbox, is_depth, false, false, 0);
2374 
2375       pipe_surface_reference(&dst_view, NULL);
2376       pipe_sampler_view_reference(&src_view, NULL);
2377    }
2378 
2379    util_blitter_restore_vertex_states(blitter);
2380    util_blitter_restore_fragment_states(blitter);
2381    util_blitter_restore_textures_internal(blitter, 1);
2382    util_blitter_restore_fb_state(blitter);
2383    util_blitter_restore_render_cond(blitter);
2384    util_blitter_unset_running_flag(blitter);
2385 }
2386 
2387 /* 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)2388 void util_blitter_clear_render_target(struct blitter_context *blitter,
2389                                       struct pipe_surface *dstsurf,
2390                                       const union pipe_color_union *color,
2391                                       unsigned dstx, unsigned dsty,
2392                                       unsigned width, unsigned height)
2393 {
2394    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2395    struct pipe_context *pipe = ctx->base.pipe;
2396    struct pipe_framebuffer_state fb_state = { 0 };
2397    bool msaa;
2398    unsigned num_layers;
2399    blitter_get_vs_func get_vs;
2400 
2401    assert(dstsurf->texture);
2402    if (!dstsurf->texture)
2403       return;
2404 
2405    /* check the saved state */
2406    util_blitter_set_running_flag(blitter);
2407    blitter_check_saved_vertex_states(ctx);
2408    blitter_check_saved_fragment_states(ctx);
2409    blitter_check_saved_fb_state(ctx);
2410    blitter_disable_render_cond(ctx);
2411 
2412    /* bind states */
2413    pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2414    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2415    bind_fs_write_one_cbuf(ctx);
2416 
2417    /* set a framebuffer state */
2418    fb_state.width = dstsurf->width;
2419    fb_state.height = dstsurf->height;
2420    fb_state.nr_cbufs = 1;
2421    fb_state.cbufs[0] = dstsurf;
2422    fb_state.zsbuf = NULL;
2423    fb_state.resolve = NULL;
2424    pipe->set_framebuffer_state(pipe, &fb_state);
2425    pipe->set_sample_mask(pipe, ~0);
2426    if (pipe->set_min_samples)
2427       pipe->set_min_samples(pipe, 1);
2428    msaa = util_framebuffer_get_num_samples(&fb_state) > 1;
2429 
2430    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2431    blitter_set_common_draw_rect_state(ctx, false, msaa);
2432 
2433    union blitter_attrib attrib;
2434    memcpy(attrib.color, color->ui, sizeof(color->ui));
2435 
2436    num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
2437 
2438    if (num_layers > 1 && ctx->has_layered) {
2439       get_vs = get_vs_layered;
2440    } else {
2441       get_vs = get_vs_passthrough_pos_generic;
2442       num_layers = 1;
2443    }
2444 
2445    blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
2446                            dstx, dsty, dstx+width, dsty+height, 0,
2447                            num_layers, UTIL_BLITTER_ATTRIB_COLOR, &attrib);
2448 
2449    util_blitter_restore_vertex_states(blitter);
2450    util_blitter_restore_fragment_states(blitter);
2451    util_blitter_restore_fb_state(blitter);
2452    util_blitter_restore_render_cond(blitter);
2453    util_blitter_unset_running_flag(blitter);
2454 }
2455 
2456 /* 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)2457 void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
2458                                       struct pipe_surface *dstsurf,
2459                                       unsigned clear_flags,
2460                                       double depth,
2461                                       unsigned stencil,
2462                                       unsigned dstx, unsigned dsty,
2463                                       unsigned width, unsigned height)
2464 {
2465    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2466    struct pipe_context *pipe = ctx->base.pipe;
2467    struct pipe_framebuffer_state fb_state = { 0 };
2468    struct pipe_stencil_ref sr = { { 0 } };
2469    unsigned num_layers;
2470 
2471    assert(dstsurf->texture);
2472    if (!dstsurf->texture)
2473       return;
2474 
2475    /* check the saved state */
2476    util_blitter_set_running_flag(blitter);
2477    blitter_check_saved_vertex_states(ctx);
2478    blitter_check_saved_fragment_states(ctx);
2479    blitter_check_saved_fb_state(ctx);
2480    blitter_disable_render_cond(ctx);
2481 
2482    /* bind states */
2483    pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2484    if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
2485       sr.ref_value[0] = stencil & 0xff;
2486       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
2487       pipe->set_stencil_ref(pipe, sr);
2488    }
2489    else if (clear_flags & PIPE_CLEAR_DEPTH) {
2490       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
2491    }
2492    else if (clear_flags & PIPE_CLEAR_STENCIL) {
2493       sr.ref_value[0] = stencil & 0xff;
2494       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
2495       pipe->set_stencil_ref(pipe, sr);
2496    }
2497    else
2498       /* hmm that should be illegal probably, or make it a no-op somewhere */
2499       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2500 
2501    bind_fs_empty(ctx);
2502 
2503    /* set a framebuffer state */
2504    fb_state.width = dstsurf->width;
2505    fb_state.height = dstsurf->height;
2506    fb_state.nr_cbufs = 0;
2507    fb_state.cbufs[0] = NULL;
2508    fb_state.zsbuf = dstsurf;
2509    fb_state.resolve = NULL;
2510    pipe->set_framebuffer_state(pipe, &fb_state);
2511    pipe->set_sample_mask(pipe, ~0);
2512    if (pipe->set_min_samples)
2513       pipe->set_min_samples(pipe, 1);
2514 
2515    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2516 
2517    num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
2518    if (num_layers > 1 && ctx->has_layered) {
2519       blitter_set_common_draw_rect_state(ctx, false, false);
2520       blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_layered,
2521                               dstx, dsty, dstx+width, dsty+height, depth,
2522                               num_layers, UTIL_BLITTER_ATTRIB_NONE, NULL);
2523    } else {
2524       blitter_set_common_draw_rect_state(ctx, false, false);
2525       blitter->draw_rectangle(blitter, ctx->velem_state,
2526                               get_vs_passthrough_pos,
2527                               dstx, dsty, dstx+width, dsty+height, depth, 1,
2528                               UTIL_BLITTER_ATTRIB_NONE, NULL);
2529    }
2530 
2531    util_blitter_restore_vertex_states(blitter);
2532    util_blitter_restore_fragment_states(blitter);
2533    util_blitter_restore_fb_state(blitter);
2534    util_blitter_restore_render_cond(blitter);
2535    util_blitter_unset_running_flag(blitter);
2536 }
2537 
2538 /* 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)2539 void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
2540                                        struct pipe_surface *zsurf,
2541                                        struct pipe_surface *cbsurf,
2542                                        unsigned sample_mask,
2543                                        void *dsa_stage, float depth)
2544 {
2545    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2546    struct pipe_context *pipe = ctx->base.pipe;
2547    struct pipe_framebuffer_state fb_state = { 0 };
2548 
2549    assert(zsurf->texture);
2550    if (!zsurf->texture)
2551       return;
2552 
2553    /* check the saved state */
2554    util_blitter_set_running_flag(blitter);
2555    blitter_check_saved_vertex_states(ctx);
2556    blitter_check_saved_fragment_states(ctx);
2557    blitter_check_saved_fb_state(ctx);
2558    blitter_disable_render_cond(ctx);
2559 
2560    /* bind states */
2561    pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA][0] :
2562                                          ctx->blend[0][0]);
2563    pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
2564    if (cbsurf)
2565       bind_fs_write_one_cbuf(ctx);
2566    else
2567       bind_fs_empty(ctx);
2568 
2569    /* set a framebuffer state */
2570    fb_state.width = zsurf->width;
2571    fb_state.height = zsurf->height;
2572    fb_state.nr_cbufs = 1;
2573    if (cbsurf) {
2574       fb_state.cbufs[0] = cbsurf;
2575       fb_state.nr_cbufs = 1;
2576    } else {
2577       fb_state.cbufs[0] = NULL;
2578       fb_state.nr_cbufs = 0;
2579    }
2580    fb_state.zsbuf = zsurf;
2581    fb_state.resolve = NULL;
2582    pipe->set_framebuffer_state(pipe, &fb_state);
2583    pipe->set_sample_mask(pipe, sample_mask);
2584    if (pipe->set_min_samples)
2585       pipe->set_min_samples(pipe, 1);
2586 
2587    blitter_set_common_draw_rect_state(ctx, false,
2588       util_framebuffer_get_num_samples(&fb_state) > 1);
2589    blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height);
2590    blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2591                            0, 0, zsurf->width, zsurf->height, depth,
2592                            1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2593 
2594    util_blitter_restore_vertex_states(blitter);
2595    util_blitter_restore_fragment_states(blitter);
2596    util_blitter_restore_fb_state(blitter);
2597    util_blitter_restore_render_cond(blitter);
2598    util_blitter_unset_running_flag(blitter);
2599 }
2600 
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)2601 void util_blitter_clear_buffer(struct blitter_context *blitter,
2602                                struct pipe_resource *dst,
2603                                unsigned offset, unsigned size,
2604                                unsigned num_channels,
2605                                const union pipe_color_union *clear_value)
2606 {
2607    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2608    struct pipe_context *pipe = ctx->base.pipe;
2609    struct pipe_vertex_buffer vb = {0};
2610    struct pipe_stream_output_target *so_target = NULL;
2611    unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
2612 
2613    assert(num_channels >= 1);
2614    assert(num_channels <= 4);
2615 
2616    /* IMPORTANT:  DON'T DO ANY BOUNDS CHECKING HERE!
2617     *
2618     * R600 uses this to initialize texture resources, so width0 might not be
2619     * what you think it is.
2620     */
2621 
2622    /* Streamout is required. */
2623    if (!ctx->has_stream_out) {
2624       assert(!"Streamout unsupported in util_blitter_clear_buffer()");
2625       return;
2626    }
2627 
2628    /* Some alignment is required. */
2629    if (offset % 4 != 0 || size % 4 != 0) {
2630       assert(!"Bad alignment in util_blitter_clear_buffer()");
2631       return;
2632    }
2633 
2634    u_upload_data(pipe->stream_uploader, 0, num_channels*4, 4, clear_value,
2635                  &vb.buffer_offset, &vb.buffer.resource);
2636    if (!vb.buffer.resource)
2637       goto out;
2638 
2639    util_blitter_set_running_flag(blitter);
2640    blitter_check_saved_vertex_states(ctx);
2641    blitter_disable_render_cond(ctx);
2642 
2643    pipe->bind_vertex_elements_state(pipe,
2644                                     ctx->velem_state_readbuf[num_channels-1]);
2645    pipe->set_vertex_buffers(pipe, 1, &vb);
2646    bind_vs_pos_only(ctx, num_channels);
2647 
2648    if (ctx->has_geometry_shader)
2649       pipe->bind_gs_state(pipe, NULL);
2650    if (ctx->has_tessellation) {
2651       pipe->bind_tcs_state(pipe, NULL);
2652       pipe->bind_tes_state(pipe, NULL);
2653    }
2654    pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
2655 
2656    so_target = pipe->create_stream_output_target(pipe, dst, offset, size);
2657    pipe->set_stream_output_targets(pipe, 1, &so_target, offsets);
2658 
2659    util_draw_arrays(pipe, MESA_PRIM_POINTS, 0, size / 4);
2660 
2661 out:
2662    util_blitter_restore_vertex_states(blitter);
2663    util_blitter_restore_render_cond(blitter);
2664    util_blitter_unset_running_flag(blitter);
2665    pipe_so_target_reference(&so_target, NULL);
2666 }
2667 
2668 /* 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)2669 void util_blitter_custom_resolve_color(struct blitter_context *blitter,
2670                                        struct pipe_resource *dst,
2671                                        unsigned dst_level,
2672                                        unsigned dst_layer,
2673                                        struct pipe_resource *src,
2674                                        unsigned src_layer,
2675                                        unsigned sample_mask,
2676                                        void *custom_blend,
2677                                        enum pipe_format format)
2678 {
2679    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2680    struct pipe_context *pipe = ctx->base.pipe;
2681    struct pipe_framebuffer_state fb_state = { 0 };
2682    struct pipe_surface *srcsurf, *dstsurf, surf_tmpl;
2683 
2684    util_blitter_set_running_flag(blitter);
2685    blitter_check_saved_vertex_states(ctx);
2686    blitter_check_saved_fragment_states(ctx);
2687    blitter_disable_render_cond(ctx);
2688 
2689    /* bind states */
2690    pipe->bind_blend_state(pipe, custom_blend);
2691    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2692    bind_fs_write_one_cbuf(ctx);
2693    pipe->set_sample_mask(pipe, sample_mask);
2694    if (pipe->set_min_samples)
2695       pipe->set_min_samples(pipe, 1);
2696 
2697    memset(&surf_tmpl, 0, sizeof(surf_tmpl));
2698    surf_tmpl.format = format;
2699    surf_tmpl.u.tex.level = dst_level;
2700    surf_tmpl.u.tex.first_layer = dst_layer;
2701    surf_tmpl.u.tex.last_layer = dst_layer;
2702 
2703    dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl);
2704 
2705    surf_tmpl.u.tex.level = 0;
2706    surf_tmpl.u.tex.first_layer = src_layer;
2707    surf_tmpl.u.tex.last_layer = src_layer;
2708 
2709    srcsurf = pipe->create_surface(pipe, src, &surf_tmpl);
2710 
2711    /* set a framebuffer state */
2712    fb_state.width = src->width0;
2713    fb_state.height = src->height0;
2714    fb_state.nr_cbufs = 2;
2715    fb_state.cbufs[0] = srcsurf;
2716    fb_state.cbufs[1] = dstsurf;
2717    fb_state.zsbuf = NULL;
2718    fb_state.resolve = NULL;
2719    pipe->set_framebuffer_state(pipe, &fb_state);
2720 
2721    blitter_set_common_draw_rect_state(ctx, false,
2722       util_framebuffer_get_num_samples(&fb_state) > 1);
2723    blitter_set_dst_dimensions(ctx, src->width0, src->height0);
2724    blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2725                            0, 0, src->width0, src->height0,
2726                            0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2727    util_blitter_restore_fb_state(blitter);
2728    util_blitter_restore_vertex_states(blitter);
2729    util_blitter_restore_fragment_states(blitter);
2730    util_blitter_restore_render_cond(blitter);
2731    util_blitter_unset_running_flag(blitter);
2732 
2733    pipe_surface_reference(&srcsurf, NULL);
2734    pipe_surface_reference(&dstsurf, NULL);
2735 }
2736 
util_blitter_custom_color(struct blitter_context * blitter,struct pipe_surface * dstsurf,void * custom_blend)2737 void util_blitter_custom_color(struct blitter_context *blitter,
2738                                struct pipe_surface *dstsurf,
2739                                void *custom_blend)
2740 {
2741    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2742    struct pipe_context *pipe = ctx->base.pipe;
2743    struct pipe_framebuffer_state fb_state = { 0 };
2744 
2745    assert(dstsurf->texture);
2746    if (!dstsurf->texture)
2747       return;
2748 
2749    /* check the saved state */
2750    util_blitter_set_running_flag(blitter);
2751    blitter_check_saved_vertex_states(ctx);
2752    blitter_check_saved_fragment_states(ctx);
2753    blitter_check_saved_fb_state(ctx);
2754    blitter_disable_render_cond(ctx);
2755 
2756    /* bind states */
2757    pipe->bind_blend_state(pipe, custom_blend ? custom_blend
2758                                              : ctx->blend[PIPE_MASK_RGBA][0]);
2759    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2760    bind_fs_write_one_cbuf(ctx);
2761 
2762    /* set a framebuffer state */
2763    fb_state.width = dstsurf->width;
2764    fb_state.height = dstsurf->height;
2765    fb_state.nr_cbufs = 1;
2766    fb_state.cbufs[0] = dstsurf;
2767    fb_state.zsbuf = NULL;
2768    fb_state.resolve = NULL;
2769    pipe->set_framebuffer_state(pipe, &fb_state);
2770    pipe->set_sample_mask(pipe, ~0);
2771    if (pipe->set_min_samples)
2772       pipe->set_min_samples(pipe, 1);
2773 
2774    blitter_set_common_draw_rect_state(ctx, false,
2775       util_framebuffer_get_num_samples(&fb_state) > 1);
2776    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2777    blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2778                            0, 0, dstsurf->width, dstsurf->height,
2779                            0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2780 
2781    util_blitter_restore_vertex_states(blitter);
2782    util_blitter_restore_fragment_states(blitter);
2783    util_blitter_restore_fb_state(blitter);
2784    util_blitter_restore_render_cond(blitter);
2785    util_blitter_unset_running_flag(blitter);
2786 }
2787 
get_custom_vs(struct blitter_context * blitter)2788 static void *get_custom_vs(struct blitter_context *blitter)
2789 {
2790    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2791 
2792    return ctx->custom_vs;
2793 }
2794 
2795 /**
2796  * Performs a custom blit to the destination surface, using the VS and FS
2797  * provided.
2798  *
2799  * Used by vc4 for the 8-bit linear-to-tiled blit.
2800  */
util_blitter_custom_shader(struct blitter_context * blitter,struct pipe_surface * dstsurf,void * custom_vs,void * custom_fs)2801 void util_blitter_custom_shader(struct blitter_context *blitter,
2802                                 struct pipe_surface *dstsurf,
2803                                 void *custom_vs, void *custom_fs)
2804 {
2805    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2806    struct pipe_context *pipe = ctx->base.pipe;
2807    struct pipe_framebuffer_state fb_state = { 0 };
2808 
2809    ctx->custom_vs = custom_vs;
2810 
2811    assert(dstsurf->texture);
2812    if (!dstsurf->texture)
2813       return;
2814 
2815    /* check the saved state */
2816    util_blitter_set_running_flag(blitter);
2817    blitter_check_saved_vertex_states(ctx);
2818    blitter_check_saved_fragment_states(ctx);
2819    blitter_check_saved_fb_state(ctx);
2820    blitter_disable_render_cond(ctx);
2821 
2822    /* bind states */
2823    pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2824    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2825    pipe->bind_fs_state(pipe, custom_fs);
2826 
2827    /* set a framebuffer state */
2828    fb_state.width = dstsurf->width;
2829    fb_state.height = dstsurf->height;
2830    fb_state.nr_cbufs = 1;
2831    fb_state.cbufs[0] = dstsurf;
2832    fb_state.resolve = NULL;
2833    pipe->set_framebuffer_state(pipe, &fb_state);
2834    pipe->set_sample_mask(pipe, ~0);
2835    if (pipe->set_min_samples)
2836       pipe->set_min_samples(pipe, 1);
2837 
2838    blitter_set_common_draw_rect_state(ctx, false,
2839       util_framebuffer_get_num_samples(&fb_state) > 1);
2840    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2841    blitter->draw_rectangle(blitter, ctx->velem_state, get_custom_vs,
2842                            0, 0, dstsurf->width, dstsurf->height,
2843                            0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2844 
2845    util_blitter_restore_vertex_states(blitter);
2846    util_blitter_restore_fragment_states(blitter);
2847    util_blitter_restore_fb_state(blitter);
2848    util_blitter_restore_render_cond(blitter);
2849    util_blitter_unset_running_flag(blitter);
2850 }
2851 
2852 static void *
get_stencil_blit_fallback_fs(struct blitter_context_priv * ctx,bool msaa_src)2853 get_stencil_blit_fallback_fs(struct blitter_context_priv *ctx, bool msaa_src)
2854 {
2855    if (!ctx->fs_stencil_blit_fallback[msaa_src]) {
2856       ctx->fs_stencil_blit_fallback[msaa_src] =
2857          util_make_fs_stencil_blit(ctx->base.pipe, msaa_src, ctx->has_txf_txq);
2858    }
2859 
2860    return ctx->fs_stencil_blit_fallback[msaa_src];
2861 }
2862 
2863 static void *
get_stencil_blit_fallback_dsa(struct blitter_context_priv * ctx,unsigned i)2864 get_stencil_blit_fallback_dsa(struct blitter_context_priv *ctx, unsigned i)
2865 {
2866    assert(i < ARRAY_SIZE(ctx->dsa_replicate_stencil_bit));
2867    if (!ctx->dsa_replicate_stencil_bit[i]) {
2868       struct pipe_depth_stencil_alpha_state dsa = { 0 };
2869       dsa.depth_func = PIPE_FUNC_ALWAYS;
2870       dsa.stencil[0].enabled = 1;
2871       dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
2872       dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
2873       dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
2874       dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
2875       dsa.stencil[0].valuemask = 0xff;
2876       dsa.stencil[0].writemask = 1u << i;
2877 
2878       ctx->dsa_replicate_stencil_bit[i] =
2879          ctx->base.pipe->create_depth_stencil_alpha_state(ctx->base.pipe, &dsa);
2880    }
2881    return ctx->dsa_replicate_stencil_bit[i];
2882 }
2883 
2884 /**
2885  * Performs a series of draws to implement stencil blits texture without
2886  * requiring stencil writes, updating a single bit per pixel at the time.
2887  */
2888 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)2889 util_blitter_stencil_fallback(struct blitter_context *blitter,
2890                               struct pipe_resource *dst,
2891                               unsigned dst_level,
2892                               const struct pipe_box *dstbox,
2893                               struct pipe_resource *src,
2894                               unsigned src_level,
2895                               const struct pipe_box *srcbox,
2896                               const struct pipe_scissor_state *scissor)
2897 {
2898    struct blitter_context_priv *ctx = (struct blitter_context_priv *)blitter;
2899    struct pipe_context *pipe = ctx->base.pipe;
2900 
2901    /* check the saved state */
2902    util_blitter_set_running_flag(blitter);
2903    blitter_check_saved_vertex_states(ctx);
2904    blitter_check_saved_fragment_states(ctx);
2905    blitter_check_saved_fb_state(ctx);
2906    blitter_disable_render_cond(ctx);
2907 
2908    /* Initialize the surface. */
2909    struct pipe_surface *dst_view, dst_templ;
2910    util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstbox->z);
2911    dst_view = pipe->create_surface(pipe, dst, &dst_templ);
2912 
2913    /* Initialize the sampler view. */
2914    struct pipe_sampler_view src_templ, *src_view;
2915    util_blitter_default_src_texture(blitter, &src_templ, src, src_level);
2916    src_templ.format = util_format_stencil_only(src_templ.format);
2917    src_view = pipe->create_sampler_view(pipe, src, &src_templ);
2918 
2919    /* bind states */
2920    pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2921    pipe->bind_fs_state(pipe,
2922       get_stencil_blit_fallback_fs(ctx, src->nr_samples > 1));
2923 
2924    /* set a framebuffer state */
2925    struct pipe_framebuffer_state fb_state = { 0 };
2926    fb_state.width = dstbox->x + dstbox->width;
2927    fb_state.height = dstbox->y + dstbox->height;
2928    fb_state.zsbuf = dst_view;
2929    fb_state.resolve = NULL;
2930    pipe->set_framebuffer_state(pipe, &fb_state);
2931    pipe->set_sample_mask(pipe, ~0);
2932    if (pipe->set_min_samples)
2933       pipe->set_min_samples(pipe, 1);
2934 
2935    blitter_set_common_draw_rect_state(ctx, scissor != NULL,
2936       util_framebuffer_get_num_samples(&fb_state) > 1);
2937    blitter_set_dst_dimensions(ctx, dst_view->width, dst_view->height);
2938 
2939    if (scissor) {
2940       pipe->set_scissor_states(pipe, 0, 1, scissor);
2941    }
2942 
2943    pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src_view);
2944    pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &ctx->sampler_state);
2945 
2946    unsigned stencil_bits =
2947       util_format_get_component_bits(dst->format,
2948                                      UTIL_FORMAT_COLORSPACE_ZS, 1);
2949 
2950    struct pipe_stencil_ref sr = { { (1u << stencil_bits) - 1 } };
2951    pipe->set_stencil_ref(pipe, sr);
2952 
2953    for (unsigned i = 0; i <= util_res_sample_count(dst) - 1; i++) {
2954       pipe->set_sample_mask(pipe, 1 << i);
2955       union blitter_attrib coord;
2956       get_texcoords(src_view, src->width0, src->height0,
2957                   srcbox->x, srcbox->y,
2958                   srcbox->x + srcbox->width, srcbox->y + srcbox->height,
2959                   srcbox->z, i, true,
2960                   &coord);
2961 
2962       for (int i = 0; i < stencil_bits; ++i) {
2963          uint32_t mask = 1 << i;
2964          struct pipe_constant_buffer cb = {
2965             .user_buffer = &mask,
2966             .buffer_size = sizeof(mask),
2967          };
2968          pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
2969                                  false, &cb);
2970 
2971          pipe->bind_depth_stencil_alpha_state(pipe,
2972             get_stencil_blit_fallback_dsa(ctx, i));
2973 
2974          blitter->draw_rectangle(blitter, ctx->velem_state,
2975                                  get_vs_passthrough_pos_generic,
2976                                  dstbox->x, dstbox->y,
2977                                  dstbox->x + dstbox->width,
2978                                  dstbox->y + dstbox->height,
2979                                  0, 1,
2980                                  UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW,
2981                                  &coord);
2982       }
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