• 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,
637                                &ctx->base.saved_vertex_buffer);
638       pipe_vertex_buffer_unreference(&ctx->base.saved_vertex_buffer);
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,
788                            ctx->base.saved_sampler_views);
789 
790    for (i = 0; i < ctx->base.saved_num_sampler_views; i++)
791       pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i], NULL);
792 
793    ctx->base.saved_num_sampler_views = ~0;
794 }
795 
util_blitter_restore_constant_buffer_state(struct blitter_context * blitter)796 void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter)
797 {
798    struct pipe_context *pipe = blitter->pipe;
799 
800    pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
801                             &blitter->saved_fs_constant_buffer);
802    pipe_resource_reference(&blitter->saved_fs_constant_buffer.buffer, NULL);
803 }
804 
blitter_set_rectangle(struct blitter_context_priv * ctx,int x1,int y1,int x2,int y2,float depth)805 static void blitter_set_rectangle(struct blitter_context_priv *ctx,
806                                   int x1, int y1, int x2, int y2,
807                                   float depth)
808 {
809    /* set vertex positions */
810    ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/
811    ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/
812 
813    ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/
814    ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/
815 
816    ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/
817    ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/
818 
819    ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/
820    ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/
821 
822    /* viewport */
823    struct pipe_viewport_state viewport;
824    viewport.scale[0] = 0.5f * ctx->dst_width;
825    viewport.scale[1] = 0.5f * ctx->dst_height;
826    viewport.scale[2] = 0.0f;
827    viewport.translate[0] = 0.5f * ctx->dst_width;
828    viewport.translate[1] = 0.5f * ctx->dst_height;
829    viewport.translate[2] = depth;
830    ctx->base.pipe->set_viewport_states(ctx->base.pipe, 0, 1, &viewport);
831 }
832 
blitter_set_clear_color(struct blitter_context_priv * ctx,const float color[4])833 static void blitter_set_clear_color(struct blitter_context_priv *ctx,
834                                     const float color[4])
835 {
836    int i;
837 
838    if (color) {
839       for (i = 0; i < 4; i++)
840          memcpy(&ctx->vertices[i][1][0], color, sizeof(uint32_t) * 4);
841    } else {
842       for (i = 0; i < 4; i++)
843          memset(&ctx->vertices[i][1][0], 0, sizeof(uint32_t) * 4);
844    }
845 }
846 
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)847 static void get_texcoords(struct pipe_sampler_view *src,
848                           unsigned src_width0, unsigned src_height0,
849                           int x1, int y1, int x2, int y2,
850                           float layer, unsigned sample,
851                           bool uses_txf, union blitter_attrib *out)
852 {
853    unsigned level = src->u.tex.first_level;
854    bool normalized = !uses_txf &&
855                         src->target != PIPE_TEXTURE_RECT &&
856                         src->texture->nr_samples <= 1;
857 
858    if (normalized) {
859       out->texcoord.x1 = x1 / (float)u_minify(src_width0,  level);
860       out->texcoord.y1 = y1 / (float)u_minify(src_height0, level);
861       out->texcoord.x2 = x2 / (float)u_minify(src_width0,  level);
862       out->texcoord.y2 = y2 / (float)u_minify(src_height0, level);
863    } else {
864       out->texcoord.x1 = x1;
865       out->texcoord.y1 = y1;
866       out->texcoord.x2 = x2;
867       out->texcoord.y2 = y2;
868    }
869 
870    out->texcoord.z = 0;
871    out->texcoord.w = 0;
872 
873    /* Set the layer. */
874    switch (src->target) {
875    case PIPE_TEXTURE_3D:
876       {
877          float r = layer;
878 
879          if (!uses_txf)
880             r /= u_minify(src->texture->depth0, src->u.tex.first_level);
881 
882          out->texcoord.z = r;
883       }
884       break;
885 
886    case PIPE_TEXTURE_1D_ARRAY:
887       out->texcoord.y1 = out->texcoord.y2 = layer;
888       break;
889 
890    case PIPE_TEXTURE_2D_ARRAY:
891       out->texcoord.z = layer;
892       out->texcoord.w = sample;
893       break;
894 
895    case PIPE_TEXTURE_CUBE_ARRAY:
896       out->texcoord.w = (unsigned)layer / 6;
897       break;
898 
899    case PIPE_TEXTURE_2D:
900       out->texcoord.w = sample;
901       break;
902 
903    default:;
904    }
905 }
906 
blitter_set_dst_dimensions(struct blitter_context_priv * ctx,unsigned width,unsigned height)907 static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
908                                        unsigned width, unsigned height)
909 {
910    ctx->dst_width = width;
911    ctx->dst_height = height;
912 }
913 
set_texcoords_in_vertices(const union blitter_attrib * attrib,float * out,unsigned stride)914 static void set_texcoords_in_vertices(const union blitter_attrib *attrib,
915                                       float *out, unsigned stride)
916 {
917    out[0] = attrib->texcoord.x1;
918    out[1] = attrib->texcoord.y1;
919    out += stride;
920    out[0] = attrib->texcoord.x2;
921    out[1] = attrib->texcoord.y1;
922    out += stride;
923    out[0] = attrib->texcoord.x2;
924    out[1] = attrib->texcoord.y2;
925    out += stride;
926    out[0] = attrib->texcoord.x1;
927    out[1] = attrib->texcoord.y2;
928 }
929 
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)930 static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
931                                          enum pipe_format src_format,
932                                          enum pipe_format dst_format,
933                                          enum pipe_texture_target target,
934                                          unsigned src_nr_samples,
935                                          unsigned dst_nr_samples,
936                                          unsigned filter,
937                                          bool use_txf)
938 {
939    struct pipe_context *pipe = ctx->base.pipe;
940    enum tgsi_texture_type tgsi_tex =
941       util_pipe_tex_to_tgsi_tex(target, src_nr_samples);
942    enum tgsi_return_type stype;
943    enum tgsi_return_type dtype;
944    unsigned type;
945 
946    assert(target < PIPE_MAX_TEXTURE_TYPES);
947 
948    if (util_format_is_pure_uint(src_format)) {
949       stype = TGSI_RETURN_TYPE_UINT;
950       if (util_format_is_pure_uint(dst_format)) {
951          dtype = TGSI_RETURN_TYPE_UINT;
952          type = 0;
953       } else {
954          assert(util_format_is_pure_sint(dst_format));
955          dtype = TGSI_RETURN_TYPE_SINT;
956          type = 1;
957       }
958    } else if (util_format_is_pure_sint(src_format)) {
959       stype = TGSI_RETURN_TYPE_SINT;
960       if (util_format_is_pure_sint(dst_format)) {
961          dtype = TGSI_RETURN_TYPE_SINT;
962          type = 2;
963       } else {
964          assert(util_format_is_pure_uint(dst_format));
965          dtype = TGSI_RETURN_TYPE_UINT;
966          type = 3;
967       }
968    } else {
969       assert(!util_format_is_pure_uint(dst_format) &&
970              !util_format_is_pure_sint(dst_format));
971       dtype = stype = TGSI_RETURN_TYPE_FLOAT;
972       type = 4;
973    }
974 
975    if (src_nr_samples > 1) {
976       void **shader;
977 
978       /* OpenGL requires that integer textures just copy 1 sample instead
979        * of averaging.
980        */
981       if (dst_nr_samples <= 1 &&
982           stype != TGSI_RETURN_TYPE_UINT &&
983           stype != TGSI_RETURN_TYPE_SINT) {
984          /* The destination has one sample, so we'll do color resolve. */
985          unsigned index = GET_MSAA_RESOLVE_FS_IDX(src_nr_samples);
986 
987          assert(filter < 2);
988 
989          shader = &ctx->fs_resolve[target][index][filter];
990 
991          if (!*shader) {
992             assert(!ctx->cached_all_shaders);
993             if (filter == PIPE_TEX_FILTER_LINEAR) {
994                *shader = util_make_fs_msaa_resolve_bilinear(pipe, tgsi_tex,
995                                                    src_nr_samples,
996                                                    stype);
997             }
998             else {
999                *shader = util_make_fs_msaa_resolve(pipe, tgsi_tex,
1000                                                    src_nr_samples,
1001                                                    stype);
1002             }
1003          }
1004       }
1005       else {
1006          /* The destination has multiple samples, we'll do
1007           * an MSAA->MSAA copy.
1008           */
1009          shader = &ctx->fs_texfetch_col_msaa[type][target];
1010 
1011          /* Create the fragment shader on-demand. */
1012          if (!*shader) {
1013             assert(!ctx->cached_all_shaders);
1014             *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex, stype, dtype);
1015          }
1016       }
1017 
1018       return *shader;
1019    } else {
1020       void **shader;
1021 
1022       if (use_txf)
1023          shader = &ctx->fs_texfetch_col[type][target][1];
1024       else
1025          shader = &ctx->fs_texfetch_col[type][target][0];
1026 
1027       /* Create the fragment shader on-demand. */
1028       if (!*shader) {
1029          assert(!ctx->cached_all_shaders);
1030          *shader = util_make_fragment_tex_shader(pipe, tgsi_tex,
1031                                                  TGSI_INTERPOLATE_LINEAR,
1032                                                  stype, dtype,
1033                                                  ctx->has_tex_lz, use_txf);
1034       }
1035 
1036       return *shader;
1037    }
1038 }
1039 
1040 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)1041 void *blitter_get_fs_pack_color_zs(struct blitter_context_priv *ctx,
1042                                    enum pipe_texture_target target,
1043                                    unsigned nr_samples,
1044                                    enum pipe_format zs_format,
1045                                    bool dst_is_color)
1046 {
1047    struct pipe_context *pipe = ctx->base.pipe;
1048    enum tgsi_texture_type tgsi_tex =
1049       util_pipe_tex_to_tgsi_tex(target, nr_samples);
1050    int format_index = zs_format == PIPE_FORMAT_Z24_UNORM_S8_UINT ? 0 :
1051                       zs_format == PIPE_FORMAT_S8_UINT_Z24_UNORM ? 1 :
1052                       zs_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ? 2 :
1053                       zs_format == PIPE_FORMAT_Z24X8_UNORM ? 3 :
1054                       zs_format == PIPE_FORMAT_X8Z24_UNORM ? 4 : -1;
1055 
1056    if (format_index == -1) {
1057       assert(0);
1058       return NULL;
1059    }
1060 
1061    /* The first 5 shaders pack ZS to color, the last 5 shaders unpack color
1062     * to ZS.
1063     */
1064    if (dst_is_color)
1065       format_index += 5;
1066 
1067    void **shader = &ctx->fs_pack_color_zs[tgsi_tex][format_index];
1068 
1069    /* Create the fragment shader on-demand. */
1070    if (!*shader) {
1071       assert(!ctx->cached_all_shaders);
1072       *shader = util_make_fs_pack_color_zs(pipe, tgsi_tex, zs_format,
1073                                            dst_is_color);
1074    }
1075    return *shader;
1076 }
1077 
1078 static inline
blitter_get_fs_texfetch_depth(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned nr_samples,bool use_txf)1079 void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
1080                                     enum pipe_texture_target target,
1081                                     unsigned nr_samples,
1082                                     bool use_txf)
1083 {
1084    struct pipe_context *pipe = ctx->base.pipe;
1085 
1086    assert(target < PIPE_MAX_TEXTURE_TYPES);
1087 
1088    if (nr_samples > 1) {
1089       void **shader = &ctx->fs_texfetch_depth_msaa[target];
1090 
1091       /* Create the fragment shader on-demand. */
1092       if (!*shader) {
1093          enum tgsi_texture_type tgsi_tex;
1094          assert(!ctx->cached_all_shaders);
1095          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples);
1096          *shader = util_make_fs_blit_msaa_depth(pipe, tgsi_tex);
1097       }
1098 
1099       return *shader;
1100    } else {
1101       void **shader;
1102 
1103       if (use_txf)
1104          shader = &ctx->fs_texfetch_depth[target][1];
1105       else
1106          shader = &ctx->fs_texfetch_depth[target][0];
1107 
1108       /* Create the fragment shader on-demand. */
1109       if (!*shader) {
1110          enum tgsi_texture_type tgsi_tex;
1111          assert(!ctx->cached_all_shaders);
1112          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1113          *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_Z, tgsi_tex,
1114                                         ctx->has_tex_lz, use_txf);
1115       }
1116 
1117       return *shader;
1118    }
1119 }
1120 
1121 static inline
blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned nr_samples,bool use_txf)1122 void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
1123                                            enum pipe_texture_target target,
1124                                            unsigned nr_samples,
1125                                            bool use_txf)
1126 {
1127    struct pipe_context *pipe = ctx->base.pipe;
1128 
1129    assert(target < PIPE_MAX_TEXTURE_TYPES);
1130 
1131    if (nr_samples > 1) {
1132       void **shader = &ctx->fs_texfetch_depthstencil_msaa[target];
1133 
1134       /* Create the fragment shader on-demand. */
1135       if (!*shader) {
1136          enum tgsi_texture_type tgsi_tex;
1137          assert(!ctx->cached_all_shaders);
1138          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples);
1139          *shader = util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex);
1140       }
1141 
1142       return *shader;
1143    } else {
1144       void **shader;
1145 
1146       if (use_txf)
1147          shader = &ctx->fs_texfetch_depthstencil[target][1];
1148       else
1149          shader = &ctx->fs_texfetch_depthstencil[target][0];
1150 
1151       /* Create the fragment shader on-demand. */
1152       if (!*shader) {
1153          enum tgsi_texture_type tgsi_tex;
1154          assert(!ctx->cached_all_shaders);
1155          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1156          *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_ZS, tgsi_tex,
1157                                         ctx->has_tex_lz, use_txf);
1158       }
1159 
1160       return *shader;
1161    }
1162 }
1163 
1164 static inline
blitter_get_fs_texfetch_stencil(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned nr_samples,bool use_txf)1165 void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
1166                                       enum pipe_texture_target target,
1167                                       unsigned nr_samples,
1168                                       bool use_txf)
1169 {
1170    struct pipe_context *pipe = ctx->base.pipe;
1171 
1172    assert(target < PIPE_MAX_TEXTURE_TYPES);
1173 
1174    if (nr_samples > 1) {
1175       void **shader = &ctx->fs_texfetch_stencil_msaa[target];
1176 
1177       /* Create the fragment shader on-demand. */
1178       if (!*shader) {
1179          enum tgsi_texture_type tgsi_tex;
1180          assert(!ctx->cached_all_shaders);
1181          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples);
1182          *shader = util_make_fs_blit_msaa_stencil(pipe, tgsi_tex);
1183       }
1184 
1185       return *shader;
1186    } else {
1187       void **shader;
1188 
1189       if (use_txf)
1190          shader = &ctx->fs_texfetch_stencil[target][1];
1191       else
1192          shader = &ctx->fs_texfetch_stencil[target][0];
1193 
1194       /* Create the fragment shader on-demand. */
1195       if (!*shader) {
1196          enum tgsi_texture_type tgsi_tex;
1197          assert(!ctx->cached_all_shaders);
1198          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1199          *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_S, tgsi_tex,
1200                                         ctx->has_tex_lz, use_txf);
1201       }
1202 
1203       return *shader;
1204    }
1205 }
1206 
1207 
1208 /**
1209  * Generate and save all fragment shaders that we will ever need for
1210  * blitting.  Drivers which use the 'draw' fallbacks will typically use
1211  * this to make sure we generate/use shaders that don't go through the
1212  * draw module's wrapper functions.
1213  */
util_blitter_cache_all_shaders(struct blitter_context * blitter)1214 void util_blitter_cache_all_shaders(struct blitter_context *blitter)
1215 {
1216    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1217    struct pipe_context *pipe = blitter->pipe;
1218    struct pipe_screen *screen = pipe->screen;
1219    unsigned samples, j, f, target, max_samples, use_txf;
1220    bool has_arraytex, has_cubearraytex;
1221 
1222    max_samples = ctx->has_texture_multisample ? 2 : 1;
1223    has_arraytex = screen->get_param(screen,
1224                                     PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) != 0;
1225    has_cubearraytex = screen->get_param(screen,
1226                                     PIPE_CAP_CUBE_MAP_ARRAY) != 0;
1227 
1228    /* It only matters if i <= 1 or > 1. */
1229    for (samples = 1; samples <= max_samples; samples++) {
1230       for (target = PIPE_TEXTURE_1D; target < PIPE_MAX_TEXTURE_TYPES; target++) {
1231          for (use_txf = 0; use_txf <= ctx->has_txf; use_txf++) {
1232             if (!has_arraytex &&
1233                 (target == PIPE_TEXTURE_1D_ARRAY ||
1234                  target == PIPE_TEXTURE_2D_ARRAY)) {
1235                continue;
1236             }
1237             if (!has_cubearraytex &&
1238                 (target == PIPE_TEXTURE_CUBE_ARRAY))
1239                continue;
1240 
1241             if (samples > 1 &&
1242                 (target != PIPE_TEXTURE_2D &&
1243                  target != PIPE_TEXTURE_2D_ARRAY))
1244                continue;
1245 
1246             if (samples > 1 && use_txf)
1247                continue; /* TXF is the only option, use_txf has no effect */
1248 
1249             /* If samples == 1, the shaders read one texel. If samples >= 1,
1250              * they read one sample.
1251              */
1252             blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT,
1253                                         PIPE_FORMAT_R32_FLOAT, target,
1254                                         samples, samples, 0, use_txf);
1255             blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1256                                         PIPE_FORMAT_R32_UINT, target,
1257                                         samples, samples, 0, use_txf);
1258             blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1259                                         PIPE_FORMAT_R32_SINT, target,
1260                                         samples, samples, 0, use_txf);
1261             blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1262                                         PIPE_FORMAT_R32_SINT, target,
1263                                         samples, samples, 0, use_txf);
1264             blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1265                                         PIPE_FORMAT_R32_UINT, target,
1266                                         samples, samples, 0, use_txf);
1267             blitter_get_fs_texfetch_depth(ctx, target, samples, use_txf);
1268             if (ctx->has_stencil_export) {
1269                blitter_get_fs_texfetch_depthstencil(ctx, target, samples, use_txf);
1270                blitter_get_fs_texfetch_stencil(ctx, target, samples, use_txf);
1271             }
1272 
1273             if (samples == 1)
1274                continue;
1275 
1276             /* MSAA resolve shaders. */
1277             for (j = 2; j < 32; j++) {
1278                if (!screen->is_format_supported(screen, PIPE_FORMAT_R32_FLOAT,
1279                                                 target, j, j,
1280                                                 PIPE_BIND_SAMPLER_VIEW)) {
1281                   continue;
1282                }
1283 
1284                for (f = 0; f < 2; f++) {
1285                   if (f != PIPE_TEX_FILTER_NEAREST && use_txf)
1286                      continue;
1287 
1288                   blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT,
1289                                               PIPE_FORMAT_R32_FLOAT, target,
1290                                               j, 1, f, use_txf);
1291                   blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1292                                               PIPE_FORMAT_R32_UINT, target,
1293                                               j, 1, f, use_txf);
1294                   blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1295                                               PIPE_FORMAT_R32_SINT, target,
1296                                               j, 1, f, use_txf);
1297                }
1298             }
1299          }
1300       }
1301    }
1302 
1303    ctx->fs_empty = util_make_empty_fragment_shader(pipe);
1304 
1305    ctx->fs_write_one_cbuf =
1306       util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
1307                                             TGSI_INTERPOLATE_CONSTANT, false);
1308 
1309    ctx->fs_write_all_cbufs =
1310       util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
1311                                             TGSI_INTERPOLATE_CONSTANT, true);
1312 
1313    ctx->cached_all_shaders = true;
1314 }
1315 
blitter_set_common_draw_rect_state(struct blitter_context_priv * ctx,bool scissor,bool msaa)1316 static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx,
1317                                                bool scissor, bool msaa)
1318 {
1319    struct pipe_context *pipe = ctx->base.pipe;
1320 
1321    if (ctx->base.saved_num_window_rectangles)
1322       pipe->set_window_rectangles(pipe, false, 0, NULL);
1323 
1324    pipe->bind_rasterizer_state(pipe, ctx->rs_state[scissor][msaa]);
1325 
1326    if (ctx->has_geometry_shader)
1327       pipe->bind_gs_state(pipe, NULL);
1328    if (ctx->has_tessellation) {
1329       pipe->bind_tcs_state(pipe, NULL);
1330       pipe->bind_tes_state(pipe, NULL);
1331    }
1332    if (ctx->has_stream_out)
1333       pipe->set_stream_output_targets(pipe, 0, NULL, NULL);
1334 }
1335 
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)1336 static void blitter_draw(struct blitter_context_priv *ctx,
1337                          void *vertex_elements_cso,
1338                          blitter_get_vs_func get_vs,
1339                          int x1, int y1, int x2, int y2, float depth,
1340                          unsigned num_instances)
1341 {
1342    struct pipe_context *pipe = ctx->base.pipe;
1343    struct pipe_vertex_buffer vb = {0};
1344 
1345    blitter_set_rectangle(ctx, x1, y1, x2, y2, depth);
1346 
1347    vb.stride = 8 * sizeof(float);
1348 
1349    u_upload_data(pipe->stream_uploader, 0, sizeof(ctx->vertices), 4, ctx->vertices,
1350                  &vb.buffer_offset, &vb.buffer.resource);
1351    if (!vb.buffer.resource)
1352       return;
1353    u_upload_unmap(pipe->stream_uploader);
1354 
1355    pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
1356    pipe->bind_vertex_elements_state(pipe, vertex_elements_cso);
1357    pipe->bind_vs_state(pipe, get_vs(&ctx->base));
1358 
1359    if (ctx->base.use_index_buffer) {
1360       /* Note that for V3D,
1361        * dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_* require
1362        * that the last vert of the two tris be the same.
1363        */
1364       static uint8_t indices[6] = { 0, 1, 2, 0, 3, 2 };
1365       util_draw_elements_instanced(pipe, indices, 1, 0,
1366                                    PIPE_PRIM_TRIANGLES, 0, 6,
1367                                    0, num_instances);
1368    } else {
1369       util_draw_arrays_instanced(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4,
1370                                  0, num_instances);
1371    }
1372    pipe_resource_reference(&vb.buffer.resource, NULL);
1373 }
1374 
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)1375 void util_blitter_draw_rectangle(struct blitter_context *blitter,
1376                                  void *vertex_elements_cso,
1377                                  blitter_get_vs_func get_vs,
1378                                  int x1, int y1, int x2, int y2,
1379                                  float depth, unsigned num_instances,
1380                                  enum blitter_attrib_type type,
1381                                  const union blitter_attrib *attrib)
1382 {
1383    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1384    unsigned i;
1385 
1386    switch (type) {
1387       case UTIL_BLITTER_ATTRIB_COLOR:
1388          blitter_set_clear_color(ctx, attrib->color);
1389          break;
1390 
1391       case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
1392          for (i = 0; i < 4; i++) {
1393             ctx->vertices[i][1][2] = attrib->texcoord.z;
1394             ctx->vertices[i][1][3] = attrib->texcoord.w;
1395          }
1396          /* fall through */
1397       case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
1398          set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8);
1399          break;
1400 
1401       default:;
1402    }
1403 
1404    blitter_draw(ctx, vertex_elements_cso, get_vs, x1, y1, x2, y2, depth,
1405                 num_instances);
1406 }
1407 
get_clear_blend_state(struct blitter_context_priv * ctx,unsigned clear_buffers)1408 static void *get_clear_blend_state(struct blitter_context_priv *ctx,
1409                                    unsigned clear_buffers)
1410 {
1411    struct pipe_context *pipe = ctx->base.pipe;
1412    int index;
1413 
1414    clear_buffers &= PIPE_CLEAR_COLOR;
1415 
1416    /* Return an existing blend state. */
1417    if (!clear_buffers)
1418       return ctx->blend[0][0];
1419 
1420    index = GET_CLEAR_BLEND_STATE_IDX(clear_buffers);
1421 
1422    if (ctx->blend_clear[index])
1423       return ctx->blend_clear[index];
1424 
1425    /* Create a new one. */
1426    {
1427       struct pipe_blend_state blend = {0};
1428       unsigned i;
1429 
1430       blend.independent_blend_enable = 1;
1431 
1432       for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
1433          if (clear_buffers & (PIPE_CLEAR_COLOR0 << i)) {
1434             blend.rt[i].colormask = PIPE_MASK_RGBA;
1435             blend.max_rt = i;
1436          }
1437       }
1438 
1439       ctx->blend_clear[index] = pipe->create_blend_state(pipe, &blend);
1440    }
1441    return ctx->blend_clear[index];
1442 }
1443 
util_blitter_common_clear_setup(struct blitter_context * blitter,unsigned width,unsigned height,unsigned clear_buffers,void * custom_blend,void * custom_dsa)1444 void util_blitter_common_clear_setup(struct blitter_context *blitter,
1445                                      unsigned width, unsigned height,
1446                                      unsigned clear_buffers,
1447                                      void *custom_blend, void *custom_dsa)
1448 {
1449    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1450    struct pipe_context *pipe = ctx->base.pipe;
1451 
1452    util_blitter_set_running_flag(blitter);
1453    blitter_check_saved_vertex_states(ctx);
1454    blitter_check_saved_fragment_states(ctx);
1455    blitter_disable_render_cond(ctx);
1456 
1457    /* bind states */
1458    if (custom_blend) {
1459       pipe->bind_blend_state(pipe, custom_blend);
1460    } else {
1461       pipe->bind_blend_state(pipe, get_clear_blend_state(ctx, clear_buffers));
1462    }
1463 
1464    if (custom_dsa) {
1465       pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa);
1466    } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
1467       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
1468    } else if (clear_buffers & PIPE_CLEAR_DEPTH) {
1469       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
1470    } else if (clear_buffers & PIPE_CLEAR_STENCIL) {
1471       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
1472    } else {
1473       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1474    }
1475 
1476    pipe->set_sample_mask(pipe, ~0);
1477    blitter_set_dst_dimensions(ctx, width, height);
1478 }
1479 
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)1480 static void util_blitter_clear_custom(struct blitter_context *blitter,
1481                                       unsigned width, unsigned height,
1482                                       unsigned num_layers,
1483                                       unsigned clear_buffers,
1484                                       const union pipe_color_union *color,
1485                                       double depth, unsigned stencil,
1486                                       void *custom_blend, void *custom_dsa,
1487                                       bool msaa)
1488 {
1489    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1490    struct pipe_context *pipe = ctx->base.pipe;
1491    struct pipe_stencil_ref sr = { { 0 } };
1492 
1493    assert(ctx->has_layered || num_layers <= 1);
1494 
1495    util_blitter_common_clear_setup(blitter, width, height, clear_buffers,
1496                                    custom_blend, custom_dsa);
1497 
1498    sr.ref_value[0] = stencil & 0xff;
1499    pipe->set_stencil_ref(pipe, &sr);
1500 
1501    bind_fs_write_all_cbufs(ctx);
1502 
1503    union blitter_attrib attrib;
1504    memcpy(attrib.color, color->ui, sizeof(color->ui));
1505 
1506    bool pass_generic = (clear_buffers & PIPE_CLEAR_COLOR) != 0;
1507    enum blitter_attrib_type type = pass_generic ? UTIL_BLITTER_ATTRIB_COLOR :
1508                                                   UTIL_BLITTER_ATTRIB_NONE;
1509 
1510    if (num_layers > 1 && ctx->has_layered) {
1511       blitter_get_vs_func get_vs = get_vs_layered;
1512 
1513       blitter_set_common_draw_rect_state(ctx, false, msaa);
1514       blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
1515                               0, 0, width, height,
1516                               (float) depth, num_layers, type, &attrib);
1517    } else {
1518       blitter_get_vs_func get_vs;
1519 
1520       if (pass_generic)
1521          get_vs = get_vs_passthrough_pos_generic;
1522       else
1523          get_vs = get_vs_passthrough_pos;
1524 
1525       blitter_set_common_draw_rect_state(ctx, false, msaa);
1526       blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
1527                               0, 0, width, height,
1528                               (float) depth, 1, type, &attrib);
1529    }
1530 
1531    util_blitter_restore_vertex_states(blitter);
1532    util_blitter_restore_fragment_states(blitter);
1533    util_blitter_restore_render_cond(blitter);
1534    util_blitter_unset_running_flag(blitter);
1535 }
1536 
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)1537 void util_blitter_clear(struct blitter_context *blitter,
1538                         unsigned width, unsigned height, unsigned num_layers,
1539                         unsigned clear_buffers,
1540                         const union pipe_color_union *color,
1541                         double depth, unsigned stencil,
1542                         bool msaa)
1543 {
1544    util_blitter_clear_custom(blitter, width, height, num_layers,
1545                              clear_buffers, color, depth, stencil,
1546                              NULL, NULL, msaa);
1547 }
1548 
util_blitter_custom_clear_depth(struct blitter_context * blitter,unsigned width,unsigned height,double depth,void * custom_dsa)1549 void util_blitter_custom_clear_depth(struct blitter_context *blitter,
1550                                      unsigned width, unsigned height,
1551                                      double depth, void *custom_dsa)
1552 {
1553    static const union pipe_color_union color;
1554    util_blitter_clear_custom(blitter, width, height, 0, 0, &color, depth, 0,
1555                              NULL, custom_dsa, false);
1556 }
1557 
util_blitter_default_dst_texture(struct pipe_surface * dst_templ,struct pipe_resource * dst,unsigned dstlevel,unsigned dstz)1558 void util_blitter_default_dst_texture(struct pipe_surface *dst_templ,
1559                                       struct pipe_resource *dst,
1560                                       unsigned dstlevel,
1561                                       unsigned dstz)
1562 {
1563    memset(dst_templ, 0, sizeof(*dst_templ));
1564    dst_templ->format = util_format_linear(dst->format);
1565    dst_templ->u.tex.level = dstlevel;
1566    dst_templ->u.tex.first_layer = dstz;
1567    dst_templ->u.tex.last_layer = dstz;
1568 }
1569 
1570 static struct pipe_surface *
util_blitter_get_next_surface_layer(struct pipe_context * pipe,struct pipe_surface * surf)1571 util_blitter_get_next_surface_layer(struct pipe_context *pipe,
1572                                     struct pipe_surface *surf)
1573 {
1574    struct pipe_surface dst_templ;
1575 
1576    memset(&dst_templ, 0, sizeof(dst_templ));
1577    dst_templ.format = surf->format;
1578    dst_templ.u.tex.level = surf->u.tex.level;
1579    dst_templ.u.tex.first_layer = surf->u.tex.first_layer + 1;
1580    dst_templ.u.tex.last_layer = surf->u.tex.last_layer + 1;
1581 
1582    return pipe->create_surface(pipe, surf->texture, &dst_templ);
1583 }
1584 
util_blitter_default_src_texture(struct blitter_context * blitter,struct pipe_sampler_view * src_templ,struct pipe_resource * src,unsigned srclevel)1585 void util_blitter_default_src_texture(struct blitter_context *blitter,
1586                                       struct pipe_sampler_view *src_templ,
1587                                       struct pipe_resource *src,
1588                                       unsigned srclevel)
1589 {
1590    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1591 
1592    memset(src_templ, 0, sizeof(*src_templ));
1593 
1594    if (ctx->cube_as_2darray &&
1595        (src->target == PIPE_TEXTURE_CUBE ||
1596         src->target == PIPE_TEXTURE_CUBE_ARRAY))
1597       src_templ->target = PIPE_TEXTURE_2D_ARRAY;
1598    else
1599       src_templ->target = src->target;
1600 
1601    src_templ->format = util_format_linear(src->format);
1602    src_templ->u.tex.first_level = srclevel;
1603    src_templ->u.tex.last_level = srclevel;
1604    src_templ->u.tex.first_layer = 0;
1605    src_templ->u.tex.last_layer =
1606       src->target == PIPE_TEXTURE_3D ? u_minify(src->depth0, srclevel) - 1
1607                                      : (unsigned)(src->array_size - 1);
1608    src_templ->swizzle_r = PIPE_SWIZZLE_X;
1609    src_templ->swizzle_g = PIPE_SWIZZLE_Y;
1610    src_templ->swizzle_b = PIPE_SWIZZLE_Z;
1611    src_templ->swizzle_a = PIPE_SWIZZLE_W;
1612 }
1613 
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)1614 static bool is_blit_generic_supported(struct blitter_context *blitter,
1615                                       const struct pipe_resource *dst,
1616                                       enum pipe_format dst_format,
1617                                       const struct pipe_resource *src,
1618                                       enum pipe_format src_format,
1619                                       unsigned mask)
1620 {
1621    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1622    struct pipe_screen *screen = ctx->base.pipe->screen;
1623 
1624    if (dst) {
1625       unsigned bind;
1626       const struct util_format_description *desc =
1627             util_format_description(dst_format);
1628       bool dst_has_stencil = util_format_has_stencil(desc);
1629 
1630       /* Stencil export must be supported for stencil copy. */
1631       if ((mask & PIPE_MASK_S) && dst_has_stencil &&
1632           !ctx->has_stencil_export) {
1633          return false;
1634       }
1635 
1636       if (dst_has_stencil || util_format_has_depth(desc))
1637          bind = PIPE_BIND_DEPTH_STENCIL;
1638       else
1639          bind = PIPE_BIND_RENDER_TARGET;
1640 
1641       if (!screen->is_format_supported(screen, dst_format, dst->target,
1642                                        dst->nr_samples, dst->nr_storage_samples,
1643                                        bind)) {
1644          return false;
1645       }
1646    }
1647 
1648    if (src) {
1649       if (src->nr_samples > 1 && !ctx->has_texture_multisample) {
1650          return false;
1651       }
1652 
1653       if (!screen->is_format_supported(screen, src_format, src->target,
1654                                        src->nr_samples, src->nr_storage_samples,
1655                                        PIPE_BIND_SAMPLER_VIEW)) {
1656          return false;
1657       }
1658 
1659       /* Check stencil sampler support for stencil copy. */
1660       if (mask & PIPE_MASK_S) {
1661          if (util_format_has_stencil(util_format_description(src_format))) {
1662             enum pipe_format stencil_format =
1663                util_format_stencil_only(src_format);
1664             assert(stencil_format != PIPE_FORMAT_NONE);
1665 
1666             if (stencil_format != src_format &&
1667                 !screen->is_format_supported(screen, stencil_format,
1668                                              src->target, src->nr_samples,
1669                                              src->nr_storage_samples,
1670                                              PIPE_BIND_SAMPLER_VIEW)) {
1671                return false;
1672             }
1673          }
1674       }
1675    }
1676 
1677    return true;
1678 }
1679 
util_blitter_is_copy_supported(struct blitter_context * blitter,const struct pipe_resource * dst,const struct pipe_resource * src)1680 bool util_blitter_is_copy_supported(struct blitter_context *blitter,
1681                                     const struct pipe_resource *dst,
1682                                     const struct pipe_resource *src)
1683 {
1684    return is_blit_generic_supported(blitter, dst, dst->format,
1685                                     src, src->format, PIPE_MASK_RGBAZS);
1686 }
1687 
util_blitter_is_blit_supported(struct blitter_context * blitter,const struct pipe_blit_info * info)1688 bool util_blitter_is_blit_supported(struct blitter_context *blitter,
1689                                     const struct pipe_blit_info *info)
1690 {
1691    return is_blit_generic_supported(blitter,
1692                                     info->dst.resource, info->dst.format,
1693                                     info->src.resource, info->src.format,
1694                                     info->mask);
1695 }
1696 
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)1697 void util_blitter_copy_texture(struct blitter_context *blitter,
1698                                struct pipe_resource *dst,
1699                                unsigned dst_level,
1700                                unsigned dstx, unsigned dsty, unsigned dstz,
1701                                struct pipe_resource *src,
1702                                unsigned src_level,
1703                                const struct pipe_box *srcbox)
1704 {
1705    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1706    struct pipe_context *pipe = ctx->base.pipe;
1707    struct pipe_surface *dst_view, dst_templ;
1708    struct pipe_sampler_view src_templ, *src_view;
1709    struct pipe_box dstbox;
1710 
1711    assert(dst && src);
1712    assert(src->target < PIPE_MAX_TEXTURE_TYPES);
1713 
1714    u_box_3d(dstx, dsty, dstz, abs(srcbox->width), abs(srcbox->height),
1715             abs(srcbox->depth), &dstbox);
1716 
1717    /* Initialize the surface. */
1718    util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz);
1719    dst_view = pipe->create_surface(pipe, dst, &dst_templ);
1720 
1721    /* Initialize the sampler view. */
1722    util_blitter_default_src_texture(blitter, &src_templ, src, src_level);
1723    src_view = pipe->create_sampler_view(pipe, src, &src_templ);
1724 
1725    /* Copy. */
1726    util_blitter_blit_generic(blitter, dst_view, &dstbox,
1727                              src_view, srcbox, src->width0, src->height0,
1728                              PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
1729                              false);
1730 
1731    pipe_surface_reference(&dst_view, NULL);
1732    pipe_sampler_view_reference(&src_view, NULL);
1733 }
1734 
1735 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)1736 blitter_draw_tex(struct blitter_context_priv *ctx,
1737                  int dst_x1, int dst_y1, int dst_x2, int dst_y2,
1738                  struct pipe_sampler_view *src,
1739                  unsigned src_width0, unsigned src_height0,
1740                  int src_x1, int src_y1, int src_x2, int src_y2,
1741                  float layer, unsigned sample,
1742                  bool uses_txf, enum blitter_attrib_type type)
1743 {
1744    union blitter_attrib coord;
1745    blitter_get_vs_func get_vs = get_vs_passthrough_pos_generic;
1746 
1747    get_texcoords(src, src_width0, src_height0,
1748                  src_x1, src_y1, src_x2, src_y2, layer, sample,
1749                  uses_txf, &coord);
1750 
1751    if (src->target == PIPE_TEXTURE_CUBE ||
1752        src->target == PIPE_TEXTURE_CUBE_ARRAY) {
1753       float face_coord[4][2];
1754 
1755       set_texcoords_in_vertices(&coord, &face_coord[0][0], 2);
1756       util_map_texcoords2d_onto_cubemap((unsigned)layer % 6,
1757                                         /* pointer, stride in floats */
1758                                         &face_coord[0][0], 2,
1759                                         &ctx->vertices[0][1][0], 8,
1760                                         false);
1761       for (unsigned i = 0; i < 4; i++)
1762          ctx->vertices[i][1][3] = coord.texcoord.w;
1763 
1764       /* Cubemaps don't use draw_rectangle. */
1765       blitter_draw(ctx, ctx->velem_state, get_vs,
1766                    dst_x1, dst_y1, dst_x2, dst_y2, 0, 1);
1767    } else {
1768       ctx->base.draw_rectangle(&ctx->base, ctx->velem_state, get_vs,
1769                                dst_x1, dst_y1, dst_x2, dst_y2,
1770                                0, 1, type, &coord);
1771    }
1772 }
1773 
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)1774 static void do_blits(struct blitter_context_priv *ctx,
1775                      struct pipe_surface *dst,
1776                      const struct pipe_box *dstbox,
1777                      struct pipe_sampler_view *src,
1778                      unsigned src_width0,
1779                      unsigned src_height0,
1780                      const struct pipe_box *srcbox,
1781                      bool is_zsbuf,
1782                      bool uses_txf)
1783 {
1784    struct pipe_context *pipe = ctx->base.pipe;
1785    unsigned src_samples = src->texture->nr_samples;
1786    unsigned dst_samples = dst->texture->nr_samples;
1787    enum pipe_texture_target src_target = src->target;
1788    struct pipe_framebuffer_state fb_state = {0};
1789 
1790    /* Initialize framebuffer state. */
1791    fb_state.width = dst->width;
1792    fb_state.height = dst->height;
1793    fb_state.nr_cbufs = is_zsbuf ? 0 : 1;
1794 
1795    blitter_set_dst_dimensions(ctx, fb_state.width, fb_state.height);
1796 
1797    if ((src_target == PIPE_TEXTURE_1D ||
1798         src_target == PIPE_TEXTURE_2D ||
1799         src_target == PIPE_TEXTURE_RECT) &&
1800        src_samples <= 1) {
1801       /* Set framebuffer state. */
1802       if (is_zsbuf) {
1803          fb_state.zsbuf = dst;
1804       } else {
1805          fb_state.cbufs[0] = dst;
1806       }
1807       pipe->set_framebuffer_state(pipe, &fb_state);
1808 
1809       /* Draw. */
1810       pipe->set_sample_mask(pipe, ~0);
1811       blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1812                        dstbox->x + dstbox->width,
1813                        dstbox->y + dstbox->height,
1814                        src, src_width0, src_height0, srcbox->x, srcbox->y,
1815                        srcbox->x + srcbox->width, srcbox->y + srcbox->height,
1816                        0, 0, uses_txf, UTIL_BLITTER_ATTRIB_TEXCOORD_XY);
1817    } else {
1818       /* Draw the quad with the generic codepath. */
1819       int dst_z;
1820       for (dst_z = 0; dst_z < dstbox->depth; dst_z++) {
1821          struct pipe_surface *old;
1822          bool flipped = (srcbox->depth < 0);
1823          float depth_center_offset = 0.0;
1824          int src_depth = abs(srcbox->depth);
1825          float src_z_step = src_depth / (float)dstbox->depth;
1826 
1827          /* Scale Z properly if the blit is scaled.
1828           *
1829           * When downscaling, we want the coordinates centered, so that
1830           * mipmapping works for 3D textures. For example, when generating
1831           * a 4x4x4 level, this wouldn't average the pixels:
1832           *
1833           *   src Z:  0 1 2 3 4 5 6 7
1834           *   dst Z:  0   1   2   3
1835           *
1836           * Because the pixels are not centered below the pixels of the higher
1837           * level. Therefore, we want this:
1838           *   src Z:  0 1 2 3 4 5 6 7
1839           *   dst Z:   0   1   2   3
1840           *
1841           * This calculation is taken from the radv driver.
1842           */
1843          if (src_target == PIPE_TEXTURE_3D)
1844             depth_center_offset = 0.5 / dstbox->depth * src_depth;
1845 
1846          if (flipped) {
1847             src_z_step *= - 1;
1848             depth_center_offset *= -1;
1849          }
1850 
1851          float src_z = dst_z * src_z_step + depth_center_offset;
1852 
1853          /* Set framebuffer state. */
1854          if (is_zsbuf) {
1855             fb_state.zsbuf = dst;
1856          } else {
1857             fb_state.cbufs[0] = dst;
1858          }
1859          pipe->set_framebuffer_state(pipe, &fb_state);
1860 
1861          /* See if we need to blit a multisample or singlesample buffer. */
1862          if (src_samples == dst_samples && dst_samples > 1) {
1863             /* MSAA copy. */
1864             unsigned i, max_sample = dst_samples - 1;
1865 
1866             for (i = 0; i <= max_sample; i++) {
1867                pipe->set_sample_mask(pipe, 1 << i);
1868                blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1869                                 dstbox->x + dstbox->width,
1870                                 dstbox->y + dstbox->height,
1871                                 src, src_width0, src_height0,
1872                                 srcbox->x, srcbox->y,
1873                                 srcbox->x + srcbox->width,
1874                                 srcbox->y + srcbox->height,
1875                                 srcbox->z + src_z, i, uses_txf,
1876                                 UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
1877             }
1878          } else {
1879             /* Normal copy, MSAA upsampling, or MSAA resolve. */
1880             pipe->set_sample_mask(pipe, ~0);
1881             blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1882                              dstbox->x + dstbox->width,
1883                              dstbox->y + dstbox->height,
1884                              src, src_width0, src_height0,
1885                              srcbox->x, srcbox->y,
1886                              srcbox->x + srcbox->width,
1887                              srcbox->y + srcbox->height,
1888                              srcbox->z + src_z, 0, uses_txf,
1889                              UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
1890          }
1891 
1892          /* Get the next surface or (if this is the last iteration)
1893           * just unreference the last one. */
1894          old = dst;
1895          if (dst_z < dstbox->depth-1) {
1896             dst = util_blitter_get_next_surface_layer(ctx->base.pipe, dst);
1897          }
1898          if (dst_z) {
1899             pipe_surface_reference(&old, NULL);
1900          }
1901       }
1902    }
1903 }
1904 
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)1905 void util_blitter_blit_generic(struct blitter_context *blitter,
1906                                struct pipe_surface *dst,
1907                                const struct pipe_box *dstbox,
1908                                struct pipe_sampler_view *src,
1909                                const struct pipe_box *srcbox,
1910                                unsigned src_width0, unsigned src_height0,
1911                                unsigned mask, unsigned filter,
1912                                const struct pipe_scissor_state *scissor,
1913                                bool alpha_blend)
1914 {
1915    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1916    struct pipe_context *pipe = ctx->base.pipe;
1917    enum pipe_texture_target src_target = src->target;
1918    unsigned src_samples = src->texture->nr_samples;
1919    unsigned dst_samples = dst->texture->nr_samples;
1920    void *sampler_state;
1921    const struct util_format_description *src_desc =
1922          util_format_description(src->format);
1923    const struct util_format_description *dst_desc =
1924          util_format_description(dst->format);
1925 
1926    bool src_has_color = src_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
1927    bool src_has_depth = util_format_has_depth(src_desc);
1928    bool src_has_stencil = util_format_has_stencil(src_desc);
1929 
1930    bool dst_has_color = mask & PIPE_MASK_RGBA &&
1931                         dst_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
1932    bool dst_has_depth = mask & PIPE_MASK_Z &&
1933                         util_format_has_depth(dst_desc);
1934    bool dst_has_stencil = ctx->has_stencil_export &&
1935                           mask & PIPE_MASK_S &&
1936                           util_format_has_stencil(dst_desc);
1937 
1938    /* Return if there is nothing to do. */
1939    if (!dst_has_color && !dst_has_depth && !dst_has_stencil) {
1940       return;
1941    }
1942 
1943    bool is_scaled = dstbox->width != abs(srcbox->width) ||
1944                     dstbox->height != abs(srcbox->height);
1945 
1946    if (src_has_stencil || !is_scaled)
1947       filter = PIPE_TEX_FILTER_NEAREST;
1948 
1949    bool use_txf = false;
1950 
1951    /* Don't support scaled blits. The TXF shader uses F2I for rounding. */
1952    if (ctx->has_txf &&
1953        !is_scaled &&
1954        filter == PIPE_TEX_FILTER_NEAREST &&
1955        src->target != PIPE_TEXTURE_CUBE &&
1956        src->target != PIPE_TEXTURE_CUBE_ARRAY) {
1957       int src_width = u_minify(src_width0, src->u.tex.first_level);
1958       int src_height = u_minify(src_height0, src->u.tex.first_level);
1959       int src_depth = src->u.tex.last_layer + 1;
1960       struct pipe_box box = *srcbox;
1961 
1962       /* Eliminate negative width/height/depth. */
1963       if (box.width < 0) {
1964          box.x += box.width;
1965          box.width *= -1;
1966       }
1967       if (box.height < 0) {
1968          box.y += box.height;
1969          box.height *= -1;
1970       }
1971       if (box.depth < 0) {
1972          box.z += box.depth;
1973          box.depth *= -1;
1974       }
1975 
1976       /* See if srcbox is in bounds. TXF doesn't clamp the coordinates. */
1977       use_txf =
1978          box.x >= 0 && box.x < src_width &&
1979          box.y >= 0 && box.y < src_height &&
1980          box.z >= 0 && box.z < src_depth &&
1981          box.x + box.width > 0 && box.x + box.width <= src_width &&
1982          box.y + box.height > 0 && box.y + box.height <= src_height &&
1983          box.z + box.depth > 0 && box.z + box.depth <= src_depth;
1984    }
1985 
1986    /* Check whether the states are properly saved. */
1987    util_blitter_set_running_flag(blitter);
1988    blitter_check_saved_vertex_states(ctx);
1989    blitter_check_saved_fragment_states(ctx);
1990    blitter_check_saved_textures(ctx);
1991    blitter_check_saved_fb_state(ctx);
1992    blitter_disable_render_cond(ctx);
1993 
1994    /* Blend, DSA, fragment shader. */
1995    if (dst_has_depth && dst_has_stencil) {
1996       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
1997       pipe->bind_depth_stencil_alpha_state(pipe,
1998                                            ctx->dsa_write_depth_stencil);
1999       if (src_has_color) {
2000          assert(use_txf);
2001          ctx->bind_fs_state(pipe,
2002             blitter_get_fs_pack_color_zs(ctx, src_target,
2003                                          src_samples, dst->format, false));
2004       } else {
2005          ctx->bind_fs_state(pipe,
2006             blitter_get_fs_texfetch_depthstencil(ctx, src_target,
2007                                                  src_samples, use_txf));
2008       }
2009    } else if (dst_has_depth) {
2010       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2011       pipe->bind_depth_stencil_alpha_state(pipe,
2012                                            ctx->dsa_write_depth_keep_stencil);
2013       if (src_has_color &&
2014           (src->format == PIPE_FORMAT_R32_UINT ||
2015            src->format == PIPE_FORMAT_R32G32_UINT)) {
2016          assert(use_txf);
2017          ctx->bind_fs_state(pipe,
2018             blitter_get_fs_pack_color_zs(ctx, src_target,
2019                                          src_samples, dst->format, false));
2020       } else {
2021          ctx->bind_fs_state(pipe,
2022             blitter_get_fs_texfetch_depth(ctx, src_target,
2023                                           src_samples, use_txf));
2024       }
2025    } else if (dst_has_stencil) {
2026       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2027       pipe->bind_depth_stencil_alpha_state(pipe,
2028                                            ctx->dsa_keep_depth_write_stencil);
2029 
2030       assert(src_has_stencil); /* unpacking from color is unsupported */
2031       ctx->bind_fs_state(pipe,
2032          blitter_get_fs_texfetch_stencil(ctx, src_target,
2033                                          src_samples, use_txf));
2034    } else {
2035       unsigned colormask = mask & PIPE_MASK_RGBA;
2036 
2037       pipe->bind_blend_state(pipe, ctx->blend[colormask][alpha_blend]);
2038       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2039 
2040       if (src_has_depth &&
2041           (dst->format == PIPE_FORMAT_R32_UINT ||
2042            dst->format == PIPE_FORMAT_R32G32_UINT)) {
2043          assert(use_txf);
2044          ctx->bind_fs_state(pipe,
2045             blitter_get_fs_pack_color_zs(ctx, src_target,
2046                                          src_samples, src->format, true));
2047       } else {
2048          ctx->bind_fs_state(pipe,
2049             blitter_get_fs_texfetch_col(ctx, src->format, dst->format, src_target,
2050                                         src_samples, dst_samples, filter,
2051                                         use_txf));
2052       }
2053    }
2054 
2055    /* Set the linear filter only for scaled color non-MSAA blits. */
2056    if (filter == PIPE_TEX_FILTER_LINEAR) {
2057       if (src_target == PIPE_TEXTURE_RECT) {
2058          sampler_state = ctx->sampler_state_rect_linear;
2059       } else {
2060          sampler_state = ctx->sampler_state_linear;
2061       }
2062    } else {
2063       if (src_target == PIPE_TEXTURE_RECT) {
2064          sampler_state = ctx->sampler_state_rect;
2065       } else {
2066          sampler_state = ctx->sampler_state;
2067       }
2068    }
2069 
2070    /* Set samplers. */
2071    if (src_has_depth && src_has_stencil &&
2072        (dst_has_color || (dst_has_depth && dst_has_stencil))) {
2073       /* Setup two samplers, one for depth and the other one for stencil. */
2074       struct pipe_sampler_view templ;
2075       struct pipe_sampler_view *views[2];
2076       void *samplers[2] = {sampler_state, sampler_state};
2077 
2078       templ = *src;
2079       templ.format = util_format_stencil_only(templ.format);
2080       assert(templ.format != PIPE_FORMAT_NONE);
2081 
2082       views[0] = src;
2083       views[1] = pipe->create_sampler_view(pipe, src->texture, &templ);
2084 
2085       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 2, views);
2086       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 2, samplers);
2087 
2088       pipe_sampler_view_reference(&views[1], NULL);
2089    } else if (src_has_stencil && dst_has_stencil) {
2090       /* Set a stencil-only sampler view for it not to sample depth instead. */
2091       struct pipe_sampler_view templ;
2092       struct pipe_sampler_view *view;
2093 
2094       templ = *src;
2095       templ.format = util_format_stencil_only(templ.format);
2096       assert(templ.format != PIPE_FORMAT_NONE);
2097 
2098       view = pipe->create_sampler_view(pipe, src->texture, &templ);
2099 
2100       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &view);
2101       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2102                                 0, 1, &sampler_state);
2103 
2104       pipe_sampler_view_reference(&view, NULL);
2105    } else {
2106       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &src);
2107       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2108                                 0, 1, &sampler_state);
2109    }
2110 
2111    if (scissor) {
2112       pipe->set_scissor_states(pipe, 0, 1, scissor);
2113    }
2114 
2115    blitter_set_common_draw_rect_state(ctx, scissor != NULL, dst_samples > 1);
2116 
2117    do_blits(ctx, dst, dstbox, src, src_width0, src_height0,
2118             srcbox, dst_has_depth || dst_has_stencil, use_txf);
2119 
2120    util_blitter_restore_vertex_states(blitter);
2121    util_blitter_restore_fragment_states(blitter);
2122    util_blitter_restore_textures(blitter);
2123    util_blitter_restore_fb_state(blitter);
2124    if (scissor) {
2125       pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor);
2126    }
2127    util_blitter_restore_render_cond(blitter);
2128    util_blitter_unset_running_flag(blitter);
2129 }
2130 
2131 void
util_blitter_blit(struct blitter_context * blitter,const struct pipe_blit_info * info)2132 util_blitter_blit(struct blitter_context *blitter,
2133                   const struct pipe_blit_info *info)
2134 {
2135    struct pipe_resource *dst = info->dst.resource;
2136    struct pipe_resource *src = info->src.resource;
2137    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2138    struct pipe_context *pipe = ctx->base.pipe;
2139    struct pipe_surface *dst_view, dst_templ;
2140    struct pipe_sampler_view src_templ, *src_view;
2141 
2142    /* Initialize the surface. */
2143    util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level,
2144                                     info->dst.box.z);
2145    dst_templ.format = info->dst.format;
2146    dst_view = pipe->create_surface(pipe, dst, &dst_templ);
2147 
2148    /* Initialize the sampler view. */
2149    util_blitter_default_src_texture(blitter, &src_templ, src, info->src.level);
2150    src_templ.format = info->src.format;
2151    src_view = pipe->create_sampler_view(pipe, src, &src_templ);
2152 
2153    /* Copy. */
2154    util_blitter_blit_generic(blitter, dst_view, &info->dst.box,
2155                              src_view, &info->src.box, src->width0, src->height0,
2156                              info->mask, info->filter,
2157                              info->scissor_enable ? &info->scissor : NULL,
2158                              info->alpha_blend);
2159 
2160    pipe_surface_reference(&dst_view, NULL);
2161    pipe_sampler_view_reference(&src_view, NULL);
2162 }
2163 
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)2164 void util_blitter_generate_mipmap(struct blitter_context *blitter,
2165                                   struct pipe_resource *tex,
2166                                   enum pipe_format format,
2167                                   unsigned base_level, unsigned last_level,
2168                                   unsigned first_layer, unsigned last_layer)
2169 {
2170    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2171    struct pipe_context *pipe = ctx->base.pipe;
2172    struct pipe_surface dst_templ, *dst_view;
2173    struct pipe_sampler_view src_templ, *src_view;
2174    bool is_depth;
2175    void *sampler_state;
2176    const struct util_format_description *desc =
2177          util_format_description(format);
2178    unsigned src_level;
2179    unsigned target = tex->target;
2180 
2181    if (ctx->cube_as_2darray &&
2182        (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY))
2183       target = PIPE_TEXTURE_2D_ARRAY;
2184 
2185    assert(tex->nr_samples <= 1);
2186    /* Disallow stencil formats without depth. */
2187    assert(!util_format_has_stencil(desc) || util_format_has_depth(desc));
2188 
2189    is_depth = desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS;
2190 
2191    /* Check whether the states are properly saved. */
2192    util_blitter_set_running_flag(blitter);
2193    blitter_check_saved_vertex_states(ctx);
2194    blitter_check_saved_fragment_states(ctx);
2195    blitter_check_saved_textures(ctx);
2196    blitter_check_saved_fb_state(ctx);
2197    blitter_disable_render_cond(ctx);
2198 
2199    /* Set states. */
2200    if (is_depth) {
2201       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2202       pipe->bind_depth_stencil_alpha_state(pipe,
2203                                            ctx->dsa_write_depth_keep_stencil);
2204       ctx->bind_fs_state(pipe,
2205                          blitter_get_fs_texfetch_depth(ctx, target, 1, false));
2206    } else {
2207       pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2208       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2209       ctx->bind_fs_state(pipe,
2210             blitter_get_fs_texfetch_col(ctx, tex->format, tex->format, target,
2211                                         1, 1, PIPE_TEX_FILTER_LINEAR, false));
2212    }
2213 
2214    if (target == PIPE_TEXTURE_RECT) {
2215       sampler_state = ctx->sampler_state_rect_linear;
2216    } else {
2217       sampler_state = ctx->sampler_state_linear;
2218    }
2219    pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2220                              0, 1, &sampler_state);
2221 
2222    blitter_set_common_draw_rect_state(ctx, false, false);
2223 
2224    for (src_level = base_level; src_level < last_level; src_level++) {
2225       struct pipe_box dstbox = {0}, srcbox = {0};
2226       unsigned dst_level = src_level + 1;
2227 
2228       dstbox.width = u_minify(tex->width0, dst_level);
2229       dstbox.height = u_minify(tex->height0, dst_level);
2230 
2231       srcbox.width = u_minify(tex->width0, src_level);
2232       srcbox.height = u_minify(tex->height0, src_level);
2233 
2234       if (target == PIPE_TEXTURE_3D) {
2235          dstbox.depth = util_num_layers(tex, dst_level);
2236          srcbox.depth = util_num_layers(tex, src_level);
2237       } else {
2238          dstbox.z = srcbox.z = first_layer;
2239          dstbox.depth = srcbox.depth = last_layer - first_layer + 1;
2240       }
2241 
2242       /* Initialize the surface. */
2243       util_blitter_default_dst_texture(&dst_templ, tex, dst_level,
2244                                        first_layer);
2245       dst_templ.format = format;
2246       dst_view = pipe->create_surface(pipe, tex, &dst_templ);
2247 
2248       /* Initialize the sampler view. */
2249       util_blitter_default_src_texture(blitter, &src_templ, tex, src_level);
2250       src_templ.format = format;
2251       src_view = pipe->create_sampler_view(pipe, tex, &src_templ);
2252 
2253       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &src_view);
2254 
2255       do_blits(ctx, dst_view, &dstbox, src_view, tex->width0, tex->height0,
2256                &srcbox, is_depth, false);
2257 
2258       pipe_surface_reference(&dst_view, NULL);
2259       pipe_sampler_view_reference(&src_view, NULL);
2260    }
2261 
2262    util_blitter_restore_vertex_states(blitter);
2263    util_blitter_restore_fragment_states(blitter);
2264    util_blitter_restore_textures(blitter);
2265    util_blitter_restore_fb_state(blitter);
2266    util_blitter_restore_render_cond(blitter);
2267    util_blitter_unset_running_flag(blitter);
2268 }
2269 
2270 /* 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)2271 void util_blitter_clear_render_target(struct blitter_context *blitter,
2272                                       struct pipe_surface *dstsurf,
2273                                       const union pipe_color_union *color,
2274                                       unsigned dstx, unsigned dsty,
2275                                       unsigned width, unsigned height)
2276 {
2277    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2278    struct pipe_context *pipe = ctx->base.pipe;
2279    struct pipe_framebuffer_state fb_state;
2280    bool msaa;
2281    unsigned num_layers;
2282 
2283    assert(dstsurf->texture);
2284    if (!dstsurf->texture)
2285       return;
2286 
2287    /* check the saved state */
2288    util_blitter_set_running_flag(blitter);
2289    blitter_check_saved_vertex_states(ctx);
2290    blitter_check_saved_fragment_states(ctx);
2291    blitter_check_saved_fb_state(ctx);
2292    blitter_disable_render_cond(ctx);
2293 
2294    /* bind states */
2295    pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2296    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2297    bind_fs_write_one_cbuf(ctx);
2298 
2299    /* set a framebuffer state */
2300    fb_state.width = dstsurf->width;
2301    fb_state.height = dstsurf->height;
2302    fb_state.nr_cbufs = 1;
2303    fb_state.cbufs[0] = dstsurf;
2304    fb_state.zsbuf = 0;
2305    pipe->set_framebuffer_state(pipe, &fb_state);
2306    pipe->set_sample_mask(pipe, ~0);
2307    msaa = util_framebuffer_get_num_samples(&fb_state) > 1;
2308 
2309    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2310 
2311    union blitter_attrib attrib;
2312    memcpy(attrib.color, color->ui, sizeof(color->ui));
2313 
2314    num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
2315    if (num_layers > 1 && ctx->has_layered) {
2316       blitter_set_common_draw_rect_state(ctx, false, msaa);
2317       blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_layered,
2318                               dstx, dsty, dstx+width, dsty+height, 0,
2319                               num_layers, UTIL_BLITTER_ATTRIB_COLOR, &attrib);
2320    } else {
2321       blitter_set_common_draw_rect_state(ctx, false, msaa);
2322       blitter->draw_rectangle(blitter, ctx->velem_state,
2323                               get_vs_passthrough_pos_generic,
2324                               dstx, dsty, dstx+width, dsty+height, 0,
2325                               1, UTIL_BLITTER_ATTRIB_COLOR, &attrib);
2326    }
2327 
2328    util_blitter_restore_vertex_states(blitter);
2329    util_blitter_restore_fragment_states(blitter);
2330    util_blitter_restore_fb_state(blitter);
2331    util_blitter_restore_render_cond(blitter);
2332    util_blitter_unset_running_flag(blitter);
2333 }
2334 
2335 /* 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)2336 void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
2337                                       struct pipe_surface *dstsurf,
2338                                       unsigned clear_flags,
2339                                       double depth,
2340                                       unsigned stencil,
2341                                       unsigned dstx, unsigned dsty,
2342                                       unsigned width, unsigned height)
2343 {
2344    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2345    struct pipe_context *pipe = ctx->base.pipe;
2346    struct pipe_framebuffer_state fb_state;
2347    struct pipe_stencil_ref sr = { { 0 } };
2348    unsigned num_layers;
2349 
2350    assert(dstsurf->texture);
2351    if (!dstsurf->texture)
2352       return;
2353 
2354    /* check the saved state */
2355    util_blitter_set_running_flag(blitter);
2356    blitter_check_saved_vertex_states(ctx);
2357    blitter_check_saved_fragment_states(ctx);
2358    blitter_check_saved_fb_state(ctx);
2359    blitter_disable_render_cond(ctx);
2360 
2361    /* bind states */
2362    pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2363    if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
2364       sr.ref_value[0] = stencil & 0xff;
2365       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
2366       pipe->set_stencil_ref(pipe, &sr);
2367    }
2368    else if (clear_flags & PIPE_CLEAR_DEPTH) {
2369       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
2370    }
2371    else if (clear_flags & PIPE_CLEAR_STENCIL) {
2372       sr.ref_value[0] = stencil & 0xff;
2373       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
2374       pipe->set_stencil_ref(pipe, &sr);
2375    }
2376    else
2377       /* hmm that should be illegal probably, or make it a no-op somewhere */
2378       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2379 
2380    bind_fs_empty(ctx);
2381 
2382    /* set a framebuffer state */
2383    fb_state.width = dstsurf->width;
2384    fb_state.height = dstsurf->height;
2385    fb_state.nr_cbufs = 0;
2386    fb_state.cbufs[0] = 0;
2387    fb_state.zsbuf = dstsurf;
2388    pipe->set_framebuffer_state(pipe, &fb_state);
2389    pipe->set_sample_mask(pipe, ~0);
2390 
2391    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2392 
2393    num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
2394    if (num_layers > 1 && ctx->has_layered) {
2395       blitter_set_common_draw_rect_state(ctx, false, false);
2396       blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_layered,
2397                               dstx, dsty, dstx+width, dsty+height, depth,
2398                               num_layers, UTIL_BLITTER_ATTRIB_NONE, NULL);
2399    } else {
2400       blitter_set_common_draw_rect_state(ctx, false, false);
2401       blitter->draw_rectangle(blitter, ctx->velem_state,
2402                               get_vs_passthrough_pos,
2403                               dstx, dsty, dstx+width, dsty+height, depth, 1,
2404                               UTIL_BLITTER_ATTRIB_NONE, NULL);
2405    }
2406 
2407    util_blitter_restore_vertex_states(blitter);
2408    util_blitter_restore_fragment_states(blitter);
2409    util_blitter_restore_fb_state(blitter);
2410    util_blitter_restore_render_cond(blitter);
2411    util_blitter_unset_running_flag(blitter);
2412 }
2413 
2414 /* 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)2415 void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
2416                                        struct pipe_surface *zsurf,
2417                                        struct pipe_surface *cbsurf,
2418                                        unsigned sample_mask,
2419                                        void *dsa_stage, float depth)
2420 {
2421    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2422    struct pipe_context *pipe = ctx->base.pipe;
2423    struct pipe_framebuffer_state fb_state;
2424 
2425    assert(zsurf->texture);
2426    if (!zsurf->texture)
2427       return;
2428 
2429    /* check the saved state */
2430    util_blitter_set_running_flag(blitter);
2431    blitter_check_saved_vertex_states(ctx);
2432    blitter_check_saved_fragment_states(ctx);
2433    blitter_check_saved_fb_state(ctx);
2434    blitter_disable_render_cond(ctx);
2435 
2436    /* bind states */
2437    pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA][0] :
2438                                          ctx->blend[0][0]);
2439    pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
2440    if (cbsurf)
2441       bind_fs_write_one_cbuf(ctx);
2442    else
2443       bind_fs_empty(ctx);
2444 
2445    /* set a framebuffer state */
2446    fb_state.width = zsurf->width;
2447    fb_state.height = zsurf->height;
2448    fb_state.nr_cbufs = 1;
2449    if (cbsurf) {
2450       fb_state.cbufs[0] = cbsurf;
2451       fb_state.nr_cbufs = 1;
2452    } else {
2453       fb_state.cbufs[0] = NULL;
2454       fb_state.nr_cbufs = 0;
2455    }
2456    fb_state.zsbuf = zsurf;
2457    pipe->set_framebuffer_state(pipe, &fb_state);
2458    pipe->set_sample_mask(pipe, sample_mask);
2459 
2460    blitter_set_common_draw_rect_state(ctx, false,
2461       util_framebuffer_get_num_samples(&fb_state) > 1);
2462    blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height);
2463    blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2464                            0, 0, zsurf->width, zsurf->height, depth,
2465                            1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2466 
2467    util_blitter_restore_vertex_states(blitter);
2468    util_blitter_restore_fragment_states(blitter);
2469    util_blitter_restore_fb_state(blitter);
2470    util_blitter_restore_render_cond(blitter);
2471    util_blitter_unset_running_flag(blitter);
2472 }
2473 
util_blitter_copy_buffer(struct blitter_context * blitter,struct pipe_resource * dst,unsigned dstx,struct pipe_resource * src,unsigned srcx,unsigned size)2474 void util_blitter_copy_buffer(struct blitter_context *blitter,
2475                               struct pipe_resource *dst,
2476                               unsigned dstx,
2477                               struct pipe_resource *src,
2478                               unsigned srcx,
2479                               unsigned size)
2480 {
2481    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2482    struct pipe_context *pipe = ctx->base.pipe;
2483    struct pipe_vertex_buffer vb;
2484    struct pipe_stream_output_target *so_target;
2485    unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
2486 
2487    if (srcx >= src->width0 ||
2488        dstx >= dst->width0) {
2489       return;
2490    }
2491    if (srcx + size > src->width0) {
2492       size = src->width0 - srcx;
2493    }
2494    if (dstx + size > dst->width0) {
2495       size = dst->width0 - dstx;
2496    }
2497 
2498    /* Drivers not capable of Stream Out should not call this function
2499     * in the first place. */
2500    assert(ctx->has_stream_out);
2501 
2502    /* Some alignment is required. */
2503    if (srcx % 4 != 0 || dstx % 4 != 0 || size % 4 != 0 ||
2504        !ctx->has_stream_out) {
2505       struct pipe_box box;
2506       u_box_1d(srcx, size, &box);
2507       util_resource_copy_region(pipe, dst, 0, dstx, 0, 0, src, 0, &box);
2508       return;
2509    }
2510 
2511    util_blitter_set_running_flag(blitter);
2512    blitter_check_saved_vertex_states(ctx);
2513    blitter_disable_render_cond(ctx);
2514 
2515    vb.is_user_buffer = false;
2516    vb.buffer.resource = src;
2517    vb.buffer_offset = srcx;
2518    vb.stride = 4;
2519 
2520    pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
2521    pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf[0]);
2522    bind_vs_pos_only(ctx, 1);
2523    if (ctx->has_geometry_shader)
2524       pipe->bind_gs_state(pipe, NULL);
2525    if (ctx->has_tessellation) {
2526       pipe->bind_tcs_state(pipe, NULL);
2527       pipe->bind_tes_state(pipe, NULL);
2528    }
2529    pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
2530 
2531    so_target = pipe->create_stream_output_target(pipe, dst, dstx, size);
2532    pipe->set_stream_output_targets(pipe, 1, &so_target, offsets);
2533 
2534    util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
2535 
2536    util_blitter_restore_vertex_states(blitter);
2537    util_blitter_restore_render_cond(blitter);
2538    util_blitter_unset_running_flag(blitter);
2539    pipe_so_target_reference(&so_target, NULL);
2540 }
2541 
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)2542 void util_blitter_clear_buffer(struct blitter_context *blitter,
2543                                struct pipe_resource *dst,
2544                                unsigned offset, unsigned size,
2545                                unsigned num_channels,
2546                                const union pipe_color_union *clear_value)
2547 {
2548    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2549    struct pipe_context *pipe = ctx->base.pipe;
2550    struct pipe_vertex_buffer vb = {0};
2551    struct pipe_stream_output_target *so_target = NULL;
2552    unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
2553 
2554    assert(num_channels >= 1);
2555    assert(num_channels <= 4);
2556 
2557    /* IMPORTANT:  DON'T DO ANY BOUNDS CHECKING HERE!
2558     *
2559     * R600 uses this to initialize texture resources, so width0 might not be
2560     * what you think it is.
2561     */
2562 
2563    /* Streamout is required. */
2564    if (!ctx->has_stream_out) {
2565       assert(!"Streamout unsupported in util_blitter_clear_buffer()");
2566       return;
2567    }
2568 
2569    /* Some alignment is required. */
2570    if (offset % 4 != 0 || size % 4 != 0) {
2571       assert(!"Bad alignment in util_blitter_clear_buffer()");
2572       return;
2573    }
2574 
2575    u_upload_data(pipe->stream_uploader, 0, num_channels*4, 4, clear_value,
2576                  &vb.buffer_offset, &vb.buffer.resource);
2577    if (!vb.buffer.resource)
2578       goto out;
2579 
2580    vb.stride = 0;
2581 
2582    util_blitter_set_running_flag(blitter);
2583    blitter_check_saved_vertex_states(ctx);
2584    blitter_disable_render_cond(ctx);
2585 
2586    pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
2587    pipe->bind_vertex_elements_state(pipe,
2588                                     ctx->velem_state_readbuf[num_channels-1]);
2589    bind_vs_pos_only(ctx, num_channels);
2590    if (ctx->has_geometry_shader)
2591       pipe->bind_gs_state(pipe, NULL);
2592    if (ctx->has_tessellation) {
2593       pipe->bind_tcs_state(pipe, NULL);
2594       pipe->bind_tes_state(pipe, NULL);
2595    }
2596    pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
2597 
2598    so_target = pipe->create_stream_output_target(pipe, dst, offset, size);
2599    pipe->set_stream_output_targets(pipe, 1, &so_target, offsets);
2600 
2601    util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
2602 
2603 out:
2604    util_blitter_restore_vertex_states(blitter);
2605    util_blitter_restore_render_cond(blitter);
2606    util_blitter_unset_running_flag(blitter);
2607    pipe_so_target_reference(&so_target, NULL);
2608    pipe_resource_reference(&vb.buffer.resource, NULL);
2609 }
2610 
2611 /* 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)2612 void util_blitter_custom_resolve_color(struct blitter_context *blitter,
2613                                        struct pipe_resource *dst,
2614                                        unsigned dst_level,
2615                                        unsigned dst_layer,
2616                                        struct pipe_resource *src,
2617                                        unsigned src_layer,
2618                                        unsigned sample_mask,
2619                                        void *custom_blend,
2620                                        enum pipe_format format)
2621 {
2622    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2623    struct pipe_context *pipe = ctx->base.pipe;
2624    struct pipe_framebuffer_state fb_state;
2625    struct pipe_surface *srcsurf, *dstsurf, surf_tmpl;
2626 
2627    util_blitter_set_running_flag(blitter);
2628    blitter_check_saved_vertex_states(ctx);
2629    blitter_check_saved_fragment_states(ctx);
2630    blitter_disable_render_cond(ctx);
2631 
2632    /* bind states */
2633    pipe->bind_blend_state(pipe, custom_blend);
2634    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2635    bind_fs_write_one_cbuf(ctx);
2636    pipe->set_sample_mask(pipe, sample_mask);
2637 
2638    memset(&surf_tmpl, 0, sizeof(surf_tmpl));
2639    surf_tmpl.format = format;
2640    surf_tmpl.u.tex.level = dst_level;
2641    surf_tmpl.u.tex.first_layer = dst_layer;
2642    surf_tmpl.u.tex.last_layer = dst_layer;
2643 
2644    dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl);
2645 
2646    surf_tmpl.u.tex.level = 0;
2647    surf_tmpl.u.tex.first_layer = src_layer;
2648    surf_tmpl.u.tex.last_layer = src_layer;
2649 
2650    srcsurf = pipe->create_surface(pipe, src, &surf_tmpl);
2651 
2652    /* set a framebuffer state */
2653    fb_state.width = src->width0;
2654    fb_state.height = src->height0;
2655    fb_state.nr_cbufs = 2;
2656    fb_state.cbufs[0] = srcsurf;
2657    fb_state.cbufs[1] = dstsurf;
2658    fb_state.zsbuf = NULL;
2659    pipe->set_framebuffer_state(pipe, &fb_state);
2660 
2661    blitter_set_common_draw_rect_state(ctx, false,
2662       util_framebuffer_get_num_samples(&fb_state) > 1);
2663    blitter_set_dst_dimensions(ctx, src->width0, src->height0);
2664    blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2665                            0, 0, src->width0, src->height0,
2666                            0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2667    util_blitter_restore_fb_state(blitter);
2668    util_blitter_restore_vertex_states(blitter);
2669    util_blitter_restore_fragment_states(blitter);
2670    util_blitter_restore_render_cond(blitter);
2671    util_blitter_unset_running_flag(blitter);
2672 
2673    pipe_surface_reference(&srcsurf, NULL);
2674    pipe_surface_reference(&dstsurf, NULL);
2675 }
2676 
util_blitter_custom_color(struct blitter_context * blitter,struct pipe_surface * dstsurf,void * custom_blend)2677 void util_blitter_custom_color(struct blitter_context *blitter,
2678                                struct pipe_surface *dstsurf,
2679                                void *custom_blend)
2680 {
2681    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2682    struct pipe_context *pipe = ctx->base.pipe;
2683    struct pipe_framebuffer_state fb_state;
2684 
2685    assert(dstsurf->texture);
2686    if (!dstsurf->texture)
2687       return;
2688 
2689    /* check the saved state */
2690    util_blitter_set_running_flag(blitter);
2691    blitter_check_saved_vertex_states(ctx);
2692    blitter_check_saved_fragment_states(ctx);
2693    blitter_check_saved_fb_state(ctx);
2694    blitter_disable_render_cond(ctx);
2695 
2696    /* bind states */
2697    pipe->bind_blend_state(pipe, custom_blend ? custom_blend
2698                                              : ctx->blend[PIPE_MASK_RGBA][0]);
2699    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2700    bind_fs_write_one_cbuf(ctx);
2701    pipe->set_sample_mask(pipe, (1ull << MAX2(1, dstsurf->texture->nr_samples)) - 1);
2702 
2703    /* set a framebuffer state */
2704    fb_state.width = dstsurf->width;
2705    fb_state.height = dstsurf->height;
2706    fb_state.nr_cbufs = 1;
2707    fb_state.cbufs[0] = dstsurf;
2708    fb_state.zsbuf = 0;
2709    pipe->set_framebuffer_state(pipe, &fb_state);
2710    pipe->set_sample_mask(pipe, ~0);
2711 
2712    blitter_set_common_draw_rect_state(ctx, false,
2713       util_framebuffer_get_num_samples(&fb_state) > 1);
2714    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2715    blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2716                            0, 0, dstsurf->width, dstsurf->height,
2717                            0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2718 
2719    util_blitter_restore_vertex_states(blitter);
2720    util_blitter_restore_fragment_states(blitter);
2721    util_blitter_restore_fb_state(blitter);
2722    util_blitter_restore_render_cond(blitter);
2723    util_blitter_unset_running_flag(blitter);
2724 }
2725 
get_custom_vs(struct blitter_context * blitter)2726 static void *get_custom_vs(struct blitter_context *blitter)
2727 {
2728    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2729 
2730    return ctx->custom_vs;
2731 }
2732 
2733 /**
2734  * Performs a custom blit to the destination surface, using the VS and FS
2735  * provided.
2736  *
2737  * Used by vc4 for the 8-bit linear-to-tiled blit.
2738  */
util_blitter_custom_shader(struct blitter_context * blitter,struct pipe_surface * dstsurf,void * custom_vs,void * custom_fs)2739 void util_blitter_custom_shader(struct blitter_context *blitter,
2740                                 struct pipe_surface *dstsurf,
2741                                 void *custom_vs, void *custom_fs)
2742 {
2743    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2744    struct pipe_context *pipe = ctx->base.pipe;
2745    struct pipe_framebuffer_state fb_state = { 0 };
2746 
2747    ctx->custom_vs = custom_vs;
2748 
2749    assert(dstsurf->texture);
2750    if (!dstsurf->texture)
2751       return;
2752 
2753    /* check the saved state */
2754    util_blitter_set_running_flag(blitter);
2755    blitter_check_saved_vertex_states(ctx);
2756    blitter_check_saved_fragment_states(ctx);
2757    blitter_check_saved_fb_state(ctx);
2758    blitter_disable_render_cond(ctx);
2759 
2760    /* bind states */
2761    pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2762    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2763    pipe->bind_fs_state(pipe, custom_fs);
2764    pipe->set_sample_mask(pipe, (1ull << MAX2(1, dstsurf->texture->nr_samples)) - 1);
2765 
2766    /* set a framebuffer state */
2767    fb_state.width = dstsurf->width;
2768    fb_state.height = dstsurf->height;
2769    fb_state.nr_cbufs = 1;
2770    fb_state.cbufs[0] = dstsurf;
2771    pipe->set_framebuffer_state(pipe, &fb_state);
2772    pipe->set_sample_mask(pipe, ~0);
2773 
2774    blitter_set_common_draw_rect_state(ctx, false,
2775       util_framebuffer_get_num_samples(&fb_state) > 1);
2776    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2777    blitter->draw_rectangle(blitter, ctx->velem_state, get_custom_vs,
2778                            0, 0, dstsurf->width, dstsurf->height,
2779                            0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2780 
2781    util_blitter_restore_vertex_states(blitter);
2782    util_blitter_restore_fragment_states(blitter);
2783    util_blitter_restore_fb_state(blitter);
2784    util_blitter_restore_render_cond(blitter);
2785    util_blitter_unset_running_flag(blitter);
2786 }
2787 
2788 static void *
get_stencil_blit_fallback_fs(struct blitter_context_priv * ctx,bool msaa_src)2789 get_stencil_blit_fallback_fs(struct blitter_context_priv *ctx, bool msaa_src)
2790 {
2791    if (!ctx->fs_stencil_blit_fallback[msaa_src]) {
2792       ctx->fs_stencil_blit_fallback[msaa_src] =
2793          util_make_fs_stencil_blit(ctx->base.pipe, msaa_src);
2794    }
2795 
2796    return ctx->fs_stencil_blit_fallback[msaa_src];
2797 }
2798 
2799 static void *
get_stencil_blit_fallback_dsa(struct blitter_context_priv * ctx,unsigned i)2800 get_stencil_blit_fallback_dsa(struct blitter_context_priv *ctx, unsigned i)
2801 {
2802    assert(i < ARRAY_SIZE(ctx->dsa_replicate_stencil_bit));
2803    if (!ctx->dsa_replicate_stencil_bit[i]) {
2804       struct pipe_depth_stencil_alpha_state dsa = { 0 };
2805       dsa.depth.func = PIPE_FUNC_ALWAYS;
2806       dsa.stencil[0].enabled = 1;
2807       dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
2808       dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
2809       dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
2810       dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
2811       dsa.stencil[0].valuemask = 0xff;
2812       dsa.stencil[0].writemask = 1u << i;
2813 
2814       ctx->dsa_replicate_stencil_bit[i] =
2815          ctx->base.pipe->create_depth_stencil_alpha_state(ctx->base.pipe, &dsa);
2816    }
2817    return ctx->dsa_replicate_stencil_bit[i];
2818 }
2819 
2820 /**
2821  * Performs a series of draws to implement stencil blits texture without
2822  * requiring stencil writes, updating a single bit per pixel at the time.
2823  */
2824 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)2825 util_blitter_stencil_fallback(struct blitter_context *blitter,
2826                               struct pipe_resource *dst,
2827                               unsigned dst_level,
2828                               const struct pipe_box *dstbox,
2829                               struct pipe_resource *src,
2830                               unsigned src_level,
2831                               const struct pipe_box *srcbox,
2832                               const struct pipe_scissor_state *scissor)
2833 {
2834    struct blitter_context_priv *ctx = (struct blitter_context_priv *)blitter;
2835    struct pipe_context *pipe = ctx->base.pipe;
2836 
2837    /* check the saved state */
2838    util_blitter_set_running_flag(blitter);
2839    blitter_check_saved_vertex_states(ctx);
2840    blitter_check_saved_fragment_states(ctx);
2841    blitter_check_saved_fb_state(ctx);
2842    blitter_disable_render_cond(ctx);
2843 
2844    /* Initialize the surface. */
2845    struct pipe_surface *dst_view, dst_templ;
2846    util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstbox->z);
2847    dst_view = pipe->create_surface(pipe, dst, &dst_templ);
2848 
2849    /* Initialize the sampler view. */
2850    struct pipe_sampler_view src_templ, *src_view;
2851    util_blitter_default_src_texture(blitter, &src_templ, src, src_level);
2852    src_templ.format = util_format_stencil_only(src_templ.format);
2853    src_view = pipe->create_sampler_view(pipe, src, &src_templ);
2854 
2855    /* bind states */
2856    pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2857    pipe->bind_fs_state(pipe,
2858       get_stencil_blit_fallback_fs(ctx, src->nr_samples > 1));
2859 
2860    /* set a framebuffer state */
2861    struct pipe_framebuffer_state fb_state = { 0 };
2862    fb_state.width = dstbox->width;
2863    fb_state.height = dstbox->height;
2864    fb_state.zsbuf = dst_view;
2865    pipe->set_framebuffer_state(pipe, &fb_state);
2866    pipe->set_sample_mask(pipe, ~0);
2867 
2868    blitter_set_common_draw_rect_state(ctx, scissor != NULL,
2869       util_framebuffer_get_num_samples(&fb_state) > 1);
2870    blitter_set_dst_dimensions(ctx, dst_view->width, dst_view->height);
2871 
2872    if (scissor) {
2873       pipe->clear_depth_stencil(pipe, dst_view, PIPE_CLEAR_STENCIL, 0.0, 0,
2874                                 MAX2(dstbox->x, scissor->minx),
2875                                 MAX2(dstbox->y, scissor->miny),
2876                                 MIN2(dstbox->x + dstbox->width, scissor->maxx) - dstbox->x,
2877                                 MIN2(dstbox->y + dstbox->height, scissor->maxy) - dstbox->y,
2878                                 true);
2879       pipe->set_scissor_states(pipe, 0, 1, scissor);
2880    } else {
2881       pipe->clear_depth_stencil(pipe, dst_view, PIPE_CLEAR_STENCIL, 0.0, 0,
2882                                 dstbox->x, dstbox->y,
2883                                 dstbox->width, dstbox->height,
2884                                 true);
2885    }
2886 
2887    pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &src_view);
2888    pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &ctx->sampler_state);
2889 
2890    unsigned stencil_bits =
2891       util_format_get_component_bits(dst->format,
2892                                      UTIL_FORMAT_COLORSPACE_ZS, 1);
2893 
2894    struct pipe_stencil_ref sr = { { (1u << stencil_bits) - 1 } };
2895    pipe->set_stencil_ref(pipe, &sr);
2896 
2897    union blitter_attrib coord;
2898    get_texcoords(src_view, src->width0, src->height0,
2899                  srcbox->x, srcbox->y,
2900                  srcbox->x + srcbox->width, srcbox->y + srcbox->height,
2901                  srcbox->z, 0, true,
2902                  &coord);
2903 
2904    for (int i = 0; i < stencil_bits; ++i) {
2905       uint32_t mask = 1 << i;
2906       struct pipe_constant_buffer cb = {
2907          .user_buffer = &mask,
2908          .buffer_size = sizeof(mask),
2909       };
2910       pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
2911                                 &cb);
2912 
2913       pipe->bind_depth_stencil_alpha_state(pipe,
2914          get_stencil_blit_fallback_dsa(ctx, i));
2915 
2916       blitter->draw_rectangle(blitter, ctx->velem_state,
2917                               get_vs_passthrough_pos_generic,
2918                               dstbox->x, dstbox->y,
2919                               dstbox->x + dstbox->width,
2920                               dstbox->y + dstbox->height,
2921                               0, 1,
2922                               UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW,
2923                               &coord);
2924    }
2925 
2926    if (scissor)
2927       pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor);
2928 
2929    util_blitter_restore_vertex_states(blitter);
2930    util_blitter_restore_fragment_states(blitter);
2931    util_blitter_restore_textures(blitter);
2932    util_blitter_restore_fb_state(blitter);
2933    util_blitter_restore_render_cond(blitter);
2934    util_blitter_restore_constant_buffer_state(blitter);
2935    util_blitter_unset_running_flag(blitter);
2936 
2937    pipe_surface_reference(&dst_view, NULL);
2938    pipe_sampler_view_reference(&src_view, NULL);
2939 }
2940