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