u_blitter.h revision 7ec681f3
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#ifndef U_BLITTER_H
28#define U_BLITTER_H
29
30#include "util/u_framebuffer.h"
31#include "util/u_inlines.h"
32
33#include "pipe/p_state.h"
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39struct pipe_context;
40
41enum blitter_attrib_type {
42   UTIL_BLITTER_ATTRIB_NONE,
43   UTIL_BLITTER_ATTRIB_COLOR,
44   UTIL_BLITTER_ATTRIB_TEXCOORD_XY,
45   UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW,
46};
47
48union blitter_attrib {
49   float color[4];
50
51   struct {
52      float x1, y1, x2, y2, z, w;
53   } texcoord;
54};
55
56struct blitter_context;
57
58typedef void *(*blitter_get_vs_func)(struct blitter_context *blitter);
59
60struct blitter_context
61{
62   /**
63    * Draw a rectangle.
64    *
65    * \param get_vs  Callback for obtaining the vertex shader for the draw call.
66    *                It might invoke the shader compiler. The driver is
67    *                responsible for setting the vertex shader, and the callback
68    *                allows the driver to query the vertex shader CSO if it
69    *                wants to use the default one.
70    * \param x1      An X coordinate of the top-left corner.
71    * \param y1      A Y coordinate of the top-left corner.
72    * \param x2      An X coordinate of the bottom-right corner.
73    * \param y2      A Y coordinate of the bottom-right corner.
74    * \param depth   A depth which the rectangle is rendered at.
75    *
76    * \param type   Semantics of the attributes "attrib".
77    *               If type is UTIL_BLITTER_ATTRIB_NONE, ignore them.
78    *               If type is UTIL_BLITTER_ATTRIB_COLOR, the attributes
79    *               make up a constant RGBA color, and should go
80    *               to the GENERIC0 varying slot of a fragment shader.
81    *               If type is UTIL_BLITTER_ATTRIB_TEXCOORD, {a1, a2} and
82    *               {a3, a4} specify top-left and bottom-right texture
83    *               coordinates of the rectangle, respectively, and should go
84    *               to the GENERIC0 varying slot of a fragment shader.
85    *
86    * \param attrib See type.
87    *
88    * \note A driver may optionally override this callback to implement
89    *       a specialized hardware path for drawing a rectangle, e.g. using
90    *       a rectangular point sprite.
91    */
92   void (*draw_rectangle)(struct blitter_context *blitter,
93                          void *vertex_elements_cso,
94                          blitter_get_vs_func get_vs,
95                          int x1, int y1, int x2, int y2,
96                          float depth, unsigned num_instances,
97                          enum blitter_attrib_type type,
98                          const union blitter_attrib *attrib);
99
100   /* Whether the blitter is running. */
101   bool running;
102
103   bool use_index_buffer;
104
105   /* Private members, really. */
106   struct pipe_context *pipe; /**< pipe context */
107
108   void *saved_blend_state;   /**< blend state */
109   void *saved_dsa_state;     /**< depth stencil alpha state */
110   void *saved_velem_state;   /**< vertex elements state */
111   void *saved_rs_state;      /**< rasterizer state */
112   void *saved_fs, *saved_vs, *saved_gs, *saved_tcs, *saved_tes; /**< shaders */
113
114   struct pipe_framebuffer_state saved_fb_state;  /**< framebuffer state */
115   struct pipe_stencil_ref saved_stencil_ref;     /**< stencil ref */
116   struct pipe_viewport_state saved_viewport;
117   struct pipe_scissor_state saved_scissor;
118   bool skip_viewport_restore;
119   bool is_sample_mask_saved;
120   unsigned saved_sample_mask;
121
122   unsigned saved_num_sampler_states;
123   void *saved_sampler_states[PIPE_MAX_SAMPLERS];
124
125   unsigned saved_num_sampler_views;
126   struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS];
127
128   unsigned cb_slot;
129   struct pipe_constant_buffer saved_fs_constant_buffer;
130
131   unsigned vb_slot;
132   struct pipe_vertex_buffer saved_vertex_buffer;
133
134   unsigned saved_num_so_targets;
135   struct pipe_stream_output_target *saved_so_targets[PIPE_MAX_SO_BUFFERS];
136
137   struct pipe_query *saved_render_cond_query;
138   uint saved_render_cond_mode;
139   bool saved_render_cond_cond;
140
141   boolean saved_window_rectangles_include;
142   unsigned saved_num_window_rectangles;
143   struct pipe_scissor_state saved_window_rectangles[PIPE_MAX_WINDOW_RECTANGLES];
144};
145
146/**
147 * Create a blitter context.
148 */
149struct blitter_context *util_blitter_create(struct pipe_context *pipe);
150
151/**
152 * Destroy a blitter context.
153 */
154void util_blitter_destroy(struct blitter_context *blitter);
155
156void util_blitter_cache_all_shaders(struct blitter_context *blitter);
157void *util_blitter_get_noop_blend_state(struct blitter_context *blitter);
158void *util_blitter_get_noop_dsa_state(struct blitter_context *blitter);
159void *util_blitter_get_discard_rasterizer_state(struct blitter_context *blitter);
160
161
162/**
163 * Return the pipe context associated with a blitter context.
164 */
165static inline
166struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter)
167{
168   return blitter->pipe;
169}
170
171/**
172 * Override PIPE_CAP_TEXTURE_MULTISAMPLE as reported by the driver.
173 */
174void util_blitter_set_texture_multisample(struct blitter_context *blitter,
175                                          bool supported);
176
177/* The default function to draw a rectangle. This can only be used
178 * inside of the draw_rectangle callback if the driver overrides it. */
179void util_blitter_draw_rectangle(struct blitter_context *blitter,
180                                 void *vertex_elements_cso,
181                                 blitter_get_vs_func get_vs,
182                                 int x1, int y1, int x2, int y2,
183                                 float depth, unsigned num_instances,
184                                 enum blitter_attrib_type type,
185                                 const union blitter_attrib *attrib);
186
187
188/*
189 * These states must be saved before any of the following functions are called:
190 * - vertex buffers
191 * - vertex elements
192 * - vertex shader
193 * - geometry shader (if supported)
194 * - stream output targets (if supported)
195 * - rasterizer state
196 */
197
198/**
199 * Clear a specified set of currently bound buffers to specified values.
200 *
201 * These states must be saved in the blitter in addition to the state objects
202 * already required to be saved:
203 * - fragment shader
204 * - depth stencil alpha state
205 * - blend state
206 */
207void util_blitter_clear(struct blitter_context *blitter,
208                        unsigned width, unsigned height, unsigned num_layers,
209                        unsigned clear_buffers,
210                        const union pipe_color_union *color,
211                        double depth, unsigned stencil,
212                        bool msaa);
213
214/**
215 * Check if the blitter (with the help of the driver) can blit between
216 * the two resources.
217 */
218bool util_blitter_is_copy_supported(struct blitter_context *blitter,
219                                    const struct pipe_resource *dst,
220                                    const struct pipe_resource *src);
221
222bool util_blitter_is_blit_supported(struct blitter_context *blitter,
223				    const struct pipe_blit_info *info);
224
225/**
226 * Copy a block of pixels from one surface to another.
227 *
228 * These states must be saved in the blitter in addition to the state objects
229 * already required to be saved:
230 * - fragment shader
231 * - depth stencil alpha state
232 * - blend state
233 * - fragment sampler states
234 * - fragment sampler textures
235 * - framebuffer state
236 * - sample mask
237 */
238void util_blitter_copy_texture(struct blitter_context *blitter,
239                               struct pipe_resource *dst,
240                               unsigned dst_level,
241                               unsigned dstx, unsigned dsty, unsigned dstz,
242                               struct pipe_resource *src,
243                               unsigned src_level,
244                               const struct pipe_box *srcbox);
245
246/**
247 * This is a generic implementation of pipe->blit, which accepts
248 * sampler/surface views instead of resources.
249 *
250 * The layer and mipmap level are specified by the views.
251 *
252 * Drivers can use this to change resource properties (like format, width,
253 * height) by changing how the views interpret them, instead of changing
254 * pipe_resource directly. This is used to blit resources of formats which
255 * are not renderable.
256 *
257 * src_width0 and src_height0 are sampler_view-private properties that
258 * override pipe_resource. The blitter uses them for computation of texture
259 * coordinates. The dst dimensions are supplied through pipe_surface::width
260 * and height.
261 *
262 * The mask is a combination of the PIPE_MASK_* flags.
263 * Set to PIPE_MASK_RGBAZS if unsure.
264 */
265void util_blitter_blit_generic(struct blitter_context *blitter,
266                               struct pipe_surface *dst,
267                               const struct pipe_box *dstbox,
268                               struct pipe_sampler_view *src,
269                               const struct pipe_box *srcbox,
270                               unsigned src_width0, unsigned src_height0,
271                               unsigned mask, unsigned filter,
272                               const struct pipe_scissor_state *scissor,
273                               bool alpha_blend, bool sample0_only);
274
275void util_blitter_blit(struct blitter_context *blitter,
276		       const struct pipe_blit_info *info);
277
278void util_blitter_generate_mipmap(struct blitter_context *blitter,
279                                  struct pipe_resource *tex,
280                                  enum pipe_format format,
281                                  unsigned base_level, unsigned last_level,
282                                  unsigned first_layer, unsigned last_layer);
283
284/**
285 * Helper function to initialize a view for copy_texture_view.
286 * The parameters must match copy_texture_view.
287 */
288void util_blitter_default_dst_texture(struct pipe_surface *dst_templ,
289                                      struct pipe_resource *dst,
290                                      unsigned dstlevel,
291                                      unsigned dstz);
292
293/**
294 * Helper function to initialize a view for copy_texture_view.
295 * The parameters must match copy_texture_view.
296 */
297void util_blitter_default_src_texture(struct blitter_context *blitter,
298                                      struct pipe_sampler_view *src_templ,
299                                      struct pipe_resource *src,
300                                      unsigned srclevel);
301
302/**
303 * Copy data from one buffer to another using the Stream Output functionality.
304 * 4-byte alignment is required, otherwise software fallback is used.
305 */
306void util_blitter_copy_buffer(struct blitter_context *blitter,
307                              struct pipe_resource *dst,
308                              unsigned dstx,
309                              struct pipe_resource *src,
310                              unsigned srcx,
311                              unsigned size);
312
313/**
314 * Clear the contents of a buffer using the Stream Output functionality.
315 * 4-byte alignment is required.
316 *
317 * "num_channels" can be 1, 2, 3, or 4, and specifies if the clear value is
318 * R, RG, RGB, or RGBA.
319 *
320 * For each element, only "num_channels" components of "clear_value" are
321 * copied to the buffer, then the offset is incremented by num_channels*4.
322 */
323void util_blitter_clear_buffer(struct blitter_context *blitter,
324                               struct pipe_resource *dst,
325                               unsigned offset, unsigned size,
326                               unsigned num_channels,
327                               const union pipe_color_union *clear_value);
328
329/**
330 * Clear a region of a (color) surface to a constant value.
331 *
332 * These states must be saved in the blitter in addition to the state objects
333 * already required to be saved:
334 * - fragment shader
335 * - depth stencil alpha state
336 * - blend state
337 * - framebuffer state
338 */
339void util_blitter_clear_render_target(struct blitter_context *blitter,
340                                      struct pipe_surface *dst,
341                                      const union pipe_color_union *color,
342                                      unsigned dstx, unsigned dsty,
343                                      unsigned width, unsigned height);
344
345/**
346 * Clear a region of a depth-stencil surface, both stencil and depth
347 * or only one of them if this is a combined depth-stencil surface.
348 *
349 * These states must be saved in the blitter in addition to the state objects
350 * already required to be saved:
351 * - fragment shader
352 * - depth stencil alpha state
353 * - blend state
354 * - framebuffer state
355 */
356void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
357                                      struct pipe_surface *dst,
358                                      unsigned clear_flags,
359                                      double depth,
360                                      unsigned stencil,
361                                      unsigned dstx, unsigned dsty,
362                                      unsigned width, unsigned height);
363
364/* The following functions are customized variants of the clear functions.
365 * Some drivers use them internally to do things like MSAA resolve
366 * and resource decompression. It usually consists of rendering a full-screen
367 * quad with a special blend or DSA state.
368 */
369
370/* Used by r300g for depth decompression. */
371void util_blitter_custom_clear_depth(struct blitter_context *blitter,
372                                     unsigned width, unsigned height,
373                                     double depth, void *custom_dsa);
374
375/* Used by r600g for depth decompression. */
376void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
377				       struct pipe_surface *zsurf,
378				       struct pipe_surface *cbsurf,
379				       unsigned sample_mask,
380				       void *dsa_stage, float depth);
381
382/* Used by r600g for color decompression. */
383void util_blitter_custom_color(struct blitter_context *blitter,
384                               struct pipe_surface *dstsurf,
385                               void *custom_blend);
386
387/* Used by r600g for MSAA color resolve. */
388void util_blitter_custom_resolve_color(struct blitter_context *blitter,
389                                       struct pipe_resource *dst,
390                                       unsigned dst_level,
391                                       unsigned dst_layer,
392                                       struct pipe_resource *src,
393                                       unsigned src_layer,
394				       unsigned sampled_mask,
395                                       void *custom_blend,
396                                       enum pipe_format format);
397
398/* Used by vc4 for 8/16-bit linear-to-tiled blits */
399void util_blitter_custom_shader(struct blitter_context *blitter,
400                                struct pipe_surface *dstsurf,
401                                void *custom_vs, void *custom_fs);
402
403/* Used by D3D12 for non-MSAA -> MSAA stencil blits */
404void util_blitter_stencil_fallback(struct blitter_context *blitter,
405                                   struct pipe_resource *dst,
406                                   unsigned dst_level,
407                                   const struct pipe_box *dstbox,
408                                   struct pipe_resource *src,
409                                   unsigned src_level,
410                                   const struct pipe_box *srcbox,
411                                   const struct pipe_scissor_state *scissor);
412
413/* The functions below should be used to save currently bound constant state
414 * objects inside a driver. The objects are automatically restored at the end
415 * of the util_blitter_{clear, copy_region, fill_region} functions and then
416 * forgotten.
417 *
418 * States not listed here are not affected by util_blitter. */
419
420static inline void
421util_blitter_save_blend(struct blitter_context *blitter, void *state)
422{
423   blitter->saved_blend_state = state;
424}
425
426static inline void
427util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter,
428                                      void *state)
429{
430   blitter->saved_dsa_state = state;
431}
432
433static inline void
434util_blitter_save_vertex_elements(struct blitter_context *blitter, void *state)
435{
436   blitter->saved_velem_state = state;
437}
438
439static inline void
440util_blitter_save_stencil_ref(struct blitter_context *blitter,
441                              const struct pipe_stencil_ref *state)
442{
443   blitter->saved_stencil_ref = *state;
444}
445
446static inline void
447util_blitter_save_rasterizer(struct blitter_context *blitter, void *state)
448{
449   blitter->saved_rs_state = state;
450}
451
452static inline void
453util_blitter_save_fragment_shader(struct blitter_context *blitter, void *fs)
454{
455   blitter->saved_fs = fs;
456}
457
458static inline void
459util_blitter_save_vertex_shader(struct blitter_context *blitter, void *vs)
460{
461   blitter->saved_vs = vs;
462}
463
464static inline void
465util_blitter_save_geometry_shader(struct blitter_context *blitter, void *gs)
466{
467   blitter->saved_gs = gs;
468}
469
470static inline void
471util_blitter_save_tessctrl_shader(struct blitter_context *blitter,
472                                  void *sh)
473{
474   blitter->saved_tcs = sh;
475}
476
477static inline void
478util_blitter_save_tesseval_shader(struct blitter_context *blitter,
479                                  void *sh)
480{
481   blitter->saved_tes = sh;
482}
483
484static inline void
485util_blitter_save_framebuffer(struct blitter_context *blitter,
486                              const struct pipe_framebuffer_state *state)
487{
488   blitter->saved_fb_state.nr_cbufs = 0; /* It's ~0 now, meaning it's unsaved. */
489   util_copy_framebuffer_state(&blitter->saved_fb_state, state);
490}
491
492static inline void
493util_blitter_save_viewport(struct blitter_context *blitter,
494                           struct pipe_viewport_state *state)
495{
496   blitter->saved_viewport = *state;
497}
498
499static inline void
500util_blitter_save_scissor(struct blitter_context *blitter,
501                          struct pipe_scissor_state *state)
502{
503   blitter->saved_scissor = *state;
504}
505
506static inline void
507util_blitter_save_fragment_sampler_states(
508                  struct blitter_context *blitter,
509                  unsigned num_sampler_states,
510                  void **sampler_states)
511{
512   assert(num_sampler_states <= ARRAY_SIZE(blitter->saved_sampler_states));
513
514   blitter->saved_num_sampler_states = num_sampler_states;
515   memcpy(blitter->saved_sampler_states, sampler_states,
516          num_sampler_states * sizeof(void *));
517}
518
519static inline void
520util_blitter_save_fragment_sampler_views(struct blitter_context *blitter,
521                                         unsigned num_views,
522                                         struct pipe_sampler_view **views)
523{
524   unsigned i;
525   assert(num_views <= ARRAY_SIZE(blitter->saved_sampler_views));
526
527   blitter->saved_num_sampler_views = num_views;
528   for (i = 0; i < num_views; i++)
529      pipe_sampler_view_reference(&blitter->saved_sampler_views[i],
530                                  views[i]);
531}
532
533static inline void
534util_blitter_save_fragment_constant_buffer_slot(
535                  struct blitter_context *blitter,
536                  struct pipe_constant_buffer *constant_buffers)
537{
538   pipe_resource_reference(&blitter->saved_fs_constant_buffer.buffer,
539                           constant_buffers[blitter->cb_slot].buffer);
540   memcpy(&blitter->saved_fs_constant_buffer, &constant_buffers[blitter->cb_slot],
541          sizeof(struct pipe_constant_buffer));
542}
543
544static inline void
545util_blitter_save_vertex_buffer_slot(struct blitter_context *blitter,
546                                     struct pipe_vertex_buffer *vertex_buffers)
547{
548   pipe_vertex_buffer_reference(&blitter->saved_vertex_buffer,
549                                &vertex_buffers[blitter->vb_slot]);
550}
551
552static inline void
553util_blitter_save_so_targets(struct blitter_context *blitter,
554                             unsigned num_targets,
555                             struct pipe_stream_output_target **targets)
556{
557   unsigned i;
558   assert(num_targets <= ARRAY_SIZE(blitter->saved_so_targets));
559
560   blitter->saved_num_so_targets = num_targets;
561   for (i = 0; i < num_targets; i++)
562      pipe_so_target_reference(&blitter->saved_so_targets[i],
563                               targets[i]);
564}
565
566static inline void
567util_blitter_save_sample_mask(struct blitter_context *blitter,
568                              unsigned sample_mask)
569{
570   blitter->is_sample_mask_saved = true;
571   blitter->saved_sample_mask = sample_mask;
572}
573
574static inline void
575util_blitter_save_render_condition(struct blitter_context *blitter,
576                                   struct pipe_query *query,
577                                   bool condition,
578                                   enum pipe_render_cond_flag mode)
579{
580   blitter->saved_render_cond_query = query;
581   blitter->saved_render_cond_mode = mode;
582   blitter->saved_render_cond_cond = condition;
583}
584
585static inline void
586util_blitter_save_window_rectangles(struct blitter_context *blitter,
587                                    boolean include,
588                                    unsigned num_rectangles,
589                                    const struct pipe_scissor_state *rects)
590{
591   blitter->saved_window_rectangles_include = include;
592   blitter->saved_num_window_rectangles = num_rectangles;
593   if (num_rectangles > 0) {
594      assert(num_rectangles < ARRAY_SIZE(blitter->saved_window_rectangles));
595      memcpy(blitter->saved_window_rectangles, rects,
596             sizeof(*rects) * num_rectangles);
597   }
598}
599
600void util_blitter_common_clear_setup(struct blitter_context *blitter,
601                                     unsigned width, unsigned height,
602                                     unsigned clear_buffers,
603                                     void *custom_blend, void *custom_dsa);
604
605void util_blitter_set_running_flag(struct blitter_context *blitter);
606void util_blitter_unset_running_flag(struct blitter_context *blitter);
607
608void util_blitter_restore_vertex_states(struct blitter_context *blitter);
609void util_blitter_restore_fragment_states(struct blitter_context *blitter);
610void util_blitter_restore_render_cond(struct blitter_context *blitter);
611void util_blitter_restore_fb_state(struct blitter_context *blitter);
612void util_blitter_restore_textures(struct blitter_context *blitter);
613void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter);
614
615/* These are supported combinations of blits from ZS to color and vice versa.
616 * The blitter will do the packing/unpacking of depth and stencil
617 * in the fragment shader.
618 */
619static inline enum pipe_format
620util_blitter_get_color_format_for_zs(enum pipe_format format)
621{
622   switch (format) {
623   case PIPE_FORMAT_Z16_UNORM:
624      return PIPE_FORMAT_R16_UNORM;
625
626   case PIPE_FORMAT_Z32_FLOAT:
627      return PIPE_FORMAT_R32_FLOAT;
628
629   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
630   case PIPE_FORMAT_Z24X8_UNORM:
631   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
632   case PIPE_FORMAT_X8Z24_UNORM:
633      return PIPE_FORMAT_R32_UINT;
634
635   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
636      return PIPE_FORMAT_R32G32_UINT;
637
638   case PIPE_FORMAT_Z32_UNORM:
639   default:
640      assert(0);
641   }
642   return PIPE_FORMAT_NONE;
643}
644
645#ifdef __cplusplus
646}
647#endif
648
649#endif
650