Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5563 serge 1
/**************************************************************************
2
 *
3
 * Copyright 2009 Marek Olšák 
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 TUNGSTEN GRAPHICS 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
struct blitter_context_priv
55
{
56
   struct blitter_context base;
57
 
58
   struct u_upload_mgr *upload;
59
 
60
   float vertices[4][2][4];   /**< {pos, color} or {pos, texcoord} */
61
 
62
   /* Templates for various state objects. */
63
 
64
   /* Constant state objects. */
65
   /* Vertex shaders. */
66
   void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/
67
   void *vs_pos_only; /**< Vertex shader which passes pos to the output.*/
68
 
69
   /* Fragment shaders. */
70
   void *fs_empty;
71
   void *fs_write_one_cbuf;
72
   void *fs_write_all_cbufs;
73
 
74
   /* FS which outputs a color from a texture,
75
      where the index is PIPE_TEXTURE_* to be sampled. */
76
   void *fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES];
77
 
78
   /* FS which outputs a depth from a texture,
79
      where the index is PIPE_TEXTURE_* to be sampled. */
80
   void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES];
81
   void *fs_texfetch_depthstencil[PIPE_MAX_TEXTURE_TYPES];
82
   void *fs_texfetch_stencil[PIPE_MAX_TEXTURE_TYPES];
83
 
84
   /* FS which outputs one sample from a multisample texture. */
85
   void *fs_texfetch_col_msaa[PIPE_MAX_TEXTURE_TYPES];
86
   void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES];
87
   void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES];
88
   void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES];
89
 
90
   /* Blend state. */
91
   void *blend[PIPE_MASK_RGBA+1]; /**< blend state with writemask */
92
 
93
   /* Depth stencil alpha state. */
94
   void *dsa_write_depth_stencil;
95
   void *dsa_write_depth_keep_stencil;
96
   void *dsa_keep_depth_stencil;
97
   void *dsa_keep_depth_write_stencil;
98
 
99
   /* Vertex elements states. */
100
   void *velem_state;
101
   void *velem_state_readbuf[4]; /**< X, XY, XYZ, XYZW */
102
 
103
   /* Sampler state. */
104
   void *sampler_state;
105
   void *sampler_state_linear;
106
   void *sampler_state_rect;
107
   void *sampler_state_rect_linear;
108
 
109
   /* Rasterizer state. */
110
   void *rs_state, *rs_state_scissor, *rs_discard_state;
111
 
112
   /* Viewport state. */
113
   struct pipe_viewport_state viewport;
114
 
115
   /* Destination surface dimensions. */
116
   unsigned dst_width;
117
   unsigned dst_height;
118
 
119
   boolean has_geometry_shader;
120
   boolean has_stream_out;
121
   boolean has_stencil_export;
122
   boolean has_texture_multisample;
123
 
124
   /* The Draw module overrides these functions.
125
    * Always create the blitter before Draw. */
126
   void   (*bind_fs_state)(struct pipe_context *, void *);
127
   void   (*delete_fs_state)(struct pipe_context *, void *);
128
};
129
 
130
static struct pipe_surface *
131
util_blitter_get_next_surface_layer(struct pipe_context *pipe,
132
                                    struct pipe_surface *surf);
133
 
134
struct blitter_context *util_blitter_create(struct pipe_context *pipe)
135
{
136
   struct blitter_context_priv *ctx;
137
   struct pipe_blend_state blend;
138
   struct pipe_depth_stencil_alpha_state dsa;
139
   struct pipe_rasterizer_state rs_state;
140
   struct pipe_sampler_state sampler_state;
141
   struct pipe_vertex_element velem[2];
142
   unsigned i;
143
 
144
   ctx = CALLOC_STRUCT(blitter_context_priv);
145
   if (!ctx)
146
      return NULL;
147
 
148
   ctx->base.pipe = pipe;
149
   ctx->base.draw_rectangle = util_blitter_draw_rectangle;
150
   ctx->base.get_next_surface_layer = util_blitter_get_next_surface_layer;
151
 
152
   ctx->bind_fs_state = pipe->bind_fs_state;
153
   ctx->delete_fs_state = pipe->delete_fs_state;
154
 
155
   /* init state objects for them to be considered invalid */
156
   ctx->base.saved_blend_state = INVALID_PTR;
157
   ctx->base.saved_dsa_state = INVALID_PTR;
158
   ctx->base.saved_rs_state = INVALID_PTR;
159
   ctx->base.saved_fs = INVALID_PTR;
160
   ctx->base.saved_vs = INVALID_PTR;
161
   ctx->base.saved_gs = INVALID_PTR;
162
   ctx->base.saved_velem_state = INVALID_PTR;
163
   ctx->base.saved_fb_state.nr_cbufs = ~0;
164
   ctx->base.saved_num_sampler_views = ~0;
165
   ctx->base.saved_num_sampler_states = ~0;
166
   ctx->base.saved_num_so_targets = ~0;
167
 
168
   ctx->has_geometry_shader =
169
      pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY,
170
                                     PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0;
171
   ctx->has_stream_out =
172
      pipe->screen->get_param(pipe->screen,
173
                              PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0;
174
 
175
   ctx->has_stencil_export =
176
         pipe->screen->get_param(pipe->screen,
177
                                 PIPE_CAP_SHADER_STENCIL_EXPORT);
178
 
179
   ctx->has_texture_multisample =
180
      pipe->screen->get_param(pipe->screen, PIPE_CAP_TEXTURE_MULTISAMPLE);
181
 
182
   /* blend state objects */
183
   memset(&blend, 0, sizeof(blend));
184
 
185
   for (i = 0; i <= PIPE_MASK_RGBA; i++) {
186
      blend.rt[0].colormask = i;
187
      ctx->blend[i] = pipe->create_blend_state(pipe, &blend);
188
   }
189
 
190
   /* depth stencil alpha state objects */
191
   memset(&dsa, 0, sizeof(dsa));
192
   ctx->dsa_keep_depth_stencil =
193
      pipe->create_depth_stencil_alpha_state(pipe, &dsa);
194
 
195
   dsa.depth.enabled = 1;
196
   dsa.depth.writemask = 1;
197
   dsa.depth.func = PIPE_FUNC_ALWAYS;
198
   ctx->dsa_write_depth_keep_stencil =
199
      pipe->create_depth_stencil_alpha_state(pipe, &dsa);
200
 
201
   dsa.stencil[0].enabled = 1;
202
   dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
203
   dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
204
   dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
205
   dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
206
   dsa.stencil[0].valuemask = 0xff;
207
   dsa.stencil[0].writemask = 0xff;
208
   ctx->dsa_write_depth_stencil =
209
      pipe->create_depth_stencil_alpha_state(pipe, &dsa);
210
 
211
   dsa.depth.enabled = 0;
212
   dsa.depth.writemask = 0;
213
   ctx->dsa_keep_depth_write_stencil =
214
      pipe->create_depth_stencil_alpha_state(pipe, &dsa);
215
 
216
   /* sampler state */
217
   memset(&sampler_state, 0, sizeof(sampler_state));
218
   sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
219
   sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
220
   sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
221
   sampler_state.normalized_coords = 1;
222
   ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state);
223
   sampler_state.normalized_coords = 0;
224
   ctx->sampler_state_rect = pipe->create_sampler_state(pipe, &sampler_state);
225
 
226
   sampler_state.min_img_filter = PIPE_TEX_FILTER_LINEAR;
227
   sampler_state.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
228
   sampler_state.normalized_coords = 1;
229
   ctx->sampler_state_linear = pipe->create_sampler_state(pipe, &sampler_state);
230
   sampler_state.normalized_coords = 0;
231
   ctx->sampler_state_rect_linear = pipe->create_sampler_state(pipe, &sampler_state);
232
 
233
   /* rasterizer state */
234
   memset(&rs_state, 0, sizeof(rs_state));
235
   rs_state.cull_face = PIPE_FACE_NONE;
236
   rs_state.half_pixel_center = 1;
237
   rs_state.bottom_edge_rule = 1;
238
   rs_state.flatshade = 1;
239
   rs_state.depth_clip = 1;
240
   ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
241
 
242
   rs_state.scissor = 1;
243
   ctx->rs_state_scissor = pipe->create_rasterizer_state(pipe, &rs_state);
244
 
245
   if (ctx->has_stream_out) {
246
      rs_state.scissor = 0;
247
      rs_state.rasterizer_discard = 1;
248
      ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state);
249
   }
250
 
251
   ctx->base.vb_slot = 0; /* 0 for now */
252
 
253
   /* vertex elements states */
254
   memset(&velem[0], 0, sizeof(velem[0]) * 2);
255
   for (i = 0; i < 2; i++) {
256
      velem[i].src_offset = i * 4 * sizeof(float);
257
      velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
258
      velem[i].vertex_buffer_index = ctx->base.vb_slot;
259
   }
260
   ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
261
 
262
   if (ctx->has_stream_out) {
263
      static enum pipe_format formats[4] = {
264
         PIPE_FORMAT_R32_UINT,
265
         PIPE_FORMAT_R32G32_UINT,
266
         PIPE_FORMAT_R32G32B32_UINT,
267
         PIPE_FORMAT_R32G32B32A32_UINT
268
      };
269
 
270
      for (i = 0; i < 4; i++) {
271
         velem[0].src_format = formats[i];
272
         velem[0].vertex_buffer_index = ctx->base.vb_slot;
273
         ctx->velem_state_readbuf[i] =
274
               pipe->create_vertex_elements_state(pipe, 1, &velem[0]);
275
      }
276
   }
277
 
278
   /* Fragment shaders are created on-demand, except these.
279
    * The interpolation must be constant for integer texture clearing to work.
280
    */
281
   ctx->fs_empty = util_make_empty_fragment_shader(pipe);
282
   ctx->fs_write_one_cbuf =
283
      util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
284
                                            TGSI_INTERPOLATE_CONSTANT, FALSE);
285
   ctx->fs_write_all_cbufs =
286
      util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
287
                                            TGSI_INTERPOLATE_CONSTANT, TRUE);
288
 
289
   /* vertex shaders */
290
   {
291
      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
292
                                      TGSI_SEMANTIC_GENERIC };
293
      const uint semantic_indices[] = { 0, 0 };
294
      ctx->vs =
295
         util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
296
                                             semantic_indices);
297
   }
298
   if (ctx->has_stream_out) {
299
      struct pipe_stream_output_info so;
300
      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION };
301
      const uint semantic_indices[] = { 0 };
302
 
303
      memset(&so, 0, sizeof(so));
304
      so.num_outputs = 1;
305
      so.output[0].num_components = 1;
306
      so.stride[0] = 1;
307
 
308
      ctx->vs_pos_only =
309
         util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names,
310
                                                     semantic_indices, &so);
311
   }
312
 
313
   /* set invariant vertex coordinates */
314
   for (i = 0; i < 4; i++)
315
      ctx->vertices[i][0][3] = 1; /*v.w*/
316
 
317
   ctx->upload = u_upload_create(pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);
318
 
319
   return &ctx->base;
320
}
321
 
322
void util_blitter_destroy(struct blitter_context *blitter)
323
{
324
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
325
   struct pipe_context *pipe = blitter->pipe;
326
   int i;
327
 
328
   for (i = 0; i <= PIPE_MASK_RGBA; i++) {
329
      pipe->delete_blend_state(pipe, ctx->blend[i]);
330
   }
331
   pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
332
   pipe->delete_depth_stencil_alpha_state(pipe,
333
                                          ctx->dsa_write_depth_keep_stencil);
334
   pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
335
   pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
336
 
337
   pipe->delete_rasterizer_state(pipe, ctx->rs_state);
338
   pipe->delete_rasterizer_state(pipe, ctx->rs_state_scissor);
339
   if (ctx->rs_discard_state)
340
      pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state);
341
   pipe->delete_vs_state(pipe, ctx->vs);
342
   if (ctx->vs_pos_only)
343
      pipe->delete_vs_state(pipe, ctx->vs_pos_only);
344
   pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
345
   for (i = 0; i < 4; i++) {
346
      if (ctx->velem_state_readbuf[i]) {
347
         pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf[i]);
348
      }
349
   }
350
 
351
   for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
352
      if (ctx->fs_texfetch_col[i])
353
         ctx->delete_fs_state(pipe, ctx->fs_texfetch_col[i]);
354
      if (ctx->fs_texfetch_depth[i])
355
         ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
356
      if (ctx->fs_texfetch_depthstencil[i])
357
         ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i]);
358
      if (ctx->fs_texfetch_stencil[i])
359
         ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i]);
360
   }
361
   ctx->delete_fs_state(pipe, ctx->fs_empty);
362
   ctx->delete_fs_state(pipe, ctx->fs_write_one_cbuf);
363
   ctx->delete_fs_state(pipe, ctx->fs_write_all_cbufs);
364
 
365
   pipe->delete_sampler_state(pipe, ctx->sampler_state_rect_linear);
366
   pipe->delete_sampler_state(pipe, ctx->sampler_state_rect);
367
   pipe->delete_sampler_state(pipe, ctx->sampler_state_linear);
368
   pipe->delete_sampler_state(pipe, ctx->sampler_state);
369
   u_upload_destroy(ctx->upload);
370
   FREE(ctx);
371
}
372
 
373
void util_blitter_set_texture_multisample(struct blitter_context *blitter,
374
                                          boolean supported)
375
{
376
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
377
 
378
   ctx->has_texture_multisample = supported;
379
}
380
 
381
static void blitter_set_running_flag(struct blitter_context_priv *ctx)
382
{
383
   if (ctx->base.running) {
384
      _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
385
                    __LINE__);
386
   }
387
   ctx->base.running = TRUE;
388
}
389
 
390
static void blitter_unset_running_flag(struct blitter_context_priv *ctx)
391
{
392
   if (!ctx->base.running) {
393
      _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
394
                    __LINE__);
395
   }
396
   ctx->base.running = FALSE;
397
}
398
 
399
static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx)
400
{
401
   assert(ctx->base.saved_velem_state != INVALID_PTR);
402
   assert(ctx->base.saved_vs != INVALID_PTR);
403
   assert(!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR);
404
   assert(!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0);
405
   assert(ctx->base.saved_rs_state != INVALID_PTR);
406
}
407
 
408
static void blitter_restore_vertex_states(struct blitter_context_priv *ctx)
409
{
410
   struct pipe_context *pipe = ctx->base.pipe;
411
   unsigned i;
412
 
413
   /* Vertex buffer. */
414
   pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1,
415
                            &ctx->base.saved_vertex_buffer);
416
   pipe_resource_reference(&ctx->base.saved_vertex_buffer.buffer, NULL);
417
 
418
   /* Vertex elements. */
419
   pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state);
420
   ctx->base.saved_velem_state = INVALID_PTR;
421
 
422
   /* Vertex shader. */
423
   pipe->bind_vs_state(pipe, ctx->base.saved_vs);
424
   ctx->base.saved_vs = INVALID_PTR;
425
 
426
   /* Geometry shader. */
427
   if (ctx->has_geometry_shader) {
428
      pipe->bind_gs_state(pipe, ctx->base.saved_gs);
429
      ctx->base.saved_gs = INVALID_PTR;
430
   }
431
 
432
   /* Stream outputs. */
433
   if (ctx->has_stream_out) {
434
      pipe->set_stream_output_targets(pipe,
435
                                      ctx->base.saved_num_so_targets,
436
                                      ctx->base.saved_so_targets, ~0);
437
 
438
      for (i = 0; i < ctx->base.saved_num_so_targets; i++)
439
         pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL);
440
 
441
      ctx->base.saved_num_so_targets = ~0;
442
   }
443
 
444
   /* Rasterizer. */
445
   pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state);
446
   ctx->base.saved_rs_state = INVALID_PTR;
447
}
448
 
449
static void blitter_check_saved_fragment_states(struct blitter_context_priv *ctx)
450
{
451
   assert(ctx->base.saved_fs != INVALID_PTR);
452
   assert(ctx->base.saved_dsa_state != INVALID_PTR);
453
   assert(ctx->base.saved_blend_state != INVALID_PTR);
454
}
455
 
456
static void blitter_restore_fragment_states(struct blitter_context_priv *ctx)
457
{
458
   struct pipe_context *pipe = ctx->base.pipe;
459
 
460
   /* Fragment shader. */
461
   ctx->bind_fs_state(pipe, ctx->base.saved_fs);
462
   ctx->base.saved_fs = INVALID_PTR;
463
 
464
   /* Depth, stencil, alpha. */
465
   pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state);
466
   ctx->base.saved_dsa_state = INVALID_PTR;
467
 
468
   /* Blend state. */
469
   pipe->bind_blend_state(pipe, ctx->base.saved_blend_state);
470
   ctx->base.saved_blend_state = INVALID_PTR;
471
 
472
   /* Sample mask. */
473
   if (ctx->base.is_sample_mask_saved) {
474
      pipe->set_sample_mask(pipe, ctx->base.saved_sample_mask);
475
      ctx->base.is_sample_mask_saved = FALSE;
476
   }
477
 
478
   /* Miscellaneous states. */
479
   /* XXX check whether these are saved and whether they need to be restored
480
    * (depending on the operation) */
481
   pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref);
482
   pipe->set_viewport_states(pipe, 0, 1, &ctx->base.saved_viewport);
483
}
484
 
485
static void blitter_check_saved_fb_state(struct blitter_context_priv *ctx)
486
{
487
   assert(ctx->base.saved_fb_state.nr_cbufs != ~0);
488
}
489
 
490
static void blitter_disable_render_cond(struct blitter_context_priv *ctx)
491
{
492
   struct pipe_context *pipe = ctx->base.pipe;
493
 
494
   if (ctx->base.saved_render_cond_query) {
495
      pipe->render_condition(pipe, NULL, FALSE, 0);
496
   }
497
}
498
 
499
static void blitter_restore_render_cond(struct blitter_context_priv *ctx)
500
{
501
   struct pipe_context *pipe = ctx->base.pipe;
502
 
503
   if (ctx->base.saved_render_cond_query) {
504
      pipe->render_condition(pipe, ctx->base.saved_render_cond_query,
505
                             ctx->base.saved_render_cond_cond,
506
                             ctx->base.saved_render_cond_mode);
507
      ctx->base.saved_render_cond_query = NULL;
508
   }
509
}
510
 
511
static void blitter_restore_fb_state(struct blitter_context_priv *ctx)
512
{
513
   struct pipe_context *pipe = ctx->base.pipe;
514
 
515
   pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state);
516
   util_unreference_framebuffer_state(&ctx->base.saved_fb_state);
517
}
518
 
519
static void blitter_check_saved_textures(struct blitter_context_priv *ctx)
520
{
521
   assert(ctx->base.saved_num_sampler_states != ~0);
522
   assert(ctx->base.saved_num_sampler_views != ~0);
523
}
524
 
525
static void blitter_restore_textures(struct blitter_context_priv *ctx)
526
{
527
   struct pipe_context *pipe = ctx->base.pipe;
528
   unsigned i;
529
 
530
   /* Fragment sampler states. */
531
   pipe->bind_fragment_sampler_states(pipe,
532
                                      ctx->base.saved_num_sampler_states,
533
                                      ctx->base.saved_sampler_states);
534
   ctx->base.saved_num_sampler_states = ~0;
535
 
536
   /* Fragment sampler views. */
537
   pipe->set_fragment_sampler_views(pipe,
538
                                    ctx->base.saved_num_sampler_views,
539
                                    ctx->base.saved_sampler_views);
540
 
541
   for (i = 0; i < ctx->base.saved_num_sampler_views; i++)
542
      pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i], NULL);
543
 
544
   ctx->base.saved_num_sampler_views = ~0;
545
}
546
 
547
static void blitter_set_rectangle(struct blitter_context_priv *ctx,
548
                                  int x1, int y1, int x2, int y2,
549
                                  float depth)
550
{
551
   int i;
552
 
553
   /* set vertex positions */
554
   ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/
555
   ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/
556
 
557
   ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/
558
   ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/
559
 
560
   ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/
561
   ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/
562
 
563
   ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/
564
   ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/
565
 
566
   for (i = 0; i < 4; i++)
567
      ctx->vertices[i][0][2] = depth; /*z*/
568
 
569
   /* viewport */
570
   ctx->viewport.scale[0] = 0.5f * ctx->dst_width;
571
   ctx->viewport.scale[1] = 0.5f * ctx->dst_height;
572
   ctx->viewport.scale[2] = 1.0f;
573
   ctx->viewport.scale[3] = 1.0f;
574
   ctx->viewport.translate[0] = 0.5f * ctx->dst_width;
575
   ctx->viewport.translate[1] = 0.5f * ctx->dst_height;
576
   ctx->viewport.translate[2] = 0.0f;
577
   ctx->viewport.translate[3] = 0.0f;
578
   ctx->base.pipe->set_viewport_states(ctx->base.pipe, 0, 1, &ctx->viewport);
579
}
580
 
581
static void blitter_set_clear_color(struct blitter_context_priv *ctx,
582
                                    const union pipe_color_union *color)
583
{
584
   int i;
585
 
586
   if (color) {
587
      for (i = 0; i < 4; i++) {
588
         uint32_t *uiverts = (uint32_t *)ctx->vertices[i][1];
589
         uiverts[0] = color->ui[0];
590
         uiverts[1] = color->ui[1];
591
         uiverts[2] = color->ui[2];
592
         uiverts[3] = color->ui[3];
593
      }
594
   } else {
595
      for (i = 0; i < 4; i++) {
596
         ctx->vertices[i][1][0] = 0;
597
         ctx->vertices[i][1][1] = 0;
598
         ctx->vertices[i][1][2] = 0;
599
         ctx->vertices[i][1][3] = 0;
600
      }
601
   }
602
}
603
 
604
static void get_texcoords(struct pipe_sampler_view *src,
605
                          unsigned src_width0, unsigned src_height0,
606
                          int x1, int y1, int x2, int y2,
607
                          float out[4])
608
{
609
   struct pipe_resource *tex = src->texture;
610
   unsigned level = src->u.tex.first_level;
611
   boolean normalized = tex->target != PIPE_TEXTURE_RECT &&
612
                        tex->nr_samples <= 1;
613
 
614
   if (normalized) {
615
      out[0] = x1 / (float)u_minify(src_width0,  level);
616
      out[1] = y1 / (float)u_minify(src_height0, level);
617
      out[2] = x2 / (float)u_minify(src_width0,  level);
618
      out[3] = y2 / (float)u_minify(src_height0, level);
619
   } else {
620
      out[0] = (float) x1;
621
      out[1] = (float) y1;
622
      out[2] = (float) x2;
623
      out[3] = (float) y2;
624
   }
625
}
626
 
627
static void set_texcoords_in_vertices(const float coord[4],
628
                                      float *out, unsigned stride)
629
{
630
   out[0] = coord[0]; /*t0.s*/
631
   out[1] = coord[1]; /*t0.t*/
632
   out += stride;
633
   out[0] = coord[2]; /*t1.s*/
634
   out[1] = coord[1]; /*t1.t*/
635
   out += stride;
636
   out[0] = coord[2]; /*t2.s*/
637
   out[1] = coord[3]; /*t2.t*/
638
   out += stride;
639
   out[0] = coord[0]; /*t3.s*/
640
   out[1] = coord[3]; /*t3.t*/
641
}
642
 
643
static void blitter_set_texcoords(struct blitter_context_priv *ctx,
644
                                  struct pipe_sampler_view *src,
645
                                  unsigned src_width0, unsigned src_height0,
646
                                  unsigned layer, unsigned sample,
647
                                  int x1, int y1, int x2, int y2)
648
{
649
   unsigned i;
650
   float coord[4];
651
   float face_coord[4][2];
652
 
653
   get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, coord);
654
 
655
   if (src->texture->target == PIPE_TEXTURE_CUBE ||
656
       src->texture->target == PIPE_TEXTURE_CUBE_ARRAY) {
657
      set_texcoords_in_vertices(coord, &face_coord[0][0], 2);
658
      util_map_texcoords2d_onto_cubemap(layer % 6,
659
                                        /* pointer, stride in floats */
660
                                        &face_coord[0][0], 2,
661
                                        &ctx->vertices[0][1][0], 8);
662
   } else {
663
      set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
664
   }
665
 
666
   /* Set the layer. */
667
   switch (src->texture->target) {
668
   case PIPE_TEXTURE_3D:
669
      {
670
         float r = layer / (float)u_minify(src->texture->depth0,
671
                                           src->u.tex.first_level);
672
         for (i = 0; i < 4; i++)
673
            ctx->vertices[i][1][2] = r; /*r*/
674
      }
675
      break;
676
 
677
   case PIPE_TEXTURE_1D_ARRAY:
678
      for (i = 0; i < 4; i++)
679
         ctx->vertices[i][1][1] = (float) layer; /*t*/
680
      break;
681
 
682
   case PIPE_TEXTURE_2D_ARRAY:
683
      for (i = 0; i < 4; i++) {
684
         ctx->vertices[i][1][2] = (float) layer;  /*r*/
685
         ctx->vertices[i][1][3] = (float) sample; /*q*/
686
      }
687
      break;
688
 
689
   case PIPE_TEXTURE_CUBE_ARRAY:
690
      for (i = 0; i < 4; i++)
691
         ctx->vertices[i][1][3] = (float) (layer / 6); /*w*/
692
      break;
693
 
694
   case PIPE_TEXTURE_2D:
695
      for (i = 0; i < 4; i++) {
696
         ctx->vertices[i][1][3] = (float) sample; /*r*/
697
      }
698
      break;
699
 
700
   default:;
701
   }
702
}
703
 
704
static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
705
                                       unsigned width, unsigned height)
706
{
707
   ctx->dst_width = width;
708
   ctx->dst_height = height;
709
}
710
 
711
static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
712
                                         enum pipe_texture_target target,
713
                                         unsigned nr_samples)
714
{
715
   struct pipe_context *pipe = ctx->base.pipe;
716
 
717
   assert(target < PIPE_MAX_TEXTURE_TYPES);
718
 
719
   if (nr_samples > 1) {
720
      void **shader = &ctx->fs_texfetch_col_msaa[target];
721
 
722
      /* Create the fragment shader on-demand. */
723
      if (!*shader) {
724
         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target,
725
                                                       nr_samples);
726
 
727
         *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex);
728
      }
729
 
730
      return *shader;
731
   } else {
732
      void **shader = &ctx->fs_texfetch_col[target];
733
 
734
      /* Create the fragment shader on-demand. */
735
      if (!*shader) {
736
         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
737
 
738
         *shader =
739
            util_make_fragment_tex_shader(pipe, tgsi_tex,
740
                                          TGSI_INTERPOLATE_LINEAR);
741
      }
742
 
743
      return *shader;
744
   }
745
}
746
 
747
static INLINE
748
void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
749
                                    enum pipe_texture_target target,
750
                                    unsigned nr_samples)
751
{
752
   struct pipe_context *pipe = ctx->base.pipe;
753
 
754
   assert(target < PIPE_MAX_TEXTURE_TYPES);
755
 
756
   if (nr_samples > 1) {
757
      void **shader = &ctx->fs_texfetch_depth_msaa[target];
758
 
759
      /* Create the fragment shader on-demand. */
760
      if (!*shader) {
761
         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target,
762
                                                       nr_samples);
763
 
764
         *shader =
765
            util_make_fs_blit_msaa_depth(pipe, tgsi_tex);
766
      }
767
 
768
      return *shader;
769
   } else {
770
      void **shader = &ctx->fs_texfetch_depth[target];
771
 
772
      /* Create the fragment shader on-demand. */
773
      if (!*shader) {
774
         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
775
 
776
         *shader =
777
            util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex,
778
                                                     TGSI_INTERPOLATE_LINEAR);
779
      }
780
 
781
      return *shader;
782
   }
783
}
784
 
785
static INLINE
786
void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
787
                                           enum pipe_texture_target target,
788
                                           unsigned nr_samples)
789
{
790
   struct pipe_context *pipe = ctx->base.pipe;
791
 
792
   assert(target < PIPE_MAX_TEXTURE_TYPES);
793
 
794
   if (nr_samples > 1) {
795
      void **shader = &ctx->fs_texfetch_depthstencil_msaa[target];
796
 
797
      /* Create the fragment shader on-demand. */
798
      if (!*shader) {
799
         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target,
800
                                                       nr_samples);
801
 
802
         *shader =
803
            util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex);
804
      }
805
 
806
      return *shader;
807
   } else {
808
      void **shader = &ctx->fs_texfetch_depthstencil[target];
809
 
810
      /* Create the fragment shader on-demand. */
811
      if (!*shader) {
812
         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
813
 
814
         *shader =
815
            util_make_fragment_tex_shader_writedepthstencil(pipe, tgsi_tex,
816
                                                     TGSI_INTERPOLATE_LINEAR);
817
      }
818
 
819
      return *shader;
820
   }
821
}
822
 
823
static INLINE
824
void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
825
                                      enum pipe_texture_target target,
826
                                      unsigned nr_samples)
827
{
828
   struct pipe_context *pipe = ctx->base.pipe;
829
 
830
   assert(target < PIPE_MAX_TEXTURE_TYPES);
831
 
832
   if (nr_samples > 1) {
833
      void **shader = &ctx->fs_texfetch_stencil_msaa[target];
834
 
835
      /* Create the fragment shader on-demand. */
836
      if (!*shader) {
837
         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target,
838
                                                       nr_samples);
839
 
840
         *shader =
841
            util_make_fs_blit_msaa_stencil(pipe, tgsi_tex);
842
      }
843
 
844
      return *shader;
845
   } else {
846
      void **shader = &ctx->fs_texfetch_stencil[target];
847
 
848
      /* Create the fragment shader on-demand. */
849
      if (!*shader) {
850
         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
851
 
852
         *shader =
853
            util_make_fragment_tex_shader_writestencil(pipe, tgsi_tex,
854
                                                       TGSI_INTERPOLATE_LINEAR);
855
      }
856
 
857
      return *shader;
858
   }
859
}
860
 
861
void util_blitter_cache_all_shaders(struct blitter_context *blitter)
862
{
863
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
864
   struct pipe_screen *screen = blitter->pipe->screen;
865
   unsigned i, target, max_samples;
866
   boolean has_arraytex, has_cubearraytex;
867
 
868
   max_samples = ctx->has_texture_multisample ? 2 : 1;
869
   has_arraytex = screen->get_param(screen,
870
                                    PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) != 0;
871
   has_cubearraytex = screen->get_param(screen,
872
                                    PIPE_CAP_CUBE_MAP_ARRAY) != 0;
873
 
874
   /* It only matters if i <= 1 or > 1. */
875
   for (i = 1; i <= max_samples; i++) {
876
      for (target = PIPE_TEXTURE_1D; target < PIPE_MAX_TEXTURE_TYPES; target++) {
877
         if (!has_arraytex &&
878
             (target == PIPE_TEXTURE_1D_ARRAY ||
879
              target == PIPE_TEXTURE_2D_ARRAY)) {
880
            continue;
881
         }
882
         if (!has_cubearraytex &&
883
             (target == PIPE_TEXTURE_CUBE_ARRAY))
884
            continue;
885
 
886
	 if (i > 1 &&
887
	     (target != PIPE_TEXTURE_2D &&
888
	      target != PIPE_TEXTURE_2D_ARRAY))
889
	    continue;
890
 
891
         blitter_get_fs_texfetch_col(ctx, target, i);
892
         blitter_get_fs_texfetch_depth(ctx, target, i);
893
         if (ctx->has_stencil_export) {
894
            blitter_get_fs_texfetch_depthstencil(ctx, target, i);
895
            blitter_get_fs_texfetch_stencil(ctx, target, i);
896
         }
897
      }
898
   }
899
}
900
 
901
static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx,
902
                                               boolean scissor)
903
{
904
   struct pipe_context *pipe = ctx->base.pipe;
905
 
906
   pipe->bind_rasterizer_state(pipe, scissor ? ctx->rs_state_scissor
907
                                             : ctx->rs_state);
908
   pipe->bind_vs_state(pipe, ctx->vs);
909
   if (ctx->has_geometry_shader)
910
      pipe->bind_gs_state(pipe, NULL);
911
   if (ctx->has_stream_out)
912
      pipe->set_stream_output_targets(pipe, 0, NULL, 0);
913
}
914
 
915
static void blitter_draw(struct blitter_context_priv *ctx,
916
                         int x1, int y1, int x2, int y2, float depth)
917
{
918
   struct pipe_resource *buf = NULL;
919
   unsigned offset = 0;
920
 
921
   blitter_set_rectangle(ctx, x1, y1, x2, y2, depth);
922
 
923
   u_upload_data(ctx->upload, 0, sizeof(ctx->vertices), ctx->vertices,
924
                 &offset, &buf);
925
   u_upload_unmap(ctx->upload);
926
   util_draw_vertex_buffer(ctx->base.pipe, NULL, buf, ctx->base.vb_slot,
927
                           offset, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
928
   pipe_resource_reference(&buf, NULL);
929
}
930
 
931
void util_blitter_draw_rectangle(struct blitter_context *blitter,
932
                                 int x1, int y1, int x2, int y2, float depth,
933
                                 enum blitter_attrib_type type,
934
                                 const union pipe_color_union *attrib)
935
{
936
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
937
 
938
   switch (type) {
939
      case UTIL_BLITTER_ATTRIB_COLOR:
940
         blitter_set_clear_color(ctx, attrib);
941
         break;
942
 
943
      case UTIL_BLITTER_ATTRIB_TEXCOORD:
944
         set_texcoords_in_vertices(attrib->f, &ctx->vertices[0][1][0], 8);
945
         break;
946
 
947
      default:;
948
   }
949
 
950
   blitter_draw(ctx, x1, y1, x2, y2, depth);
951
}
952
 
953
static void util_blitter_clear_custom(struct blitter_context *blitter,
954
                                      unsigned width, unsigned height,
955
                                      unsigned clear_buffers,
956
                                      const union pipe_color_union *color,
957
                                      double depth, unsigned stencil,
958
                                      void *custom_blend, void *custom_dsa)
959
{
960
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
961
   struct pipe_context *pipe = ctx->base.pipe;
962
   struct pipe_stencil_ref sr = { { 0 } };
963
 
964
   blitter_set_running_flag(ctx);
965
   blitter_check_saved_vertex_states(ctx);
966
   blitter_check_saved_fragment_states(ctx);
967
   blitter_disable_render_cond(ctx);
968
 
969
   /* bind states */
970
   if (custom_blend) {
971
      pipe->bind_blend_state(pipe, custom_blend);
972
   } else if (clear_buffers & PIPE_CLEAR_COLOR) {
973
      pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA]);
974
   } else {
975
      pipe->bind_blend_state(pipe, ctx->blend[0]);
976
   }
977
 
978
   if (custom_dsa) {
979
      pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa);
980
   } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
981
      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
982
   } else if (clear_buffers & PIPE_CLEAR_DEPTH) {
983
      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
984
   } else if (clear_buffers & PIPE_CLEAR_STENCIL) {
985
      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
986
   } else {
987
      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
988
   }
989
 
990
   sr.ref_value[0] = stencil & 0xff;
991
   pipe->set_stencil_ref(pipe, &sr);
992
 
993
   pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
994
   ctx->bind_fs_state(pipe, ctx->fs_write_all_cbufs);
995
   pipe->set_sample_mask(pipe, ~0);
996
 
997
   blitter_set_common_draw_rect_state(ctx, FALSE);
998
   blitter_set_dst_dimensions(ctx, width, height);
999
   blitter->draw_rectangle(blitter, 0, 0, width, height, (float) depth,
1000
                           UTIL_BLITTER_ATTRIB_COLOR, color);
1001
 
1002
   blitter_restore_vertex_states(ctx);
1003
   blitter_restore_fragment_states(ctx);
1004
   blitter_restore_render_cond(ctx);
1005
   blitter_unset_running_flag(ctx);
1006
}
1007
 
1008
void util_blitter_clear(struct blitter_context *blitter,
1009
                        unsigned width, unsigned height,
1010
                        unsigned clear_buffers,
1011
                        const union pipe_color_union *color,
1012
                        double depth, unsigned stencil)
1013
{
1014
   util_blitter_clear_custom(blitter, width, height,
1015
                             clear_buffers, color, depth, stencil,
1016
                             NULL, NULL);
1017
}
1018
 
1019
void util_blitter_custom_clear_depth(struct blitter_context *blitter,
1020
                                     unsigned width, unsigned height,
1021
                                     double depth, void *custom_dsa)
1022
{
1023
    static const union pipe_color_union color;
1024
    util_blitter_clear_custom(blitter, width, height, 0, &color, depth, 0,
1025
                              NULL, custom_dsa);
1026
}
1027
 
1028
void util_blitter_default_dst_texture(struct pipe_surface *dst_templ,
1029
                                      struct pipe_resource *dst,
1030
                                      unsigned dstlevel,
1031
                                      unsigned dstz)
1032
{
1033
    memset(dst_templ, 0, sizeof(*dst_templ));
1034
    dst_templ->format = util_format_linear(dst->format);
1035
    dst_templ->u.tex.level = dstlevel;
1036
    dst_templ->u.tex.first_layer = dstz;
1037
    dst_templ->u.tex.last_layer = dstz;
1038
}
1039
 
1040
static struct pipe_surface *
1041
util_blitter_get_next_surface_layer(struct pipe_context *pipe,
1042
                                    struct pipe_surface *surf)
1043
{
1044
   struct pipe_surface dst_templ;
1045
 
1046
   memset(&dst_templ, 0, sizeof(dst_templ));
1047
   dst_templ.format = surf->format;
1048
   dst_templ.u.tex.level = surf->u.tex.level;
1049
   dst_templ.u.tex.first_layer = surf->u.tex.first_layer + 1;
1050
   dst_templ.u.tex.last_layer = surf->u.tex.last_layer + 1;
1051
 
1052
   return pipe->create_surface(pipe, surf->texture, &dst_templ);
1053
}
1054
 
1055
void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ,
1056
                                      struct pipe_resource *src,
1057
                                      unsigned srclevel)
1058
{
1059
    memset(src_templ, 0, sizeof(*src_templ));
1060
    src_templ->format = util_format_linear(src->format);
1061
    src_templ->u.tex.first_level = srclevel;
1062
    src_templ->u.tex.last_level = srclevel;
1063
    src_templ->u.tex.first_layer = 0;
1064
    src_templ->u.tex.last_layer =
1065
        src->target == PIPE_TEXTURE_3D ? u_minify(src->depth0, srclevel) - 1
1066
                                       : src->array_size - 1;
1067
    src_templ->swizzle_r = PIPE_SWIZZLE_RED;
1068
    src_templ->swizzle_g = PIPE_SWIZZLE_GREEN;
1069
    src_templ->swizzle_b = PIPE_SWIZZLE_BLUE;
1070
    src_templ->swizzle_a = PIPE_SWIZZLE_ALPHA;
1071
}
1072
 
1073
static boolean is_blit_generic_supported(struct blitter_context *blitter,
1074
                                         const struct pipe_resource *dst,
1075
                                         enum pipe_format dst_format,
1076
                                         const struct pipe_resource *src,
1077
                                         enum pipe_format src_format,
1078
                                         unsigned mask)
1079
{
1080
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1081
   struct pipe_screen *screen = ctx->base.pipe->screen;
1082
 
1083
   if (dst) {
1084
      unsigned bind;
1085
      const struct util_format_description *desc =
1086
            util_format_description(dst_format);
1087
      boolean dst_has_stencil = util_format_has_stencil(desc);
1088
 
1089
      /* Stencil export must be supported for stencil copy. */
1090
      if ((mask & PIPE_MASK_S) && dst_has_stencil &&
1091
          !ctx->has_stencil_export) {
1092
         return FALSE;
1093
      }
1094
 
1095
      if (dst_has_stencil || util_format_has_depth(desc))
1096
         bind = PIPE_BIND_DEPTH_STENCIL;
1097
      else
1098
         bind = PIPE_BIND_RENDER_TARGET;
1099
 
1100
      if (!screen->is_format_supported(screen, dst_format, dst->target,
1101
                                       dst->nr_samples, bind)) {
1102
         return FALSE;
1103
      }
1104
   }
1105
 
1106
   if (src) {
1107
      if (src->nr_samples > 1 && !ctx->has_texture_multisample) {
1108
         return FALSE;
1109
      }
1110
 
1111
      if (!screen->is_format_supported(screen, src_format, src->target,
1112
                                 src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
1113
         return FALSE;
1114
      }
1115
 
1116
      /* Check stencil sampler support for stencil copy. */
1117
      if (mask & PIPE_MASK_S) {
1118
         if (util_format_has_stencil(util_format_description(src_format))) {
1119
            enum pipe_format stencil_format =
1120
               util_format_stencil_only(src_format);
1121
            assert(stencil_format != PIPE_FORMAT_NONE);
1122
 
1123
            if (stencil_format != src_format &&
1124
                !screen->is_format_supported(screen, stencil_format,
1125
                                             src->target, src->nr_samples,
1126
                                             PIPE_BIND_SAMPLER_VIEW)) {
1127
               return FALSE;
1128
            }
1129
         }
1130
      }
1131
   }
1132
 
1133
   return TRUE;
1134
}
1135
 
1136
boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
1137
                                       const struct pipe_resource *dst,
1138
                                       const struct pipe_resource *src,
1139
                                       unsigned mask)
1140
{
1141
   return is_blit_generic_supported(blitter, dst, dst->format,
1142
                                    src, src->format, mask);
1143
}
1144
 
1145
boolean util_blitter_is_blit_supported(struct blitter_context *blitter,
1146
				       const struct pipe_blit_info *info)
1147
{
1148
   return is_blit_generic_supported(blitter,
1149
                                    info->dst.resource, info->dst.format,
1150
                                    info->src.resource, info->src.format,
1151
                                    info->mask);
1152
}
1153
 
1154
void util_blitter_copy_texture(struct blitter_context *blitter,
1155
                               struct pipe_resource *dst,
1156
                               unsigned dst_level,
1157
                               unsigned dstx, unsigned dsty, unsigned dstz,
1158
                               struct pipe_resource *src,
1159
                               unsigned src_level,
1160
                               const struct pipe_box *srcbox, unsigned mask,
1161
                               boolean copy_all_samples)
1162
{
1163
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1164
   struct pipe_context *pipe = ctx->base.pipe;
1165
   struct pipe_surface *dst_view, dst_templ;
1166
   struct pipe_sampler_view src_templ, *src_view;
1167
   struct pipe_box dstbox;
1168
 
1169
   assert(dst && src);
1170
   assert(src->target < PIPE_MAX_TEXTURE_TYPES);
1171
 
1172
   u_box_3d(dstx, dsty, dstz, abs(srcbox->width), abs(srcbox->height),
1173
            abs(srcbox->depth), &dstbox);
1174
 
1175
   /* Initialize the surface. */
1176
   util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz);
1177
   dst_view = pipe->create_surface(pipe, dst, &dst_templ);
1178
 
1179
   /* Initialize the sampler view. */
1180
   util_blitter_default_src_texture(&src_templ, src, src_level);
1181
   src_view = pipe->create_sampler_view(pipe, src, &src_templ);
1182
 
1183
   /* Copy. */
1184
   util_blitter_blit_generic(blitter, dst_view, &dstbox,
1185
                             src_view, srcbox, src->width0, src->height0,
1186
                             mask, PIPE_TEX_FILTER_NEAREST, NULL,
1187
                             copy_all_samples);
1188
 
1189
   pipe_surface_reference(&dst_view, NULL);
1190
   pipe_sampler_view_reference(&src_view, NULL);
1191
}
1192
 
1193
void util_blitter_blit_generic(struct blitter_context *blitter,
1194
                               struct pipe_surface *dst,
1195
                               const struct pipe_box *dstbox,
1196
                               struct pipe_sampler_view *src,
1197
                               const struct pipe_box *srcbox,
1198
                               unsigned src_width0, unsigned src_height0,
1199
                               unsigned mask, unsigned filter,
1200
                               const struct pipe_scissor_state *scissor,
1201
                               boolean copy_all_samples)
1202
{
1203
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1204
   struct pipe_context *pipe = ctx->base.pipe;
1205
   struct pipe_framebuffer_state fb_state;
1206
   enum pipe_texture_target src_target = src->texture->target;
1207
   unsigned src_samples = src->texture->nr_samples;
1208
   boolean has_depth, has_stencil, has_color;
1209
   boolean blit_stencil, blit_depth, blit_color;
1210
   void *sampler_state;
1211
   const struct util_format_description *src_desc =
1212
         util_format_description(src->format);
1213
   const struct util_format_description *dst_desc =
1214
         util_format_description(dst->format);
1215
 
1216
   has_color = src_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
1217
               dst_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
1218
   has_depth = util_format_has_depth(src_desc) &&
1219
               util_format_has_depth(dst_desc);
1220
   has_stencil = util_format_has_stencil(src_desc) &&
1221
                 util_format_has_stencil(dst_desc);
1222
 
1223
   blit_color = has_color && (mask & PIPE_MASK_RGBA);
1224
   blit_depth = has_depth && (mask & PIPE_MASK_Z);
1225
   blit_stencil = has_stencil && (mask & PIPE_MASK_S) &&
1226
                  ctx->has_stencil_export;
1227
 
1228
   if (!blit_stencil && !blit_depth && !blit_color) {
1229
      return;
1230
   }
1231
 
1232
   /* Check whether the states are properly saved. */
1233
   blitter_set_running_flag(ctx);
1234
   blitter_check_saved_vertex_states(ctx);
1235
   blitter_check_saved_fragment_states(ctx);
1236
   blitter_check_saved_textures(ctx);
1237
   blitter_check_saved_fb_state(ctx);
1238
   blitter_disable_render_cond(ctx);
1239
 
1240
   /* Initialize framebuffer state. */
1241
   fb_state.width = dst->width;
1242
   fb_state.height = dst->height;
1243
   fb_state.nr_cbufs = blit_depth || blit_stencil ? 0 : 1;
1244
   fb_state.cbufs[0] = NULL;
1245
   fb_state.zsbuf = NULL;
1246
 
1247
   if (blit_depth || blit_stencil) {
1248
      pipe->bind_blend_state(pipe, ctx->blend[0]);
1249
 
1250
      if (blit_depth && blit_stencil) {
1251
         pipe->bind_depth_stencil_alpha_state(pipe,
1252
                                              ctx->dsa_write_depth_stencil);
1253
         ctx->bind_fs_state(pipe,
1254
               blitter_get_fs_texfetch_depthstencil(ctx, src_target,
1255
                                                    src_samples));
1256
      } else if (blit_depth) {
1257
         pipe->bind_depth_stencil_alpha_state(pipe,
1258
                                              ctx->dsa_write_depth_keep_stencil);
1259
         ctx->bind_fs_state(pipe,
1260
               blitter_get_fs_texfetch_depth(ctx, src_target,
1261
                                             src_samples));
1262
      } else { /* is_stencil */
1263
         pipe->bind_depth_stencil_alpha_state(pipe,
1264
                                              ctx->dsa_keep_depth_write_stencil);
1265
         ctx->bind_fs_state(pipe,
1266
               blitter_get_fs_texfetch_stencil(ctx, src_target,
1267
                                               src_samples));
1268
      }
1269
 
1270
   } else {
1271
      pipe->bind_blend_state(pipe, ctx->blend[mask & PIPE_MASK_RGBA]);
1272
      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1273
      ctx->bind_fs_state(pipe,
1274
            blitter_get_fs_texfetch_col(ctx, src_target,
1275
                                        src_samples));
1276
   }
1277
 
1278
   /* Set the linear filter only for scaled color non-MSAA blits. */
1279
   if (filter == PIPE_TEX_FILTER_LINEAR &&
1280
       !blit_depth && !blit_stencil &&
1281
       src_samples <= 1 &&
1282
       (dstbox->width != abs(srcbox->width) ||
1283
        dstbox->height != abs(srcbox->height))) {
1284
      if (src_target == PIPE_TEXTURE_RECT) {
1285
         sampler_state = ctx->sampler_state_rect_linear;
1286
      } else {
1287
         sampler_state = ctx->sampler_state_linear;
1288
      }
1289
   } else {
1290
      if (src_target == PIPE_TEXTURE_RECT) {
1291
         sampler_state = ctx->sampler_state_rect;
1292
      } else {
1293
         sampler_state = ctx->sampler_state;
1294
      }
1295
   }
1296
 
1297
   /* Set samplers. */
1298
   if (blit_depth && blit_stencil) {
1299
      /* Setup two samplers, one for depth and the other one for stencil. */
1300
      struct pipe_sampler_view templ;
1301
      struct pipe_sampler_view *views[2];
1302
      void *samplers[2] = {sampler_state, sampler_state};
1303
 
1304
      templ = *src;
1305
      templ.format = util_format_stencil_only(templ.format);
1306
      assert(templ.format != PIPE_FORMAT_NONE);
1307
 
1308
      views[0] = src;
1309
      views[1] = pipe->create_sampler_view(pipe, src->texture, &templ);
1310
 
1311
      pipe->set_fragment_sampler_views(pipe, 2, views);
1312
      pipe->bind_fragment_sampler_states(pipe, 2, samplers);
1313
 
1314
      pipe_sampler_view_reference(&views[1], NULL);
1315
   } else if (blit_stencil) {
1316
      /* Set a stencil-only sampler view for it not to sample depth instead. */
1317
      struct pipe_sampler_view templ;
1318
      struct pipe_sampler_view *view;
1319
 
1320
      templ = *src;
1321
      templ.format = util_format_stencil_only(templ.format);
1322
      assert(templ.format != PIPE_FORMAT_NONE);
1323
 
1324
      view = pipe->create_sampler_view(pipe, src->texture, &templ);
1325
 
1326
      pipe->set_fragment_sampler_views(pipe, 1, &view);
1327
      pipe->bind_fragment_sampler_states(pipe, 1, &sampler_state);
1328
 
1329
      pipe_sampler_view_reference(&view, NULL);
1330
   } else {
1331
      pipe->set_fragment_sampler_views(pipe, 1, &src);
1332
      pipe->bind_fragment_sampler_states(pipe, 1, &sampler_state);
1333
   }
1334
 
1335
   pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1336
   if (scissor) {
1337
      pipe->set_scissor_states(pipe, 0, 1, scissor);
1338
   }
1339
 
1340
   blitter_set_common_draw_rect_state(ctx, scissor != NULL);
1341
   blitter_set_dst_dimensions(ctx, dst->width, dst->height);
1342
 
1343
   if ((src_target == PIPE_TEXTURE_1D ||
1344
        src_target == PIPE_TEXTURE_2D ||
1345
        src_target == PIPE_TEXTURE_RECT) &&
1346
       src_samples <= 1) {
1347
      /* Draw the quad with the draw_rectangle callback. */
1348
 
1349
      /* Set texture coordinates. - use a pipe color union
1350
       * for interface purposes.
1351
       * XXX pipe_color_union is a wrong name since we use that to set
1352
       * texture coordinates too.
1353
       */
1354
      union pipe_color_union coord;
1355
      get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y,
1356
                    srcbox->x+srcbox->width, srcbox->y+srcbox->height, coord.f);
1357
 
1358
      /* Set framebuffer state. */
1359
      if (blit_depth || blit_stencil) {
1360
         fb_state.zsbuf = dst;
1361
      } else {
1362
         fb_state.cbufs[0] = dst;
1363
      }
1364
      pipe->set_framebuffer_state(pipe, &fb_state);
1365
 
1366
      /* Draw. */
1367
      pipe->set_sample_mask(pipe, ~0);
1368
      blitter->draw_rectangle(blitter, dstbox->x, dstbox->y,
1369
                              dstbox->x + dstbox->width,
1370
                              dstbox->y + dstbox->height, 0,
1371
                              UTIL_BLITTER_ATTRIB_TEXCOORD, &coord);
1372
   } else {
1373
      /* Draw the quad with the generic codepath. */
1374
      int z;
1375
      for (z = 0; z < dstbox->depth; z++) {
1376
         struct pipe_surface *old;
1377
 
1378
         /* Set framebuffer state. */
1379
         if (blit_depth || blit_stencil) {
1380
            fb_state.zsbuf = dst;
1381
         } else {
1382
            fb_state.cbufs[0] = dst;
1383
         }
1384
         pipe->set_framebuffer_state(pipe, &fb_state);
1385
 
1386
         /* See if we need to blit a multisample or singlesample buffer. */
1387
         if (copy_all_samples &&
1388
             src_samples == dst->texture->nr_samples &&
1389
             dst->texture->nr_samples > 1) {
1390
            unsigned i, max_sample = MAX2(dst->texture->nr_samples, 1) - 1;
1391
 
1392
            for (i = 0; i <= max_sample; i++) {
1393
               pipe->set_sample_mask(pipe, 1 << i);
1394
               blitter_set_texcoords(ctx, src, src_width0, src_height0,
1395
                                     srcbox->z + z,
1396
                                     i, srcbox->x, srcbox->y,
1397
                                     srcbox->x + srcbox->width,
1398
                                     srcbox->y + srcbox->height);
1399
               blitter_draw(ctx, dstbox->x, dstbox->y,
1400
                            dstbox->x + dstbox->width,
1401
                            dstbox->y + dstbox->height, 0);
1402
            }
1403
         } else {
1404
            pipe->set_sample_mask(pipe, ~0);
1405
            blitter_set_texcoords(ctx, src, src_width0, src_height0,
1406
                                  srcbox->z + z, 0,
1407
                                  srcbox->x, srcbox->y,
1408
                                  srcbox->x + srcbox->width,
1409
                                  srcbox->y + srcbox->height);
1410
            blitter_draw(ctx, dstbox->x, dstbox->y,
1411
                         dstbox->x + dstbox->width,
1412
                         dstbox->y + dstbox->height, 0);
1413
         }
1414
 
1415
         /* Get the next surface or (if this is the last iteration)
1416
          * just unreference the last one. */
1417
         old = dst;
1418
         if (z < dstbox->depth-1) {
1419
            dst = ctx->base.get_next_surface_layer(ctx->base.pipe, dst);
1420
         }
1421
         if (z) {
1422
            pipe_surface_reference(&old, NULL);
1423
         }
1424
      }
1425
   }
1426
 
1427
   blitter_restore_vertex_states(ctx);
1428
   blitter_restore_fragment_states(ctx);
1429
   blitter_restore_textures(ctx);
1430
   blitter_restore_fb_state(ctx);
1431
   if (scissor) {
1432
      pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor);
1433
   }
1434
   blitter_restore_render_cond(ctx);
1435
   blitter_unset_running_flag(ctx);
1436
}
1437
 
1438
void
1439
util_blitter_blit(struct blitter_context *blitter,
1440
		  const struct pipe_blit_info *info)
1441
{
1442
   struct pipe_resource *dst = info->dst.resource;
1443
   struct pipe_resource *src = info->src.resource;
1444
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1445
   struct pipe_context *pipe = ctx->base.pipe;
1446
   struct pipe_surface *dst_view, dst_templ;
1447
   struct pipe_sampler_view src_templ, *src_view;
1448
 
1449
   /* Initialize the surface. */
1450
   util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level,
1451
                                    info->dst.box.z);
1452
   dst_templ.format = info->dst.format;
1453
   dst_view = pipe->create_surface(pipe, dst, &dst_templ);
1454
 
1455
   /* Initialize the sampler view. */
1456
   util_blitter_default_src_texture(&src_templ, src, info->src.level);
1457
   src_templ.format = info->src.format;
1458
   src_view = pipe->create_sampler_view(pipe, src, &src_templ);
1459
 
1460
   /* Copy. */
1461
   util_blitter_blit_generic(blitter, dst_view, &info->dst.box,
1462
                             src_view, &info->src.box, src->width0, src->height0,
1463
                             info->mask, info->filter,
1464
                             info->scissor_enable ? &info->scissor : NULL, TRUE);
1465
 
1466
   pipe_surface_reference(&dst_view, NULL);
1467
   pipe_sampler_view_reference(&src_view, NULL);
1468
}
1469
 
1470
/* Clear a region of a color surface to a constant value. */
1471
void util_blitter_clear_render_target(struct blitter_context *blitter,
1472
                                      struct pipe_surface *dstsurf,
1473
                                      const union pipe_color_union *color,
1474
                                      unsigned dstx, unsigned dsty,
1475
                                      unsigned width, unsigned height)
1476
{
1477
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1478
   struct pipe_context *pipe = ctx->base.pipe;
1479
   struct pipe_framebuffer_state fb_state;
1480
 
1481
   assert(dstsurf->texture);
1482
   if (!dstsurf->texture)
1483
      return;
1484
 
1485
   /* check the saved state */
1486
   blitter_set_running_flag(ctx);
1487
   blitter_check_saved_vertex_states(ctx);
1488
   blitter_check_saved_fragment_states(ctx);
1489
   blitter_check_saved_fb_state(ctx);
1490
   blitter_disable_render_cond(ctx);
1491
 
1492
   /* bind states */
1493
   pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA]);
1494
   pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1495
   ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf);
1496
   pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1497
 
1498
   /* set a framebuffer state */
1499
   fb_state.width = dstsurf->width;
1500
   fb_state.height = dstsurf->height;
1501
   fb_state.nr_cbufs = 1;
1502
   fb_state.cbufs[0] = dstsurf;
1503
   fb_state.zsbuf = 0;
1504
   pipe->set_framebuffer_state(pipe, &fb_state);
1505
   pipe->set_sample_mask(pipe, ~0);
1506
 
1507
   blitter_set_common_draw_rect_state(ctx, FALSE);
1508
   blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
1509
   blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
1510
                           UTIL_BLITTER_ATTRIB_COLOR, color);
1511
 
1512
   blitter_restore_vertex_states(ctx);
1513
   blitter_restore_fragment_states(ctx);
1514
   blitter_restore_fb_state(ctx);
1515
   blitter_restore_render_cond(ctx);
1516
   blitter_unset_running_flag(ctx);
1517
}
1518
 
1519
/* Clear a region of a depth stencil surface. */
1520
void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
1521
                                      struct pipe_surface *dstsurf,
1522
                                      unsigned clear_flags,
1523
                                      double depth,
1524
                                      unsigned stencil,
1525
                                      unsigned dstx, unsigned dsty,
1526
                                      unsigned width, unsigned height)
1527
{
1528
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1529
   struct pipe_context *pipe = ctx->base.pipe;
1530
   struct pipe_framebuffer_state fb_state;
1531
   struct pipe_stencil_ref sr = { { 0 } };
1532
 
1533
   assert(dstsurf->texture);
1534
   if (!dstsurf->texture)
1535
      return;
1536
 
1537
   /* check the saved state */
1538
   blitter_set_running_flag(ctx);
1539
   blitter_check_saved_vertex_states(ctx);
1540
   blitter_check_saved_fragment_states(ctx);
1541
   blitter_check_saved_fb_state(ctx);
1542
   blitter_disable_render_cond(ctx);
1543
 
1544
   /* bind states */
1545
   pipe->bind_blend_state(pipe, ctx->blend[0]);
1546
   if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
1547
      sr.ref_value[0] = stencil & 0xff;
1548
      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
1549
      pipe->set_stencil_ref(pipe, &sr);
1550
   }
1551
   else if (clear_flags & PIPE_CLEAR_DEPTH) {
1552
      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
1553
   }
1554
   else if (clear_flags & PIPE_CLEAR_STENCIL) {
1555
      sr.ref_value[0] = stencil & 0xff;
1556
      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
1557
      pipe->set_stencil_ref(pipe, &sr);
1558
   }
1559
   else
1560
      /* hmm that should be illegal probably, or make it a no-op somewhere */
1561
      pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1562
 
1563
   ctx->bind_fs_state(pipe, ctx->fs_empty);
1564
   pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1565
 
1566
   /* set a framebuffer state */
1567
   fb_state.width = dstsurf->width;
1568
   fb_state.height = dstsurf->height;
1569
   fb_state.nr_cbufs = 0;
1570
   fb_state.cbufs[0] = 0;
1571
   fb_state.zsbuf = dstsurf;
1572
   pipe->set_framebuffer_state(pipe, &fb_state);
1573
   pipe->set_sample_mask(pipe, ~0);
1574
 
1575
   blitter_set_common_draw_rect_state(ctx, FALSE);
1576
   blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
1577
   blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height,
1578
                           (float) depth,
1579
                           UTIL_BLITTER_ATTRIB_NONE, NULL);
1580
 
1581
   blitter_restore_vertex_states(ctx);
1582
   blitter_restore_fragment_states(ctx);
1583
   blitter_restore_fb_state(ctx);
1584
   blitter_restore_render_cond(ctx);
1585
   blitter_unset_running_flag(ctx);
1586
}
1587
 
1588
/* draw a rectangle across a region using a custom dsa stage - for r600g */
1589
void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
1590
				       struct pipe_surface *zsurf,
1591
				       struct pipe_surface *cbsurf,
1592
				       unsigned sample_mask,
1593
				       void *dsa_stage, float depth)
1594
{
1595
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1596
   struct pipe_context *pipe = ctx->base.pipe;
1597
   struct pipe_framebuffer_state fb_state;
1598
 
1599
   assert(zsurf->texture);
1600
   if (!zsurf->texture)
1601
      return;
1602
 
1603
   /* check the saved state */
1604
   blitter_set_running_flag(ctx);
1605
   blitter_check_saved_vertex_states(ctx);
1606
   blitter_check_saved_fragment_states(ctx);
1607
   blitter_check_saved_fb_state(ctx);
1608
   blitter_disable_render_cond(ctx);
1609
 
1610
   /* bind states */
1611
   pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA] :
1612
                                         ctx->blend[0]);
1613
   pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
1614
   ctx->bind_fs_state(pipe, ctx->fs_empty);
1615
   pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1616
 
1617
   /* set a framebuffer state */
1618
   fb_state.width = zsurf->width;
1619
   fb_state.height = zsurf->height;
1620
   fb_state.nr_cbufs = 1;
1621
   if (cbsurf) {
1622
	   fb_state.cbufs[0] = cbsurf;
1623
	   fb_state.nr_cbufs = 1;
1624
   } else {
1625
	   fb_state.cbufs[0] = NULL;
1626
	   fb_state.nr_cbufs = 0;
1627
   }
1628
   fb_state.zsbuf = zsurf;
1629
   pipe->set_framebuffer_state(pipe, &fb_state);
1630
   pipe->set_sample_mask(pipe, sample_mask);
1631
 
1632
   blitter_set_common_draw_rect_state(ctx, FALSE);
1633
   blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height);
1634
   blitter->draw_rectangle(blitter, 0, 0, zsurf->width, zsurf->height, depth,
1635
                           UTIL_BLITTER_ATTRIB_NONE, NULL);
1636
 
1637
   blitter_restore_vertex_states(ctx);
1638
   blitter_restore_fragment_states(ctx);
1639
   blitter_restore_fb_state(ctx);
1640
   blitter_restore_render_cond(ctx);
1641
   blitter_unset_running_flag(ctx);
1642
}
1643
 
1644
void util_blitter_copy_buffer(struct blitter_context *blitter,
1645
                              struct pipe_resource *dst,
1646
                              unsigned dstx,
1647
                              struct pipe_resource *src,
1648
                              unsigned srcx,
1649
                              unsigned size)
1650
{
1651
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1652
   struct pipe_context *pipe = ctx->base.pipe;
1653
   struct pipe_vertex_buffer vb;
1654
   struct pipe_stream_output_target *so_target;
1655
 
1656
   if (srcx >= src->width0 ||
1657
       dstx >= dst->width0) {
1658
      return;
1659
   }
1660
   if (srcx + size > src->width0) {
1661
      size = src->width0 - srcx;
1662
   }
1663
   if (dstx + size > dst->width0) {
1664
      size = dst->width0 - dstx;
1665
   }
1666
 
1667
   /* Drivers not capable of Stream Out should not call this function
1668
    * in the first place. */
1669
   assert(ctx->has_stream_out);
1670
 
1671
   /* Some alignment is required. */
1672
   if (srcx % 4 != 0 || dstx % 4 != 0 || size % 4 != 0 ||
1673
       !ctx->has_stream_out) {
1674
      struct pipe_box box;
1675
      u_box_1d(srcx, size, &box);
1676
      util_resource_copy_region(pipe, dst, 0, dstx, 0, 0, src, 0, &box);
1677
      return;
1678
   }
1679
 
1680
   blitter_set_running_flag(ctx);
1681
   blitter_check_saved_vertex_states(ctx);
1682
   blitter_disable_render_cond(ctx);
1683
 
1684
   vb.buffer = src;
1685
   vb.buffer_offset = srcx;
1686
   vb.stride = 4;
1687
 
1688
   pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
1689
   pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf[0]);
1690
   pipe->bind_vs_state(pipe, ctx->vs_pos_only);
1691
   if (ctx->has_geometry_shader)
1692
      pipe->bind_gs_state(pipe, NULL);
1693
   pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
1694
 
1695
   so_target = pipe->create_stream_output_target(pipe, dst, dstx, size);
1696
   pipe->set_stream_output_targets(pipe, 1, &so_target, 0);
1697
 
1698
   util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
1699
 
1700
   blitter_restore_vertex_states(ctx);
1701
   blitter_restore_render_cond(ctx);
1702
   blitter_unset_running_flag(ctx);
1703
   pipe_so_target_reference(&so_target, NULL);
1704
}
1705
 
1706
void util_blitter_clear_buffer(struct blitter_context *blitter,
1707
                               struct pipe_resource *dst,
1708
                               unsigned offset, unsigned size,
1709
                               unsigned num_channels,
1710
                               const union pipe_color_union *clear_value)
1711
{
1712
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1713
   struct pipe_context *pipe = ctx->base.pipe;
1714
   struct pipe_vertex_buffer vb = {0};
1715
   struct pipe_stream_output_target *so_target;
1716
 
1717
   assert(num_channels >= 1);
1718
   assert(num_channels <= 4);
1719
 
1720
   /* IMPORTANT:  DON'T DO ANY BOUNDS CHECKING HERE!
1721
    *
1722
    * R600 uses this to initialize texture resources, so width0 might not be
1723
    * what you think it is.
1724
    */
1725
 
1726
   /* Streamout is required. */
1727
   if (!ctx->has_stream_out) {
1728
      assert(!"Streamout unsupported in util_blitter_clear_buffer()");
1729
      return;
1730
   }
1731
 
1732
   /* Some alignment is required. */
1733
   if (offset % 4 != 0 || size % 4 != 0) {
1734
      assert(!"Bad alignment in util_blitter_clear_buffer()");
1735
      return;
1736
   }
1737
 
1738
   u_upload_data(ctx->upload, 0, num_channels*4, clear_value,
1739
                 &vb.buffer_offset, &vb.buffer);
1740
   vb.stride = 0;
1741
 
1742
   blitter_set_running_flag(ctx);
1743
   blitter_check_saved_vertex_states(ctx);
1744
   blitter_disable_render_cond(ctx);
1745
 
1746
   pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
1747
   pipe->bind_vertex_elements_state(pipe,
1748
                                    ctx->velem_state_readbuf[num_channels-1]);
1749
   pipe->bind_vs_state(pipe, ctx->vs_pos_only);
1750
   if (ctx->has_geometry_shader)
1751
      pipe->bind_gs_state(pipe, NULL);
1752
   pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
1753
 
1754
   so_target = pipe->create_stream_output_target(pipe, dst, offset, size);
1755
   pipe->set_stream_output_targets(pipe, 1, &so_target, 0);
1756
 
1757
   util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
1758
 
1759
   blitter_restore_vertex_states(ctx);
1760
   blitter_restore_render_cond(ctx);
1761
   blitter_unset_running_flag(ctx);
1762
   pipe_so_target_reference(&so_target, NULL);
1763
   pipe_resource_reference(&vb.buffer, NULL);
1764
}
1765
 
1766
/* probably radeon specific */
1767
void util_blitter_custom_resolve_color(struct blitter_context *blitter,
1768
				       struct pipe_resource *dst,
1769
				       unsigned dst_level,
1770
				       unsigned dst_layer,
1771
				       struct pipe_resource *src,
1772
				       unsigned src_layer,
1773
				       unsigned sample_mask,
1774
				       void *custom_blend,
1775
                                       enum pipe_format format)
1776
{
1777
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1778
   struct pipe_context *pipe = ctx->base.pipe;
1779
   struct pipe_framebuffer_state fb_state;
1780
   struct pipe_surface *srcsurf, *dstsurf, surf_tmpl;
1781
 
1782
   blitter_set_running_flag(ctx);
1783
   blitter_check_saved_vertex_states(ctx);
1784
   blitter_check_saved_fragment_states(ctx);
1785
   blitter_disable_render_cond(ctx);
1786
 
1787
   /* bind states */
1788
   pipe->bind_blend_state(pipe, custom_blend);
1789
   pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1790
   pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1791
   ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf);
1792
   pipe->set_sample_mask(pipe, sample_mask);
1793
 
1794
   memset(&surf_tmpl, 0, sizeof(surf_tmpl));
1795
   surf_tmpl.format = format;
1796
   surf_tmpl.u.tex.level = dst_level;
1797
   surf_tmpl.u.tex.first_layer = dst_layer;
1798
   surf_tmpl.u.tex.last_layer = dst_layer;
1799
 
1800
   dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl);
1801
 
1802
   surf_tmpl.u.tex.level = 0;
1803
   surf_tmpl.u.tex.first_layer = src_layer;
1804
   surf_tmpl.u.tex.last_layer = src_layer;
1805
 
1806
   srcsurf = pipe->create_surface(pipe, src, &surf_tmpl);
1807
 
1808
   /* set a framebuffer state */
1809
   fb_state.width = src->width0;
1810
   fb_state.height = src->height0;
1811
   fb_state.nr_cbufs = 2;
1812
   fb_state.cbufs[0] = srcsurf;
1813
   fb_state.cbufs[1] = dstsurf;
1814
   fb_state.zsbuf = NULL;
1815
   pipe->set_framebuffer_state(pipe, &fb_state);
1816
 
1817
   blitter_set_common_draw_rect_state(ctx, FALSE);
1818
   blitter_set_dst_dimensions(ctx, src->width0, src->height0);
1819
   blitter->draw_rectangle(blitter, 0, 0, src->width0, src->height0,
1820
                           0, 0, NULL);
1821
   blitter_restore_fb_state(ctx);
1822
   blitter_restore_vertex_states(ctx);
1823
   blitter_restore_fragment_states(ctx);
1824
   blitter_restore_render_cond(ctx);
1825
   blitter_unset_running_flag(ctx);
1826
 
1827
   pipe_surface_reference(&srcsurf, NULL);
1828
   pipe_surface_reference(&dstsurf, NULL);
1829
}
1830
 
1831
void util_blitter_custom_color(struct blitter_context *blitter,
1832
                               struct pipe_surface *dstsurf,
1833
                               void *custom_blend)
1834
{
1835
   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1836
   struct pipe_context *pipe = ctx->base.pipe;
1837
   struct pipe_framebuffer_state fb_state;
1838
 
1839
   assert(dstsurf->texture);
1840
   if (!dstsurf->texture)
1841
      return;
1842
 
1843
   /* check the saved state */
1844
   blitter_set_running_flag(ctx);
1845
   blitter_check_saved_vertex_states(ctx);
1846
   blitter_check_saved_fragment_states(ctx);
1847
   blitter_check_saved_fb_state(ctx);
1848
   blitter_disable_render_cond(ctx);
1849
 
1850
   /* bind states */
1851
   pipe->bind_blend_state(pipe, custom_blend ? custom_blend
1852
                                             : ctx->blend[PIPE_MASK_RGBA]);
1853
   pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1854
   ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf);
1855
   pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1856
   pipe->set_sample_mask(pipe, (1ull << MAX2(1, dstsurf->texture->nr_samples)) - 1);
1857
 
1858
   /* set a framebuffer state */
1859
   fb_state.width = dstsurf->width;
1860
   fb_state.height = dstsurf->height;
1861
   fb_state.nr_cbufs = 1;
1862
   fb_state.cbufs[0] = dstsurf;
1863
   fb_state.zsbuf = 0;
1864
   pipe->set_framebuffer_state(pipe, &fb_state);
1865
   pipe->set_sample_mask(pipe, ~0);
1866
 
1867
   blitter_set_common_draw_rect_state(ctx, FALSE);
1868
   blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
1869
   blitter->draw_rectangle(blitter, 0, 0, dstsurf->width, dstsurf->height,
1870
                           0, 0, NULL);
1871
 
1872
   blitter_restore_vertex_states(ctx);
1873
   blitter_restore_fragment_states(ctx);
1874
   blitter_restore_fb_state(ctx);
1875
   blitter_restore_render_cond(ctx);
1876
   blitter_unset_running_flag(ctx);
1877
}