u_blitter.c revision 89ce12a2d20b6662abb7240c1becba11d53b215a
180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/************************************************************************** 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2009 Marek Olšák <maraeo@gmail.com> 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Permission is hereby granted, free of charge, to any person obtaining a 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * copy of this software and associated documentation files (the 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * "Software"), to deal in the Software without restriction, including 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * without limitation the rights to use, copy, modify, merge, publish, 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * distribute, sub license, and/or sell copies of the Software, and to 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * permit persons to whom the Software is furnished to do so, subject to 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * the following conditions: 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * The above copyright notice and this permission notice (including the 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * next paragraph) shall be included in all copies or substantial portions 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * of the Software. 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru **************************************************************************/ 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @file 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Blitter utility to facilitate acceleration of the clear, clear_render_target, 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * clear_depth_stencil, and resource_copy_region functions. 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @author Marek Olšák 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "pipe/p_context.h" 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "pipe/p_defines.h" 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "util/u_inlines.h" 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "pipe/p_shader_tokens.h" 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "pipe/p_state.h" 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "util/u_format.h" 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "util/u_memory.h" 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "util/u_math.h" 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "util/u_blitter.h" 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "util/u_draw_quad.h" 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "util/u_sampler.h" 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "util/u_simple_shaders.h" 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "util/u_surface.h" 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "util/u_texture.h" 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define INVALID_PTR ((void*)~0) 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct blitter_context_priv 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct blitter_context base; 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct pipe_resource *vbuf; /**< quad */ 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */ 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* Templates for various state objects. */ 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* Constant state objects. */ 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* Vertex shaders. */ 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/ 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* Fragment shaders. */ 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* The shader at index i outputs color to color buffers 0,1,...,i-1. */ 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *fs_col[PIPE_MAX_COLOR_BUFS+1]; 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *fs_col_int[PIPE_MAX_COLOR_BUFS+1]; 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* FS which outputs a color from a texture, 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru where the index is PIPE_TEXTURE_* to be sampled. */ 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES]; 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* FS which outputs a depth from a texture, 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru where the index is PIPE_TEXTURE_* to be sampled. */ 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES]; 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* Blend state. */ 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *blend_write_color; /**< blend state with writemask of RGBA */ 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *blend_keep_color; /**< blend state with writemask of 0 */ 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* Depth stencil alpha state. */ 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *dsa_write_depth_stencil; 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *dsa_write_depth_keep_stencil; 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *dsa_keep_depth_stencil; 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *dsa_keep_depth_write_stencil; 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *velem_state; 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *velem_uint_state; 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *velem_sint_state; 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* Sampler state. */ 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *sampler_state; 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* Rasterizer state. */ 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void *rs_state; 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* Viewport state. */ 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct pipe_viewport_state viewport; 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* Clip state. */ 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct pipe_clip_state clip; 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* Destination surface dimensions. */ 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned dst_width; 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned dst_height; 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru boolean has_geometry_shader; 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru boolean vertex_has_integers; 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void blitter_draw_rectangle(struct blitter_context *blitter, 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned x, unsigned y, 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned width, unsigned height, 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float depth, 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru enum blitter_attrib_type type, 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const union pipe_color_union *attrib); 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct blitter_context *util_blitter_create(struct pipe_context *pipe) 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct blitter_context_priv *ctx; 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct pipe_blend_state blend; 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct pipe_depth_stencil_alpha_state dsa; 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct pipe_rasterizer_state rs_state; 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct pipe_sampler_state sampler_state; 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru struct pipe_vertex_element velem[2]; 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned i; 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx = CALLOC_STRUCT(blitter_context_priv); 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!ctx) 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.pipe = pipe; 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.draw_rectangle = blitter_draw_rectangle; 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* init state objects for them to be considered invalid */ 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.saved_blend_state = INVALID_PTR; 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.saved_dsa_state = INVALID_PTR; 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.saved_rs_state = INVALID_PTR; 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.saved_fs = INVALID_PTR; 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.saved_vs = INVALID_PTR; 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.saved_gs = INVALID_PTR; 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.saved_velem_state = INVALID_PTR; 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.saved_fb_state.nr_cbufs = ~0; 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.saved_num_sampler_views = ~0; 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.saved_num_sampler_states = ~0; 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->base.saved_num_vertex_buffers = ~0; 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->has_geometry_shader = 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY, 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0; 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->vertex_has_integers = 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_VERTEX, 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru PIPE_SHADER_CAP_INTEGERS); 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* blend state objects */ 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memset(&blend, 0, sizeof(blend)); 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend); 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru blend.rt[0].colormask = PIPE_MASK_RGBA; 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->blend_write_color = pipe->create_blend_state(pipe, &blend); 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* depth stencil alpha state objects */ 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memset(&dsa, 0, sizeof(dsa)); 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ctx->dsa_keep_depth_stencil = 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pipe->create_depth_stencil_alpha_state(pipe, &dsa); 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dsa.depth.enabled = 1; 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dsa.depth.writemask = 1; 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dsa.depth.func = PIPE_FUNC_ALWAYS; 174 ctx->dsa_write_depth_keep_stencil = 175 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 176 177 dsa.stencil[0].enabled = 1; 178 dsa.stencil[0].func = PIPE_FUNC_ALWAYS; 179 dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; 180 dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; 181 dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; 182 dsa.stencil[0].valuemask = 0xff; 183 dsa.stencil[0].writemask = 0xff; 184 ctx->dsa_write_depth_stencil = 185 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 186 187 188 dsa.depth.enabled = 0; 189 dsa.depth.writemask = 0; 190 ctx->dsa_keep_depth_write_stencil = 191 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 192 193 /* sampler state */ 194 memset(&sampler_state, 0, sizeof(sampler_state)); 195 sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 196 sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 197 sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 198 sampler_state.normalized_coords = 1; 199 ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state); 200 201 /* rasterizer state */ 202 memset(&rs_state, 0, sizeof(rs_state)); 203 rs_state.cull_face = PIPE_FACE_NONE; 204 rs_state.gl_rasterization_rules = 1; 205 rs_state.flatshade = 1; 206 ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state); 207 208 /* vertex elements state */ 209 memset(&velem[0], 0, sizeof(velem[0]) * 2); 210 for (i = 0; i < 2; i++) { 211 velem[i].src_offset = i * 4 * sizeof(float); 212 velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 213 } 214 ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); 215 216 if (ctx->vertex_has_integers) { 217 memset(&velem[0], 0, sizeof(velem[0]) * 2); 218 velem[0].src_offset = 0; 219 velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 220 velem[1].src_offset = 4 * sizeof(float); 221 velem[1].src_format = PIPE_FORMAT_R32G32B32A32_SINT; 222 ctx->velem_sint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); 223 224 memset(&velem[0], 0, sizeof(velem[0]) * 2); 225 velem[0].src_offset = 0; 226 velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 227 velem[1].src_offset = 4 * sizeof(float); 228 velem[1].src_format = PIPE_FORMAT_R32G32B32A32_UINT; 229 ctx->velem_uint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); 230 } 231 232 /* fragment shaders are created on-demand */ 233 234 /* vertex shader */ 235 { 236 const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, 237 TGSI_SEMANTIC_GENERIC }; 238 const uint semantic_indices[] = { 0, 0 }; 239 ctx->vs = 240 util_make_vertex_passthrough_shader(pipe, 2, semantic_names, 241 semantic_indices); 242 } 243 244 /* set invariant vertex coordinates */ 245 for (i = 0; i < 4; i++) 246 ctx->vertices[i][0][3] = 1; /*v.w*/ 247 248 /* create the vertex buffer */ 249 ctx->vbuf = pipe_user_buffer_create(ctx->base.pipe->screen, 250 ctx->vertices, 251 sizeof(ctx->vertices), 252 PIPE_BIND_VERTEX_BUFFER); 253 254 return &ctx->base; 255} 256 257void util_blitter_destroy(struct blitter_context *blitter) 258{ 259 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 260 struct pipe_context *pipe = blitter->pipe; 261 int i; 262 263 pipe->delete_blend_state(pipe, ctx->blend_write_color); 264 pipe->delete_blend_state(pipe, ctx->blend_keep_color); 265 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 266 pipe->delete_depth_stencil_alpha_state(pipe, 267 ctx->dsa_write_depth_keep_stencil); 268 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 269 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 270 271 pipe->delete_rasterizer_state(pipe, ctx->rs_state); 272 pipe->delete_vs_state(pipe, ctx->vs); 273 pipe->delete_vertex_elements_state(pipe, ctx->velem_state); 274 if (ctx->vertex_has_integers) { 275 pipe->delete_vertex_elements_state(pipe, ctx->velem_sint_state); 276 pipe->delete_vertex_elements_state(pipe, ctx->velem_uint_state); 277 } 278 279 for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) { 280 if (ctx->fs_texfetch_col[i]) 281 pipe->delete_fs_state(pipe, ctx->fs_texfetch_col[i]); 282 if (ctx->fs_texfetch_depth[i]) 283 pipe->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]); 284 } 285 286 for (i = 0; i <= PIPE_MAX_COLOR_BUFS; i++) { 287 if (ctx->fs_col[i]) 288 pipe->delete_fs_state(pipe, ctx->fs_col[i]); 289 if (ctx->fs_col_int[i]) 290 pipe->delete_fs_state(pipe, ctx->fs_col_int[i]); 291 } 292 293 pipe->delete_sampler_state(pipe, ctx->sampler_state); 294 pipe_resource_reference(&ctx->vbuf, NULL); 295 FREE(ctx); 296} 297 298static void blitter_set_running_flag(struct blitter_context_priv *ctx) 299{ 300 if (ctx->base.running) { 301 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", 302 __LINE__); 303 } 304 ctx->base.running = TRUE; 305} 306 307static void blitter_unset_running_flag(struct blitter_context_priv *ctx) 308{ 309 if (!ctx->base.running) { 310 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", 311 __LINE__); 312 } 313 ctx->base.running = FALSE; 314} 315 316static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx) 317{ 318 assert(ctx->base.saved_num_vertex_buffers != ~0 && 319 ctx->base.saved_velem_state != INVALID_PTR && 320 ctx->base.saved_vs != INVALID_PTR && 321 (!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR) && 322 ctx->base.saved_rs_state != INVALID_PTR); 323} 324 325static void blitter_restore_vertex_states(struct blitter_context_priv *ctx) 326{ 327 struct pipe_context *pipe = ctx->base.pipe; 328 unsigned i; 329 330 /* Vertex buffers. */ 331 pipe->set_vertex_buffers(pipe, 332 ctx->base.saved_num_vertex_buffers, 333 ctx->base.saved_vertex_buffers); 334 335 for (i = 0; i < ctx->base.saved_num_vertex_buffers; i++) { 336 if (ctx->base.saved_vertex_buffers[i].buffer) { 337 pipe_resource_reference(&ctx->base.saved_vertex_buffers[i].buffer, 338 NULL); 339 } 340 } 341 ctx->base.saved_num_vertex_buffers = ~0; 342 343 /* Vertex elements. */ 344 pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state); 345 ctx->base.saved_velem_state = INVALID_PTR; 346 347 /* Vertex shader. */ 348 pipe->bind_vs_state(pipe, ctx->base.saved_vs); 349 ctx->base.saved_vs = INVALID_PTR; 350 351 /* Geometry shader. */ 352 if (ctx->has_geometry_shader) { 353 pipe->bind_gs_state(pipe, ctx->base.saved_gs); 354 ctx->base.saved_gs = INVALID_PTR; 355 } 356 357 /* Rasterizer. */ 358 pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state); 359 ctx->base.saved_rs_state = INVALID_PTR; 360} 361 362static void blitter_check_saved_fragment_states(struct blitter_context_priv *ctx) 363{ 364 assert(ctx->base.saved_fs != INVALID_PTR && 365 ctx->base.saved_dsa_state != INVALID_PTR && 366 ctx->base.saved_blend_state != INVALID_PTR); 367} 368 369static void blitter_restore_fragment_states(struct blitter_context_priv *ctx) 370{ 371 struct pipe_context *pipe = ctx->base.pipe; 372 373 /* Fragment shader. */ 374 pipe->bind_fs_state(pipe, ctx->base.saved_fs); 375 ctx->base.saved_fs = INVALID_PTR; 376 377 /* Depth, stencil, alpha. */ 378 pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state); 379 ctx->base.saved_dsa_state = INVALID_PTR; 380 381 /* Blend state. */ 382 pipe->bind_blend_state(pipe, ctx->base.saved_blend_state); 383 ctx->base.saved_blend_state = INVALID_PTR; 384 385 /* Miscellaneous states. */ 386 /* XXX check whether these are saved and whether they need to be restored 387 * (depending on the operation) */ 388 pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref); 389 pipe->set_viewport_state(pipe, &ctx->base.saved_viewport); 390 pipe->set_clip_state(pipe, &ctx->base.saved_clip); 391} 392 393static void blitter_check_saved_fb_state(struct blitter_context_priv *ctx) 394{ 395 assert(ctx->base.saved_fb_state.nr_cbufs != ~0); 396} 397 398static void blitter_restore_fb_state(struct blitter_context_priv *ctx) 399{ 400 struct pipe_context *pipe = ctx->base.pipe; 401 402 pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state); 403 util_unreference_framebuffer_state(&ctx->base.saved_fb_state); 404} 405 406static void blitter_check_saved_textures(struct blitter_context_priv *ctx) 407{ 408 assert(ctx->base.saved_num_sampler_states != ~0 && 409 ctx->base.saved_num_sampler_views != ~0); 410} 411 412static void blitter_restore_textures(struct blitter_context_priv *ctx) 413{ 414 struct pipe_context *pipe = ctx->base.pipe; 415 unsigned i; 416 417 /* Fragment sampler states. */ 418 pipe->bind_fragment_sampler_states(pipe, 419 ctx->base.saved_num_sampler_states, 420 ctx->base.saved_sampler_states); 421 ctx->base.saved_num_sampler_states = ~0; 422 423 /* Fragment sampler views. */ 424 pipe->set_fragment_sampler_views(pipe, 425 ctx->base.saved_num_sampler_views, 426 ctx->base.saved_sampler_views); 427 428 for (i = 0; i < ctx->base.saved_num_sampler_views; i++) 429 pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i], NULL); 430 431 ctx->base.saved_num_sampler_views = ~0; 432} 433 434static void blitter_set_rectangle(struct blitter_context_priv *ctx, 435 unsigned x1, unsigned y1, 436 unsigned x2, unsigned y2, 437 float depth) 438{ 439 int i; 440 441 /* set vertex positions */ 442 ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/ 443 ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/ 444 445 ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/ 446 ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/ 447 448 ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/ 449 ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/ 450 451 ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/ 452 ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/ 453 454 for (i = 0; i < 4; i++) 455 ctx->vertices[i][0][2] = depth; /*z*/ 456 457 /* viewport */ 458 ctx->viewport.scale[0] = 0.5f * ctx->dst_width; 459 ctx->viewport.scale[1] = 0.5f * ctx->dst_height; 460 ctx->viewport.scale[2] = 1.0f; 461 ctx->viewport.scale[3] = 1.0f; 462 ctx->viewport.translate[0] = 0.5f * ctx->dst_width; 463 ctx->viewport.translate[1] = 0.5f * ctx->dst_height; 464 ctx->viewport.translate[2] = 0.0f; 465 ctx->viewport.translate[3] = 0.0f; 466 ctx->base.pipe->set_viewport_state(ctx->base.pipe, &ctx->viewport); 467 468 /* clip */ 469 ctx->base.pipe->set_clip_state(ctx->base.pipe, &ctx->clip); 470} 471 472static void blitter_set_clear_color(struct blitter_context_priv *ctx, 473 const union pipe_color_union *color) 474{ 475 int i; 476 477 if (color) { 478 for (i = 0; i < 4; i++) { 479 uint32_t *uiverts = (uint32_t *)ctx->vertices[i][1]; 480 uiverts[0] = color->ui[0]; 481 uiverts[1] = color->ui[1]; 482 uiverts[2] = color->ui[2]; 483 uiverts[3] = color->ui[3]; 484 } 485 } else { 486 for (i = 0; i < 4; i++) { 487 ctx->vertices[i][1][0] = 0; 488 ctx->vertices[i][1][1] = 0; 489 ctx->vertices[i][1][2] = 0; 490 ctx->vertices[i][1][3] = 0; 491 } 492 } 493} 494 495static void get_texcoords(struct pipe_sampler_view *src, 496 unsigned src_width0, unsigned src_height0, 497 unsigned x1, unsigned y1, 498 unsigned x2, unsigned y2, 499 float out[4]) 500{ 501 struct pipe_resource *tex = src->texture; 502 unsigned level = src->u.tex.first_level; 503 boolean normalized = tex->target != PIPE_TEXTURE_RECT; 504 505 if (normalized) { 506 out[0] = x1 / (float)u_minify(src_width0, level); 507 out[1] = y1 / (float)u_minify(src_height0, level); 508 out[2] = x2 / (float)u_minify(src_width0, level); 509 out[3] = y2 / (float)u_minify(src_height0, level); 510 } else { 511 out[0] = x1; 512 out[1] = y1; 513 out[2] = x2; 514 out[3] = y2; 515 } 516} 517 518static void set_texcoords_in_vertices(const float coord[4], 519 float *out, unsigned stride) 520{ 521 out[0] = coord[0]; /*t0.s*/ 522 out[1] = coord[1]; /*t0.t*/ 523 out += stride; 524 out[0] = coord[2]; /*t1.s*/ 525 out[1] = coord[1]; /*t1.t*/ 526 out += stride; 527 out[0] = coord[2]; /*t2.s*/ 528 out[1] = coord[3]; /*t2.t*/ 529 out += stride; 530 out[0] = coord[0]; /*t3.s*/ 531 out[1] = coord[3]; /*t3.t*/ 532} 533 534static void blitter_set_texcoords(struct blitter_context_priv *ctx, 535 struct pipe_sampler_view *src, 536 unsigned src_width0, unsigned src_height0, 537 unsigned layer, 538 unsigned x1, unsigned y1, 539 unsigned x2, unsigned y2) 540{ 541 unsigned i; 542 float coord[4]; 543 float face_coord[4][2]; 544 545 get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, coord); 546 547 if (src->texture->target == PIPE_TEXTURE_CUBE) { 548 set_texcoords_in_vertices(coord, &face_coord[0][0], 2); 549 util_map_texcoords2d_onto_cubemap(layer, 550 /* pointer, stride in floats */ 551 &face_coord[0][0], 2, 552 &ctx->vertices[0][1][0], 8); 553 } else { 554 set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8); 555 } 556 557 /* Set the layer. */ 558 switch (src->texture->target) { 559 case PIPE_TEXTURE_3D: 560 { 561 float r = layer / (float)u_minify(src->texture->depth0, 562 src->u.tex.first_level); 563 for (i = 0; i < 4; i++) 564 ctx->vertices[i][1][2] = r; /*r*/ 565 } 566 break; 567 568 case PIPE_TEXTURE_1D_ARRAY: 569 for (i = 0; i < 4; i++) 570 ctx->vertices[i][1][1] = layer; /*t*/ 571 break; 572 573 case PIPE_TEXTURE_2D_ARRAY: 574 for (i = 0; i < 4; i++) 575 ctx->vertices[i][1][2] = layer; /*r*/ 576 break; 577 578 default:; 579 } 580} 581 582static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx, 583 unsigned width, unsigned height) 584{ 585 ctx->dst_width = width; 586 ctx->dst_height = height; 587} 588 589static INLINE 590void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs, 591 boolean int_format) 592{ 593 struct pipe_context *pipe = ctx->base.pipe; 594 595 assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); 596 597 if (int_format) { 598 if (!ctx->fs_col_int[num_cbufs]) 599 ctx->fs_col_int[num_cbufs] = 600 util_make_fragment_cloneinput_shader(pipe, num_cbufs, 601 TGSI_SEMANTIC_GENERIC, 602 TGSI_INTERPOLATE_CONSTANT); 603 return ctx->fs_col_int[num_cbufs]; 604 } else { 605 if (!ctx->fs_col[num_cbufs]) 606 ctx->fs_col[num_cbufs] = 607 util_make_fragment_cloneinput_shader(pipe, num_cbufs, 608 TGSI_SEMANTIC_GENERIC, 609 TGSI_INTERPOLATE_LINEAR); 610 return ctx->fs_col[num_cbufs]; 611 } 612} 613 614/** Convert PIPE_TEXTURE_x to TGSI_TEXTURE_x */ 615static unsigned 616pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target) 617{ 618 switch (pipe_tex_target) { 619 case PIPE_TEXTURE_1D: 620 return TGSI_TEXTURE_1D; 621 case PIPE_TEXTURE_2D: 622 return TGSI_TEXTURE_2D; 623 case PIPE_TEXTURE_RECT: 624 return TGSI_TEXTURE_RECT; 625 case PIPE_TEXTURE_3D: 626 return TGSI_TEXTURE_3D; 627 case PIPE_TEXTURE_CUBE: 628 return TGSI_TEXTURE_CUBE; 629 case PIPE_TEXTURE_1D_ARRAY: 630 return TGSI_TEXTURE_1D_ARRAY; 631 case PIPE_TEXTURE_2D_ARRAY: 632 return TGSI_TEXTURE_2D_ARRAY; 633 default: 634 assert(0 && "unexpected texture target"); 635 return TGSI_TEXTURE_UNKNOWN; 636 } 637} 638 639 640static INLINE 641void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx, 642 unsigned tex_target) 643{ 644 struct pipe_context *pipe = ctx->base.pipe; 645 646 assert(tex_target < PIPE_MAX_TEXTURE_TYPES); 647 648 /* Create the fragment shader on-demand. */ 649 if (!ctx->fs_texfetch_col[tex_target]) { 650 unsigned tgsi_tex = pipe_tex_to_tgsi_tex(tex_target); 651 652 ctx->fs_texfetch_col[tex_target] = 653 util_make_fragment_tex_shader(pipe, tgsi_tex, TGSI_INTERPOLATE_LINEAR); 654 } 655 656 return ctx->fs_texfetch_col[tex_target]; 657} 658 659static INLINE 660void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx, 661 unsigned tex_target) 662{ 663 struct pipe_context *pipe = ctx->base.pipe; 664 665 assert(tex_target < PIPE_MAX_TEXTURE_TYPES); 666 667 /* Create the fragment shader on-demand. */ 668 if (!ctx->fs_texfetch_depth[tex_target]) { 669 unsigned tgsi_tex = pipe_tex_to_tgsi_tex(tex_target); 670 671 ctx->fs_texfetch_depth[tex_target] = 672 util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex, 673 TGSI_INTERPOLATE_LINEAR); 674 } 675 676 return ctx->fs_texfetch_depth[tex_target]; 677} 678 679static void blitter_draw_rectangle(struct blitter_context *blitter, 680 unsigned x1, unsigned y1, 681 unsigned x2, unsigned y2, 682 float depth, 683 enum blitter_attrib_type type, 684 const union pipe_color_union *attrib) 685{ 686 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 687 688 switch (type) { 689 case UTIL_BLITTER_ATTRIB_COLOR: 690 blitter_set_clear_color(ctx, attrib); 691 break; 692 693 case UTIL_BLITTER_ATTRIB_TEXCOORD: 694 set_texcoords_in_vertices(attrib->f, &ctx->vertices[0][1][0], 8); 695 break; 696 697 default:; 698 } 699 700 blitter_set_rectangle(ctx, x1, y1, x2, y2, depth); 701 ctx->base.pipe->redefine_user_buffer(ctx->base.pipe, ctx->vbuf, 702 0, ctx->vbuf->width0); 703 util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0, 704 PIPE_PRIM_TRIANGLE_FAN, 4, 2); 705} 706 707static void util_blitter_clear_custom(struct blitter_context *blitter, 708 unsigned width, unsigned height, 709 unsigned num_cbufs, 710 unsigned clear_buffers, 711 enum pipe_format cbuf_format, 712 const union pipe_color_union *color, 713 double depth, unsigned stencil, 714 void *custom_blend, void *custom_dsa) 715{ 716 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 717 struct pipe_context *pipe = ctx->base.pipe; 718 struct pipe_stencil_ref sr = { { 0 } }; 719 boolean int_format = util_format_is_pure_integer(cbuf_format); 720 assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); 721 722 blitter_set_running_flag(ctx); 723 blitter_check_saved_vertex_states(ctx); 724 blitter_check_saved_fragment_states(ctx); 725 726 /* bind states */ 727 if (custom_blend) { 728 pipe->bind_blend_state(pipe, custom_blend); 729 } else if (clear_buffers & PIPE_CLEAR_COLOR) { 730 pipe->bind_blend_state(pipe, ctx->blend_write_color); 731 } else { 732 pipe->bind_blend_state(pipe, ctx->blend_keep_color); 733 } 734 735 if (custom_dsa) { 736 pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa); 737 } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { 738 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 739 } else if (clear_buffers & PIPE_CLEAR_DEPTH) { 740 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); 741 } else if (clear_buffers & PIPE_CLEAR_STENCIL) { 742 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 743 } else { 744 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 745 } 746 747 sr.ref_value[0] = stencil & 0xff; 748 pipe->set_stencil_ref(pipe, &sr); 749 750 pipe->bind_rasterizer_state(pipe, ctx->rs_state); 751 if (util_format_is_pure_sint(cbuf_format)) { 752 pipe->bind_vertex_elements_state(pipe, ctx->velem_sint_state); 753 } else if (util_format_is_pure_uint(cbuf_format)) { 754 pipe->bind_vertex_elements_state(pipe, ctx->velem_uint_state); 755 } else { 756 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 757 } 758 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs, int_format)); 759 pipe->bind_vs_state(pipe, ctx->vs); 760 if (ctx->has_geometry_shader) 761 pipe->bind_gs_state(pipe, NULL); 762 763 blitter_set_dst_dimensions(ctx, width, height); 764 blitter->draw_rectangle(blitter, 0, 0, width, height, depth, 765 UTIL_BLITTER_ATTRIB_COLOR, color); 766 767 blitter_restore_vertex_states(ctx); 768 blitter_restore_fragment_states(ctx); 769 blitter_unset_running_flag(ctx); 770} 771 772void util_blitter_clear(struct blitter_context *blitter, 773 unsigned width, unsigned height, 774 unsigned num_cbufs, 775 unsigned clear_buffers, 776 enum pipe_format cbuf_format, 777 const union pipe_color_union *color, 778 double depth, unsigned stencil) 779{ 780 util_blitter_clear_custom(blitter, width, height, num_cbufs, 781 clear_buffers, cbuf_format, color, depth, stencil, 782 NULL, NULL); 783} 784 785void util_blitter_clear_depth_custom(struct blitter_context *blitter, 786 unsigned width, unsigned height, 787 double depth, void *custom_dsa) 788{ 789 static const union pipe_color_union color; 790 util_blitter_clear_custom(blitter, width, height, 0, 791 0, PIPE_FORMAT_NONE, &color, depth, 0, NULL, custom_dsa); 792} 793 794static 795boolean is_overlap(unsigned sx1, unsigned sx2, unsigned sy1, unsigned sy2, 796 unsigned dx1, unsigned dx2, unsigned dy1, unsigned dy2) 797{ 798 return sx1 < dx2 && sx2 > dx1 && sy1 < dy2 && sy2 > dy1; 799} 800 801void util_blitter_copy_texture(struct blitter_context *blitter, 802 struct pipe_resource *dst, 803 unsigned dstlevel, 804 unsigned dstx, unsigned dsty, unsigned dstz, 805 struct pipe_resource *src, 806 unsigned srclevel, 807 const struct pipe_box *srcbox, 808 boolean ignore_stencil) 809{ 810 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 811 struct pipe_context *pipe = ctx->base.pipe; 812 struct pipe_screen *screen = pipe->screen; 813 struct pipe_surface *dstsurf, surf_templ; 814 struct pipe_sampler_view viewTempl, *view; 815 unsigned bind; 816 boolean is_stencil, is_depth; 817 818 /* Give up if textures are not set. */ 819 assert(dst && src); 820 if (!dst || !src) 821 return; 822 823 assert(src->target < PIPE_MAX_TEXTURE_TYPES); 824 825 /* Is this a ZS format? */ 826 is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0; 827 is_stencil = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0; 828 829 if (is_depth || is_stencil) 830 bind = PIPE_BIND_DEPTH_STENCIL; 831 else 832 bind = PIPE_BIND_RENDER_TARGET; 833 834 /* Check if we can sample from and render to the surfaces. */ 835 /* (assuming copying a stencil buffer is not possible) */ 836 if ((!ignore_stencil && is_stencil) || 837 !screen->is_format_supported(screen, dst->format, dst->target, 838 dst->nr_samples, bind) || 839 !screen->is_format_supported(screen, src->format, src->target, 840 src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) { 841 blitter_set_running_flag(ctx); 842 util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz, 843 src, srclevel, srcbox); 844 blitter_unset_running_flag(ctx); 845 return; 846 } 847 848 /* Initialize the surface. */ 849 memset(&surf_templ, 0, sizeof(surf_templ)); 850 u_surface_default_template(&surf_templ, dst, bind); 851 surf_templ.format = util_format_linear(dst->format); 852 surf_templ.u.tex.level = dstlevel; 853 surf_templ.u.tex.first_layer = dstz; 854 surf_templ.u.tex.last_layer = dstz + srcbox->depth - 1; 855 dstsurf = pipe->create_surface(pipe, dst, &surf_templ); 856 857 /* Initialize the sampler view. */ 858 u_sampler_view_default_template(&viewTempl, src, 859 util_format_linear(src->format)); 860 viewTempl.u.tex.first_level = srclevel; 861 viewTempl.u.tex.last_level = srclevel; 862 view = pipe->create_sampler_view(pipe, src, &viewTempl); 863 864 /* Copy. */ 865 util_blitter_copy_texture_view(blitter, dstsurf, dstx, dsty, view, srcbox, 866 src->width0, src->height0); 867 868 pipe_surface_reference(&dstsurf, NULL); 869 pipe_sampler_view_reference(&view, NULL); 870} 871 872void util_blitter_copy_texture_view(struct blitter_context *blitter, 873 struct pipe_surface *dst, 874 unsigned dstx, unsigned dsty, 875 struct pipe_sampler_view *src, 876 const struct pipe_box *srcbox, 877 unsigned src_width0, unsigned src_height0) 878{ 879 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 880 struct pipe_context *pipe = ctx->base.pipe; 881 struct pipe_framebuffer_state fb_state; 882 enum pipe_texture_target src_target = src->texture->target; 883 unsigned width = srcbox->width; 884 unsigned height = srcbox->height; 885 886 /* Sanity checks. */ 887 if (dst->texture == src->texture && 888 dst->u.tex.level == src->u.tex.first_level) { 889 assert(!is_overlap(srcbox->x, srcbox->x + width, srcbox->y, srcbox->y + height, 890 dstx, dstx + width, dsty, dsty + height)); 891 } 892 /* XXX should handle 3d regions */ 893 assert(srcbox->depth == 1); 894 895 /* Check whether the states are properly saved. */ 896 blitter_set_running_flag(ctx); 897 blitter_check_saved_vertex_states(ctx); 898 blitter_check_saved_fragment_states(ctx); 899 blitter_check_saved_textures(ctx); 900 blitter_check_saved_fb_state(ctx); 901 902 /* Initialize framebuffer state. */ 903 fb_state.width = dst->width; 904 fb_state.height = dst->height; 905 906 if (util_format_is_depth_or_stencil(dst->format)) { 907 pipe->bind_blend_state(pipe, ctx->blend_keep_color); 908 pipe->bind_depth_stencil_alpha_state(pipe, 909 ctx->dsa_write_depth_keep_stencil); 910 pipe->bind_fs_state(pipe, 911 blitter_get_fs_texfetch_depth(ctx, src_target)); 912 913 fb_state.nr_cbufs = 0; 914 fb_state.zsbuf = dst; 915 } else { 916 pipe->bind_blend_state(pipe, ctx->blend_write_color); 917 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 918 pipe->bind_fs_state(pipe, 919 blitter_get_fs_texfetch_col(ctx, src_target)); 920 921 fb_state.nr_cbufs = 1; 922 fb_state.cbufs[0] = dst; 923 fb_state.zsbuf = 0; 924 } 925 926 /* Set rasterizer state, shaders, and textures. */ 927 pipe->bind_rasterizer_state(pipe, ctx->rs_state); 928 pipe->bind_vs_state(pipe, ctx->vs); 929 if (ctx->has_geometry_shader) 930 pipe->bind_gs_state(pipe, NULL); 931 pipe->bind_fragment_sampler_states(pipe, 1, &ctx->sampler_state); 932 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 933 pipe->set_fragment_sampler_views(pipe, 1, &src); 934 pipe->set_framebuffer_state(pipe, &fb_state); 935 936 blitter_set_dst_dimensions(ctx, dst->width, dst->height); 937 938 switch (src_target) { 939 /* Draw the quad with the draw_rectangle callback. */ 940 case PIPE_TEXTURE_1D: 941 case PIPE_TEXTURE_2D: 942 case PIPE_TEXTURE_RECT: 943 { 944 /* Set texture coordinates. - use a pipe color union 945 * for interface purposes. 946 * XXX pipe_color_union is a wrong name since we use that to set 947 * texture coordinates too. 948 */ 949 union pipe_color_union coord; 950 get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y, 951 srcbox->x+width, srcbox->y+height, coord.f); 952 953 /* Draw. */ 954 blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0, 955 UTIL_BLITTER_ATTRIB_TEXCOORD, &coord); 956 } 957 break; 958 959 /* Draw the quad with the generic codepath. */ 960 default: 961 /* Set texture coordinates. */ 962 switch (src_target) { 963 case PIPE_TEXTURE_1D_ARRAY: 964 case PIPE_TEXTURE_2D_ARRAY: 965 case PIPE_TEXTURE_3D: 966 case PIPE_TEXTURE_CUBE: 967 blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z, 968 srcbox->y, srcbox->x, 969 srcbox->x + width, srcbox->y + height); 970 break; 971 972 default: 973 assert(0); 974 } 975 976 /* Draw. */ 977 blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0); 978 ctx->base.pipe->redefine_user_buffer(ctx->base.pipe, ctx->vbuf, 979 0, ctx->vbuf->width0); 980 util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0, 981 PIPE_PRIM_TRIANGLE_FAN, 4, 2); 982 break; 983 } 984 985 blitter_restore_vertex_states(ctx); 986 blitter_restore_fragment_states(ctx); 987 blitter_restore_textures(ctx); 988 blitter_restore_fb_state(ctx); 989 blitter_unset_running_flag(ctx); 990} 991 992/* Clear a region of a color surface to a constant value. */ 993void util_blitter_clear_render_target(struct blitter_context *blitter, 994 struct pipe_surface *dstsurf, 995 const union pipe_color_union *color, 996 unsigned dstx, unsigned dsty, 997 unsigned width, unsigned height) 998{ 999 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1000 struct pipe_context *pipe = ctx->base.pipe; 1001 struct pipe_framebuffer_state fb_state; 1002 1003 assert(dstsurf->texture); 1004 if (!dstsurf->texture) 1005 return; 1006 1007 /* check the saved state */ 1008 blitter_set_running_flag(ctx); 1009 blitter_check_saved_vertex_states(ctx); 1010 blitter_check_saved_fragment_states(ctx); 1011 blitter_check_saved_fb_state(ctx); 1012 1013 /* bind states */ 1014 pipe->bind_blend_state(pipe, ctx->blend_write_color); 1015 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 1016 pipe->bind_rasterizer_state(pipe, ctx->rs_state); 1017 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE)); 1018 pipe->bind_vs_state(pipe, ctx->vs); 1019 if (ctx->has_geometry_shader) 1020 pipe->bind_gs_state(pipe, NULL); 1021 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 1022 1023 /* set a framebuffer state */ 1024 fb_state.width = dstsurf->width; 1025 fb_state.height = dstsurf->height; 1026 fb_state.nr_cbufs = 1; 1027 fb_state.cbufs[0] = dstsurf; 1028 fb_state.zsbuf = 0; 1029 pipe->set_framebuffer_state(pipe, &fb_state); 1030 1031 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 1032 blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0, 1033 UTIL_BLITTER_ATTRIB_COLOR, color); 1034 1035 blitter_restore_vertex_states(ctx); 1036 blitter_restore_fragment_states(ctx); 1037 blitter_restore_fb_state(ctx); 1038 blitter_unset_running_flag(ctx); 1039} 1040 1041/* Clear a region of a depth stencil surface. */ 1042void util_blitter_clear_depth_stencil(struct blitter_context *blitter, 1043 struct pipe_surface *dstsurf, 1044 unsigned clear_flags, 1045 double depth, 1046 unsigned stencil, 1047 unsigned dstx, unsigned dsty, 1048 unsigned width, unsigned height) 1049{ 1050 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1051 struct pipe_context *pipe = ctx->base.pipe; 1052 struct pipe_framebuffer_state fb_state; 1053 struct pipe_stencil_ref sr = { { 0 } }; 1054 1055 assert(dstsurf->texture); 1056 if (!dstsurf->texture) 1057 return; 1058 1059 /* check the saved state */ 1060 blitter_set_running_flag(ctx); 1061 blitter_check_saved_vertex_states(ctx); 1062 blitter_check_saved_fragment_states(ctx); 1063 blitter_check_saved_fb_state(ctx); 1064 1065 /* bind states */ 1066 pipe->bind_blend_state(pipe, ctx->blend_keep_color); 1067 if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { 1068 sr.ref_value[0] = stencil & 0xff; 1069 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 1070 pipe->set_stencil_ref(pipe, &sr); 1071 } 1072 else if (clear_flags & PIPE_CLEAR_DEPTH) { 1073 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); 1074 } 1075 else if (clear_flags & PIPE_CLEAR_STENCIL) { 1076 sr.ref_value[0] = stencil & 0xff; 1077 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 1078 pipe->set_stencil_ref(pipe, &sr); 1079 } 1080 else 1081 /* hmm that should be illegal probably, or make it a no-op somewhere */ 1082 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 1083 1084 pipe->bind_rasterizer_state(pipe, ctx->rs_state); 1085 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE)); 1086 pipe->bind_vs_state(pipe, ctx->vs); 1087 if (ctx->has_geometry_shader) 1088 pipe->bind_gs_state(pipe, NULL); 1089 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 1090 1091 /* set a framebuffer state */ 1092 fb_state.width = dstsurf->width; 1093 fb_state.height = dstsurf->height; 1094 fb_state.nr_cbufs = 0; 1095 fb_state.cbufs[0] = 0; 1096 fb_state.zsbuf = dstsurf; 1097 pipe->set_framebuffer_state(pipe, &fb_state); 1098 1099 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 1100 blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, depth, 1101 UTIL_BLITTER_ATTRIB_NONE, NULL); 1102 1103 blitter_restore_vertex_states(ctx); 1104 blitter_restore_fragment_states(ctx); 1105 blitter_restore_fb_state(ctx); 1106 blitter_unset_running_flag(ctx); 1107} 1108 1109/* draw a rectangle across a region using a custom dsa stage - for r600g */ 1110void util_blitter_custom_depth_stencil(struct blitter_context *blitter, 1111 struct pipe_surface *zsurf, 1112 struct pipe_surface *cbsurf, 1113 void *dsa_stage, float depth) 1114{ 1115 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1116 struct pipe_context *pipe = ctx->base.pipe; 1117 struct pipe_framebuffer_state fb_state; 1118 1119 assert(zsurf->texture); 1120 if (!zsurf->texture) 1121 return; 1122 1123 /* check the saved state */ 1124 blitter_set_running_flag(ctx); 1125 blitter_check_saved_vertex_states(ctx); 1126 blitter_check_saved_fragment_states(ctx); 1127 blitter_check_saved_fb_state(ctx); 1128 1129 /* bind states */ 1130 pipe->bind_blend_state(pipe, ctx->blend_write_color); 1131 pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage); 1132 1133 pipe->bind_rasterizer_state(pipe, ctx->rs_state); 1134 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE)); 1135 pipe->bind_vs_state(pipe, ctx->vs); 1136 if (ctx->has_geometry_shader) 1137 pipe->bind_gs_state(pipe, NULL); 1138 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 1139 1140 /* set a framebuffer state */ 1141 fb_state.width = zsurf->width; 1142 fb_state.height = zsurf->height; 1143 fb_state.nr_cbufs = 1; 1144 if (cbsurf) { 1145 fb_state.cbufs[0] = cbsurf; 1146 fb_state.nr_cbufs = 1; 1147 } else { 1148 fb_state.cbufs[0] = NULL; 1149 fb_state.nr_cbufs = 0; 1150 } 1151 fb_state.zsbuf = zsurf; 1152 pipe->set_framebuffer_state(pipe, &fb_state); 1153 1154 blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height); 1155 blitter->draw_rectangle(blitter, 0, 0, zsurf->width, zsurf->height, depth, 1156 UTIL_BLITTER_ATTRIB_NONE, NULL); 1157 1158 blitter_restore_vertex_states(ctx); 1159 blitter_restore_fragment_states(ctx); 1160 blitter_restore_fb_state(ctx); 1161 blitter_unset_running_flag(ctx); 1162} 1163