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