• 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/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    struct u_upload_mgr *upload;
65 
66    float vertices[4][2][4];   /**< {pos, color} or {pos, texcoord} */
67 
68    /* Templates for various state objects. */
69 
70    /* Constant state objects. */
71    /* Vertex shaders. */
72    void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/
73    void *vs_pos_only[4]; /**< Vertex shader which passes pos to the output.*/
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.
82     * The first index indicates the texture type / destination type,
83     * the second index is the PIPE_TEXTURE_* to be sampled. */
84    void *fs_texfetch_col[5][PIPE_MAX_TEXTURE_TYPES];
85 
86    /* FS which outputs a depth from a texture,
87       where the index is PIPE_TEXTURE_* to be sampled. */
88    void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES];
89    void *fs_texfetch_depthstencil[PIPE_MAX_TEXTURE_TYPES];
90    void *fs_texfetch_stencil[PIPE_MAX_TEXTURE_TYPES];
91 
92    /* FS which outputs one sample from a multisample texture. */
93    void *fs_texfetch_col_msaa[5][PIPE_MAX_TEXTURE_TYPES];
94    void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES];
95    void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES];
96    void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES];
97 
98    /* FS which outputs an average of all samples. */
99    void *fs_resolve[PIPE_MAX_TEXTURE_TYPES][NUM_RESOLVE_FRAG_SHADERS][2];
100 
101    /* Blend state. */
102    void *blend[PIPE_MASK_RGBA+1][2]; /**< blend state with writemask */
103    void *blend_clear[GET_CLEAR_BLEND_STATE_IDX(PIPE_CLEAR_COLOR)+1];
104 
105    /* Depth stencil alpha state. */
106    void *dsa_write_depth_stencil;
107    void *dsa_write_depth_keep_stencil;
108    void *dsa_keep_depth_stencil;
109    void *dsa_keep_depth_write_stencil;
110 
111    /* Vertex elements states. */
112    void *velem_state;
113    void *velem_state_readbuf[4]; /**< X, XY, XYZ, XYZW */
114 
115    /* Sampler state. */
116    void *sampler_state;
117    void *sampler_state_linear;
118    void *sampler_state_rect;
119    void *sampler_state_rect_linear;
120 
121    /* Rasterizer state. */
122    void *rs_state, *rs_state_scissor, *rs_discard_state;
123 
124    /* Viewport state. */
125    struct pipe_viewport_state viewport;
126 
127    /* Destination surface dimensions. */
128    unsigned dst_width;
129    unsigned dst_height;
130 
131    boolean has_geometry_shader;
132    boolean has_tessellation;
133    boolean has_layered;
134    boolean has_stream_out;
135    boolean has_stencil_export;
136    boolean has_texture_multisample;
137    boolean cached_all_shaders;
138 
139    /* The Draw module overrides these functions.
140     * Always create the blitter before Draw. */
141    void   (*bind_fs_state)(struct pipe_context *, void *);
142    void   (*delete_fs_state)(struct pipe_context *, void *);
143 };
144 
145 static struct pipe_surface *
146 util_blitter_get_next_surface_layer(struct pipe_context *pipe,
147                                     struct pipe_surface *surf);
148 
util_blitter_create(struct pipe_context * pipe)149 struct blitter_context *util_blitter_create(struct pipe_context *pipe)
150 {
151    struct blitter_context_priv *ctx;
152    struct pipe_blend_state blend;
153    struct pipe_depth_stencil_alpha_state dsa;
154    struct pipe_rasterizer_state rs_state;
155    struct pipe_sampler_state sampler_state;
156    struct pipe_vertex_element velem[2];
157    unsigned i, j;
158 
159    ctx = CALLOC_STRUCT(blitter_context_priv);
160    if (!ctx)
161       return NULL;
162 
163    ctx->base.pipe = pipe;
164    ctx->base.draw_rectangle = util_blitter_draw_rectangle;
165    ctx->base.get_next_surface_layer = util_blitter_get_next_surface_layer;
166 
167    ctx->bind_fs_state = pipe->bind_fs_state;
168    ctx->delete_fs_state = pipe->delete_fs_state;
169 
170    /* init state objects for them to be considered invalid */
171    ctx->base.saved_blend_state = INVALID_PTR;
172    ctx->base.saved_dsa_state = INVALID_PTR;
173    ctx->base.saved_rs_state = INVALID_PTR;
174    ctx->base.saved_fs = INVALID_PTR;
175    ctx->base.saved_vs = INVALID_PTR;
176    ctx->base.saved_gs = INVALID_PTR;
177    ctx->base.saved_velem_state = INVALID_PTR;
178    ctx->base.saved_fb_state.nr_cbufs = ~0;
179    ctx->base.saved_num_sampler_views = ~0;
180    ctx->base.saved_num_sampler_states = ~0;
181    ctx->base.saved_num_so_targets = ~0;
182 
183    ctx->has_geometry_shader =
184       pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY,
185                                      PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0;
186 
187    ctx->has_tessellation =
188       pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_TESS_CTRL,
189                                      PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0;
190 
191    ctx->has_stream_out =
192       pipe->screen->get_param(pipe->screen,
193                               PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0;
194 
195    ctx->has_stencil_export =
196          pipe->screen->get_param(pipe->screen,
197                                  PIPE_CAP_SHADER_STENCIL_EXPORT);
198 
199    ctx->has_texture_multisample =
200       pipe->screen->get_param(pipe->screen, PIPE_CAP_TEXTURE_MULTISAMPLE);
201 
202    /* blend state objects */
203    memset(&blend, 0, sizeof(blend));
204 
205    for (i = 0; i <= PIPE_MASK_RGBA; i++) {
206       for (j = 0; j < 2; j++) {
207          memset(&blend.rt[0], 0, sizeof(blend.rt[0]));
208          blend.rt[0].colormask = i;
209          if (j) {
210             blend.rt[0].blend_enable = 1;
211             blend.rt[0].rgb_func = PIPE_BLEND_ADD;
212             blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
213             blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
214             blend.rt[0].alpha_func = PIPE_BLEND_ADD;
215             blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
216             blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
217          }
218          ctx->blend[i][j] = pipe->create_blend_state(pipe, &blend);
219       }
220    }
221 
222    /* depth stencil alpha state objects */
223    memset(&dsa, 0, sizeof(dsa));
224    ctx->dsa_keep_depth_stencil =
225       pipe->create_depth_stencil_alpha_state(pipe, &dsa);
226 
227    dsa.depth.enabled = 1;
228    dsa.depth.writemask = 1;
229    dsa.depth.func = PIPE_FUNC_ALWAYS;
230    ctx->dsa_write_depth_keep_stencil =
231       pipe->create_depth_stencil_alpha_state(pipe, &dsa);
232 
233    dsa.stencil[0].enabled = 1;
234    dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
235    dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
236    dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
237    dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
238    dsa.stencil[0].valuemask = 0xff;
239    dsa.stencil[0].writemask = 0xff;
240    ctx->dsa_write_depth_stencil =
241       pipe->create_depth_stencil_alpha_state(pipe, &dsa);
242 
243    dsa.depth.enabled = 0;
244    dsa.depth.writemask = 0;
245    ctx->dsa_keep_depth_write_stencil =
246       pipe->create_depth_stencil_alpha_state(pipe, &dsa);
247 
248    /* sampler state */
249    memset(&sampler_state, 0, sizeof(sampler_state));
250    sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
251    sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
252    sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
253    sampler_state.normalized_coords = 1;
254    ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state);
255    sampler_state.normalized_coords = 0;
256    ctx->sampler_state_rect = pipe->create_sampler_state(pipe, &sampler_state);
257 
258    sampler_state.min_img_filter = PIPE_TEX_FILTER_LINEAR;
259    sampler_state.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
260    sampler_state.normalized_coords = 1;
261    ctx->sampler_state_linear = pipe->create_sampler_state(pipe, &sampler_state);
262    sampler_state.normalized_coords = 0;
263    ctx->sampler_state_rect_linear = pipe->create_sampler_state(pipe, &sampler_state);
264 
265    /* rasterizer state */
266    memset(&rs_state, 0, sizeof(rs_state));
267    rs_state.cull_face = PIPE_FACE_NONE;
268    rs_state.half_pixel_center = 1;
269    rs_state.bottom_edge_rule = 1;
270    rs_state.flatshade = 1;
271    rs_state.depth_clip = 1;
272    ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
273 
274    rs_state.scissor = 1;
275    ctx->rs_state_scissor = pipe->create_rasterizer_state(pipe, &rs_state);
276 
277    if (ctx->has_stream_out) {
278       rs_state.scissor = 0;
279       rs_state.rasterizer_discard = 1;
280       ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state);
281    }
282 
283    ctx->base.cb_slot = 0; /* 0 for now */
284    ctx->base.vb_slot = 0; /* 0 for now */
285 
286    /* vertex elements states */
287    memset(&velem[0], 0, sizeof(velem[0]) * 2);
288    for (i = 0; i < 2; i++) {
289       velem[i].src_offset = i * 4 * sizeof(float);
290       velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
291       velem[i].vertex_buffer_index = ctx->base.vb_slot;
292    }
293    ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
294 
295    if (ctx->has_stream_out) {
296       static enum pipe_format formats[4] = {
297          PIPE_FORMAT_R32_UINT,
298          PIPE_FORMAT_R32G32_UINT,
299          PIPE_FORMAT_R32G32B32_UINT,
300          PIPE_FORMAT_R32G32B32A32_UINT
301       };
302 
303       for (i = 0; i < 4; i++) {
304          velem[0].src_format = formats[i];
305          velem[0].vertex_buffer_index = ctx->base.vb_slot;
306          ctx->velem_state_readbuf[i] =
307                pipe->create_vertex_elements_state(pipe, 1, &velem[0]);
308       }
309    }
310 
311    ctx->has_layered =
312       pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) &&
313       pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT);
314 
315    /* set invariant vertex coordinates */
316    for (i = 0; i < 4; i++)
317       ctx->vertices[i][0][3] = 1; /*v.w*/
318 
319    ctx->upload = u_upload_create(pipe, 65536, PIPE_BIND_VERTEX_BUFFER,
320                                  PIPE_USAGE_STREAM);
321 
322    return &ctx->base;
323 }
324 
bind_vs_pos_only(struct blitter_context_priv * ctx,unsigned num_so_channels)325 static void bind_vs_pos_only(struct blitter_context_priv *ctx,
326                              unsigned num_so_channels)
327 {
328    struct pipe_context *pipe = ctx->base.pipe;
329    int index = num_so_channels ? num_so_channels - 1 : 0;
330 
331    if (!ctx->vs_pos_only[index]) {
332       struct pipe_stream_output_info so;
333       const uint semantic_names[] = { TGSI_SEMANTIC_POSITION };
334       const uint semantic_indices[] = { 0 };
335 
336       memset(&so, 0, sizeof(so));
337       so.num_outputs = 1;
338       so.output[0].num_components = num_so_channels;
339       so.stride[0] = num_so_channels;
340 
341       ctx->vs_pos_only[index] =
342          util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names,
343                                                      semantic_indices, FALSE,
344                                                      &so);
345    }
346 
347    pipe->bind_vs_state(pipe, ctx->vs_pos_only[index]);
348 }
349 
bind_vs_passthrough(struct blitter_context_priv * ctx)350 static void bind_vs_passthrough(struct blitter_context_priv *ctx)
351 {
352    struct pipe_context *pipe = ctx->base.pipe;
353 
354    if (!ctx->vs) {
355       const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
356                                       TGSI_SEMANTIC_GENERIC };
357       const uint semantic_indices[] = { 0, 0 };
358       ctx->vs =
359          util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
360                                              semantic_indices, FALSE);
361    }
362 
363    pipe->bind_vs_state(pipe, ctx->vs);
364 }
365 
bind_vs_layered(struct blitter_context_priv * ctx)366 static void bind_vs_layered(struct blitter_context_priv *ctx)
367 {
368    struct pipe_context *pipe = ctx->base.pipe;
369 
370    if (!ctx->vs_layered) {
371       ctx->vs_layered = util_make_layered_clear_vertex_shader(pipe);
372    }
373 
374    pipe->bind_vs_state(pipe, ctx->vs_layered);
375 }
376 
bind_fs_empty(struct blitter_context_priv * ctx)377 static void bind_fs_empty(struct blitter_context_priv *ctx)
378 {
379    struct pipe_context *pipe = ctx->base.pipe;
380 
381    if (!ctx->fs_empty) {
382       assert(!ctx->cached_all_shaders);
383       ctx->fs_empty = util_make_empty_fragment_shader(pipe);
384    }
385 
386    ctx->bind_fs_state(pipe, ctx->fs_empty);
387 }
388 
bind_fs_write_one_cbuf(struct blitter_context_priv * ctx)389 static void bind_fs_write_one_cbuf(struct blitter_context_priv *ctx)
390 {
391    struct pipe_context *pipe = ctx->base.pipe;
392 
393    if (!ctx->fs_write_one_cbuf) {
394       assert(!ctx->cached_all_shaders);
395       ctx->fs_write_one_cbuf =
396          util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
397                                                TGSI_INTERPOLATE_CONSTANT, FALSE);
398    }
399 
400    ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf);
401 }
402 
bind_fs_write_all_cbufs(struct blitter_context_priv * ctx)403 static void bind_fs_write_all_cbufs(struct blitter_context_priv *ctx)
404 {
405    struct pipe_context *pipe = ctx->base.pipe;
406 
407    if (!ctx->fs_write_all_cbufs) {
408       assert(!ctx->cached_all_shaders);
409       ctx->fs_write_all_cbufs =
410          util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
411                                                TGSI_INTERPOLATE_CONSTANT, TRUE);
412    }
413 
414    ctx->bind_fs_state(pipe, ctx->fs_write_all_cbufs);
415 }
416 
util_blitter_destroy(struct blitter_context * blitter)417 void util_blitter_destroy(struct blitter_context *blitter)
418 {
419    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
420    struct pipe_context *pipe = blitter->pipe;
421    unsigned i, j, f;
422 
423    for (i = 0; i <= PIPE_MASK_RGBA; i++)
424       for (j = 0; j < 2; j++)
425          pipe->delete_blend_state(pipe, ctx->blend[i][j]);
426 
427    for (i = 0; i < ARRAY_SIZE(ctx->blend_clear); i++) {
428       if (ctx->blend_clear[i])
429          pipe->delete_blend_state(pipe, ctx->blend_clear[i]);
430    }
431    pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
432    pipe->delete_depth_stencil_alpha_state(pipe,
433                                           ctx->dsa_write_depth_keep_stencil);
434    pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
435    pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
436 
437    pipe->delete_rasterizer_state(pipe, ctx->rs_state);
438    pipe->delete_rasterizer_state(pipe, ctx->rs_state_scissor);
439    if (ctx->rs_discard_state)
440       pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state);
441    if (ctx->vs)
442       pipe->delete_vs_state(pipe, ctx->vs);
443    for (i = 0; i < 4; i++)
444       if (ctx->vs_pos_only[i])
445          pipe->delete_vs_state(pipe, ctx->vs_pos_only[i]);
446    if (ctx->vs_layered)
447       pipe->delete_vs_state(pipe, ctx->vs_layered);
448    pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
449    for (i = 0; i < 4; i++) {
450       if (ctx->velem_state_readbuf[i]) {
451          pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf[i]);
452       }
453    }
454 
455    for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
456       for (unsigned type = 0; type < ARRAY_SIZE(ctx->fs_texfetch_col); ++type) {
457          if (ctx->fs_texfetch_col[type][i])
458             ctx->delete_fs_state(pipe, ctx->fs_texfetch_col[type][i]);
459          if (ctx->fs_texfetch_col_msaa[type][i])
460             ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa[type][i]);
461       }
462 
463       if (ctx->fs_texfetch_depth[i])
464          ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
465       if (ctx->fs_texfetch_depthstencil[i])
466          ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i]);
467       if (ctx->fs_texfetch_stencil[i])
468          ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i]);
469 
470       if (ctx->fs_texfetch_depth_msaa[i])
471          ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth_msaa[i]);
472       if (ctx->fs_texfetch_depthstencil_msaa[i])
473          ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil_msaa[i]);
474       if (ctx->fs_texfetch_stencil_msaa[i])
475          ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil_msaa[i]);
476 
477       for (j = 0; j< ARRAY_SIZE(ctx->fs_resolve[i]); j++)
478          for (f = 0; f < 2; f++)
479             if (ctx->fs_resolve[i][j][f])
480                ctx->delete_fs_state(pipe, ctx->fs_resolve[i][j][f]);
481    }
482 
483    if (ctx->fs_empty)
484       ctx->delete_fs_state(pipe, ctx->fs_empty);
485    if (ctx->fs_write_one_cbuf)
486       ctx->delete_fs_state(pipe, ctx->fs_write_one_cbuf);
487    if (ctx->fs_write_all_cbufs)
488       ctx->delete_fs_state(pipe, ctx->fs_write_all_cbufs);
489 
490    pipe->delete_sampler_state(pipe, ctx->sampler_state_rect_linear);
491    pipe->delete_sampler_state(pipe, ctx->sampler_state_rect);
492    pipe->delete_sampler_state(pipe, ctx->sampler_state_linear);
493    pipe->delete_sampler_state(pipe, ctx->sampler_state);
494    u_upload_destroy(ctx->upload);
495    FREE(ctx);
496 }
497 
util_blitter_set_texture_multisample(struct blitter_context * blitter,boolean supported)498 void util_blitter_set_texture_multisample(struct blitter_context *blitter,
499                                           boolean supported)
500 {
501    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
502 
503    ctx->has_texture_multisample = supported;
504 }
505 
util_blitter_set_running_flag(struct blitter_context * blitter)506 void util_blitter_set_running_flag(struct blitter_context *blitter)
507 {
508    if (blitter->running) {
509       _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
510                     __LINE__);
511    }
512    blitter->running = TRUE;
513 
514    blitter->pipe->set_active_query_state(blitter->pipe, false);
515 }
516 
util_blitter_unset_running_flag(struct blitter_context * blitter)517 void util_blitter_unset_running_flag(struct blitter_context *blitter)
518 {
519    if (!blitter->running) {
520       _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
521                     __LINE__);
522    }
523    blitter->running = FALSE;
524 
525    blitter->pipe->set_active_query_state(blitter->pipe, true);
526 }
527 
blitter_check_saved_vertex_states(struct blitter_context_priv * ctx)528 static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx)
529 {
530    assert(ctx->base.saved_velem_state != INVALID_PTR);
531    assert(ctx->base.saved_vs != INVALID_PTR);
532    assert(!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR);
533    assert(!ctx->has_tessellation || ctx->base.saved_tcs != INVALID_PTR);
534    assert(!ctx->has_tessellation || ctx->base.saved_tes != INVALID_PTR);
535    assert(!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0u);
536    assert(ctx->base.saved_rs_state != INVALID_PTR);
537 }
538 
util_blitter_restore_vertex_states(struct blitter_context * blitter)539 void util_blitter_restore_vertex_states(struct blitter_context *blitter)
540 {
541    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
542    struct pipe_context *pipe = ctx->base.pipe;
543    unsigned i;
544 
545    /* Vertex buffer. */
546    pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1,
547                             &ctx->base.saved_vertex_buffer);
548    pipe_resource_reference(&ctx->base.saved_vertex_buffer.buffer, NULL);
549 
550    /* Vertex elements. */
551    pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state);
552    ctx->base.saved_velem_state = INVALID_PTR;
553 
554    /* Vertex shader. */
555    pipe->bind_vs_state(pipe, ctx->base.saved_vs);
556    ctx->base.saved_vs = INVALID_PTR;
557 
558    /* Geometry shader. */
559    if (ctx->has_geometry_shader) {
560       pipe->bind_gs_state(pipe, ctx->base.saved_gs);
561       ctx->base.saved_gs = INVALID_PTR;
562    }
563 
564    if (ctx->has_tessellation) {
565       pipe->bind_tcs_state(pipe, ctx->base.saved_tcs);
566       pipe->bind_tes_state(pipe, ctx->base.saved_tes);
567       ctx->base.saved_tcs = INVALID_PTR;
568       ctx->base.saved_tes = INVALID_PTR;
569    }
570 
571    /* Stream outputs. */
572    if (ctx->has_stream_out) {
573       unsigned offsets[PIPE_MAX_SO_BUFFERS];
574       for (i = 0; i < ctx->base.saved_num_so_targets; i++)
575          offsets[i] = (unsigned)-1;
576       pipe->set_stream_output_targets(pipe,
577                                       ctx->base.saved_num_so_targets,
578                                       ctx->base.saved_so_targets, offsets);
579 
580       for (i = 0; i < ctx->base.saved_num_so_targets; i++)
581          pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL);
582 
583       ctx->base.saved_num_so_targets = ~0;
584    }
585 
586    /* Rasterizer. */
587    pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state);
588    ctx->base.saved_rs_state = INVALID_PTR;
589 }
590 
blitter_check_saved_fragment_states(struct blitter_context_priv * ctx)591 static void blitter_check_saved_fragment_states(struct blitter_context_priv *ctx)
592 {
593    assert(ctx->base.saved_fs != INVALID_PTR);
594    assert(ctx->base.saved_dsa_state != INVALID_PTR);
595    assert(ctx->base.saved_blend_state != INVALID_PTR);
596 }
597 
util_blitter_restore_fragment_states(struct blitter_context * blitter)598 void util_blitter_restore_fragment_states(struct blitter_context *blitter)
599 {
600    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
601    struct pipe_context *pipe = ctx->base.pipe;
602 
603    /* Fragment shader. */
604    ctx->bind_fs_state(pipe, ctx->base.saved_fs);
605    ctx->base.saved_fs = INVALID_PTR;
606 
607    /* Depth, stencil, alpha. */
608    pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state);
609    ctx->base.saved_dsa_state = INVALID_PTR;
610 
611    /* Blend state. */
612    pipe->bind_blend_state(pipe, ctx->base.saved_blend_state);
613    ctx->base.saved_blend_state = INVALID_PTR;
614 
615    /* Sample mask. */
616    if (ctx->base.is_sample_mask_saved) {
617       pipe->set_sample_mask(pipe, ctx->base.saved_sample_mask);
618       ctx->base.is_sample_mask_saved = FALSE;
619    }
620 
621    /* Miscellaneous states. */
622    /* XXX check whether these are saved and whether they need to be restored
623     * (depending on the operation) */
624    pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref);
625    pipe->set_viewport_states(pipe, 0, 1, &ctx->base.saved_viewport);
626 }
627 
blitter_check_saved_fb_state(struct blitter_context_priv * ctx)628 static void blitter_check_saved_fb_state(struct blitter_context_priv *ctx)
629 {
630    assert(ctx->base.saved_fb_state.nr_cbufs != ~0u);
631 }
632 
blitter_disable_render_cond(struct blitter_context_priv * ctx)633 static void blitter_disable_render_cond(struct blitter_context_priv *ctx)
634 {
635    struct pipe_context *pipe = ctx->base.pipe;
636 
637    if (ctx->base.saved_render_cond_query) {
638       pipe->render_condition(pipe, NULL, FALSE, 0);
639    }
640 }
641 
util_blitter_restore_render_cond(struct blitter_context * blitter)642 void util_blitter_restore_render_cond(struct blitter_context *blitter)
643 {
644    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
645    struct pipe_context *pipe = ctx->base.pipe;
646 
647    if (ctx->base.saved_render_cond_query) {
648       pipe->render_condition(pipe, ctx->base.saved_render_cond_query,
649                              ctx->base.saved_render_cond_cond,
650                              ctx->base.saved_render_cond_mode);
651       ctx->base.saved_render_cond_query = NULL;
652    }
653 }
654 
util_blitter_restore_fb_state(struct blitter_context * blitter)655 void util_blitter_restore_fb_state(struct blitter_context *blitter)
656 {
657    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
658    struct pipe_context *pipe = ctx->base.pipe;
659 
660    pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state);
661    util_unreference_framebuffer_state(&ctx->base.saved_fb_state);
662 }
663 
blitter_check_saved_textures(struct blitter_context_priv * ctx)664 static void blitter_check_saved_textures(struct blitter_context_priv *ctx)
665 {
666    assert(ctx->base.saved_num_sampler_states != ~0u);
667    assert(ctx->base.saved_num_sampler_views != ~0u);
668 }
669 
util_blitter_restore_textures(struct blitter_context * blitter)670 void util_blitter_restore_textures(struct blitter_context *blitter)
671 {
672    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
673    struct pipe_context *pipe = ctx->base.pipe;
674    unsigned i;
675 
676    /* Fragment sampler states. */
677    pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0,
678                              ctx->base.saved_num_sampler_states,
679                              ctx->base.saved_sampler_states);
680 
681    ctx->base.saved_num_sampler_states = ~0;
682 
683    /* Fragment sampler views. */
684    pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0,
685                            ctx->base.saved_num_sampler_views,
686                            ctx->base.saved_sampler_views);
687 
688    for (i = 0; i < ctx->base.saved_num_sampler_views; i++)
689       pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i], NULL);
690 
691    ctx->base.saved_num_sampler_views = ~0;
692 }
693 
util_blitter_restore_constant_buffer_state(struct blitter_context * blitter)694 void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter)
695 {
696    struct pipe_context *pipe = blitter->pipe;
697 
698    pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
699                             &blitter->saved_fs_constant_buffer);
700    pipe_resource_reference(&blitter->saved_fs_constant_buffer.buffer, NULL);
701 }
702 
blitter_set_rectangle(struct blitter_context_priv * ctx,int x1,int y1,int x2,int y2,float depth)703 static void blitter_set_rectangle(struct blitter_context_priv *ctx,
704                                   int x1, int y1, int x2, int y2,
705                                   float depth)
706 {
707    int i;
708 
709    /* set vertex positions */
710    ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/
711    ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/
712 
713    ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/
714    ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/
715 
716    ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/
717    ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/
718 
719    ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/
720    ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/
721 
722    for (i = 0; i < 4; i++)
723       ctx->vertices[i][0][2] = depth; /*z*/
724 
725    /* viewport */
726    ctx->viewport.scale[0] = 0.5f * ctx->dst_width;
727    ctx->viewport.scale[1] = 0.5f * ctx->dst_height;
728    ctx->viewport.scale[2] = 1.0f;
729    ctx->viewport.translate[0] = 0.5f * ctx->dst_width;
730    ctx->viewport.translate[1] = 0.5f * ctx->dst_height;
731    ctx->viewport.translate[2] = 0.0f;
732    ctx->base.pipe->set_viewport_states(ctx->base.pipe, 0, 1, &ctx->viewport);
733 }
734 
blitter_set_clear_color(struct blitter_context_priv * ctx,const union pipe_color_union * color)735 static void blitter_set_clear_color(struct blitter_context_priv *ctx,
736                                     const union pipe_color_union *color)
737 {
738    int i;
739 
740    if (color) {
741       for (i = 0; i < 4; i++) {
742          uint32_t *uiverts = (uint32_t *)ctx->vertices[i][1];
743          uiverts[0] = color->ui[0];
744          uiverts[1] = color->ui[1];
745          uiverts[2] = color->ui[2];
746          uiverts[3] = color->ui[3];
747       }
748    } else {
749       for (i = 0; i < 4; i++) {
750          ctx->vertices[i][1][0] = 0;
751          ctx->vertices[i][1][1] = 0;
752          ctx->vertices[i][1][2] = 0;
753          ctx->vertices[i][1][3] = 0;
754       }
755    }
756 }
757 
get_texcoords(struct pipe_sampler_view * src,unsigned src_width0,unsigned src_height0,int x1,int y1,int x2,int y2,float out[4])758 static void get_texcoords(struct pipe_sampler_view *src,
759                           unsigned src_width0, unsigned src_height0,
760                           int x1, int y1, int x2, int y2,
761                           float out[4])
762 {
763    struct pipe_resource *tex = src->texture;
764    unsigned level = src->u.tex.first_level;
765    boolean normalized = tex->target != PIPE_TEXTURE_RECT &&
766                         tex->nr_samples <= 1;
767 
768    if (normalized) {
769       out[0] = x1 / (float)u_minify(src_width0,  level);
770       out[1] = y1 / (float)u_minify(src_height0, level);
771       out[2] = x2 / (float)u_minify(src_width0,  level);
772       out[3] = y2 / (float)u_minify(src_height0, level);
773    } else {
774       out[0] = (float) x1;
775       out[1] = (float) y1;
776       out[2] = (float) x2;
777       out[3] = (float) y2;
778    }
779 }
780 
set_texcoords_in_vertices(const float coord[4],float * out,unsigned stride)781 static void set_texcoords_in_vertices(const float coord[4],
782                                       float *out, unsigned stride)
783 {
784    out[0] = coord[0]; /*t0.s*/
785    out[1] = coord[1]; /*t0.t*/
786    out += stride;
787    out[0] = coord[2]; /*t1.s*/
788    out[1] = coord[1]; /*t1.t*/
789    out += stride;
790    out[0] = coord[2]; /*t2.s*/
791    out[1] = coord[3]; /*t2.t*/
792    out += stride;
793    out[0] = coord[0]; /*t3.s*/
794    out[1] = coord[3]; /*t3.t*/
795 }
796 
blitter_set_texcoords(struct blitter_context_priv * ctx,struct pipe_sampler_view * src,unsigned src_width0,unsigned src_height0,float layer,unsigned sample,int x1,int y1,int x2,int y2)797 static void blitter_set_texcoords(struct blitter_context_priv *ctx,
798                                   struct pipe_sampler_view *src,
799                                   unsigned src_width0, unsigned src_height0,
800                                   float layer, unsigned sample,
801                                   int x1, int y1, int x2, int y2)
802 {
803    unsigned i;
804    float coord[4];
805    float face_coord[4][2];
806 
807    get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, coord);
808 
809    if (src->texture->target == PIPE_TEXTURE_CUBE ||
810        src->texture->target == PIPE_TEXTURE_CUBE_ARRAY) {
811       set_texcoords_in_vertices(coord, &face_coord[0][0], 2);
812       util_map_texcoords2d_onto_cubemap((unsigned)layer % 6,
813                                         /* pointer, stride in floats */
814                                         &face_coord[0][0], 2,
815                                         &ctx->vertices[0][1][0], 8,
816                                         FALSE);
817    } else {
818       set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
819    }
820 
821    /* Set the layer. */
822    switch (src->texture->target) {
823    case PIPE_TEXTURE_3D:
824       {
825          float r = layer / (float)u_minify(src->texture->depth0,
826                                            src->u.tex.first_level);
827          for (i = 0; i < 4; i++)
828             ctx->vertices[i][1][2] = r; /*r*/
829       }
830       break;
831 
832    case PIPE_TEXTURE_1D_ARRAY:
833       for (i = 0; i < 4; i++)
834          ctx->vertices[i][1][1] = (float) layer; /*t*/
835       break;
836 
837    case PIPE_TEXTURE_2D_ARRAY:
838       for (i = 0; i < 4; i++) {
839          ctx->vertices[i][1][2] = (float) layer;  /*r*/
840          ctx->vertices[i][1][3] = (float) sample; /*q*/
841       }
842       break;
843 
844    case PIPE_TEXTURE_CUBE_ARRAY:
845       for (i = 0; i < 4; i++)
846          ctx->vertices[i][1][3] = (float) ((unsigned)layer / 6); /*w*/
847       break;
848 
849    case PIPE_TEXTURE_2D:
850       for (i = 0; i < 4; i++) {
851          ctx->vertices[i][1][3] = (float) sample; /*r*/
852       }
853       break;
854 
855    default:;
856    }
857 }
858 
blitter_set_dst_dimensions(struct blitter_context_priv * ctx,unsigned width,unsigned height)859 static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
860                                        unsigned width, unsigned height)
861 {
862    ctx->dst_width = width;
863    ctx->dst_height = height;
864 }
865 
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)866 static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
867                                          enum pipe_format src_format,
868                                          enum pipe_format dst_format,
869                                          enum pipe_texture_target target,
870                                          unsigned src_nr_samples,
871                                          unsigned dst_nr_samples,
872                                          unsigned filter)
873 {
874    struct pipe_context *pipe = ctx->base.pipe;
875    unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, src_nr_samples);
876    enum tgsi_return_type stype;
877    enum tgsi_return_type dtype;
878    unsigned type;
879 
880    assert(target < PIPE_MAX_TEXTURE_TYPES);
881 
882    if (util_format_is_pure_uint(src_format)) {
883       stype = TGSI_RETURN_TYPE_UINT;
884       if (util_format_is_pure_uint(dst_format)) {
885          dtype = TGSI_RETURN_TYPE_UINT;
886          type = 0;
887       } else {
888          assert(util_format_is_pure_sint(dst_format));
889          dtype = TGSI_RETURN_TYPE_SINT;
890          type = 1;
891       }
892    } else if (util_format_is_pure_sint(src_format)) {
893       stype = TGSI_RETURN_TYPE_SINT;
894       if (util_format_is_pure_sint(dst_format)) {
895          dtype = TGSI_RETURN_TYPE_SINT;
896          type = 2;
897       } else {
898          assert(util_format_is_pure_uint(dst_format));
899          dtype = TGSI_RETURN_TYPE_UINT;
900          type = 3;
901       }
902    } else {
903       assert(!util_format_is_pure_uint(dst_format) &&
904              !util_format_is_pure_sint(dst_format));
905       dtype = stype = TGSI_RETURN_TYPE_FLOAT;
906       type = 4;
907    }
908 
909    if (src_nr_samples > 1) {
910       void **shader;
911 
912       /* OpenGL requires that integer textures just copy 1 sample instead
913        * of averaging.
914        */
915       if (dst_nr_samples <= 1 &&
916           stype != TGSI_RETURN_TYPE_UINT &&
917           stype != TGSI_RETURN_TYPE_SINT) {
918          /* The destination has one sample, so we'll do color resolve. */
919          unsigned index = GET_MSAA_RESOLVE_FS_IDX(src_nr_samples);
920 
921          assert(filter < 2);
922 
923          shader = &ctx->fs_resolve[target][index][filter];
924 
925          if (!*shader) {
926             assert(!ctx->cached_all_shaders);
927             if (filter == PIPE_TEX_FILTER_LINEAR) {
928                *shader = util_make_fs_msaa_resolve_bilinear(pipe, tgsi_tex,
929                                                    src_nr_samples,
930                                                    stype);
931             }
932             else {
933                *shader = util_make_fs_msaa_resolve(pipe, tgsi_tex,
934                                                    src_nr_samples,
935                                                    stype);
936             }
937          }
938       }
939       else {
940          /* The destination has multiple samples, we'll do
941           * an MSAA->MSAA copy.
942           */
943          shader = &ctx->fs_texfetch_col_msaa[type][target];
944 
945          /* Create the fragment shader on-demand. */
946          if (!*shader) {
947             assert(!ctx->cached_all_shaders);
948             *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex, stype, dtype);
949          }
950       }
951 
952       return *shader;
953    } else {
954       void **shader = &ctx->fs_texfetch_col[type][target];
955 
956       /* Create the fragment shader on-demand. */
957       if (!*shader) {
958          assert(!ctx->cached_all_shaders);
959          *shader = util_make_fragment_tex_shader(pipe, tgsi_tex,
960                                                  TGSI_INTERPOLATE_LINEAR,
961                                                  stype, dtype);
962       }
963 
964       return *shader;
965    }
966 }
967 
968 static inline
blitter_get_fs_texfetch_depth(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned nr_samples)969 void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
970                                     enum pipe_texture_target target,
971                                     unsigned nr_samples)
972 {
973    struct pipe_context *pipe = ctx->base.pipe;
974 
975    assert(target < PIPE_MAX_TEXTURE_TYPES);
976 
977    if (nr_samples > 1) {
978       void **shader = &ctx->fs_texfetch_depth_msaa[target];
979 
980       /* Create the fragment shader on-demand. */
981       if (!*shader) {
982          unsigned tgsi_tex;
983          assert(!ctx->cached_all_shaders);
984          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples);
985          *shader = util_make_fs_blit_msaa_depth(pipe, tgsi_tex);
986       }
987 
988       return *shader;
989    } else {
990       void **shader = &ctx->fs_texfetch_depth[target];
991 
992       /* Create the fragment shader on-demand. */
993       if (!*shader) {
994          unsigned tgsi_tex;
995          assert(!ctx->cached_all_shaders);
996          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
997          *shader =
998             util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex,
999                                                      TGSI_INTERPOLATE_LINEAR);
1000       }
1001 
1002       return *shader;
1003    }
1004 }
1005 
1006 static inline
blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned nr_samples)1007 void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
1008                                            enum pipe_texture_target target,
1009                                            unsigned nr_samples)
1010 {
1011    struct pipe_context *pipe = ctx->base.pipe;
1012 
1013    assert(target < PIPE_MAX_TEXTURE_TYPES);
1014 
1015    if (nr_samples > 1) {
1016       void **shader = &ctx->fs_texfetch_depthstencil_msaa[target];
1017 
1018       /* Create the fragment shader on-demand. */
1019       if (!*shader) {
1020          unsigned tgsi_tex;
1021          assert(!ctx->cached_all_shaders);
1022          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples);
1023          *shader = util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex);
1024       }
1025 
1026       return *shader;
1027    } else {
1028       void **shader = &ctx->fs_texfetch_depthstencil[target];
1029 
1030       /* Create the fragment shader on-demand. */
1031       if (!*shader) {
1032          unsigned tgsi_tex;
1033          assert(!ctx->cached_all_shaders);
1034          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1035          *shader =
1036             util_make_fragment_tex_shader_writedepthstencil(pipe, tgsi_tex,
1037                                                      TGSI_INTERPOLATE_LINEAR);
1038       }
1039 
1040       return *shader;
1041    }
1042 }
1043 
1044 static inline
blitter_get_fs_texfetch_stencil(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned nr_samples)1045 void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
1046                                       enum pipe_texture_target target,
1047                                       unsigned nr_samples)
1048 {
1049    struct pipe_context *pipe = ctx->base.pipe;
1050 
1051    assert(target < PIPE_MAX_TEXTURE_TYPES);
1052 
1053    if (nr_samples > 1) {
1054       void **shader = &ctx->fs_texfetch_stencil_msaa[target];
1055 
1056       /* Create the fragment shader on-demand. */
1057       if (!*shader) {
1058          unsigned tgsi_tex;
1059          assert(!ctx->cached_all_shaders);
1060          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples);
1061          *shader = util_make_fs_blit_msaa_stencil(pipe, tgsi_tex);
1062       }
1063 
1064       return *shader;
1065    } else {
1066       void **shader = &ctx->fs_texfetch_stencil[target];
1067 
1068       /* Create the fragment shader on-demand. */
1069       if (!*shader) {
1070          unsigned tgsi_tex;
1071          assert(!ctx->cached_all_shaders);
1072          tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1073          *shader =
1074             util_make_fragment_tex_shader_writestencil(pipe, tgsi_tex,
1075                                                        TGSI_INTERPOLATE_LINEAR);
1076       }
1077 
1078       return *shader;
1079    }
1080 }
1081 
1082 
1083 /**
1084  * Generate and save all fragment shaders that we will ever need for
1085  * blitting.  Drivers which use the 'draw' fallbacks will typically use
1086  * this to make sure we generate/use shaders that don't go through the
1087  * draw module's wrapper functions.
1088  */
util_blitter_cache_all_shaders(struct blitter_context * blitter)1089 void util_blitter_cache_all_shaders(struct blitter_context *blitter)
1090 {
1091    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1092    struct pipe_context *pipe = blitter->pipe;
1093    struct pipe_screen *screen = pipe->screen;
1094    unsigned samples, j, f, target, max_samples;
1095    boolean has_arraytex, has_cubearraytex;
1096 
1097    max_samples = ctx->has_texture_multisample ? 2 : 1;
1098    has_arraytex = screen->get_param(screen,
1099                                     PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) != 0;
1100    has_cubearraytex = screen->get_param(screen,
1101                                     PIPE_CAP_CUBE_MAP_ARRAY) != 0;
1102 
1103    /* It only matters if i <= 1 or > 1. */
1104    for (samples = 1; samples <= max_samples; samples++) {
1105       for (target = PIPE_TEXTURE_1D; target < PIPE_MAX_TEXTURE_TYPES; target++) {
1106          if (!has_arraytex &&
1107              (target == PIPE_TEXTURE_1D_ARRAY ||
1108               target == PIPE_TEXTURE_2D_ARRAY)) {
1109             continue;
1110          }
1111          if (!has_cubearraytex &&
1112              (target == PIPE_TEXTURE_CUBE_ARRAY))
1113             continue;
1114 
1115 	 if (samples > 1 &&
1116 	     (target != PIPE_TEXTURE_2D &&
1117 	      target != PIPE_TEXTURE_2D_ARRAY))
1118 	    continue;
1119 
1120          /* If samples == 1, the shaders read one texel. If samples >= 1,
1121           * they read one sample.
1122           */
1123          blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT,
1124                                      PIPE_FORMAT_R32_FLOAT, target,
1125                                      samples, samples, 0);
1126          blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1127                                      PIPE_FORMAT_R32_UINT, target,
1128                                      samples, samples, 0);
1129          blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1130                                      PIPE_FORMAT_R32_SINT, target,
1131                                      samples, samples, 0);
1132          blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1133                                      PIPE_FORMAT_R32_SINT, target,
1134                                      samples, samples, 0);
1135          blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1136                                      PIPE_FORMAT_R32_UINT, target,
1137                                      samples, samples, 0);
1138          blitter_get_fs_texfetch_depth(ctx, target, samples);
1139          if (ctx->has_stencil_export) {
1140             blitter_get_fs_texfetch_depthstencil(ctx, target, samples);
1141             blitter_get_fs_texfetch_stencil(ctx, target, samples);
1142          }
1143 
1144          if (samples == 1)
1145             continue;
1146 
1147          /* MSAA resolve shaders. */
1148          for (j = 2; j < 32; j++) {
1149             if (!screen->is_format_supported(screen, PIPE_FORMAT_R32_FLOAT,
1150                                              target, j,
1151                                              PIPE_BIND_SAMPLER_VIEW)) {
1152                continue;
1153             }
1154 
1155             for (f = 0; f < 2; f++) {
1156                blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT,
1157                                            PIPE_FORMAT_R32_FLOAT, target,
1158                                            j, 1, f);
1159                blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1160                                            PIPE_FORMAT_R32_UINT, target,
1161                                            j, 1, f);
1162                blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1163                                            PIPE_FORMAT_R32_SINT, target,
1164                                            j, 1, f);
1165             }
1166          }
1167       }
1168    }
1169 
1170    ctx->fs_empty = util_make_empty_fragment_shader(pipe);
1171 
1172    ctx->fs_write_one_cbuf =
1173       util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
1174                                             TGSI_INTERPOLATE_CONSTANT, FALSE);
1175 
1176    ctx->fs_write_all_cbufs =
1177       util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
1178                                             TGSI_INTERPOLATE_CONSTANT, TRUE);
1179 
1180    ctx->cached_all_shaders = TRUE;
1181 }
1182 
blitter_set_common_draw_rect_state(struct blitter_context_priv * ctx,boolean scissor,boolean vs_layered)1183 static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx,
1184                                                boolean scissor,
1185                                                boolean vs_layered)
1186 {
1187    struct pipe_context *pipe = ctx->base.pipe;
1188 
1189    pipe->bind_rasterizer_state(pipe, scissor ? ctx->rs_state_scissor
1190                                              : ctx->rs_state);
1191    if (vs_layered)
1192       bind_vs_layered(ctx);
1193    else
1194       bind_vs_passthrough(ctx);
1195 
1196    if (ctx->has_geometry_shader)
1197       pipe->bind_gs_state(pipe, NULL);
1198    if (ctx->has_tessellation) {
1199       pipe->bind_tcs_state(pipe, NULL);
1200       pipe->bind_tes_state(pipe, NULL);
1201    }
1202    if (ctx->has_stream_out)
1203       pipe->set_stream_output_targets(pipe, 0, NULL, NULL);
1204 }
1205 
blitter_draw(struct blitter_context_priv * ctx,int x1,int y1,int x2,int y2,float depth,unsigned num_instances)1206 static void blitter_draw(struct blitter_context_priv *ctx,
1207                          int x1, int y1, int x2, int y2, float depth,
1208                          unsigned num_instances)
1209 {
1210    struct pipe_context *pipe = ctx->base.pipe;
1211    struct pipe_vertex_buffer vb = {0};
1212 
1213    blitter_set_rectangle(ctx, x1, y1, x2, y2, depth);
1214 
1215    vb.stride = 8 * sizeof(float);
1216 
1217    u_upload_data(ctx->upload, 0, sizeof(ctx->vertices), 4, ctx->vertices,
1218                  &vb.buffer_offset, &vb.buffer);
1219    if (!vb.buffer)
1220       return;
1221    u_upload_unmap(ctx->upload);
1222 
1223    pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
1224    util_draw_arrays_instanced(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4,
1225                               0, num_instances);
1226    pipe_resource_reference(&vb.buffer, NULL);
1227 }
1228 
util_blitter_draw_rectangle(struct blitter_context * blitter,int x1,int y1,int x2,int y2,float depth,enum blitter_attrib_type type,const union pipe_color_union * attrib)1229 void util_blitter_draw_rectangle(struct blitter_context *blitter,
1230                                  int x1, int y1, int x2, int y2, float depth,
1231                                  enum blitter_attrib_type type,
1232                                  const union pipe_color_union *attrib)
1233 {
1234    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1235 
1236    switch (type) {
1237       case UTIL_BLITTER_ATTRIB_COLOR:
1238          blitter_set_clear_color(ctx, attrib);
1239          break;
1240 
1241       case UTIL_BLITTER_ATTRIB_TEXCOORD:
1242          set_texcoords_in_vertices(attrib->f, &ctx->vertices[0][1][0], 8);
1243          break;
1244 
1245       default:;
1246    }
1247 
1248    blitter_draw(ctx, x1, y1, x2, y2, depth, 1);
1249 }
1250 
get_clear_blend_state(struct blitter_context_priv * ctx,unsigned clear_buffers)1251 static void *get_clear_blend_state(struct blitter_context_priv *ctx,
1252                                    unsigned clear_buffers)
1253 {
1254    struct pipe_context *pipe = ctx->base.pipe;
1255    int index;
1256 
1257    clear_buffers &= PIPE_CLEAR_COLOR;
1258 
1259    /* Return an existing blend state. */
1260    if (!clear_buffers)
1261       return ctx->blend[0][0];
1262 
1263    index = GET_CLEAR_BLEND_STATE_IDX(clear_buffers);
1264 
1265    if (ctx->blend_clear[index])
1266       return ctx->blend_clear[index];
1267 
1268    /* Create a new one. */
1269    {
1270       struct pipe_blend_state blend = {0};
1271       unsigned i;
1272 
1273       blend.independent_blend_enable = 1;
1274 
1275       for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
1276          if (clear_buffers & (PIPE_CLEAR_COLOR0 << i)) {
1277             blend.rt[i].colormask = PIPE_MASK_RGBA;
1278          }
1279       }
1280 
1281       ctx->blend_clear[index] = pipe->create_blend_state(pipe, &blend);
1282    }
1283    return ctx->blend_clear[index];
1284 }
1285 
util_blitter_common_clear_setup(struct blitter_context * blitter,unsigned width,unsigned height,unsigned clear_buffers,void * custom_blend,void * custom_dsa)1286 void util_blitter_common_clear_setup(struct blitter_context *blitter,
1287                                      unsigned width, unsigned height,
1288                                      unsigned clear_buffers,
1289                                      void *custom_blend, void *custom_dsa)
1290 {
1291    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1292    struct pipe_context *pipe = ctx->base.pipe;
1293 
1294    util_blitter_set_running_flag(blitter);
1295    blitter_check_saved_vertex_states(ctx);
1296    blitter_check_saved_fragment_states(ctx);
1297    blitter_disable_render_cond(ctx);
1298 
1299    /* bind states */
1300    if (custom_blend) {
1301       pipe->bind_blend_state(pipe, custom_blend);
1302    } else {
1303       pipe->bind_blend_state(pipe, get_clear_blend_state(ctx, clear_buffers));
1304    }
1305 
1306    if (custom_dsa) {
1307       pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa);
1308    } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
1309       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
1310    } else if (clear_buffers & PIPE_CLEAR_DEPTH) {
1311       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
1312    } else if (clear_buffers & PIPE_CLEAR_STENCIL) {
1313       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
1314    } else {
1315       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1316    }
1317 
1318    pipe->set_sample_mask(pipe, ~0);
1319    blitter_set_dst_dimensions(ctx, width, height);
1320 }
1321 
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)1322 static void util_blitter_clear_custom(struct blitter_context *blitter,
1323                                       unsigned width, unsigned height,
1324                                       unsigned num_layers,
1325                                       unsigned clear_buffers,
1326                                       const union pipe_color_union *color,
1327                                       double depth, unsigned stencil,
1328                                       void *custom_blend, void *custom_dsa)
1329 {
1330    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1331    struct pipe_context *pipe = ctx->base.pipe;
1332    struct pipe_stencil_ref sr = { { 0 } };
1333 
1334    assert(ctx->has_layered || num_layers <= 1);
1335 
1336    util_blitter_common_clear_setup(blitter, width, height, clear_buffers,
1337                                    custom_blend, custom_dsa);
1338 
1339    sr.ref_value[0] = stencil & 0xff;
1340    pipe->set_stencil_ref(pipe, &sr);
1341 
1342    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1343    bind_fs_write_all_cbufs(ctx);
1344 
1345    if (num_layers > 1 && ctx->has_layered) {
1346       blitter_set_common_draw_rect_state(ctx, FALSE, TRUE);
1347       blitter_set_clear_color(ctx, color);
1348       blitter_draw(ctx, 0, 0, width, height, depth, num_layers);
1349    }
1350    else {
1351       blitter_set_common_draw_rect_state(ctx, FALSE, FALSE);
1352       blitter->draw_rectangle(blitter, 0, 0, width, height, (float) depth,
1353                               UTIL_BLITTER_ATTRIB_COLOR, color);
1354    }
1355 
1356    util_blitter_restore_vertex_states(blitter);
1357    util_blitter_restore_fragment_states(blitter);
1358    util_blitter_restore_render_cond(blitter);
1359    util_blitter_unset_running_flag(blitter);
1360 }
1361 
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)1362 void util_blitter_clear(struct blitter_context *blitter,
1363                         unsigned width, unsigned height, unsigned num_layers,
1364                         unsigned clear_buffers,
1365                         const union pipe_color_union *color,
1366                         double depth, unsigned stencil)
1367 {
1368    util_blitter_clear_custom(blitter, width, height, num_layers,
1369                              clear_buffers, color, depth, stencil,
1370                              NULL, NULL);
1371 }
1372 
util_blitter_custom_clear_depth(struct blitter_context * blitter,unsigned width,unsigned height,double depth,void * custom_dsa)1373 void util_blitter_custom_clear_depth(struct blitter_context *blitter,
1374                                      unsigned width, unsigned height,
1375                                      double depth, void *custom_dsa)
1376 {
1377    static const union pipe_color_union color;
1378    util_blitter_clear_custom(blitter, width, height, 0, 0, &color, depth, 0,
1379                              NULL, custom_dsa);
1380 }
1381 
util_blitter_default_dst_texture(struct pipe_surface * dst_templ,struct pipe_resource * dst,unsigned dstlevel,unsigned dstz)1382 void util_blitter_default_dst_texture(struct pipe_surface *dst_templ,
1383                                       struct pipe_resource *dst,
1384                                       unsigned dstlevel,
1385                                       unsigned dstz)
1386 {
1387    memset(dst_templ, 0, sizeof(*dst_templ));
1388    dst_templ->format = util_format_linear(dst->format);
1389    dst_templ->u.tex.level = dstlevel;
1390    dst_templ->u.tex.first_layer = dstz;
1391    dst_templ->u.tex.last_layer = dstz;
1392 }
1393 
1394 static struct pipe_surface *
util_blitter_get_next_surface_layer(struct pipe_context * pipe,struct pipe_surface * surf)1395 util_blitter_get_next_surface_layer(struct pipe_context *pipe,
1396                                     struct pipe_surface *surf)
1397 {
1398    struct pipe_surface dst_templ;
1399 
1400    memset(&dst_templ, 0, sizeof(dst_templ));
1401    dst_templ.format = surf->format;
1402    dst_templ.u.tex.level = surf->u.tex.level;
1403    dst_templ.u.tex.first_layer = surf->u.tex.first_layer + 1;
1404    dst_templ.u.tex.last_layer = surf->u.tex.last_layer + 1;
1405 
1406    return pipe->create_surface(pipe, surf->texture, &dst_templ);
1407 }
1408 
util_blitter_default_src_texture(struct pipe_sampler_view * src_templ,struct pipe_resource * src,unsigned srclevel)1409 void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ,
1410                                       struct pipe_resource *src,
1411                                       unsigned srclevel)
1412 {
1413    memset(src_templ, 0, sizeof(*src_templ));
1414    src_templ->target = src->target;
1415    src_templ->format = util_format_linear(src->format);
1416    src_templ->u.tex.first_level = srclevel;
1417    src_templ->u.tex.last_level = srclevel;
1418    src_templ->u.tex.first_layer = 0;
1419    src_templ->u.tex.last_layer =
1420       src->target == PIPE_TEXTURE_3D ? u_minify(src->depth0, srclevel) - 1
1421                                      : src->array_size - 1;
1422    src_templ->swizzle_r = PIPE_SWIZZLE_X;
1423    src_templ->swizzle_g = PIPE_SWIZZLE_Y;
1424    src_templ->swizzle_b = PIPE_SWIZZLE_Z;
1425    src_templ->swizzle_a = PIPE_SWIZZLE_W;
1426 }
1427 
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)1428 static boolean is_blit_generic_supported(struct blitter_context *blitter,
1429                                          const struct pipe_resource *dst,
1430                                          enum pipe_format dst_format,
1431                                          const struct pipe_resource *src,
1432                                          enum pipe_format src_format,
1433                                          unsigned mask)
1434 {
1435    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1436    struct pipe_screen *screen = ctx->base.pipe->screen;
1437 
1438    if (dst) {
1439       unsigned bind;
1440       const struct util_format_description *desc =
1441             util_format_description(dst_format);
1442       boolean dst_has_stencil = util_format_has_stencil(desc);
1443 
1444       /* Stencil export must be supported for stencil copy. */
1445       if ((mask & PIPE_MASK_S) && dst_has_stencil &&
1446           !ctx->has_stencil_export) {
1447          return FALSE;
1448       }
1449 
1450       if (dst_has_stencil || util_format_has_depth(desc))
1451          bind = PIPE_BIND_DEPTH_STENCIL;
1452       else
1453          bind = PIPE_BIND_RENDER_TARGET;
1454 
1455       if (!screen->is_format_supported(screen, dst_format, dst->target,
1456                                        dst->nr_samples, bind)) {
1457          return FALSE;
1458       }
1459    }
1460 
1461    if (src) {
1462       if (src->nr_samples > 1 && !ctx->has_texture_multisample) {
1463          return FALSE;
1464       }
1465 
1466       if (!screen->is_format_supported(screen, src_format, src->target,
1467                                  src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
1468          return FALSE;
1469       }
1470 
1471       /* Check stencil sampler support for stencil copy. */
1472       if (mask & PIPE_MASK_S) {
1473          if (util_format_has_stencil(util_format_description(src_format))) {
1474             enum pipe_format stencil_format =
1475                util_format_stencil_only(src_format);
1476             assert(stencil_format != PIPE_FORMAT_NONE);
1477 
1478             if (stencil_format != src_format &&
1479                 !screen->is_format_supported(screen, stencil_format,
1480                                              src->target, src->nr_samples,
1481                                              PIPE_BIND_SAMPLER_VIEW)) {
1482                return FALSE;
1483             }
1484          }
1485       }
1486    }
1487 
1488    return TRUE;
1489 }
1490 
util_blitter_is_copy_supported(struct blitter_context * blitter,const struct pipe_resource * dst,const struct pipe_resource * src)1491 boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
1492                                        const struct pipe_resource *dst,
1493                                        const struct pipe_resource *src)
1494 {
1495    return is_blit_generic_supported(blitter, dst, dst->format,
1496                                     src, src->format, PIPE_MASK_RGBAZS);
1497 }
1498 
util_blitter_is_blit_supported(struct blitter_context * blitter,const struct pipe_blit_info * info)1499 boolean util_blitter_is_blit_supported(struct blitter_context *blitter,
1500 				       const struct pipe_blit_info *info)
1501 {
1502    return is_blit_generic_supported(blitter,
1503                                     info->dst.resource, info->dst.format,
1504                                     info->src.resource, info->src.format,
1505                                     info->mask);
1506 }
1507 
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)1508 void util_blitter_copy_texture(struct blitter_context *blitter,
1509                                struct pipe_resource *dst,
1510                                unsigned dst_level,
1511                                unsigned dstx, unsigned dsty, unsigned dstz,
1512                                struct pipe_resource *src,
1513                                unsigned src_level,
1514                                const struct pipe_box *srcbox)
1515 {
1516    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1517    struct pipe_context *pipe = ctx->base.pipe;
1518    struct pipe_surface *dst_view, dst_templ;
1519    struct pipe_sampler_view src_templ, *src_view;
1520    struct pipe_box dstbox;
1521 
1522    assert(dst && src);
1523    assert(src->target < PIPE_MAX_TEXTURE_TYPES);
1524 
1525    u_box_3d(dstx, dsty, dstz, abs(srcbox->width), abs(srcbox->height),
1526             abs(srcbox->depth), &dstbox);
1527 
1528    /* Initialize the surface. */
1529    util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz);
1530    dst_view = pipe->create_surface(pipe, dst, &dst_templ);
1531 
1532    /* Initialize the sampler view. */
1533    util_blitter_default_src_texture(&src_templ, src, src_level);
1534    src_view = pipe->create_sampler_view(pipe, src, &src_templ);
1535 
1536    /* Copy. */
1537    util_blitter_blit_generic(blitter, dst_view, &dstbox,
1538                              src_view, srcbox, src->width0, src->height0,
1539                              PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
1540                              FALSE);
1541 
1542    pipe_surface_reference(&dst_view, NULL);
1543    pipe_sampler_view_reference(&src_view, NULL);
1544 }
1545 
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)1546 static void do_blits(struct blitter_context_priv *ctx,
1547                      struct pipe_surface *dst,
1548                      const struct pipe_box *dstbox,
1549                      struct pipe_sampler_view *src,
1550                      unsigned src_width0,
1551                      unsigned src_height0,
1552                      const struct pipe_box *srcbox,
1553                      bool is_zsbuf)
1554 {
1555    struct pipe_context *pipe = ctx->base.pipe;
1556    unsigned src_samples = src->texture->nr_samples;
1557    unsigned dst_samples = dst->texture->nr_samples;
1558    enum pipe_texture_target src_target = src->texture->target;
1559    struct pipe_framebuffer_state fb_state = {0};
1560 
1561    /* Initialize framebuffer state. */
1562    fb_state.width = dst->width;
1563    fb_state.height = dst->height;
1564    fb_state.nr_cbufs = is_zsbuf ? 0 : 1;
1565 
1566    blitter_set_dst_dimensions(ctx, fb_state.width, fb_state.height);
1567 
1568    if ((src_target == PIPE_TEXTURE_1D ||
1569         src_target == PIPE_TEXTURE_2D ||
1570         src_target == PIPE_TEXTURE_RECT) &&
1571        src_samples <= 1) {
1572       /* Draw the quad with the draw_rectangle callback. */
1573 
1574       /* Set texture coordinates. - use a pipe color union
1575        * for interface purposes.
1576        * XXX pipe_color_union is a wrong name since we use that to set
1577        * texture coordinates too.
1578        */
1579       union pipe_color_union coord;
1580       get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y,
1581                     srcbox->x+srcbox->width, srcbox->y+srcbox->height, coord.f);
1582 
1583       /* Set framebuffer state. */
1584       if (is_zsbuf) {
1585          fb_state.zsbuf = dst;
1586       } else {
1587          fb_state.cbufs[0] = dst;
1588       }
1589       pipe->set_framebuffer_state(pipe, &fb_state);
1590 
1591       /* Draw. */
1592       pipe->set_sample_mask(pipe, ~0);
1593       ctx->base.draw_rectangle(&ctx->base, dstbox->x, dstbox->y,
1594                                dstbox->x + dstbox->width,
1595                                dstbox->y + dstbox->height, 0,
1596                                UTIL_BLITTER_ATTRIB_TEXCOORD, &coord);
1597    } else {
1598       /* Draw the quad with the generic codepath. */
1599       int dst_z;
1600       for (dst_z = 0; dst_z < dstbox->depth; dst_z++) {
1601          struct pipe_surface *old;
1602          float dst2src_scale = srcbox->depth / (float)dstbox->depth;
1603 
1604          /* Scale Z properly if the blit is scaled.
1605           *
1606           * When downscaling, we want the coordinates centered, so that
1607           * mipmapping works for 3D textures. For example, when generating
1608           * a 4x4x4 level, this wouldn't average the pixels:
1609           *
1610           *   src Z:  0 1 2 3 4 5 6 7
1611           *   dst Z:  0   1   2   3
1612           *
1613           * Because the pixels are not centered below the pixels of the higher
1614           * level. Therefore, we want this:
1615           *   src Z:  0 1 2 3 4 5 6 7
1616           *   dst Z:   0   1   2   3
1617           *
1618           * dst_offset defines the offset needed for centering the pixels and
1619           * it works with any scaling (not just 2x).
1620           */
1621          float dst_offset = ((srcbox->depth - 1) -
1622                              (dstbox->depth - 1) * dst2src_scale) * 0.5;
1623          float src_z = (dst_z + dst_offset) * dst2src_scale;
1624 
1625          /* Set framebuffer state. */
1626          if (is_zsbuf) {
1627             fb_state.zsbuf = dst;
1628          } else {
1629             fb_state.cbufs[0] = dst;
1630          }
1631          pipe->set_framebuffer_state(pipe, &fb_state);
1632 
1633          /* See if we need to blit a multisample or singlesample buffer. */
1634          if (src_samples == dst_samples && dst_samples > 1) {
1635             /* MSAA copy. */
1636             unsigned i, max_sample = dst_samples - 1;
1637 
1638             for (i = 0; i <= max_sample; i++) {
1639                pipe->set_sample_mask(pipe, 1 << i);
1640                blitter_set_texcoords(ctx, src, src_width0, src_height0,
1641                                      srcbox->z + src_z,
1642                                      i, srcbox->x, srcbox->y,
1643                                      srcbox->x + srcbox->width,
1644                                      srcbox->y + srcbox->height);
1645                blitter_draw(ctx, dstbox->x, dstbox->y,
1646                             dstbox->x + dstbox->width,
1647                             dstbox->y + dstbox->height, 0, 1);
1648             }
1649          } else {
1650             /* Normal copy, MSAA upsampling, or MSAA resolve. */
1651             pipe->set_sample_mask(pipe, ~0);
1652             blitter_set_texcoords(ctx, src, src_width0, src_height0,
1653                                   srcbox->z + src_z, 0,
1654                                   srcbox->x, srcbox->y,
1655                                   srcbox->x + srcbox->width,
1656                                   srcbox->y + srcbox->height);
1657             blitter_draw(ctx, dstbox->x, dstbox->y,
1658                          dstbox->x + dstbox->width,
1659                          dstbox->y + dstbox->height, 0, 1);
1660          }
1661 
1662          /* Get the next surface or (if this is the last iteration)
1663           * just unreference the last one. */
1664          old = dst;
1665          if (dst_z < dstbox->depth-1) {
1666             dst = ctx->base.get_next_surface_layer(ctx->base.pipe, dst);
1667          }
1668          if (dst_z) {
1669             pipe_surface_reference(&old, NULL);
1670          }
1671       }
1672    }
1673 }
1674 
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,boolean alpha_blend)1675 void util_blitter_blit_generic(struct blitter_context *blitter,
1676                                struct pipe_surface *dst,
1677                                const struct pipe_box *dstbox,
1678                                struct pipe_sampler_view *src,
1679                                const struct pipe_box *srcbox,
1680                                unsigned src_width0, unsigned src_height0,
1681                                unsigned mask, unsigned filter,
1682                                const struct pipe_scissor_state *scissor,
1683                                boolean alpha_blend)
1684 {
1685    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1686    struct pipe_context *pipe = ctx->base.pipe;
1687    enum pipe_texture_target src_target = src->texture->target;
1688    unsigned src_samples = src->texture->nr_samples;
1689    unsigned dst_samples = dst->texture->nr_samples;
1690    boolean has_depth, has_stencil, has_color;
1691    boolean blit_stencil, blit_depth, blit_color;
1692    void *sampler_state;
1693    const struct util_format_description *src_desc =
1694          util_format_description(src->format);
1695    const struct util_format_description *dst_desc =
1696          util_format_description(dst->format);
1697 
1698    has_color = src_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
1699                dst_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
1700    has_depth = util_format_has_depth(src_desc) &&
1701                util_format_has_depth(dst_desc);
1702    has_stencil = util_format_has_stencil(src_desc) &&
1703                  util_format_has_stencil(dst_desc);
1704 
1705    blit_color = has_color && (mask & PIPE_MASK_RGBA);
1706    blit_depth = has_depth && (mask & PIPE_MASK_Z);
1707    blit_stencil = has_stencil && (mask & PIPE_MASK_S) &&
1708                   ctx->has_stencil_export;
1709 
1710    if (!blit_stencil && !blit_depth && !blit_color) {
1711       return;
1712    }
1713 
1714    if (blit_stencil ||
1715        (dstbox->width == abs(srcbox->width) &&
1716         dstbox->height == abs(srcbox->height))) {
1717       filter = PIPE_TEX_FILTER_NEAREST;
1718    }
1719 
1720    /* Check whether the states are properly saved. */
1721    util_blitter_set_running_flag(blitter);
1722    blitter_check_saved_vertex_states(ctx);
1723    blitter_check_saved_fragment_states(ctx);
1724    blitter_check_saved_textures(ctx);
1725    blitter_check_saved_fb_state(ctx);
1726    blitter_disable_render_cond(ctx);
1727 
1728    if (blit_depth || blit_stencil) {
1729       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
1730 
1731       if (blit_depth && blit_stencil) {
1732          pipe->bind_depth_stencil_alpha_state(pipe,
1733                                               ctx->dsa_write_depth_stencil);
1734          ctx->bind_fs_state(pipe,
1735                blitter_get_fs_texfetch_depthstencil(ctx, src_target,
1736                                                     src_samples));
1737       } else if (blit_depth) {
1738          pipe->bind_depth_stencil_alpha_state(pipe,
1739                                               ctx->dsa_write_depth_keep_stencil);
1740          ctx->bind_fs_state(pipe,
1741                blitter_get_fs_texfetch_depth(ctx, src_target,
1742                                              src_samples));
1743       } else { /* is_stencil */
1744          pipe->bind_depth_stencil_alpha_state(pipe,
1745                                               ctx->dsa_keep_depth_write_stencil);
1746          ctx->bind_fs_state(pipe,
1747                blitter_get_fs_texfetch_stencil(ctx, src_target,
1748                                                src_samples));
1749       }
1750 
1751    } else {
1752       unsigned colormask = mask & PIPE_MASK_RGBA;
1753 
1754       pipe->bind_blend_state(pipe, ctx->blend[colormask][alpha_blend]);
1755       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1756       ctx->bind_fs_state(pipe,
1757             blitter_get_fs_texfetch_col(ctx, src->format, dst->format, src_target,
1758                                         src_samples, dst_samples, filter));
1759    }
1760 
1761    /* Set the linear filter only for scaled color non-MSAA blits. */
1762    if (filter == PIPE_TEX_FILTER_LINEAR) {
1763       if (src_target == PIPE_TEXTURE_RECT) {
1764          sampler_state = ctx->sampler_state_rect_linear;
1765       } else {
1766          sampler_state = ctx->sampler_state_linear;
1767       }
1768    } else {
1769       if (src_target == PIPE_TEXTURE_RECT) {
1770          sampler_state = ctx->sampler_state_rect;
1771       } else {
1772          sampler_state = ctx->sampler_state;
1773       }
1774    }
1775 
1776    /* Set samplers. */
1777    if (blit_depth && blit_stencil) {
1778       /* Setup two samplers, one for depth and the other one for stencil. */
1779       struct pipe_sampler_view templ;
1780       struct pipe_sampler_view *views[2];
1781       void *samplers[2] = {sampler_state, sampler_state};
1782 
1783       templ = *src;
1784       templ.format = util_format_stencil_only(templ.format);
1785       assert(templ.format != PIPE_FORMAT_NONE);
1786 
1787       views[0] = src;
1788       views[1] = pipe->create_sampler_view(pipe, src->texture, &templ);
1789 
1790       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 2, views);
1791       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 2, samplers);
1792 
1793       pipe_sampler_view_reference(&views[1], NULL);
1794    } else if (blit_stencil) {
1795       /* Set a stencil-only sampler view for it not to sample depth instead. */
1796       struct pipe_sampler_view templ;
1797       struct pipe_sampler_view *view;
1798 
1799       templ = *src;
1800       templ.format = util_format_stencil_only(templ.format);
1801       assert(templ.format != PIPE_FORMAT_NONE);
1802 
1803       view = pipe->create_sampler_view(pipe, src->texture, &templ);
1804 
1805       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &view);
1806       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
1807                                 0, 1, &sampler_state);
1808 
1809       pipe_sampler_view_reference(&view, NULL);
1810    } else {
1811       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &src);
1812       pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
1813                                 0, 1, &sampler_state);
1814    }
1815 
1816    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1817    if (scissor) {
1818       pipe->set_scissor_states(pipe, 0, 1, scissor);
1819    }
1820 
1821    blitter_set_common_draw_rect_state(ctx, scissor != NULL, FALSE);
1822 
1823    do_blits(ctx, dst, dstbox, src, src_width0, src_height0,
1824             srcbox, blit_depth || blit_stencil);
1825 
1826    util_blitter_restore_vertex_states(blitter);
1827    util_blitter_restore_fragment_states(blitter);
1828    util_blitter_restore_textures(blitter);
1829    util_blitter_restore_fb_state(blitter);
1830    if (scissor) {
1831       pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor);
1832    }
1833    util_blitter_restore_render_cond(blitter);
1834    util_blitter_unset_running_flag(blitter);
1835 }
1836 
1837 void
util_blitter_blit(struct blitter_context * blitter,const struct pipe_blit_info * info)1838 util_blitter_blit(struct blitter_context *blitter,
1839 		  const struct pipe_blit_info *info)
1840 {
1841    struct pipe_resource *dst = info->dst.resource;
1842    struct pipe_resource *src = info->src.resource;
1843    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1844    struct pipe_context *pipe = ctx->base.pipe;
1845    struct pipe_surface *dst_view, dst_templ;
1846    struct pipe_sampler_view src_templ, *src_view;
1847 
1848    /* Initialize the surface. */
1849    util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level,
1850                                     info->dst.box.z);
1851    dst_templ.format = info->dst.format;
1852    dst_view = pipe->create_surface(pipe, dst, &dst_templ);
1853 
1854    /* Initialize the sampler view. */
1855    util_blitter_default_src_texture(&src_templ, src, info->src.level);
1856    src_templ.format = info->src.format;
1857    src_view = pipe->create_sampler_view(pipe, src, &src_templ);
1858 
1859    /* Copy. */
1860    util_blitter_blit_generic(blitter, dst_view, &info->dst.box,
1861                              src_view, &info->src.box, src->width0, src->height0,
1862                              info->mask, info->filter,
1863                              info->scissor_enable ? &info->scissor : NULL,
1864                              info->alpha_blend);
1865 
1866    pipe_surface_reference(&dst_view, NULL);
1867    pipe_sampler_view_reference(&src_view, NULL);
1868 }
1869 
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)1870 void util_blitter_generate_mipmap(struct blitter_context *blitter,
1871 				  struct pipe_resource *tex,
1872                                   enum pipe_format format,
1873                                   unsigned base_level, unsigned last_level,
1874                                   unsigned first_layer, unsigned last_layer)
1875 {
1876    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1877    struct pipe_context *pipe = ctx->base.pipe;
1878    struct pipe_surface dst_templ, *dst_view;
1879    struct pipe_sampler_view src_templ, *src_view;
1880    boolean is_depth;
1881    void *sampler_state;
1882    const struct util_format_description *desc =
1883          util_format_description(format);
1884    unsigned src_level;
1885 
1886    assert(tex->nr_samples <= 1);
1887    assert(!util_format_has_stencil(desc));
1888 
1889    is_depth = desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS;
1890 
1891    /* Check whether the states are properly saved. */
1892    util_blitter_set_running_flag(blitter);
1893    blitter_check_saved_vertex_states(ctx);
1894    blitter_check_saved_fragment_states(ctx);
1895    blitter_check_saved_textures(ctx);
1896    blitter_check_saved_fb_state(ctx);
1897    blitter_disable_render_cond(ctx);
1898 
1899    /* Set states. */
1900    if (is_depth) {
1901       pipe->bind_blend_state(pipe, ctx->blend[0][0]);
1902       pipe->bind_depth_stencil_alpha_state(pipe,
1903                                            ctx->dsa_write_depth_keep_stencil);
1904       ctx->bind_fs_state(pipe,
1905                          blitter_get_fs_texfetch_depth(ctx, tex->target, 1));
1906    } else {
1907       pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
1908       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1909       ctx->bind_fs_state(pipe,
1910             blitter_get_fs_texfetch_col(ctx, tex->format, tex->format, tex->target,
1911                                         1, 1, PIPE_TEX_FILTER_LINEAR));
1912    }
1913 
1914    if (tex->target == PIPE_TEXTURE_RECT) {
1915       sampler_state = ctx->sampler_state_rect_linear;
1916    } else {
1917       sampler_state = ctx->sampler_state_linear;
1918    }
1919    pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
1920                              0, 1, &sampler_state);
1921 
1922    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1923    blitter_set_common_draw_rect_state(ctx, FALSE, FALSE);
1924 
1925    for (src_level = base_level; src_level < last_level; src_level++) {
1926       struct pipe_box dstbox = {0}, srcbox = {0};
1927       unsigned dst_level = src_level + 1;
1928 
1929       dstbox.width = u_minify(tex->width0, dst_level);
1930       dstbox.height = u_minify(tex->height0, dst_level);
1931 
1932       srcbox.width = u_minify(tex->width0, src_level);
1933       srcbox.height = u_minify(tex->height0, src_level);
1934 
1935       if (tex->target == PIPE_TEXTURE_3D) {
1936          dstbox.depth = util_max_layer(tex, dst_level) + 1;
1937          srcbox.depth = util_max_layer(tex, src_level) + 1;
1938       } else {
1939          dstbox.z = srcbox.z = first_layer;
1940          dstbox.depth = srcbox.depth = last_layer - first_layer + 1;
1941       }
1942 
1943       /* Initialize the surface. */
1944       util_blitter_default_dst_texture(&dst_templ, tex, dst_level,
1945                                        first_layer);
1946       dst_templ.format = format;
1947       dst_view = pipe->create_surface(pipe, tex, &dst_templ);
1948 
1949       /* Initialize the sampler view. */
1950       util_blitter_default_src_texture(&src_templ, tex, src_level);
1951       src_templ.format = format;
1952       src_view = pipe->create_sampler_view(pipe, tex, &src_templ);
1953 
1954       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &src_view);
1955 
1956       do_blits(ctx, dst_view, &dstbox, src_view, tex->width0, tex->height0,
1957                &srcbox, is_depth);
1958 
1959       pipe_surface_reference(&dst_view, NULL);
1960       pipe_sampler_view_reference(&src_view, NULL);
1961    }
1962 
1963    util_blitter_restore_vertex_states(blitter);
1964    util_blitter_restore_fragment_states(blitter);
1965    util_blitter_restore_textures(blitter);
1966    util_blitter_restore_fb_state(blitter);
1967    util_blitter_restore_render_cond(blitter);
1968    util_blitter_unset_running_flag(blitter);
1969 }
1970 
1971 /* 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)1972 void util_blitter_clear_render_target(struct blitter_context *blitter,
1973                                       struct pipe_surface *dstsurf,
1974                                       const union pipe_color_union *color,
1975                                       unsigned dstx, unsigned dsty,
1976                                       unsigned width, unsigned height)
1977 {
1978    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1979    struct pipe_context *pipe = ctx->base.pipe;
1980    struct pipe_framebuffer_state fb_state;
1981    unsigned num_layers;
1982 
1983    assert(dstsurf->texture);
1984    if (!dstsurf->texture)
1985       return;
1986 
1987    /* check the saved state */
1988    util_blitter_set_running_flag(blitter);
1989    blitter_check_saved_vertex_states(ctx);
1990    blitter_check_saved_fragment_states(ctx);
1991    blitter_check_saved_fb_state(ctx);
1992    blitter_disable_render_cond(ctx);
1993 
1994    /* bind states */
1995    pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
1996    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1997    bind_fs_write_one_cbuf(ctx);
1998    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1999 
2000    /* set a framebuffer state */
2001    fb_state.width = dstsurf->width;
2002    fb_state.height = dstsurf->height;
2003    fb_state.nr_cbufs = 1;
2004    fb_state.cbufs[0] = dstsurf;
2005    fb_state.zsbuf = 0;
2006    pipe->set_framebuffer_state(pipe, &fb_state);
2007    pipe->set_sample_mask(pipe, ~0);
2008 
2009    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2010 
2011    num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
2012    if (num_layers > 1 && ctx->has_layered) {
2013       blitter_set_common_draw_rect_state(ctx, FALSE, TRUE);
2014       blitter_set_clear_color(ctx, color);
2015       blitter_draw(ctx, dstx, dsty, dstx+width, dsty+height, 0, num_layers);
2016    }
2017    else {
2018       blitter_set_common_draw_rect_state(ctx, FALSE, FALSE);
2019       blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
2020                               UTIL_BLITTER_ATTRIB_COLOR, color);
2021    }
2022 
2023    util_blitter_restore_vertex_states(blitter);
2024    util_blitter_restore_fragment_states(blitter);
2025    util_blitter_restore_fb_state(blitter);
2026    util_blitter_restore_render_cond(blitter);
2027    util_blitter_unset_running_flag(blitter);
2028 }
2029 
2030 /* 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)2031 void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
2032                                       struct pipe_surface *dstsurf,
2033                                       unsigned clear_flags,
2034                                       double depth,
2035                                       unsigned stencil,
2036                                       unsigned dstx, unsigned dsty,
2037                                       unsigned width, unsigned height)
2038 {
2039    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2040    struct pipe_context *pipe = ctx->base.pipe;
2041    struct pipe_framebuffer_state fb_state;
2042    struct pipe_stencil_ref sr = { { 0 } };
2043    unsigned num_layers;
2044 
2045    assert(dstsurf->texture);
2046    if (!dstsurf->texture)
2047       return;
2048 
2049    /* check the saved state */
2050    util_blitter_set_running_flag(blitter);
2051    blitter_check_saved_vertex_states(ctx);
2052    blitter_check_saved_fragment_states(ctx);
2053    blitter_check_saved_fb_state(ctx);
2054    blitter_disable_render_cond(ctx);
2055 
2056    /* bind states */
2057    pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2058    if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
2059       sr.ref_value[0] = stencil & 0xff;
2060       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
2061       pipe->set_stencil_ref(pipe, &sr);
2062    }
2063    else if (clear_flags & PIPE_CLEAR_DEPTH) {
2064       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
2065    }
2066    else if (clear_flags & PIPE_CLEAR_STENCIL) {
2067       sr.ref_value[0] = stencil & 0xff;
2068       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
2069       pipe->set_stencil_ref(pipe, &sr);
2070    }
2071    else
2072       /* hmm that should be illegal probably, or make it a no-op somewhere */
2073       pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2074 
2075    bind_fs_empty(ctx);
2076    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
2077 
2078    /* set a framebuffer state */
2079    fb_state.width = dstsurf->width;
2080    fb_state.height = dstsurf->height;
2081    fb_state.nr_cbufs = 0;
2082    fb_state.cbufs[0] = 0;
2083    fb_state.zsbuf = dstsurf;
2084    pipe->set_framebuffer_state(pipe, &fb_state);
2085    pipe->set_sample_mask(pipe, ~0);
2086 
2087    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2088 
2089    num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
2090    if (num_layers > 1 && ctx->has_layered) {
2091       blitter_set_common_draw_rect_state(ctx, FALSE, TRUE);
2092       blitter_draw(ctx, dstx, dsty, dstx+width, dsty+height, (float) depth, num_layers);
2093    }
2094    else {
2095       blitter_set_common_draw_rect_state(ctx, FALSE, FALSE);
2096       blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height,
2097                               (float) depth,
2098                               UTIL_BLITTER_ATTRIB_NONE, NULL);
2099    }
2100 
2101    util_blitter_restore_vertex_states(blitter);
2102    util_blitter_restore_fragment_states(blitter);
2103    util_blitter_restore_fb_state(blitter);
2104    util_blitter_restore_render_cond(blitter);
2105    util_blitter_unset_running_flag(blitter);
2106 }
2107 
2108 /* 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)2109 void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
2110 				       struct pipe_surface *zsurf,
2111 				       struct pipe_surface *cbsurf,
2112 				       unsigned sample_mask,
2113 				       void *dsa_stage, float depth)
2114 {
2115    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2116    struct pipe_context *pipe = ctx->base.pipe;
2117    struct pipe_framebuffer_state fb_state;
2118 
2119    assert(zsurf->texture);
2120    if (!zsurf->texture)
2121       return;
2122 
2123    /* check the saved state */
2124    util_blitter_set_running_flag(blitter);
2125    blitter_check_saved_vertex_states(ctx);
2126    blitter_check_saved_fragment_states(ctx);
2127    blitter_check_saved_fb_state(ctx);
2128    blitter_disable_render_cond(ctx);
2129 
2130    /* bind states */
2131    pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA][0] :
2132                                          ctx->blend[0][0]);
2133    pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
2134    if (cbsurf)
2135       bind_fs_write_one_cbuf(ctx);
2136    else
2137       bind_fs_empty(ctx);
2138    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
2139 
2140    /* set a framebuffer state */
2141    fb_state.width = zsurf->width;
2142    fb_state.height = zsurf->height;
2143    fb_state.nr_cbufs = 1;
2144    if (cbsurf) {
2145 	   fb_state.cbufs[0] = cbsurf;
2146 	   fb_state.nr_cbufs = 1;
2147    } else {
2148 	   fb_state.cbufs[0] = NULL;
2149 	   fb_state.nr_cbufs = 0;
2150    }
2151    fb_state.zsbuf = zsurf;
2152    pipe->set_framebuffer_state(pipe, &fb_state);
2153    pipe->set_sample_mask(pipe, sample_mask);
2154 
2155    blitter_set_common_draw_rect_state(ctx, FALSE, FALSE);
2156    blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height);
2157    blitter->draw_rectangle(blitter, 0, 0, zsurf->width, zsurf->height, depth,
2158                            UTIL_BLITTER_ATTRIB_NONE, NULL);
2159 
2160    util_blitter_restore_vertex_states(blitter);
2161    util_blitter_restore_fragment_states(blitter);
2162    util_blitter_restore_fb_state(blitter);
2163    util_blitter_restore_render_cond(blitter);
2164    util_blitter_unset_running_flag(blitter);
2165 }
2166 
util_blitter_copy_buffer(struct blitter_context * blitter,struct pipe_resource * dst,unsigned dstx,struct pipe_resource * src,unsigned srcx,unsigned size)2167 void util_blitter_copy_buffer(struct blitter_context *blitter,
2168                               struct pipe_resource *dst,
2169                               unsigned dstx,
2170                               struct pipe_resource *src,
2171                               unsigned srcx,
2172                               unsigned size)
2173 {
2174    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2175    struct pipe_context *pipe = ctx->base.pipe;
2176    struct pipe_vertex_buffer vb;
2177    struct pipe_stream_output_target *so_target;
2178    unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
2179 
2180    if (srcx >= src->width0 ||
2181        dstx >= dst->width0) {
2182       return;
2183    }
2184    if (srcx + size > src->width0) {
2185       size = src->width0 - srcx;
2186    }
2187    if (dstx + size > dst->width0) {
2188       size = dst->width0 - dstx;
2189    }
2190 
2191    /* Drivers not capable of Stream Out should not call this function
2192     * in the first place. */
2193    assert(ctx->has_stream_out);
2194 
2195    /* Some alignment is required. */
2196    if (srcx % 4 != 0 || dstx % 4 != 0 || size % 4 != 0 ||
2197        !ctx->has_stream_out) {
2198       struct pipe_box box;
2199       u_box_1d(srcx, size, &box);
2200       util_resource_copy_region(pipe, dst, 0, dstx, 0, 0, src, 0, &box);
2201       return;
2202    }
2203 
2204    util_blitter_set_running_flag(blitter);
2205    blitter_check_saved_vertex_states(ctx);
2206    blitter_disable_render_cond(ctx);
2207 
2208    vb.buffer = src;
2209    vb.buffer_offset = srcx;
2210    vb.stride = 4;
2211 
2212    pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
2213    pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf[0]);
2214    bind_vs_pos_only(ctx, 1);
2215    if (ctx->has_geometry_shader)
2216       pipe->bind_gs_state(pipe, NULL);
2217    if (ctx->has_tessellation) {
2218       pipe->bind_tcs_state(pipe, NULL);
2219       pipe->bind_tes_state(pipe, NULL);
2220    }
2221    pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
2222 
2223    so_target = pipe->create_stream_output_target(pipe, dst, dstx, size);
2224    pipe->set_stream_output_targets(pipe, 1, &so_target, offsets);
2225 
2226    util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
2227 
2228    util_blitter_restore_vertex_states(blitter);
2229    util_blitter_restore_render_cond(blitter);
2230    util_blitter_unset_running_flag(blitter);
2231    pipe_so_target_reference(&so_target, NULL);
2232 }
2233 
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)2234 void util_blitter_clear_buffer(struct blitter_context *blitter,
2235                                struct pipe_resource *dst,
2236                                unsigned offset, unsigned size,
2237                                unsigned num_channels,
2238                                const union pipe_color_union *clear_value)
2239 {
2240    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2241    struct pipe_context *pipe = ctx->base.pipe;
2242    struct pipe_vertex_buffer vb = {0};
2243    struct pipe_stream_output_target *so_target = NULL;
2244    unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
2245 
2246    assert(num_channels >= 1);
2247    assert(num_channels <= 4);
2248 
2249    /* IMPORTANT:  DON'T DO ANY BOUNDS CHECKING HERE!
2250     *
2251     * R600 uses this to initialize texture resources, so width0 might not be
2252     * what you think it is.
2253     */
2254 
2255    /* Streamout is required. */
2256    if (!ctx->has_stream_out) {
2257       assert(!"Streamout unsupported in util_blitter_clear_buffer()");
2258       return;
2259    }
2260 
2261    /* Some alignment is required. */
2262    if (offset % 4 != 0 || size % 4 != 0) {
2263       assert(!"Bad alignment in util_blitter_clear_buffer()");
2264       return;
2265    }
2266 
2267    u_upload_data(ctx->upload, 0, num_channels*4, 4, clear_value,
2268                  &vb.buffer_offset, &vb.buffer);
2269    if (!vb.buffer)
2270       goto out;
2271 
2272    vb.stride = 0;
2273 
2274    util_blitter_set_running_flag(blitter);
2275    blitter_check_saved_vertex_states(ctx);
2276    blitter_disable_render_cond(ctx);
2277 
2278    pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
2279    pipe->bind_vertex_elements_state(pipe,
2280                                     ctx->velem_state_readbuf[num_channels-1]);
2281    bind_vs_pos_only(ctx, num_channels);
2282    if (ctx->has_geometry_shader)
2283       pipe->bind_gs_state(pipe, NULL);
2284    if (ctx->has_tessellation) {
2285       pipe->bind_tcs_state(pipe, NULL);
2286       pipe->bind_tes_state(pipe, NULL);
2287    }
2288    pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
2289 
2290    so_target = pipe->create_stream_output_target(pipe, dst, offset, size);
2291    pipe->set_stream_output_targets(pipe, 1, &so_target, offsets);
2292 
2293    util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
2294 
2295 out:
2296    util_blitter_restore_vertex_states(blitter);
2297    util_blitter_restore_render_cond(blitter);
2298    util_blitter_unset_running_flag(blitter);
2299    pipe_so_target_reference(&so_target, NULL);
2300    pipe_resource_reference(&vb.buffer, NULL);
2301 }
2302 
2303 /* 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)2304 void util_blitter_custom_resolve_color(struct blitter_context *blitter,
2305 				       struct pipe_resource *dst,
2306 				       unsigned dst_level,
2307 				       unsigned dst_layer,
2308 				       struct pipe_resource *src,
2309 				       unsigned src_layer,
2310 				       unsigned sample_mask,
2311 				       void *custom_blend,
2312                                        enum pipe_format format)
2313 {
2314    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2315    struct pipe_context *pipe = ctx->base.pipe;
2316    struct pipe_framebuffer_state fb_state;
2317    struct pipe_surface *srcsurf, *dstsurf, surf_tmpl;
2318 
2319    util_blitter_set_running_flag(blitter);
2320    blitter_check_saved_vertex_states(ctx);
2321    blitter_check_saved_fragment_states(ctx);
2322    blitter_disable_render_cond(ctx);
2323 
2324    /* bind states */
2325    pipe->bind_blend_state(pipe, custom_blend);
2326    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2327    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
2328    bind_fs_write_one_cbuf(ctx);
2329    pipe->set_sample_mask(pipe, sample_mask);
2330 
2331    memset(&surf_tmpl, 0, sizeof(surf_tmpl));
2332    surf_tmpl.format = format;
2333    surf_tmpl.u.tex.level = dst_level;
2334    surf_tmpl.u.tex.first_layer = dst_layer;
2335    surf_tmpl.u.tex.last_layer = dst_layer;
2336 
2337    dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl);
2338 
2339    surf_tmpl.u.tex.level = 0;
2340    surf_tmpl.u.tex.first_layer = src_layer;
2341    surf_tmpl.u.tex.last_layer = src_layer;
2342 
2343    srcsurf = pipe->create_surface(pipe, src, &surf_tmpl);
2344 
2345    /* set a framebuffer state */
2346    fb_state.width = src->width0;
2347    fb_state.height = src->height0;
2348    fb_state.nr_cbufs = 2;
2349    fb_state.cbufs[0] = srcsurf;
2350    fb_state.cbufs[1] = dstsurf;
2351    fb_state.zsbuf = NULL;
2352    pipe->set_framebuffer_state(pipe, &fb_state);
2353 
2354    blitter_set_common_draw_rect_state(ctx, FALSE, FALSE);
2355    blitter_set_dst_dimensions(ctx, src->width0, src->height0);
2356    blitter->draw_rectangle(blitter, 0, 0, src->width0, src->height0,
2357                            0, 0, NULL);
2358    util_blitter_restore_fb_state(blitter);
2359    util_blitter_restore_vertex_states(blitter);
2360    util_blitter_restore_fragment_states(blitter);
2361    util_blitter_restore_render_cond(blitter);
2362    util_blitter_unset_running_flag(blitter);
2363 
2364    pipe_surface_reference(&srcsurf, NULL);
2365    pipe_surface_reference(&dstsurf, NULL);
2366 }
2367 
util_blitter_custom_color(struct blitter_context * blitter,struct pipe_surface * dstsurf,void * custom_blend)2368 void util_blitter_custom_color(struct blitter_context *blitter,
2369                                struct pipe_surface *dstsurf,
2370                                void *custom_blend)
2371 {
2372    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2373    struct pipe_context *pipe = ctx->base.pipe;
2374    struct pipe_framebuffer_state fb_state;
2375 
2376    assert(dstsurf->texture);
2377    if (!dstsurf->texture)
2378       return;
2379 
2380    /* check the saved state */
2381    util_blitter_set_running_flag(blitter);
2382    blitter_check_saved_vertex_states(ctx);
2383    blitter_check_saved_fragment_states(ctx);
2384    blitter_check_saved_fb_state(ctx);
2385    blitter_disable_render_cond(ctx);
2386 
2387    /* bind states */
2388    pipe->bind_blend_state(pipe, custom_blend ? custom_blend
2389                                              : ctx->blend[PIPE_MASK_RGBA][0]);
2390    pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2391    bind_fs_write_one_cbuf(ctx);
2392    pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
2393    pipe->set_sample_mask(pipe, (1ull << MAX2(1, dstsurf->texture->nr_samples)) - 1);
2394 
2395    /* set a framebuffer state */
2396    fb_state.width = dstsurf->width;
2397    fb_state.height = dstsurf->height;
2398    fb_state.nr_cbufs = 1;
2399    fb_state.cbufs[0] = dstsurf;
2400    fb_state.zsbuf = 0;
2401    pipe->set_framebuffer_state(pipe, &fb_state);
2402    pipe->set_sample_mask(pipe, ~0);
2403 
2404    blitter_set_common_draw_rect_state(ctx, FALSE, FALSE);
2405    blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2406    blitter->draw_rectangle(blitter, 0, 0, dstsurf->width, dstsurf->height,
2407                            0, 0, NULL);
2408 
2409    util_blitter_restore_vertex_states(blitter);
2410    util_blitter_restore_fragment_states(blitter);
2411    util_blitter_restore_fb_state(blitter);
2412    util_blitter_restore_render_cond(blitter);
2413    util_blitter_unset_running_flag(blitter);
2414 }
2415