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