u_blitter.h revision af69d88d
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/* u_memory.h conflicts with st/mesa */
36#ifndef Elements
37#define Elements(x) (sizeof(x)/sizeof((x)[0]))
38#endif
39
40
41#ifdef __cplusplus
42extern "C" {
43#endif
44
45struct pipe_context;
46
47enum blitter_attrib_type {
48   UTIL_BLITTER_ATTRIB_NONE,
49   UTIL_BLITTER_ATTRIB_COLOR,
50   UTIL_BLITTER_ATTRIB_TEXCOORD
51};
52
53struct blitter_context
54{
55   /**
56    * Draw a rectangle.
57    *
58    * \param x1      An X coordinate of the top-left corner.
59    * \param y1      A Y coordinate of the top-left corner.
60    * \param x2      An X coordinate of the bottom-right corner.
61    * \param y2      A Y coordinate of the bottom-right corner.
62    * \param depth   A depth which the rectangle is rendered at.
63    *
64    * \param type   Semantics of the attributes "attrib".
65    *               If type is UTIL_BLITTER_ATTRIB_NONE, ignore them.
66    *               If type is UTIL_BLITTER_ATTRIB_COLOR, the attributes
67    *               make up a constant RGBA color, and should go
68    *               to the GENERIC0 varying slot of a fragment shader.
69    *               If type is UTIL_BLITTER_ATTRIB_TEXCOORD, {a1, a2} and
70    *               {a3, a4} specify top-left and bottom-right texture
71    *               coordinates of the rectangle, respectively, and should go
72    *               to the GENERIC0 varying slot of a fragment shader.
73    *
74    * \param attrib See type.
75    *
76    * \note A driver may optionally override this callback to implement
77    *       a specialized hardware path for drawing a rectangle, e.g. using
78    *       a rectangular point sprite.
79    */
80   void (*draw_rectangle)(struct blitter_context *blitter,
81                          int x1, int y1, int x2, int y2,
82                          float depth,
83                          enum blitter_attrib_type type,
84                          const union pipe_color_union *color);
85
86   /**
87    * Get the next surface layer for the pipe surface, i.e. make a copy
88    * of the surface and increment the first and last layer by 1.
89    *
90    * This callback is exposed, so that drivers can override it if needed.
91    */
92   struct pipe_surface *(*get_next_surface_layer)(struct pipe_context *pipe,
93                                                  struct pipe_surface *surf);
94
95   /* Whether the blitter is running. */
96   boolean running;
97
98   /* Private members, really. */
99   struct pipe_context *pipe; /**< pipe context */
100
101   void *saved_blend_state;   /**< blend state */
102   void *saved_dsa_state;     /**< depth stencil alpha state */
103   void *saved_velem_state;   /**< vertex elements state */
104   void *saved_rs_state;      /**< rasterizer state */
105   void *saved_fs, *saved_vs, *saved_gs; /**< shaders */
106
107   struct pipe_framebuffer_state saved_fb_state;  /**< framebuffer state */
108   struct pipe_stencil_ref saved_stencil_ref;     /**< stencil ref */
109   struct pipe_viewport_state saved_viewport;
110   struct pipe_scissor_state saved_scissor;
111   boolean is_sample_mask_saved;
112   unsigned saved_sample_mask;
113
114   unsigned saved_num_sampler_states;
115   void *saved_sampler_states[PIPE_MAX_SAMPLERS];
116
117   unsigned saved_num_sampler_views;
118   struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS];
119
120   unsigned vb_slot;
121   struct pipe_vertex_buffer saved_vertex_buffer;
122
123   unsigned saved_num_so_targets;
124   struct pipe_stream_output_target *saved_so_targets[PIPE_MAX_SO_BUFFERS];
125
126   struct pipe_query *saved_render_cond_query;
127   uint saved_render_cond_mode;
128   boolean saved_render_cond_cond;
129};
130
131/**
132 * Create a blitter context.
133 */
134struct blitter_context *util_blitter_create(struct pipe_context *pipe);
135
136/**
137 * Destroy a blitter context.
138 */
139void util_blitter_destroy(struct blitter_context *blitter);
140
141void util_blitter_cache_all_shaders(struct blitter_context *blitter);
142
143/**
144 * Return the pipe context associated with a blitter context.
145 */
146static INLINE
147struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter)
148{
149   return blitter->pipe;
150}
151
152/**
153 * Override PIPE_CAP_TEXTURE_MULTISAMPLE as reported by the driver.
154 */
155void util_blitter_set_texture_multisample(struct blitter_context *blitter,
156                                          boolean supported);
157
158/* The default function to draw a rectangle. This can only be used
159 * inside of the draw_rectangle callback if the driver overrides it. */
160void util_blitter_draw_rectangle(struct blitter_context *blitter,
161                                 int x1, int y1, int x2, int y2, float depth,
162                                 enum blitter_attrib_type type,
163                                 const union pipe_color_union *attrib);
164
165
166/*
167 * These states must be saved before any of the following functions are called:
168 * - vertex buffers
169 * - vertex elements
170 * - vertex shader
171 * - geometry shader (if supported)
172 * - stream output targets (if supported)
173 * - rasterizer state
174 */
175
176/**
177 * Clear a specified set of currently bound buffers to specified values.
178 *
179 * These states must be saved in the blitter in addition to the state objects
180 * already required to be saved:
181 * - fragment shader
182 * - depth stencil alpha state
183 * - blend state
184 */
185void util_blitter_clear(struct blitter_context *blitter,
186                        unsigned width, unsigned height, unsigned num_layers,
187                        unsigned clear_buffers,
188                        const union pipe_color_union *color,
189                        double depth, unsigned stencil);
190
191/**
192 * Check if the blitter (with the help of the driver) can blit between
193 * the two resources.
194 */
195boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
196                                       const struct pipe_resource *dst,
197                                       const struct pipe_resource *src);
198
199boolean util_blitter_is_blit_supported(struct blitter_context *blitter,
200				       const struct pipe_blit_info *info);
201
202/**
203 * Copy a block of pixels from one surface to another.
204 *
205 * These states must be saved in the blitter in addition to the state objects
206 * already required to be saved:
207 * - fragment shader
208 * - depth stencil alpha state
209 * - blend state
210 * - fragment sampler states
211 * - fragment sampler textures
212 * - framebuffer state
213 * - sample mask
214 */
215void util_blitter_copy_texture(struct blitter_context *blitter,
216                               struct pipe_resource *dst,
217                               unsigned dst_level,
218                               unsigned dstx, unsigned dsty, unsigned dstz,
219                               struct pipe_resource *src,
220                               unsigned src_level,
221                               const struct pipe_box *srcbox);
222
223/**
224 * This is a generic implementation of pipe->blit, which accepts
225 * sampler/surface views instead of resources.
226 *
227 * The layer and mipmap level are specified by the views.
228 *
229 * Drivers can use this to change resource properties (like format, width,
230 * height) by changing how the views interpret them, instead of changing
231 * pipe_resource directly. This is used to blit resources of formats which
232 * are not renderable.
233 *
234 * src_width0 and src_height0 are sampler_view-private properties that
235 * override pipe_resource. The blitter uses them for computation of texture
236 * coordinates. The dst dimensions are supplied through pipe_surface::width
237 * and height.
238 *
239 * The mask is a combination of the PIPE_MASK_* flags.
240 * Set to PIPE_MASK_RGBAZS if unsure.
241 */
242void util_blitter_blit_generic(struct blitter_context *blitter,
243                               struct pipe_surface *dst,
244                               const struct pipe_box *dstbox,
245                               struct pipe_sampler_view *src,
246                               const struct pipe_box *srcbox,
247                               unsigned src_width0, unsigned src_height0,
248                               unsigned mask, unsigned filter,
249                               const struct pipe_scissor_state *scissor);
250
251void util_blitter_blit(struct blitter_context *blitter,
252		       const struct pipe_blit_info *info);
253
254/**
255 * Helper function to initialize a view for copy_texture_view.
256 * The parameters must match copy_texture_view.
257 */
258void util_blitter_default_dst_texture(struct pipe_surface *dst_templ,
259                                      struct pipe_resource *dst,
260                                      unsigned dstlevel,
261                                      unsigned dstz);
262
263/**
264 * Helper function to initialize a view for copy_texture_view.
265 * The parameters must match copy_texture_view.
266 */
267void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ,
268                                      struct pipe_resource *src,
269                                      unsigned srclevel);
270
271/**
272 * Copy data from one buffer to another using the Stream Output functionality.
273 * 4-byte alignment is required, otherwise software fallback is used.
274 */
275void util_blitter_copy_buffer(struct blitter_context *blitter,
276                              struct pipe_resource *dst,
277                              unsigned dstx,
278                              struct pipe_resource *src,
279                              unsigned srcx,
280                              unsigned size);
281
282/**
283 * Clear the contents of a buffer using the Stream Output functionality.
284 * 4-byte alignment is required.
285 *
286 * "num_channels" can be 1, 2, 3, or 4, and specifies if the clear value is
287 * R, RG, RGB, or RGBA.
288 *
289 * For each element, only "num_channels" components of "clear_value" are
290 * copied to the buffer, then the offset is incremented by num_channels*4.
291 */
292void util_blitter_clear_buffer(struct blitter_context *blitter,
293                               struct pipe_resource *dst,
294                               unsigned offset, unsigned size,
295                               unsigned num_channels,
296                               const union pipe_color_union *clear_value);
297
298/**
299 * Clear a region of a (color) surface to a constant value.
300 *
301 * These states must be saved in the blitter in addition to the state objects
302 * already required to be saved:
303 * - fragment shader
304 * - depth stencil alpha state
305 * - blend state
306 * - framebuffer state
307 */
308void util_blitter_clear_render_target(struct blitter_context *blitter,
309                                      struct pipe_surface *dst,
310                                      const union pipe_color_union *color,
311                                      unsigned dstx, unsigned dsty,
312                                      unsigned width, unsigned height);
313
314/**
315 * Clear a region of a depth-stencil surface, both stencil and depth
316 * or only one of them if this is a combined depth-stencil surface.
317 *
318 * These states must be saved in the blitter in addition to the state objects
319 * already required to be saved:
320 * - fragment shader
321 * - depth stencil alpha state
322 * - blend state
323 * - framebuffer state
324 */
325void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
326                                      struct pipe_surface *dst,
327                                      unsigned clear_flags,
328                                      double depth,
329                                      unsigned stencil,
330                                      unsigned dstx, unsigned dsty,
331                                      unsigned width, unsigned height);
332
333/* The following functions are customized variants of the clear functions.
334 * Some drivers use them internally to do things like MSAA resolve
335 * and resource decompression. It usually consists of rendering a full-screen
336 * quad with a special blend or DSA state.
337 */
338
339/* Used by r300g for depth decompression. */
340void util_blitter_custom_clear_depth(struct blitter_context *blitter,
341                                     unsigned width, unsigned height,
342                                     double depth, void *custom_dsa);
343
344/* Used by r600g for depth decompression. */
345void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
346				       struct pipe_surface *zsurf,
347				       struct pipe_surface *cbsurf,
348				       unsigned sample_mask,
349				       void *dsa_stage, float depth);
350
351/* Used by r600g for color decompression. */
352void util_blitter_custom_color(struct blitter_context *blitter,
353                               struct pipe_surface *dstsurf,
354                               void *custom_blend);
355
356/* Used by r600g for MSAA color resolve. */
357void util_blitter_custom_resolve_color(struct blitter_context *blitter,
358                                       struct pipe_resource *dst,
359                                       unsigned dst_level,
360                                       unsigned dst_layer,
361                                       struct pipe_resource *src,
362                                       unsigned src_layer,
363				       unsigned sampled_mask,
364                                       void *custom_blend,
365                                       enum pipe_format format);
366
367/* The functions below should be used to save currently bound constant state
368 * objects inside a driver. The objects are automatically restored at the end
369 * of the util_blitter_{clear, copy_region, fill_region} functions and then
370 * forgotten.
371 *
372 * States not listed here are not affected by util_blitter. */
373
374static INLINE
375void util_blitter_save_blend(struct blitter_context *blitter,
376                             void *state)
377{
378   blitter->saved_blend_state = state;
379}
380
381static INLINE
382void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter,
383                                           void *state)
384{
385   blitter->saved_dsa_state = state;
386}
387
388static INLINE
389void util_blitter_save_vertex_elements(struct blitter_context *blitter,
390                                       void *state)
391{
392   blitter->saved_velem_state = state;
393}
394
395static INLINE
396void util_blitter_save_stencil_ref(struct blitter_context *blitter,
397                                   const struct pipe_stencil_ref *state)
398{
399   blitter->saved_stencil_ref = *state;
400}
401
402static INLINE
403void util_blitter_save_rasterizer(struct blitter_context *blitter,
404                                  void *state)
405{
406   blitter->saved_rs_state = state;
407}
408
409static INLINE
410void util_blitter_save_fragment_shader(struct blitter_context *blitter,
411                                       void *fs)
412{
413   blitter->saved_fs = fs;
414}
415
416static INLINE
417void util_blitter_save_vertex_shader(struct blitter_context *blitter,
418                                     void *vs)
419{
420   blitter->saved_vs = vs;
421}
422
423static INLINE
424void util_blitter_save_geometry_shader(struct blitter_context *blitter,
425                                       void *gs)
426{
427   blitter->saved_gs = gs;
428}
429
430static INLINE
431void util_blitter_save_framebuffer(struct blitter_context *blitter,
432                                   const struct pipe_framebuffer_state *state)
433{
434   blitter->saved_fb_state.nr_cbufs = 0; /* It's ~0 now, meaning it's unsaved. */
435   util_copy_framebuffer_state(&blitter->saved_fb_state, state);
436}
437
438static INLINE
439void util_blitter_save_viewport(struct blitter_context *blitter,
440                                struct pipe_viewport_state *state)
441{
442   blitter->saved_viewport = *state;
443}
444
445static INLINE
446void util_blitter_save_scissor(struct blitter_context *blitter,
447                               struct pipe_scissor_state *state)
448{
449   blitter->saved_scissor = *state;
450}
451
452static INLINE
453void util_blitter_save_fragment_sampler_states(
454                  struct blitter_context *blitter,
455                  unsigned num_sampler_states,
456                  void **sampler_states)
457{
458   assert(num_sampler_states <= Elements(blitter->saved_sampler_states));
459
460   blitter->saved_num_sampler_states = num_sampler_states;
461   memcpy(blitter->saved_sampler_states, sampler_states,
462          num_sampler_states * sizeof(void *));
463}
464
465static INLINE void
466util_blitter_save_fragment_sampler_views(struct blitter_context *blitter,
467                                         unsigned num_views,
468                                         struct pipe_sampler_view **views)
469{
470   unsigned i;
471   assert(num_views <= Elements(blitter->saved_sampler_views));
472
473   blitter->saved_num_sampler_views = num_views;
474   for (i = 0; i < num_views; i++)
475      pipe_sampler_view_reference(&blitter->saved_sampler_views[i],
476                                  views[i]);
477}
478
479static INLINE void
480util_blitter_save_vertex_buffer_slot(struct blitter_context *blitter,
481                                     struct pipe_vertex_buffer *vertex_buffers)
482{
483   pipe_resource_reference(&blitter->saved_vertex_buffer.buffer,
484                           vertex_buffers[blitter->vb_slot].buffer);
485   memcpy(&blitter->saved_vertex_buffer, &vertex_buffers[blitter->vb_slot],
486          sizeof(struct pipe_vertex_buffer));
487}
488
489static INLINE void
490util_blitter_save_so_targets(struct blitter_context *blitter,
491                             unsigned num_targets,
492                             struct pipe_stream_output_target **targets)
493{
494   unsigned i;
495   assert(num_targets <= Elements(blitter->saved_so_targets));
496
497   blitter->saved_num_so_targets = num_targets;
498   for (i = 0; i < num_targets; i++)
499      pipe_so_target_reference(&blitter->saved_so_targets[i],
500                               targets[i]);
501}
502
503static INLINE void
504util_blitter_save_sample_mask(struct blitter_context *blitter,
505                              unsigned sample_mask)
506{
507   blitter->is_sample_mask_saved = TRUE;
508   blitter->saved_sample_mask = sample_mask;
509}
510
511static INLINE void
512util_blitter_save_render_condition(struct blitter_context *blitter,
513                                   struct pipe_query *query,
514                                   boolean condition,
515                                   uint mode)
516{
517   blitter->saved_render_cond_query = query;
518   blitter->saved_render_cond_mode = mode;
519   blitter->saved_render_cond_cond = condition;
520}
521
522#ifdef __cplusplus
523}
524#endif
525
526#endif
527