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