Path: blob/21.2-virgl/src/gallium/auxiliary/util/u_blitter.h
4561 views
/**************************************************************************1*2* Copyright 2009 Marek Olšák <[email protected]>3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the6* "Software"), to deal in the Software without restriction, including7* without limitation the rights to use, copy, modify, merge, publish,8* distribute, sub license, and/or sell copies of the Software, and to9* permit persons to whom the Software is furnished to do so, subject to10* the following conditions:11*12* The above copyright notice and this permission notice (including the13* next paragraph) shall be included in all copies or substantial portions14* of the Software.15*16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS17* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF18* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.19* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR20* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,21* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE22* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.23*24**************************************************************************/2526#ifndef U_BLITTER_H27#define U_BLITTER_H2829#include "util/u_framebuffer.h"30#include "util/u_inlines.h"3132#include "pipe/p_state.h"3334#ifdef __cplusplus35extern "C" {36#endif3738struct pipe_context;3940enum blitter_attrib_type {41UTIL_BLITTER_ATTRIB_NONE,42UTIL_BLITTER_ATTRIB_COLOR,43UTIL_BLITTER_ATTRIB_TEXCOORD_XY,44UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW,45};4647union blitter_attrib {48float color[4];4950struct {51float x1, y1, x2, y2, z, w;52} texcoord;53};5455struct blitter_context;5657typedef void *(*blitter_get_vs_func)(struct blitter_context *blitter);5859struct blitter_context60{61/**62* Draw a rectangle.63*64* \param get_vs Callback for obtaining the vertex shader for the draw call.65* It might invoke the shader compiler. The driver is66* responsible for setting the vertex shader, and the callback67* allows the driver to query the vertex shader CSO if it68* wants to use the default one.69* \param x1 An X coordinate of the top-left corner.70* \param y1 A Y coordinate of the top-left corner.71* \param x2 An X coordinate of the bottom-right corner.72* \param y2 A Y coordinate of the bottom-right corner.73* \param depth A depth which the rectangle is rendered at.74*75* \param type Semantics of the attributes "attrib".76* If type is UTIL_BLITTER_ATTRIB_NONE, ignore them.77* If type is UTIL_BLITTER_ATTRIB_COLOR, the attributes78* make up a constant RGBA color, and should go79* to the GENERIC0 varying slot of a fragment shader.80* If type is UTIL_BLITTER_ATTRIB_TEXCOORD, {a1, a2} and81* {a3, a4} specify top-left and bottom-right texture82* coordinates of the rectangle, respectively, and should go83* to the GENERIC0 varying slot of a fragment shader.84*85* \param attrib See type.86*87* \note A driver may optionally override this callback to implement88* a specialized hardware path for drawing a rectangle, e.g. using89* a rectangular point sprite.90*/91void (*draw_rectangle)(struct blitter_context *blitter,92void *vertex_elements_cso,93blitter_get_vs_func get_vs,94int x1, int y1, int x2, int y2,95float depth, unsigned num_instances,96enum blitter_attrib_type type,97const union blitter_attrib *attrib);9899/* Whether the blitter is running. */100bool running;101102bool use_index_buffer;103104/* Private members, really. */105struct pipe_context *pipe; /**< pipe context */106107void *saved_blend_state; /**< blend state */108void *saved_dsa_state; /**< depth stencil alpha state */109void *saved_velem_state; /**< vertex elements state */110void *saved_rs_state; /**< rasterizer state */111void *saved_fs, *saved_vs, *saved_gs, *saved_tcs, *saved_tes; /**< shaders */112113struct pipe_framebuffer_state saved_fb_state; /**< framebuffer state */114struct pipe_stencil_ref saved_stencil_ref; /**< stencil ref */115struct pipe_viewport_state saved_viewport;116struct pipe_scissor_state saved_scissor;117bool skip_viewport_restore;118bool is_sample_mask_saved;119unsigned saved_sample_mask;120121unsigned saved_num_sampler_states;122void *saved_sampler_states[PIPE_MAX_SAMPLERS];123124unsigned saved_num_sampler_views;125struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS];126127unsigned cb_slot;128struct pipe_constant_buffer saved_fs_constant_buffer;129130unsigned vb_slot;131struct pipe_vertex_buffer saved_vertex_buffer;132133unsigned saved_num_so_targets;134struct pipe_stream_output_target *saved_so_targets[PIPE_MAX_SO_BUFFERS];135136struct pipe_query *saved_render_cond_query;137uint saved_render_cond_mode;138bool saved_render_cond_cond;139140boolean saved_window_rectangles_include;141unsigned saved_num_window_rectangles;142struct pipe_scissor_state saved_window_rectangles[PIPE_MAX_WINDOW_RECTANGLES];143};144145/**146* Create a blitter context.147*/148struct blitter_context *util_blitter_create(struct pipe_context *pipe);149150/**151* Destroy a blitter context.152*/153void util_blitter_destroy(struct blitter_context *blitter);154155void util_blitter_cache_all_shaders(struct blitter_context *blitter);156void *util_blitter_get_noop_blend_state(struct blitter_context *blitter);157void *util_blitter_get_noop_dsa_state(struct blitter_context *blitter);158void *util_blitter_get_discard_rasterizer_state(struct blitter_context *blitter);159160161/**162* Return the pipe context associated with a blitter context.163*/164static inline165struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter)166{167return blitter->pipe;168}169170/**171* Override PIPE_CAP_TEXTURE_MULTISAMPLE as reported by the driver.172*/173void util_blitter_set_texture_multisample(struct blitter_context *blitter,174bool supported);175176/* The default function to draw a rectangle. This can only be used177* inside of the draw_rectangle callback if the driver overrides it. */178void util_blitter_draw_rectangle(struct blitter_context *blitter,179void *vertex_elements_cso,180blitter_get_vs_func get_vs,181int x1, int y1, int x2, int y2,182float depth, unsigned num_instances,183enum blitter_attrib_type type,184const union blitter_attrib *attrib);185186187/*188* These states must be saved before any of the following functions are called:189* - vertex buffers190* - vertex elements191* - vertex shader192* - geometry shader (if supported)193* - stream output targets (if supported)194* - rasterizer state195*/196197/**198* Clear a specified set of currently bound buffers to specified values.199*200* These states must be saved in the blitter in addition to the state objects201* already required to be saved:202* - fragment shader203* - depth stencil alpha state204* - blend state205*/206void util_blitter_clear(struct blitter_context *blitter,207unsigned width, unsigned height, unsigned num_layers,208unsigned clear_buffers,209const union pipe_color_union *color,210double depth, unsigned stencil,211bool msaa);212213/**214* Check if the blitter (with the help of the driver) can blit between215* the two resources.216*/217bool util_blitter_is_copy_supported(struct blitter_context *blitter,218const struct pipe_resource *dst,219const struct pipe_resource *src);220221bool util_blitter_is_blit_supported(struct blitter_context *blitter,222const struct pipe_blit_info *info);223224/**225* Copy a block of pixels from one surface to another.226*227* These states must be saved in the blitter in addition to the state objects228* already required to be saved:229* - fragment shader230* - depth stencil alpha state231* - blend state232* - fragment sampler states233* - fragment sampler textures234* - framebuffer state235* - sample mask236*/237void util_blitter_copy_texture(struct blitter_context *blitter,238struct pipe_resource *dst,239unsigned dst_level,240unsigned dstx, unsigned dsty, unsigned dstz,241struct pipe_resource *src,242unsigned src_level,243const struct pipe_box *srcbox);244245/**246* This is a generic implementation of pipe->blit, which accepts247* sampler/surface views instead of resources.248*249* The layer and mipmap level are specified by the views.250*251* Drivers can use this to change resource properties (like format, width,252* height) by changing how the views interpret them, instead of changing253* pipe_resource directly. This is used to blit resources of formats which254* are not renderable.255*256* src_width0 and src_height0 are sampler_view-private properties that257* override pipe_resource. The blitter uses them for computation of texture258* coordinates. The dst dimensions are supplied through pipe_surface::width259* and height.260*261* The mask is a combination of the PIPE_MASK_* flags.262* Set to PIPE_MASK_RGBAZS if unsure.263*/264void util_blitter_blit_generic(struct blitter_context *blitter,265struct pipe_surface *dst,266const struct pipe_box *dstbox,267struct pipe_sampler_view *src,268const struct pipe_box *srcbox,269unsigned src_width0, unsigned src_height0,270unsigned mask, unsigned filter,271const struct pipe_scissor_state *scissor,272bool alpha_blend);273274void util_blitter_blit(struct blitter_context *blitter,275const struct pipe_blit_info *info);276277void util_blitter_generate_mipmap(struct blitter_context *blitter,278struct pipe_resource *tex,279enum pipe_format format,280unsigned base_level, unsigned last_level,281unsigned first_layer, unsigned last_layer);282283/**284* Helper function to initialize a view for copy_texture_view.285* The parameters must match copy_texture_view.286*/287void util_blitter_default_dst_texture(struct pipe_surface *dst_templ,288struct pipe_resource *dst,289unsigned dstlevel,290unsigned dstz);291292/**293* Helper function to initialize a view for copy_texture_view.294* The parameters must match copy_texture_view.295*/296void util_blitter_default_src_texture(struct blitter_context *blitter,297struct pipe_sampler_view *src_templ,298struct pipe_resource *src,299unsigned srclevel);300301/**302* Copy data from one buffer to another using the Stream Output functionality.303* 4-byte alignment is required, otherwise software fallback is used.304*/305void util_blitter_copy_buffer(struct blitter_context *blitter,306struct pipe_resource *dst,307unsigned dstx,308struct pipe_resource *src,309unsigned srcx,310unsigned size);311312/**313* Clear the contents of a buffer using the Stream Output functionality.314* 4-byte alignment is required.315*316* "num_channels" can be 1, 2, 3, or 4, and specifies if the clear value is317* R, RG, RGB, or RGBA.318*319* For each element, only "num_channels" components of "clear_value" are320* copied to the buffer, then the offset is incremented by num_channels*4.321*/322void util_blitter_clear_buffer(struct blitter_context *blitter,323struct pipe_resource *dst,324unsigned offset, unsigned size,325unsigned num_channels,326const union pipe_color_union *clear_value);327328/**329* Clear a region of a (color) surface to a constant value.330*331* These states must be saved in the blitter in addition to the state objects332* already required to be saved:333* - fragment shader334* - depth stencil alpha state335* - blend state336* - framebuffer state337*/338void util_blitter_clear_render_target(struct blitter_context *blitter,339struct pipe_surface *dst,340const union pipe_color_union *color,341unsigned dstx, unsigned dsty,342unsigned width, unsigned height);343344/**345* Clear a region of a depth-stencil surface, both stencil and depth346* or only one of them if this is a combined depth-stencil surface.347*348* These states must be saved in the blitter in addition to the state objects349* already required to be saved:350* - fragment shader351* - depth stencil alpha state352* - blend state353* - framebuffer state354*/355void util_blitter_clear_depth_stencil(struct blitter_context *blitter,356struct pipe_surface *dst,357unsigned clear_flags,358double depth,359unsigned stencil,360unsigned dstx, unsigned dsty,361unsigned width, unsigned height);362363/* The following functions are customized variants of the clear functions.364* Some drivers use them internally to do things like MSAA resolve365* and resource decompression. It usually consists of rendering a full-screen366* quad with a special blend or DSA state.367*/368369/* Used by r300g for depth decompression. */370void util_blitter_custom_clear_depth(struct blitter_context *blitter,371unsigned width, unsigned height,372double depth, void *custom_dsa);373374/* Used by r600g for depth decompression. */375void util_blitter_custom_depth_stencil(struct blitter_context *blitter,376struct pipe_surface *zsurf,377struct pipe_surface *cbsurf,378unsigned sample_mask,379void *dsa_stage, float depth);380381/* Used by r600g for color decompression. */382void util_blitter_custom_color(struct blitter_context *blitter,383struct pipe_surface *dstsurf,384void *custom_blend);385386/* Used by r600g for MSAA color resolve. */387void util_blitter_custom_resolve_color(struct blitter_context *blitter,388struct pipe_resource *dst,389unsigned dst_level,390unsigned dst_layer,391struct pipe_resource *src,392unsigned src_layer,393unsigned sampled_mask,394void *custom_blend,395enum pipe_format format);396397/* Used by vc4 for 8/16-bit linear-to-tiled blits */398void util_blitter_custom_shader(struct blitter_context *blitter,399struct pipe_surface *dstsurf,400void *custom_vs, void *custom_fs);401402/* Used by D3D12 for non-MSAA -> MSAA stencil blits */403void util_blitter_stencil_fallback(struct blitter_context *blitter,404struct pipe_resource *dst,405unsigned dst_level,406const struct pipe_box *dstbox,407struct pipe_resource *src,408unsigned src_level,409const struct pipe_box *srcbox,410const struct pipe_scissor_state *scissor);411412/* The functions below should be used to save currently bound constant state413* objects inside a driver. The objects are automatically restored at the end414* of the util_blitter_{clear, copy_region, fill_region} functions and then415* forgotten.416*417* States not listed here are not affected by util_blitter. */418419static inline void420util_blitter_save_blend(struct blitter_context *blitter, void *state)421{422blitter->saved_blend_state = state;423}424425static inline void426util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter,427void *state)428{429blitter->saved_dsa_state = state;430}431432static inline void433util_blitter_save_vertex_elements(struct blitter_context *blitter, void *state)434{435blitter->saved_velem_state = state;436}437438static inline void439util_blitter_save_stencil_ref(struct blitter_context *blitter,440const struct pipe_stencil_ref *state)441{442blitter->saved_stencil_ref = *state;443}444445static inline void446util_blitter_save_rasterizer(struct blitter_context *blitter, void *state)447{448blitter->saved_rs_state = state;449}450451static inline void452util_blitter_save_fragment_shader(struct blitter_context *blitter, void *fs)453{454blitter->saved_fs = fs;455}456457static inline void458util_blitter_save_vertex_shader(struct blitter_context *blitter, void *vs)459{460blitter->saved_vs = vs;461}462463static inline void464util_blitter_save_geometry_shader(struct blitter_context *blitter, void *gs)465{466blitter->saved_gs = gs;467}468469static inline void470util_blitter_save_tessctrl_shader(struct blitter_context *blitter,471void *sh)472{473blitter->saved_tcs = sh;474}475476static inline void477util_blitter_save_tesseval_shader(struct blitter_context *blitter,478void *sh)479{480blitter->saved_tes = sh;481}482483static inline void484util_blitter_save_framebuffer(struct blitter_context *blitter,485const struct pipe_framebuffer_state *state)486{487blitter->saved_fb_state.nr_cbufs = 0; /* It's ~0 now, meaning it's unsaved. */488util_copy_framebuffer_state(&blitter->saved_fb_state, state);489}490491static inline void492util_blitter_save_viewport(struct blitter_context *blitter,493struct pipe_viewport_state *state)494{495blitter->saved_viewport = *state;496}497498static inline void499util_blitter_save_scissor(struct blitter_context *blitter,500struct pipe_scissor_state *state)501{502blitter->saved_scissor = *state;503}504505static inline void506util_blitter_save_fragment_sampler_states(507struct blitter_context *blitter,508unsigned num_sampler_states,509void **sampler_states)510{511assert(num_sampler_states <= ARRAY_SIZE(blitter->saved_sampler_states));512513blitter->saved_num_sampler_states = num_sampler_states;514memcpy(blitter->saved_sampler_states, sampler_states,515num_sampler_states * sizeof(void *));516}517518static inline void519util_blitter_save_fragment_sampler_views(struct blitter_context *blitter,520unsigned num_views,521struct pipe_sampler_view **views)522{523unsigned i;524assert(num_views <= ARRAY_SIZE(blitter->saved_sampler_views));525526blitter->saved_num_sampler_views = num_views;527for (i = 0; i < num_views; i++)528pipe_sampler_view_reference(&blitter->saved_sampler_views[i],529views[i]);530}531532static inline void533util_blitter_save_fragment_constant_buffer_slot(534struct blitter_context *blitter,535struct pipe_constant_buffer *constant_buffers)536{537pipe_resource_reference(&blitter->saved_fs_constant_buffer.buffer,538constant_buffers[blitter->cb_slot].buffer);539memcpy(&blitter->saved_fs_constant_buffer, &constant_buffers[blitter->cb_slot],540sizeof(struct pipe_constant_buffer));541}542543static inline void544util_blitter_save_vertex_buffer_slot(struct blitter_context *blitter,545struct pipe_vertex_buffer *vertex_buffers)546{547pipe_vertex_buffer_reference(&blitter->saved_vertex_buffer,548&vertex_buffers[blitter->vb_slot]);549}550551static inline void552util_blitter_save_so_targets(struct blitter_context *blitter,553unsigned num_targets,554struct pipe_stream_output_target **targets)555{556unsigned i;557assert(num_targets <= ARRAY_SIZE(blitter->saved_so_targets));558559blitter->saved_num_so_targets = num_targets;560for (i = 0; i < num_targets; i++)561pipe_so_target_reference(&blitter->saved_so_targets[i],562targets[i]);563}564565static inline void566util_blitter_save_sample_mask(struct blitter_context *blitter,567unsigned sample_mask)568{569blitter->is_sample_mask_saved = true;570blitter->saved_sample_mask = sample_mask;571}572573static inline void574util_blitter_save_render_condition(struct blitter_context *blitter,575struct pipe_query *query,576bool condition,577enum pipe_render_cond_flag mode)578{579blitter->saved_render_cond_query = query;580blitter->saved_render_cond_mode = mode;581blitter->saved_render_cond_cond = condition;582}583584static inline void585util_blitter_save_window_rectangles(struct blitter_context *blitter,586boolean include,587unsigned num_rectangles,588const struct pipe_scissor_state *rects)589{590blitter->saved_window_rectangles_include = include;591blitter->saved_num_window_rectangles = num_rectangles;592if (num_rectangles > 0) {593assert(num_rectangles < ARRAY_SIZE(blitter->saved_window_rectangles));594memcpy(blitter->saved_window_rectangles, rects,595sizeof(*rects) * num_rectangles);596}597}598599void util_blitter_common_clear_setup(struct blitter_context *blitter,600unsigned width, unsigned height,601unsigned clear_buffers,602void *custom_blend, void *custom_dsa);603604void util_blitter_set_running_flag(struct blitter_context *blitter);605void util_blitter_unset_running_flag(struct blitter_context *blitter);606607void util_blitter_restore_vertex_states(struct blitter_context *blitter);608void util_blitter_restore_fragment_states(struct blitter_context *blitter);609void util_blitter_restore_render_cond(struct blitter_context *blitter);610void util_blitter_restore_fb_state(struct blitter_context *blitter);611void util_blitter_restore_textures(struct blitter_context *blitter);612void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter);613614/* These are supported combinations of blits from ZS to color and vice versa.615* The blitter will do the packing/unpacking of depth and stencil616* in the fragment shader.617*/618static inline enum pipe_format619util_blitter_get_color_format_for_zs(enum pipe_format format)620{621switch (format) {622case PIPE_FORMAT_Z16_UNORM:623return PIPE_FORMAT_R16_UNORM;624625case PIPE_FORMAT_Z32_FLOAT:626return PIPE_FORMAT_R32_FLOAT;627628case PIPE_FORMAT_Z24_UNORM_S8_UINT:629case PIPE_FORMAT_Z24X8_UNORM:630case PIPE_FORMAT_S8_UINT_Z24_UNORM:631case PIPE_FORMAT_X8Z24_UNORM:632return PIPE_FORMAT_R32_UINT;633634case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:635return PIPE_FORMAT_R32G32_UINT;636637case PIPE_FORMAT_Z32_UNORM:638default:639assert(0);640}641return PIPE_FORMAT_NONE;642}643644#ifdef __cplusplus645}646#endif647648#endif649650651