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