u_blitter.h revision 4c7001462607e6e99e474d6271dd481d3f8f201c
1/************************************************************************** 2 * 3 * Copyright 2009 Marek Olšák <maraeo@gmail.com> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL 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 38extern "C" { 39#endif 40 41struct pipe_context; 42 43enum blitter_attrib_type { 44 UTIL_BLITTER_ATTRIB_NONE, 45 UTIL_BLITTER_ATTRIB_COLOR, 46 UTIL_BLITTER_ATTRIB_TEXCOORD 47}; 48 49struct 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 to the COLOR0 64 * 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 float attrib[4]); 81 82 /* Private members, really. */ 83 struct pipe_context *pipe; /**< pipe context */ 84 85 void *saved_blend_state; /**< blend state */ 86 void *saved_dsa_state; /**< depth stencil alpha state */ 87 void *saved_velem_state; /**< vertex elements state */ 88 void *saved_rs_state; /**< rasterizer state */ 89 void *saved_fs, *saved_vs; /**< fragment shader, vertex shader */ 90 91 struct pipe_framebuffer_state saved_fb_state; /**< framebuffer state */ 92 struct pipe_stencil_ref saved_stencil_ref; /**< stencil ref */ 93 struct pipe_viewport_state saved_viewport; 94 struct pipe_clip_state saved_clip; 95 96 int saved_num_sampler_states; 97 void *saved_sampler_states[PIPE_MAX_SAMPLERS]; 98 99 int saved_num_sampler_views; 100 struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS]; 101 102 int saved_num_vertex_buffers; 103 struct pipe_vertex_buffer saved_vertex_buffers[PIPE_MAX_ATTRIBS]; 104}; 105 106/** 107 * Create a blitter context. 108 */ 109struct blitter_context *util_blitter_create(struct pipe_context *pipe); 110 111/** 112 * Destroy a blitter context. 113 */ 114void util_blitter_destroy(struct blitter_context *blitter); 115 116/** 117 * Return the pipe context associated with a blitter context. 118 */ 119static INLINE 120struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter) 121{ 122 return blitter->pipe; 123} 124 125/* 126 * These CSOs must be saved before any of the following functions is called: 127 * - blend state 128 * - depth stencil alpha state 129 * - rasterizer state 130 * - vertex shader 131 * - fragment shader 132 */ 133 134/** 135 * Clear a specified set of currently bound buffers to specified values. 136 */ 137void util_blitter_clear(struct blitter_context *blitter, 138 unsigned width, unsigned height, 139 unsigned num_cbufs, 140 unsigned clear_buffers, 141 const float *rgba, 142 double depth, unsigned stencil); 143 144/** 145 * Copy a block of pixels from one surface to another. 146 * 147 * You can copy from any color format to any other color format provided 148 * the former can be sampled and the latter can be rendered to. Otherwise, 149 * a software fallback path is taken and both surfaces must be of the same 150 * format. 151 * 152 * The same holds for depth-stencil formats with the exception that stencil 153 * cannot be copied unless you set ignore_stencil to FALSE. In that case, 154 * a software fallback path is taken and both surfaces must be of the same 155 * format. 156 * 157 * Use pipe_screen->is_format_supported to know your options. 158 * 159 * These states must be saved in the blitter in addition to the state objects 160 * already required to be saved: 161 * - framebuffer state 162 * - fragment sampler states 163 * - fragment sampler textures 164 */ 165void util_blitter_copy_region(struct blitter_context *blitter, 166 struct pipe_resource *dst, 167 unsigned dstlevel, 168 unsigned dstx, unsigned dsty, unsigned dstz, 169 struct pipe_resource *src, 170 unsigned srclevel, 171 const struct pipe_box *srcbox, 172 boolean ignore_stencil); 173 174/** 175 * Clear a region of a (color) surface to a constant value. 176 * 177 * These states must be saved in the blitter in addition to the state objects 178 * already required to be saved: 179 * - framebuffer state 180 */ 181void util_blitter_clear_render_target(struct blitter_context *blitter, 182 struct pipe_surface *dst, 183 const float *rgba, 184 unsigned dstx, unsigned dsty, 185 unsigned width, unsigned height); 186 187/** 188 * Clear a region of a depth-stencil surface, both stencil and depth 189 * or only one of them if this is a combined depth-stencil surface. 190 * 191 * These states must be saved in the blitter in addition to the state objects 192 * already required to be saved: 193 * - framebuffer state 194 */ 195void util_blitter_clear_depth_stencil(struct blitter_context *blitter, 196 struct pipe_surface *dst, 197 unsigned clear_flags, 198 double depth, 199 unsigned stencil, 200 unsigned dstx, unsigned dsty, 201 unsigned width, unsigned height); 202 203void util_blitter_flush_depth_stencil(struct blitter_context *blitter, 204 struct pipe_surface *dstsurf); 205 206void util_blitter_custom_depth_stencil(struct blitter_context *blitter, 207 struct pipe_surface *zsurf, 208 struct pipe_surface *cbsurf, 209 void *dsa_stage, float depth); 210 211/* The functions below should be used to save currently bound constant state 212 * objects inside a driver. The objects are automatically restored at the end 213 * of the util_blitter_{clear, copy_region, fill_region} functions and then 214 * forgotten. 215 * 216 * CSOs not listed here are not affected by util_blitter. */ 217 218static INLINE 219void util_blitter_save_blend(struct blitter_context *blitter, 220 void *state) 221{ 222 blitter->saved_blend_state = state; 223} 224 225static INLINE 226void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter, 227 void *state) 228{ 229 blitter->saved_dsa_state = state; 230} 231 232static INLINE 233void util_blitter_save_vertex_elements(struct blitter_context *blitter, 234 void *state) 235{ 236 blitter->saved_velem_state = state; 237} 238 239static INLINE 240void util_blitter_save_stencil_ref(struct blitter_context *blitter, 241 const struct pipe_stencil_ref *state) 242{ 243 blitter->saved_stencil_ref = *state; 244} 245 246static INLINE 247void util_blitter_save_rasterizer(struct blitter_context *blitter, 248 void *state) 249{ 250 blitter->saved_rs_state = state; 251} 252 253static INLINE 254void util_blitter_save_fragment_shader(struct blitter_context *blitter, 255 void *fs) 256{ 257 blitter->saved_fs = fs; 258} 259 260static INLINE 261void util_blitter_save_vertex_shader(struct blitter_context *blitter, 262 void *vs) 263{ 264 blitter->saved_vs = vs; 265} 266 267static INLINE 268void util_blitter_save_framebuffer(struct blitter_context *blitter, 269 const struct pipe_framebuffer_state *state) 270{ 271 blitter->saved_fb_state.nr_cbufs = 0; /* It's ~0 now, meaning it's unsaved. */ 272 util_copy_framebuffer_state(&blitter->saved_fb_state, state); 273} 274 275static INLINE 276void util_blitter_save_viewport(struct blitter_context *blitter, 277 struct pipe_viewport_state *state) 278{ 279 blitter->saved_viewport = *state; 280} 281 282static INLINE 283void util_blitter_save_clip(struct blitter_context *blitter, 284 struct pipe_clip_state *state) 285{ 286 blitter->saved_clip = *state; 287} 288 289static INLINE 290void util_blitter_save_fragment_sampler_states( 291 struct blitter_context *blitter, 292 int num_sampler_states, 293 void **sampler_states) 294{ 295 assert(num_sampler_states <= Elements(blitter->saved_sampler_states)); 296 297 blitter->saved_num_sampler_states = num_sampler_states; 298 memcpy(blitter->saved_sampler_states, sampler_states, 299 num_sampler_states * sizeof(void *)); 300} 301 302static INLINE void 303util_blitter_save_fragment_sampler_views(struct blitter_context *blitter, 304 int num_views, 305 struct pipe_sampler_view **views) 306{ 307 unsigned i; 308 assert(num_views <= Elements(blitter->saved_sampler_views)); 309 310 blitter->saved_num_sampler_views = num_views; 311 for (i = 0; i < num_views; i++) 312 pipe_sampler_view_reference(&blitter->saved_sampler_views[i], 313 views[i]); 314} 315 316static INLINE void 317util_blitter_save_vertex_buffers(struct blitter_context *blitter, 318 int num_vertex_buffers, 319 struct pipe_vertex_buffer *vertex_buffers) 320{ 321 unsigned i; 322 assert(num_vertex_buffers <= Elements(blitter->saved_vertex_buffers)); 323 324 blitter->saved_num_vertex_buffers = num_vertex_buffers; 325 326 for (i = 0; i < num_vertex_buffers; i++) { 327 if (vertex_buffers[i].buffer) { 328 pipe_resource_reference(&blitter->saved_vertex_buffers[i].buffer, 329 vertex_buffers[i].buffer); 330 } 331 } 332 333 memcpy(blitter->saved_vertex_buffers, 334 vertex_buffers, 335 num_vertex_buffers * sizeof(struct pipe_vertex_buffer)); 336} 337 338#ifdef __cplusplus 339} 340#endif 341 342#endif 343