1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2009 Marek Olšák <maraeo@gmail.com> 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 7bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 8bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 9bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 10bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 11bf215546Sopenharmony_ci * the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 14bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 15bf215546Sopenharmony_ci * of the Software. 16bf215546Sopenharmony_ci * 17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 21bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24bf215546Sopenharmony_ci * 25bf215546Sopenharmony_ci **************************************************************************/ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci/** 28bf215546Sopenharmony_ci * @file 29bf215546Sopenharmony_ci * Blitter utility to facilitate acceleration of the clear, clear_render_target, 30bf215546Sopenharmony_ci * clear_depth_stencil, resource_copy_region, and blit functions. 31bf215546Sopenharmony_ci * 32bf215546Sopenharmony_ci * @author Marek Olšák 33bf215546Sopenharmony_ci */ 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci#include "pipe/p_context.h" 36bf215546Sopenharmony_ci#include "pipe/p_defines.h" 37bf215546Sopenharmony_ci#include "util/u_inlines.h" 38bf215546Sopenharmony_ci#include "pipe/p_shader_tokens.h" 39bf215546Sopenharmony_ci#include "pipe/p_state.h" 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci#include "util/format/u_format.h" 42bf215546Sopenharmony_ci#include "util/u_memory.h" 43bf215546Sopenharmony_ci#include "util/u_math.h" 44bf215546Sopenharmony_ci#include "util/u_blitter.h" 45bf215546Sopenharmony_ci#include "util/u_draw_quad.h" 46bf215546Sopenharmony_ci#include "util/u_sampler.h" 47bf215546Sopenharmony_ci#include "util/u_simple_shaders.h" 48bf215546Sopenharmony_ci#include "util/u_surface.h" 49bf215546Sopenharmony_ci#include "util/u_texture.h" 50bf215546Sopenharmony_ci#include "util/u_upload_mgr.h" 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci#define INVALID_PTR ((void*)~0) 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci#define GET_CLEAR_BLEND_STATE_IDX(clear_buffers) \ 55bf215546Sopenharmony_ci ((clear_buffers) / PIPE_CLEAR_COLOR0) 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci#define NUM_RESOLVE_FRAG_SHADERS 5 /* MSAA 2x, 4x, 8x, 16x, 32x */ 58bf215546Sopenharmony_ci#define GET_MSAA_RESOLVE_FS_IDX(nr_samples) (util_logbase2(nr_samples)-1) 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_cistruct blitter_context_priv 61bf215546Sopenharmony_ci{ 62bf215546Sopenharmony_ci struct blitter_context base; 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */ 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci /* Templates for various state objects. */ 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci /* Constant state objects. */ 69bf215546Sopenharmony_ci /* Vertex shaders. */ 70bf215546Sopenharmony_ci void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/ 71bf215546Sopenharmony_ci void *vs_nogeneric; 72bf215546Sopenharmony_ci void *vs_pos_only[4]; /**< Vertex shader which passes pos to the output 73bf215546Sopenharmony_ci for clear_buffer.*/ 74bf215546Sopenharmony_ci void *vs_layered; /**< Vertex shader which sets LAYER = INSTANCEID. */ 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci /* Fragment shaders. */ 77bf215546Sopenharmony_ci void *fs_empty; 78bf215546Sopenharmony_ci void *fs_write_one_cbuf; 79bf215546Sopenharmony_ci void *fs_clear_all_cbufs; 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci /* FS which outputs a color from a texture where 82bf215546Sopenharmony_ci * the 1st index indicates the texture type / destination type, 83bf215546Sopenharmony_ci * the 2nd index is the PIPE_TEXTURE_* to be sampled, 84bf215546Sopenharmony_ci * the 3rd index is 0 = use TEX, 1 = use TXF. 85bf215546Sopenharmony_ci */ 86bf215546Sopenharmony_ci void *fs_texfetch_col[5][PIPE_MAX_TEXTURE_TYPES][2]; 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci /* FS which outputs a depth from a texture, where 89bf215546Sopenharmony_ci * the 1st index is the PIPE_TEXTURE_* to be sampled, 90bf215546Sopenharmony_ci * the 2nd index is 0 = use TEX, 1 = use TXF. 91bf215546Sopenharmony_ci */ 92bf215546Sopenharmony_ci void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES][2]; 93bf215546Sopenharmony_ci void *fs_texfetch_depthstencil[PIPE_MAX_TEXTURE_TYPES][2]; 94bf215546Sopenharmony_ci void *fs_texfetch_stencil[PIPE_MAX_TEXTURE_TYPES][2]; 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci /* FS which outputs one sample from a multisample texture. */ 97bf215546Sopenharmony_ci void *fs_texfetch_col_msaa[5][PIPE_MAX_TEXTURE_TYPES]; 98bf215546Sopenharmony_ci void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES][2]; 99bf215546Sopenharmony_ci void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES][2]; 100bf215546Sopenharmony_ci void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES][2]; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci /* FS which outputs an average of all samples. */ 103bf215546Sopenharmony_ci void *fs_resolve[PIPE_MAX_TEXTURE_TYPES][NUM_RESOLVE_FRAG_SHADERS][2]; 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci /* FS which unpacks color to ZS or packs ZS to color, matching 106bf215546Sopenharmony_ci * the ZS format. See util_blitter_get_color_format_for_zs(). 107bf215546Sopenharmony_ci */ 108bf215546Sopenharmony_ci void *fs_pack_color_zs[TGSI_TEXTURE_COUNT][10]; 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci /* FS which is meant for replicating indevidual stencil-buffer bits */ 111bf215546Sopenharmony_ci void *fs_stencil_blit_fallback[2]; 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci /* Blend state. */ 114bf215546Sopenharmony_ci void *blend[PIPE_MASK_RGBA+1][2]; /**< blend state with writemask */ 115bf215546Sopenharmony_ci void *blend_clear[GET_CLEAR_BLEND_STATE_IDX(PIPE_CLEAR_COLOR)+1]; 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci /* Depth stencil alpha state. */ 118bf215546Sopenharmony_ci void *dsa_write_depth_stencil; 119bf215546Sopenharmony_ci void *dsa_write_depth_keep_stencil; 120bf215546Sopenharmony_ci void *dsa_keep_depth_stencil; 121bf215546Sopenharmony_ci void *dsa_keep_depth_write_stencil; 122bf215546Sopenharmony_ci void *dsa_replicate_stencil_bit[8]; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci /* Vertex elements states. */ 125bf215546Sopenharmony_ci void *velem_state; 126bf215546Sopenharmony_ci void *velem_state_readbuf[4]; /**< X, XY, XYZ, XYZW */ 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci /* Sampler state. */ 129bf215546Sopenharmony_ci void *sampler_state; 130bf215546Sopenharmony_ci void *sampler_state_linear; 131bf215546Sopenharmony_ci void *sampler_state_rect; 132bf215546Sopenharmony_ci void *sampler_state_rect_linear; 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci /* Rasterizer state. */ 135bf215546Sopenharmony_ci void *rs_state[2][2]; /**< [scissor][msaa] */ 136bf215546Sopenharmony_ci void *rs_discard_state; 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci /* Destination surface dimensions. */ 139bf215546Sopenharmony_ci unsigned dst_width; 140bf215546Sopenharmony_ci unsigned dst_height; 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci void *custom_vs; 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci bool has_geometry_shader; 145bf215546Sopenharmony_ci bool has_tessellation; 146bf215546Sopenharmony_ci bool has_layered; 147bf215546Sopenharmony_ci bool has_stream_out; 148bf215546Sopenharmony_ci bool has_stencil_export; 149bf215546Sopenharmony_ci bool has_texture_multisample; 150bf215546Sopenharmony_ci bool has_tex_lz; 151bf215546Sopenharmony_ci bool has_txf; 152bf215546Sopenharmony_ci bool has_sample_shading; 153bf215546Sopenharmony_ci bool cube_as_2darray; 154bf215546Sopenharmony_ci bool has_texrect; 155bf215546Sopenharmony_ci bool cached_all_shaders; 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci /* The Draw module overrides these functions. 158bf215546Sopenharmony_ci * Always create the blitter before Draw. */ 159bf215546Sopenharmony_ci void (*bind_fs_state)(struct pipe_context *, void *); 160bf215546Sopenharmony_ci void (*delete_fs_state)(struct pipe_context *, void *); 161bf215546Sopenharmony_ci}; 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_cistruct blitter_context *util_blitter_create(struct pipe_context *pipe) 164bf215546Sopenharmony_ci{ 165bf215546Sopenharmony_ci struct blitter_context_priv *ctx; 166bf215546Sopenharmony_ci struct pipe_blend_state blend; 167bf215546Sopenharmony_ci struct pipe_depth_stencil_alpha_state dsa; 168bf215546Sopenharmony_ci struct pipe_rasterizer_state rs_state; 169bf215546Sopenharmony_ci struct pipe_sampler_state sampler_state; 170bf215546Sopenharmony_ci struct pipe_vertex_element velem[2]; 171bf215546Sopenharmony_ci unsigned i, j; 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci ctx = CALLOC_STRUCT(blitter_context_priv); 174bf215546Sopenharmony_ci if (!ctx) 175bf215546Sopenharmony_ci return NULL; 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci ctx->base.pipe = pipe; 178bf215546Sopenharmony_ci ctx->base.draw_rectangle = util_blitter_draw_rectangle; 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci ctx->bind_fs_state = pipe->bind_fs_state; 181bf215546Sopenharmony_ci ctx->delete_fs_state = pipe->delete_fs_state; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci /* init state objects for them to be considered invalid */ 184bf215546Sopenharmony_ci ctx->base.saved_blend_state = INVALID_PTR; 185bf215546Sopenharmony_ci ctx->base.saved_dsa_state = INVALID_PTR; 186bf215546Sopenharmony_ci ctx->base.saved_rs_state = INVALID_PTR; 187bf215546Sopenharmony_ci ctx->base.saved_fs = INVALID_PTR; 188bf215546Sopenharmony_ci ctx->base.saved_vs = INVALID_PTR; 189bf215546Sopenharmony_ci ctx->base.saved_gs = INVALID_PTR; 190bf215546Sopenharmony_ci ctx->base.saved_velem_state = INVALID_PTR; 191bf215546Sopenharmony_ci ctx->base.saved_fb_state.nr_cbufs = ~0; 192bf215546Sopenharmony_ci ctx->base.saved_num_sampler_views = ~0; 193bf215546Sopenharmony_ci ctx->base.saved_num_sampler_states = ~0; 194bf215546Sopenharmony_ci ctx->base.saved_num_so_targets = ~0; 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci ctx->has_geometry_shader = 197bf215546Sopenharmony_ci pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY, 198bf215546Sopenharmony_ci PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0; 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci ctx->has_tessellation = 201bf215546Sopenharmony_ci pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_TESS_CTRL, 202bf215546Sopenharmony_ci PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0; 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci ctx->has_stream_out = 205bf215546Sopenharmony_ci pipe->screen->get_param(pipe->screen, 206bf215546Sopenharmony_ci PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0; 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci ctx->has_stencil_export = 209bf215546Sopenharmony_ci pipe->screen->get_param(pipe->screen, 210bf215546Sopenharmony_ci PIPE_CAP_SHADER_STENCIL_EXPORT); 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci ctx->has_texture_multisample = 213bf215546Sopenharmony_ci pipe->screen->get_param(pipe->screen, PIPE_CAP_TEXTURE_MULTISAMPLE); 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci ctx->has_tex_lz = pipe->screen->get_param(pipe->screen, 216bf215546Sopenharmony_ci PIPE_CAP_TGSI_TEX_TXF_LZ); 217bf215546Sopenharmony_ci ctx->has_txf = pipe->screen->get_param(pipe->screen, 218bf215546Sopenharmony_ci PIPE_CAP_GLSL_FEATURE_LEVEL) > 130; 219bf215546Sopenharmony_ci ctx->has_sample_shading = pipe->screen->get_param(pipe->screen, 220bf215546Sopenharmony_ci PIPE_CAP_SAMPLE_SHADING); 221bf215546Sopenharmony_ci ctx->cube_as_2darray = pipe->screen->get_param(pipe->screen, 222bf215546Sopenharmony_ci PIPE_CAP_SAMPLER_VIEW_TARGET); 223bf215546Sopenharmony_ci ctx->has_texrect = pipe->screen->get_param(pipe->screen, PIPE_CAP_TEXRECT); 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci /* blend state objects */ 226bf215546Sopenharmony_ci memset(&blend, 0, sizeof(blend)); 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci for (i = 0; i <= PIPE_MASK_RGBA; i++) { 229bf215546Sopenharmony_ci for (j = 0; j < 2; j++) { 230bf215546Sopenharmony_ci memset(&blend.rt[0], 0, sizeof(blend.rt[0])); 231bf215546Sopenharmony_ci blend.rt[0].colormask = i; 232bf215546Sopenharmony_ci if (j) { 233bf215546Sopenharmony_ci blend.rt[0].blend_enable = 1; 234bf215546Sopenharmony_ci blend.rt[0].rgb_func = PIPE_BLEND_ADD; 235bf215546Sopenharmony_ci blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; 236bf215546Sopenharmony_ci blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; 237bf215546Sopenharmony_ci blend.rt[0].alpha_func = PIPE_BLEND_ADD; 238bf215546Sopenharmony_ci blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; 239bf215546Sopenharmony_ci blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; 240bf215546Sopenharmony_ci } 241bf215546Sopenharmony_ci ctx->blend[i][j] = pipe->create_blend_state(pipe, &blend); 242bf215546Sopenharmony_ci } 243bf215546Sopenharmony_ci } 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci /* depth stencil alpha state objects */ 246bf215546Sopenharmony_ci memset(&dsa, 0, sizeof(dsa)); 247bf215546Sopenharmony_ci ctx->dsa_keep_depth_stencil = 248bf215546Sopenharmony_ci pipe->create_depth_stencil_alpha_state(pipe, &dsa); 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci dsa.depth_enabled = 1; 251bf215546Sopenharmony_ci dsa.depth_writemask = 1; 252bf215546Sopenharmony_ci dsa.depth_func = PIPE_FUNC_ALWAYS; 253bf215546Sopenharmony_ci ctx->dsa_write_depth_keep_stencil = 254bf215546Sopenharmony_ci pipe->create_depth_stencil_alpha_state(pipe, &dsa); 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci dsa.stencil[0].enabled = 1; 257bf215546Sopenharmony_ci dsa.stencil[0].func = PIPE_FUNC_ALWAYS; 258bf215546Sopenharmony_ci dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; 259bf215546Sopenharmony_ci dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; 260bf215546Sopenharmony_ci dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; 261bf215546Sopenharmony_ci dsa.stencil[0].valuemask = 0xff; 262bf215546Sopenharmony_ci dsa.stencil[0].writemask = 0xff; 263bf215546Sopenharmony_ci ctx->dsa_write_depth_stencil = 264bf215546Sopenharmony_ci pipe->create_depth_stencil_alpha_state(pipe, &dsa); 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci dsa.depth_enabled = 0; 267bf215546Sopenharmony_ci dsa.depth_writemask = 0; 268bf215546Sopenharmony_ci ctx->dsa_keep_depth_write_stencil = 269bf215546Sopenharmony_ci pipe->create_depth_stencil_alpha_state(pipe, &dsa); 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci /* sampler state */ 272bf215546Sopenharmony_ci memset(&sampler_state, 0, sizeof(sampler_state)); 273bf215546Sopenharmony_ci sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 274bf215546Sopenharmony_ci sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 275bf215546Sopenharmony_ci sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 276bf215546Sopenharmony_ci sampler_state.normalized_coords = 1; 277bf215546Sopenharmony_ci ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state); 278bf215546Sopenharmony_ci if (ctx->has_texrect) { 279bf215546Sopenharmony_ci sampler_state.normalized_coords = 0; 280bf215546Sopenharmony_ci ctx->sampler_state_rect = pipe->create_sampler_state(pipe, &sampler_state); 281bf215546Sopenharmony_ci } 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci sampler_state.min_img_filter = PIPE_TEX_FILTER_LINEAR; 284bf215546Sopenharmony_ci sampler_state.mag_img_filter = PIPE_TEX_FILTER_LINEAR; 285bf215546Sopenharmony_ci sampler_state.normalized_coords = 1; 286bf215546Sopenharmony_ci ctx->sampler_state_linear = pipe->create_sampler_state(pipe, &sampler_state); 287bf215546Sopenharmony_ci if (ctx->has_texrect) { 288bf215546Sopenharmony_ci sampler_state.normalized_coords = 0; 289bf215546Sopenharmony_ci ctx->sampler_state_rect_linear = pipe->create_sampler_state(pipe, &sampler_state); 290bf215546Sopenharmony_ci } 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci /* rasterizer state */ 293bf215546Sopenharmony_ci memset(&rs_state, 0, sizeof(rs_state)); 294bf215546Sopenharmony_ci rs_state.cull_face = PIPE_FACE_NONE; 295bf215546Sopenharmony_ci rs_state.half_pixel_center = 1; 296bf215546Sopenharmony_ci rs_state.bottom_edge_rule = 1; 297bf215546Sopenharmony_ci rs_state.flatshade = 1; 298bf215546Sopenharmony_ci rs_state.depth_clip_near = 1; 299bf215546Sopenharmony_ci rs_state.depth_clip_far = 1; 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci unsigned scissor, msaa; 302bf215546Sopenharmony_ci for (scissor = 0; scissor < 2; scissor++) { 303bf215546Sopenharmony_ci for (msaa = 0; msaa < 2; msaa++) { 304bf215546Sopenharmony_ci rs_state.scissor = scissor; 305bf215546Sopenharmony_ci rs_state.multisample = msaa; 306bf215546Sopenharmony_ci ctx->rs_state[scissor][msaa] = 307bf215546Sopenharmony_ci pipe->create_rasterizer_state(pipe, &rs_state); 308bf215546Sopenharmony_ci } 309bf215546Sopenharmony_ci } 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci if (ctx->has_stream_out) { 312bf215546Sopenharmony_ci rs_state.scissor = rs_state.multisample = 0; 313bf215546Sopenharmony_ci rs_state.rasterizer_discard = 1; 314bf215546Sopenharmony_ci ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state); 315bf215546Sopenharmony_ci } 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci ctx->base.cb_slot = 0; /* 0 for now */ 318bf215546Sopenharmony_ci ctx->base.vb_slot = 0; /* 0 for now */ 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci /* vertex elements states */ 321bf215546Sopenharmony_ci memset(&velem[0], 0, sizeof(velem[0]) * 2); 322bf215546Sopenharmony_ci for (i = 0; i < 2; i++) { 323bf215546Sopenharmony_ci velem[i].src_offset = i * 4 * sizeof(float); 324bf215546Sopenharmony_ci velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 325bf215546Sopenharmony_ci velem[i].vertex_buffer_index = ctx->base.vb_slot; 326bf215546Sopenharmony_ci } 327bf215546Sopenharmony_ci ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci if (ctx->has_stream_out) { 330bf215546Sopenharmony_ci static enum pipe_format formats[4] = { 331bf215546Sopenharmony_ci PIPE_FORMAT_R32_UINT, 332bf215546Sopenharmony_ci PIPE_FORMAT_R32G32_UINT, 333bf215546Sopenharmony_ci PIPE_FORMAT_R32G32B32_UINT, 334bf215546Sopenharmony_ci PIPE_FORMAT_R32G32B32A32_UINT 335bf215546Sopenharmony_ci }; 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci for (i = 0; i < 4; i++) { 338bf215546Sopenharmony_ci velem[0].src_format = formats[i]; 339bf215546Sopenharmony_ci velem[0].vertex_buffer_index = ctx->base.vb_slot; 340bf215546Sopenharmony_ci ctx->velem_state_readbuf[i] = 341bf215546Sopenharmony_ci pipe->create_vertex_elements_state(pipe, 1, &velem[0]); 342bf215546Sopenharmony_ci } 343bf215546Sopenharmony_ci } 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci ctx->has_layered = 346bf215546Sopenharmony_ci pipe->screen->get_param(pipe->screen, PIPE_CAP_VS_INSTANCEID) && 347bf215546Sopenharmony_ci pipe->screen->get_param(pipe->screen, PIPE_CAP_VS_LAYER_VIEWPORT); 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci /* set invariant vertex coordinates */ 350bf215546Sopenharmony_ci for (i = 0; i < 4; i++) { 351bf215546Sopenharmony_ci ctx->vertices[i][0][2] = 0; /*v.z*/ 352bf215546Sopenharmony_ci ctx->vertices[i][0][3] = 1; /*v.w*/ 353bf215546Sopenharmony_ci } 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci return &ctx->base; 356bf215546Sopenharmony_ci} 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_civoid *util_blitter_get_noop_blend_state(struct blitter_context *blitter) 359bf215546Sopenharmony_ci{ 360bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci return ctx->blend[0][0]; 363bf215546Sopenharmony_ci} 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_civoid *util_blitter_get_noop_dsa_state(struct blitter_context *blitter) 366bf215546Sopenharmony_ci{ 367bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci return ctx->dsa_keep_depth_stencil; 370bf215546Sopenharmony_ci} 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_civoid *util_blitter_get_discard_rasterizer_state(struct blitter_context *blitter) 373bf215546Sopenharmony_ci{ 374bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci return ctx->rs_discard_state; 377bf215546Sopenharmony_ci} 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_cistatic void bind_vs_pos_only(struct blitter_context_priv *ctx, 380bf215546Sopenharmony_ci unsigned num_so_channels) 381bf215546Sopenharmony_ci{ 382bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 383bf215546Sopenharmony_ci int index = num_so_channels ? num_so_channels - 1 : 0; 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci if (!ctx->vs_pos_only[index]) { 386bf215546Sopenharmony_ci struct pipe_stream_output_info so; 387bf215546Sopenharmony_ci static const enum tgsi_semantic semantic_names[] = 388bf215546Sopenharmony_ci { TGSI_SEMANTIC_POSITION }; 389bf215546Sopenharmony_ci const uint semantic_indices[] = { 0 }; 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci memset(&so, 0, sizeof(so)); 392bf215546Sopenharmony_ci so.num_outputs = 1; 393bf215546Sopenharmony_ci so.output[0].num_components = num_so_channels; 394bf215546Sopenharmony_ci so.stride[0] = num_so_channels; 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ci ctx->vs_pos_only[index] = 397bf215546Sopenharmony_ci util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names, 398bf215546Sopenharmony_ci semantic_indices, false, 399bf215546Sopenharmony_ci false, &so); 400bf215546Sopenharmony_ci } 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci pipe->bind_vs_state(pipe, ctx->vs_pos_only[index]); 403bf215546Sopenharmony_ci} 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_cistatic void *get_vs_passthrough_pos_generic(struct blitter_context *blitter) 406bf215546Sopenharmony_ci{ 407bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 408bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci if (!ctx->vs) { 411bf215546Sopenharmony_ci static const enum tgsi_semantic semantic_names[] = 412bf215546Sopenharmony_ci { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC }; 413bf215546Sopenharmony_ci const uint semantic_indices[] = { 0, 0 }; 414bf215546Sopenharmony_ci ctx->vs = 415bf215546Sopenharmony_ci util_make_vertex_passthrough_shader(pipe, 2, semantic_names, 416bf215546Sopenharmony_ci semantic_indices, false); 417bf215546Sopenharmony_ci } 418bf215546Sopenharmony_ci return ctx->vs; 419bf215546Sopenharmony_ci} 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_cistatic void *get_vs_passthrough_pos(struct blitter_context *blitter) 422bf215546Sopenharmony_ci{ 423bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 424bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci if (!ctx->vs_nogeneric) { 427bf215546Sopenharmony_ci static const enum tgsi_semantic semantic_names[] = 428bf215546Sopenharmony_ci { TGSI_SEMANTIC_POSITION }; 429bf215546Sopenharmony_ci const uint semantic_indices[] = { 0 }; 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_ci ctx->vs_nogeneric = 432bf215546Sopenharmony_ci util_make_vertex_passthrough_shader(pipe, 1, 433bf215546Sopenharmony_ci semantic_names, 434bf215546Sopenharmony_ci semantic_indices, false); 435bf215546Sopenharmony_ci } 436bf215546Sopenharmony_ci return ctx->vs_nogeneric; 437bf215546Sopenharmony_ci} 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_cistatic void *get_vs_layered(struct blitter_context *blitter) 440bf215546Sopenharmony_ci{ 441bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 442bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 443bf215546Sopenharmony_ci 444bf215546Sopenharmony_ci if (!ctx->vs_layered) { 445bf215546Sopenharmony_ci ctx->vs_layered = util_make_layered_clear_vertex_shader(pipe); 446bf215546Sopenharmony_ci } 447bf215546Sopenharmony_ci return ctx->vs_layered; 448bf215546Sopenharmony_ci} 449bf215546Sopenharmony_ci 450bf215546Sopenharmony_cistatic void bind_fs_empty(struct blitter_context_priv *ctx) 451bf215546Sopenharmony_ci{ 452bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_ci if (!ctx->fs_empty) { 455bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 456bf215546Sopenharmony_ci ctx->fs_empty = util_make_empty_fragment_shader(pipe); 457bf215546Sopenharmony_ci } 458bf215546Sopenharmony_ci 459bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, ctx->fs_empty); 460bf215546Sopenharmony_ci} 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_cistatic void bind_fs_write_one_cbuf(struct blitter_context_priv *ctx) 463bf215546Sopenharmony_ci{ 464bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci if (!ctx->fs_write_one_cbuf) { 467bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 468bf215546Sopenharmony_ci ctx->fs_write_one_cbuf = 469bf215546Sopenharmony_ci util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC, 470bf215546Sopenharmony_ci TGSI_INTERPOLATE_CONSTANT, false); 471bf215546Sopenharmony_ci } 472bf215546Sopenharmony_ci 473bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf); 474bf215546Sopenharmony_ci} 475bf215546Sopenharmony_ci 476bf215546Sopenharmony_cistatic void bind_fs_clear_all_cbufs(struct blitter_context_priv *ctx) 477bf215546Sopenharmony_ci{ 478bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci if (!ctx->fs_clear_all_cbufs) { 481bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 482bf215546Sopenharmony_ci ctx->fs_clear_all_cbufs = util_make_fs_clear_all_cbufs(pipe); 483bf215546Sopenharmony_ci } 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, ctx->fs_clear_all_cbufs); 486bf215546Sopenharmony_ci} 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_civoid util_blitter_destroy(struct blitter_context *blitter) 489bf215546Sopenharmony_ci{ 490bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 491bf215546Sopenharmony_ci struct pipe_context *pipe = blitter->pipe; 492bf215546Sopenharmony_ci unsigned i, j, f; 493bf215546Sopenharmony_ci 494bf215546Sopenharmony_ci for (i = 0; i <= PIPE_MASK_RGBA; i++) 495bf215546Sopenharmony_ci for (j = 0; j < 2; j++) 496bf215546Sopenharmony_ci pipe->delete_blend_state(pipe, ctx->blend[i][j]); 497bf215546Sopenharmony_ci 498bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ctx->blend_clear); i++) { 499bf215546Sopenharmony_ci if (ctx->blend_clear[i]) 500bf215546Sopenharmony_ci pipe->delete_blend_state(pipe, ctx->blend_clear[i]); 501bf215546Sopenharmony_ci } 502bf215546Sopenharmony_ci pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 503bf215546Sopenharmony_ci pipe->delete_depth_stencil_alpha_state(pipe, 504bf215546Sopenharmony_ci ctx->dsa_write_depth_keep_stencil); 505bf215546Sopenharmony_ci pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 506bf215546Sopenharmony_ci pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ctx->dsa_replicate_stencil_bit); i++) { 509bf215546Sopenharmony_ci if (ctx->dsa_replicate_stencil_bit[i]) 510bf215546Sopenharmony_ci pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_replicate_stencil_bit[i]); 511bf215546Sopenharmony_ci } 512bf215546Sopenharmony_ci 513bf215546Sopenharmony_ci unsigned scissor, msaa; 514bf215546Sopenharmony_ci for (scissor = 0; scissor < 2; scissor++) { 515bf215546Sopenharmony_ci for (msaa = 0; msaa < 2; msaa++) { 516bf215546Sopenharmony_ci pipe->delete_rasterizer_state(pipe, ctx->rs_state[scissor][msaa]); 517bf215546Sopenharmony_ci } 518bf215546Sopenharmony_ci } 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci if (ctx->rs_discard_state) 521bf215546Sopenharmony_ci pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state); 522bf215546Sopenharmony_ci if (ctx->vs) 523bf215546Sopenharmony_ci pipe->delete_vs_state(pipe, ctx->vs); 524bf215546Sopenharmony_ci if (ctx->vs_nogeneric) 525bf215546Sopenharmony_ci pipe->delete_vs_state(pipe, ctx->vs_nogeneric); 526bf215546Sopenharmony_ci for (i = 0; i < 4; i++) 527bf215546Sopenharmony_ci if (ctx->vs_pos_only[i]) 528bf215546Sopenharmony_ci pipe->delete_vs_state(pipe, ctx->vs_pos_only[i]); 529bf215546Sopenharmony_ci if (ctx->vs_layered) 530bf215546Sopenharmony_ci pipe->delete_vs_state(pipe, ctx->vs_layered); 531bf215546Sopenharmony_ci pipe->delete_vertex_elements_state(pipe, ctx->velem_state); 532bf215546Sopenharmony_ci for (i = 0; i < 4; i++) { 533bf215546Sopenharmony_ci if (ctx->velem_state_readbuf[i]) { 534bf215546Sopenharmony_ci pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf[i]); 535bf215546Sopenharmony_ci } 536bf215546Sopenharmony_ci } 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) { 539bf215546Sopenharmony_ci for (unsigned type = 0; type < ARRAY_SIZE(ctx->fs_texfetch_col); ++type) { 540bf215546Sopenharmony_ci for (unsigned inst = 0; inst < 2; inst++) { 541bf215546Sopenharmony_ci if (ctx->fs_texfetch_col[type][i][inst]) 542bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_texfetch_col[type][i][inst]); 543bf215546Sopenharmony_ci } 544bf215546Sopenharmony_ci if (ctx->fs_texfetch_col_msaa[type][i]) 545bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa[type][i]); 546bf215546Sopenharmony_ci } 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci for (unsigned inst = 0; inst < 2; inst++) { 549bf215546Sopenharmony_ci if (ctx->fs_texfetch_depth[i][inst]) 550bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth[i][inst]); 551bf215546Sopenharmony_ci if (ctx->fs_texfetch_depthstencil[i][inst]) 552bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i][inst]); 553bf215546Sopenharmony_ci if (ctx->fs_texfetch_stencil[i][inst]) 554bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i][inst]); 555bf215546Sopenharmony_ci } 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci for (unsigned ss = 0; ss < 2; ss++) { 558bf215546Sopenharmony_ci if (ctx->fs_texfetch_depth_msaa[i][ss]) 559bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth_msaa[i][ss]); 560bf215546Sopenharmony_ci if (ctx->fs_texfetch_depthstencil_msaa[i][ss]) 561bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil_msaa[i][ss]); 562bf215546Sopenharmony_ci if (ctx->fs_texfetch_stencil_msaa[i][ss]) 563bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil_msaa[i][ss]); 564bf215546Sopenharmony_ci } 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci for (j = 0; j< ARRAY_SIZE(ctx->fs_resolve[i]); j++) 567bf215546Sopenharmony_ci for (f = 0; f < 2; f++) 568bf215546Sopenharmony_ci if (ctx->fs_resolve[i][j][f]) 569bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_resolve[i][j][f]); 570bf215546Sopenharmony_ci } 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ctx->fs_pack_color_zs); i++) { 573bf215546Sopenharmony_ci for (j = 0; j < ARRAY_SIZE(ctx->fs_pack_color_zs[0]); j++) { 574bf215546Sopenharmony_ci if (ctx->fs_pack_color_zs[i][j]) 575bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_pack_color_zs[i][j]); 576bf215546Sopenharmony_ci } 577bf215546Sopenharmony_ci } 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_ci if (ctx->fs_empty) 580bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_empty); 581bf215546Sopenharmony_ci if (ctx->fs_write_one_cbuf) 582bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_write_one_cbuf); 583bf215546Sopenharmony_ci if (ctx->fs_clear_all_cbufs) 584bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_clear_all_cbufs); 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ctx->fs_stencil_blit_fallback); ++i) 587bf215546Sopenharmony_ci if (ctx->fs_stencil_blit_fallback[i]) 588bf215546Sopenharmony_ci ctx->delete_fs_state(pipe, ctx->fs_stencil_blit_fallback[i]); 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_ci if (ctx->sampler_state_rect_linear) 591bf215546Sopenharmony_ci pipe->delete_sampler_state(pipe, ctx->sampler_state_rect_linear); 592bf215546Sopenharmony_ci if (ctx->sampler_state_rect) 593bf215546Sopenharmony_ci pipe->delete_sampler_state(pipe, ctx->sampler_state_rect); 594bf215546Sopenharmony_ci pipe->delete_sampler_state(pipe, ctx->sampler_state_linear); 595bf215546Sopenharmony_ci pipe->delete_sampler_state(pipe, ctx->sampler_state); 596bf215546Sopenharmony_ci FREE(ctx); 597bf215546Sopenharmony_ci} 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_civoid util_blitter_set_texture_multisample(struct blitter_context *blitter, 600bf215546Sopenharmony_ci bool supported) 601bf215546Sopenharmony_ci{ 602bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci ctx->has_texture_multisample = supported; 605bf215546Sopenharmony_ci} 606bf215546Sopenharmony_ci 607bf215546Sopenharmony_civoid util_blitter_set_running_flag(struct blitter_context *blitter) 608bf215546Sopenharmony_ci{ 609bf215546Sopenharmony_ci if (blitter->running) { 610bf215546Sopenharmony_ci _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", 611bf215546Sopenharmony_ci __LINE__); 612bf215546Sopenharmony_ci } 613bf215546Sopenharmony_ci blitter->running = true; 614bf215546Sopenharmony_ci 615bf215546Sopenharmony_ci blitter->pipe->set_active_query_state(blitter->pipe, false); 616bf215546Sopenharmony_ci} 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_civoid util_blitter_unset_running_flag(struct blitter_context *blitter) 619bf215546Sopenharmony_ci{ 620bf215546Sopenharmony_ci if (!blitter->running) { 621bf215546Sopenharmony_ci _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", 622bf215546Sopenharmony_ci __LINE__); 623bf215546Sopenharmony_ci } 624bf215546Sopenharmony_ci blitter->running = false; 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci blitter->pipe->set_active_query_state(blitter->pipe, true); 627bf215546Sopenharmony_ci} 628bf215546Sopenharmony_ci 629bf215546Sopenharmony_cistatic void blitter_check_saved_vertex_states(ASSERTED struct blitter_context_priv *ctx) 630bf215546Sopenharmony_ci{ 631bf215546Sopenharmony_ci assert(ctx->base.saved_vs != INVALID_PTR); 632bf215546Sopenharmony_ci assert(!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR); 633bf215546Sopenharmony_ci assert(!ctx->has_tessellation || ctx->base.saved_tcs != INVALID_PTR); 634bf215546Sopenharmony_ci assert(!ctx->has_tessellation || ctx->base.saved_tes != INVALID_PTR); 635bf215546Sopenharmony_ci assert(!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0u); 636bf215546Sopenharmony_ci assert(ctx->base.saved_rs_state != INVALID_PTR); 637bf215546Sopenharmony_ci} 638bf215546Sopenharmony_ci 639bf215546Sopenharmony_civoid util_blitter_restore_vertex_states(struct blitter_context *blitter) 640bf215546Sopenharmony_ci{ 641bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 642bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 643bf215546Sopenharmony_ci unsigned i; 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci /* Vertex buffer. */ 646bf215546Sopenharmony_ci if (ctx->base.saved_vertex_buffer.buffer.resource) { 647bf215546Sopenharmony_ci pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, true, 648bf215546Sopenharmony_ci &ctx->base.saved_vertex_buffer); 649bf215546Sopenharmony_ci ctx->base.saved_vertex_buffer.buffer.resource = NULL; 650bf215546Sopenharmony_ci } 651bf215546Sopenharmony_ci 652bf215546Sopenharmony_ci /* Vertex elements. */ 653bf215546Sopenharmony_ci if (ctx->base.saved_velem_state != INVALID_PTR) { 654bf215546Sopenharmony_ci pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state); 655bf215546Sopenharmony_ci ctx->base.saved_velem_state = INVALID_PTR; 656bf215546Sopenharmony_ci } 657bf215546Sopenharmony_ci 658bf215546Sopenharmony_ci /* Vertex shader. */ 659bf215546Sopenharmony_ci pipe->bind_vs_state(pipe, ctx->base.saved_vs); 660bf215546Sopenharmony_ci ctx->base.saved_vs = INVALID_PTR; 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_ci /* Geometry shader. */ 663bf215546Sopenharmony_ci if (ctx->has_geometry_shader) { 664bf215546Sopenharmony_ci pipe->bind_gs_state(pipe, ctx->base.saved_gs); 665bf215546Sopenharmony_ci ctx->base.saved_gs = INVALID_PTR; 666bf215546Sopenharmony_ci } 667bf215546Sopenharmony_ci 668bf215546Sopenharmony_ci if (ctx->has_tessellation) { 669bf215546Sopenharmony_ci pipe->bind_tcs_state(pipe, ctx->base.saved_tcs); 670bf215546Sopenharmony_ci pipe->bind_tes_state(pipe, ctx->base.saved_tes); 671bf215546Sopenharmony_ci ctx->base.saved_tcs = INVALID_PTR; 672bf215546Sopenharmony_ci ctx->base.saved_tes = INVALID_PTR; 673bf215546Sopenharmony_ci } 674bf215546Sopenharmony_ci 675bf215546Sopenharmony_ci /* Stream outputs. */ 676bf215546Sopenharmony_ci if (ctx->has_stream_out) { 677bf215546Sopenharmony_ci unsigned offsets[PIPE_MAX_SO_BUFFERS]; 678bf215546Sopenharmony_ci for (i = 0; i < ctx->base.saved_num_so_targets; i++) 679bf215546Sopenharmony_ci offsets[i] = (unsigned)-1; 680bf215546Sopenharmony_ci pipe->set_stream_output_targets(pipe, 681bf215546Sopenharmony_ci ctx->base.saved_num_so_targets, 682bf215546Sopenharmony_ci ctx->base.saved_so_targets, offsets); 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_ci for (i = 0; i < ctx->base.saved_num_so_targets; i++) 685bf215546Sopenharmony_ci pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL); 686bf215546Sopenharmony_ci 687bf215546Sopenharmony_ci ctx->base.saved_num_so_targets = ~0; 688bf215546Sopenharmony_ci } 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_ci /* Rasterizer. */ 691bf215546Sopenharmony_ci pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state); 692bf215546Sopenharmony_ci ctx->base.saved_rs_state = INVALID_PTR; 693bf215546Sopenharmony_ci} 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_cistatic void blitter_check_saved_fragment_states(ASSERTED struct blitter_context_priv *ctx) 696bf215546Sopenharmony_ci{ 697bf215546Sopenharmony_ci assert(ctx->base.saved_fs != INVALID_PTR); 698bf215546Sopenharmony_ci assert(ctx->base.saved_dsa_state != INVALID_PTR); 699bf215546Sopenharmony_ci assert(ctx->base.saved_blend_state != INVALID_PTR); 700bf215546Sopenharmony_ci} 701bf215546Sopenharmony_ci 702bf215546Sopenharmony_civoid util_blitter_restore_fragment_states(struct blitter_context *blitter) 703bf215546Sopenharmony_ci{ 704bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 705bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 706bf215546Sopenharmony_ci 707bf215546Sopenharmony_ci /* Fragment shader. */ 708bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, ctx->base.saved_fs); 709bf215546Sopenharmony_ci ctx->base.saved_fs = INVALID_PTR; 710bf215546Sopenharmony_ci 711bf215546Sopenharmony_ci /* Depth, stencil, alpha. */ 712bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state); 713bf215546Sopenharmony_ci ctx->base.saved_dsa_state = INVALID_PTR; 714bf215546Sopenharmony_ci 715bf215546Sopenharmony_ci /* Blend state. */ 716bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, ctx->base.saved_blend_state); 717bf215546Sopenharmony_ci ctx->base.saved_blend_state = INVALID_PTR; 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ci /* Sample mask. */ 720bf215546Sopenharmony_ci if (ctx->base.is_sample_mask_saved) { 721bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, ctx->base.saved_sample_mask); 722bf215546Sopenharmony_ci ctx->base.is_sample_mask_saved = false; 723bf215546Sopenharmony_ci } 724bf215546Sopenharmony_ci 725bf215546Sopenharmony_ci if (ctx->base.saved_min_samples != ~0 && pipe->set_min_samples) 726bf215546Sopenharmony_ci pipe->set_min_samples(pipe, ctx->base.saved_min_samples); 727bf215546Sopenharmony_ci ctx->base.saved_min_samples = ~0; 728bf215546Sopenharmony_ci 729bf215546Sopenharmony_ci /* Miscellaneous states. */ 730bf215546Sopenharmony_ci /* XXX check whether these are saved and whether they need to be restored 731bf215546Sopenharmony_ci * (depending on the operation) */ 732bf215546Sopenharmony_ci pipe->set_stencil_ref(pipe, ctx->base.saved_stencil_ref); 733bf215546Sopenharmony_ci 734bf215546Sopenharmony_ci if (!blitter->skip_viewport_restore) 735bf215546Sopenharmony_ci pipe->set_viewport_states(pipe, 0, 1, &ctx->base.saved_viewport); 736bf215546Sopenharmony_ci 737bf215546Sopenharmony_ci if (blitter->saved_num_window_rectangles) { 738bf215546Sopenharmony_ci pipe->set_window_rectangles(pipe, 739bf215546Sopenharmony_ci blitter->saved_window_rectangles_include, 740bf215546Sopenharmony_ci blitter->saved_num_window_rectangles, 741bf215546Sopenharmony_ci blitter->saved_window_rectangles); 742bf215546Sopenharmony_ci } 743bf215546Sopenharmony_ci} 744bf215546Sopenharmony_ci 745bf215546Sopenharmony_cistatic void blitter_check_saved_fb_state(ASSERTED struct blitter_context_priv *ctx) 746bf215546Sopenharmony_ci{ 747bf215546Sopenharmony_ci assert(ctx->base.saved_fb_state.nr_cbufs != (ubyte) ~0); 748bf215546Sopenharmony_ci} 749bf215546Sopenharmony_ci 750bf215546Sopenharmony_cistatic void blitter_disable_render_cond(struct blitter_context_priv *ctx) 751bf215546Sopenharmony_ci{ 752bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 753bf215546Sopenharmony_ci 754bf215546Sopenharmony_ci if (ctx->base.saved_render_cond_query) { 755bf215546Sopenharmony_ci pipe->render_condition(pipe, NULL, false, 0); 756bf215546Sopenharmony_ci } 757bf215546Sopenharmony_ci} 758bf215546Sopenharmony_ci 759bf215546Sopenharmony_civoid util_blitter_restore_render_cond(struct blitter_context *blitter) 760bf215546Sopenharmony_ci{ 761bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 762bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 763bf215546Sopenharmony_ci 764bf215546Sopenharmony_ci if (ctx->base.saved_render_cond_query) { 765bf215546Sopenharmony_ci pipe->render_condition(pipe, ctx->base.saved_render_cond_query, 766bf215546Sopenharmony_ci ctx->base.saved_render_cond_cond, 767bf215546Sopenharmony_ci ctx->base.saved_render_cond_mode); 768bf215546Sopenharmony_ci ctx->base.saved_render_cond_query = NULL; 769bf215546Sopenharmony_ci } 770bf215546Sopenharmony_ci} 771bf215546Sopenharmony_ci 772bf215546Sopenharmony_civoid util_blitter_restore_fb_state(struct blitter_context *blitter) 773bf215546Sopenharmony_ci{ 774bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 775bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 776bf215546Sopenharmony_ci 777bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state); 778bf215546Sopenharmony_ci util_unreference_framebuffer_state(&ctx->base.saved_fb_state); 779bf215546Sopenharmony_ci} 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_cistatic void blitter_check_saved_textures(ASSERTED struct blitter_context_priv *ctx) 782bf215546Sopenharmony_ci{ 783bf215546Sopenharmony_ci assert(ctx->base.saved_num_sampler_states != ~0u); 784bf215546Sopenharmony_ci assert(ctx->base.saved_num_sampler_views != ~0u); 785bf215546Sopenharmony_ci} 786bf215546Sopenharmony_ci 787bf215546Sopenharmony_cistatic void util_blitter_restore_textures_internal(struct blitter_context *blitter, unsigned count) 788bf215546Sopenharmony_ci{ 789bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 790bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 791bf215546Sopenharmony_ci unsigned i; 792bf215546Sopenharmony_ci 793bf215546Sopenharmony_ci /* Fragment sampler states. */ 794bf215546Sopenharmony_ci void *states[2] = {NULL}; 795bf215546Sopenharmony_ci assert(count <= ARRAY_SIZE(states)); 796bf215546Sopenharmony_ci if (ctx->base.saved_num_sampler_states) 797bf215546Sopenharmony_ci pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 798bf215546Sopenharmony_ci ctx->base.saved_num_sampler_states, 799bf215546Sopenharmony_ci ctx->base.saved_sampler_states); 800bf215546Sopenharmony_ci else if (count) 801bf215546Sopenharmony_ci pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 802bf215546Sopenharmony_ci count, 803bf215546Sopenharmony_ci states); 804bf215546Sopenharmony_ci 805bf215546Sopenharmony_ci ctx->base.saved_num_sampler_states = ~0; 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ci /* Fragment sampler views. */ 808bf215546Sopenharmony_ci if (ctx->base.saved_num_sampler_views) 809bf215546Sopenharmony_ci pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 810bf215546Sopenharmony_ci ctx->base.saved_num_sampler_views, 0, true, 811bf215546Sopenharmony_ci ctx->base.saved_sampler_views); 812bf215546Sopenharmony_ci else if (count) 813bf215546Sopenharmony_ci pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 814bf215546Sopenharmony_ci 0, count, true, 815bf215546Sopenharmony_ci NULL); 816bf215546Sopenharmony_ci 817bf215546Sopenharmony_ci /* Just clear them to NULL because set_sampler_views(take_ownership = true). */ 818bf215546Sopenharmony_ci for (i = 0; i < ctx->base.saved_num_sampler_views; i++) 819bf215546Sopenharmony_ci ctx->base.saved_sampler_views[i] = NULL; 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci ctx->base.saved_num_sampler_views = ~0; 822bf215546Sopenharmony_ci} 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_civoid util_blitter_restore_textures(struct blitter_context *blitter) 825bf215546Sopenharmony_ci{ 826bf215546Sopenharmony_ci util_blitter_restore_textures_internal(blitter, 0); 827bf215546Sopenharmony_ci} 828bf215546Sopenharmony_ci 829bf215546Sopenharmony_civoid util_blitter_restore_constant_buffer_state(struct blitter_context *blitter) 830bf215546Sopenharmony_ci{ 831bf215546Sopenharmony_ci struct pipe_context *pipe = blitter->pipe; 832bf215546Sopenharmony_ci 833bf215546Sopenharmony_ci pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot, 834bf215546Sopenharmony_ci true, &blitter->saved_fs_constant_buffer); 835bf215546Sopenharmony_ci blitter->saved_fs_constant_buffer.buffer = NULL; 836bf215546Sopenharmony_ci} 837bf215546Sopenharmony_ci 838bf215546Sopenharmony_cistatic void blitter_set_rectangle(struct blitter_context_priv *ctx, 839bf215546Sopenharmony_ci int x1, int y1, int x2, int y2, 840bf215546Sopenharmony_ci float depth) 841bf215546Sopenharmony_ci{ 842bf215546Sopenharmony_ci /* set vertex positions */ 843bf215546Sopenharmony_ci ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/ 844bf215546Sopenharmony_ci ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/ 845bf215546Sopenharmony_ci 846bf215546Sopenharmony_ci ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/ 847bf215546Sopenharmony_ci ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/ 848bf215546Sopenharmony_ci 849bf215546Sopenharmony_ci ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/ 850bf215546Sopenharmony_ci ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/ 851bf215546Sopenharmony_ci 852bf215546Sopenharmony_ci ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/ 853bf215546Sopenharmony_ci ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/ 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_ci for (unsigned i = 0; i < 4; ++i) 856bf215546Sopenharmony_ci ctx->vertices[i][0][2] = depth; 857bf215546Sopenharmony_ci 858bf215546Sopenharmony_ci /* viewport */ 859bf215546Sopenharmony_ci struct pipe_viewport_state viewport; 860bf215546Sopenharmony_ci viewport.scale[0] = 0.5f * ctx->dst_width; 861bf215546Sopenharmony_ci viewport.scale[1] = 0.5f * ctx->dst_height; 862bf215546Sopenharmony_ci viewport.scale[2] = 1.0f; 863bf215546Sopenharmony_ci viewport.translate[0] = 0.5f * ctx->dst_width; 864bf215546Sopenharmony_ci viewport.translate[1] = 0.5f * ctx->dst_height; 865bf215546Sopenharmony_ci viewport.translate[2] = 0.0f; 866bf215546Sopenharmony_ci viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X; 867bf215546Sopenharmony_ci viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y; 868bf215546Sopenharmony_ci viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z; 869bf215546Sopenharmony_ci viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W; 870bf215546Sopenharmony_ci ctx->base.pipe->set_viewport_states(ctx->base.pipe, 0, 1, &viewport); 871bf215546Sopenharmony_ci} 872bf215546Sopenharmony_ci 873bf215546Sopenharmony_cistatic void blitter_set_clear_color(struct blitter_context_priv *ctx, 874bf215546Sopenharmony_ci const float color[4]) 875bf215546Sopenharmony_ci{ 876bf215546Sopenharmony_ci int i; 877bf215546Sopenharmony_ci 878bf215546Sopenharmony_ci if (color) { 879bf215546Sopenharmony_ci for (i = 0; i < 4; i++) 880bf215546Sopenharmony_ci memcpy(&ctx->vertices[i][1][0], color, sizeof(uint32_t) * 4); 881bf215546Sopenharmony_ci } else { 882bf215546Sopenharmony_ci for (i = 0; i < 4; i++) 883bf215546Sopenharmony_ci memset(&ctx->vertices[i][1][0], 0, sizeof(uint32_t) * 4); 884bf215546Sopenharmony_ci } 885bf215546Sopenharmony_ci} 886bf215546Sopenharmony_ci 887bf215546Sopenharmony_cistatic void get_texcoords(struct pipe_sampler_view *src, 888bf215546Sopenharmony_ci unsigned src_width0, unsigned src_height0, 889bf215546Sopenharmony_ci int x1, int y1, int x2, int y2, 890bf215546Sopenharmony_ci float layer, unsigned sample, 891bf215546Sopenharmony_ci bool uses_txf, union blitter_attrib *out) 892bf215546Sopenharmony_ci{ 893bf215546Sopenharmony_ci unsigned level = src->u.tex.first_level; 894bf215546Sopenharmony_ci bool normalized = !uses_txf && 895bf215546Sopenharmony_ci src->target != PIPE_TEXTURE_RECT && 896bf215546Sopenharmony_ci src->texture->nr_samples <= 1; 897bf215546Sopenharmony_ci 898bf215546Sopenharmony_ci if (normalized) { 899bf215546Sopenharmony_ci out->texcoord.x1 = x1 / (float)u_minify(src_width0, level); 900bf215546Sopenharmony_ci out->texcoord.y1 = y1 / (float)u_minify(src_height0, level); 901bf215546Sopenharmony_ci out->texcoord.x2 = x2 / (float)u_minify(src_width0, level); 902bf215546Sopenharmony_ci out->texcoord.y2 = y2 / (float)u_minify(src_height0, level); 903bf215546Sopenharmony_ci } else { 904bf215546Sopenharmony_ci out->texcoord.x1 = x1; 905bf215546Sopenharmony_ci out->texcoord.y1 = y1; 906bf215546Sopenharmony_ci out->texcoord.x2 = x2; 907bf215546Sopenharmony_ci out->texcoord.y2 = y2; 908bf215546Sopenharmony_ci } 909bf215546Sopenharmony_ci 910bf215546Sopenharmony_ci out->texcoord.z = 0; 911bf215546Sopenharmony_ci out->texcoord.w = 0; 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci /* Set the layer. */ 914bf215546Sopenharmony_ci switch (src->target) { 915bf215546Sopenharmony_ci case PIPE_TEXTURE_3D: 916bf215546Sopenharmony_ci { 917bf215546Sopenharmony_ci float r = layer; 918bf215546Sopenharmony_ci 919bf215546Sopenharmony_ci if (!uses_txf) 920bf215546Sopenharmony_ci r /= u_minify(src->texture->depth0, src->u.tex.first_level); 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci out->texcoord.z = r; 923bf215546Sopenharmony_ci } 924bf215546Sopenharmony_ci break; 925bf215546Sopenharmony_ci 926bf215546Sopenharmony_ci case PIPE_TEXTURE_1D_ARRAY: 927bf215546Sopenharmony_ci out->texcoord.y1 = out->texcoord.y2 = layer; 928bf215546Sopenharmony_ci break; 929bf215546Sopenharmony_ci 930bf215546Sopenharmony_ci case PIPE_TEXTURE_2D_ARRAY: 931bf215546Sopenharmony_ci out->texcoord.z = layer; 932bf215546Sopenharmony_ci out->texcoord.w = sample; 933bf215546Sopenharmony_ci break; 934bf215546Sopenharmony_ci 935bf215546Sopenharmony_ci case PIPE_TEXTURE_CUBE_ARRAY: 936bf215546Sopenharmony_ci out->texcoord.w = (unsigned)layer / 6; 937bf215546Sopenharmony_ci break; 938bf215546Sopenharmony_ci 939bf215546Sopenharmony_ci case PIPE_TEXTURE_2D: 940bf215546Sopenharmony_ci out->texcoord.w = sample; 941bf215546Sopenharmony_ci break; 942bf215546Sopenharmony_ci 943bf215546Sopenharmony_ci default:; 944bf215546Sopenharmony_ci } 945bf215546Sopenharmony_ci} 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_cistatic void blitter_set_dst_dimensions(struct blitter_context_priv *ctx, 948bf215546Sopenharmony_ci unsigned width, unsigned height) 949bf215546Sopenharmony_ci{ 950bf215546Sopenharmony_ci ctx->dst_width = width; 951bf215546Sopenharmony_ci ctx->dst_height = height; 952bf215546Sopenharmony_ci} 953bf215546Sopenharmony_ci 954bf215546Sopenharmony_cistatic void set_texcoords_in_vertices(const union blitter_attrib *attrib, 955bf215546Sopenharmony_ci float *out, unsigned stride) 956bf215546Sopenharmony_ci{ 957bf215546Sopenharmony_ci out[0] = attrib->texcoord.x1; 958bf215546Sopenharmony_ci out[1] = attrib->texcoord.y1; 959bf215546Sopenharmony_ci out += stride; 960bf215546Sopenharmony_ci out[0] = attrib->texcoord.x2; 961bf215546Sopenharmony_ci out[1] = attrib->texcoord.y1; 962bf215546Sopenharmony_ci out += stride; 963bf215546Sopenharmony_ci out[0] = attrib->texcoord.x2; 964bf215546Sopenharmony_ci out[1] = attrib->texcoord.y2; 965bf215546Sopenharmony_ci out += stride; 966bf215546Sopenharmony_ci out[0] = attrib->texcoord.x1; 967bf215546Sopenharmony_ci out[1] = attrib->texcoord.y2; 968bf215546Sopenharmony_ci} 969bf215546Sopenharmony_ci 970bf215546Sopenharmony_cistatic void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx, 971bf215546Sopenharmony_ci enum pipe_format src_format, 972bf215546Sopenharmony_ci enum pipe_format dst_format, 973bf215546Sopenharmony_ci enum pipe_texture_target target, 974bf215546Sopenharmony_ci unsigned src_nr_samples, 975bf215546Sopenharmony_ci unsigned dst_nr_samples, 976bf215546Sopenharmony_ci unsigned filter, 977bf215546Sopenharmony_ci bool use_txf) 978bf215546Sopenharmony_ci{ 979bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 980bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex = 981bf215546Sopenharmony_ci util_pipe_tex_to_tgsi_tex(target, src_nr_samples); 982bf215546Sopenharmony_ci enum tgsi_return_type stype; 983bf215546Sopenharmony_ci enum tgsi_return_type dtype; 984bf215546Sopenharmony_ci unsigned type; 985bf215546Sopenharmony_ci 986bf215546Sopenharmony_ci assert(target < PIPE_MAX_TEXTURE_TYPES); 987bf215546Sopenharmony_ci 988bf215546Sopenharmony_ci if (util_format_is_pure_uint(src_format)) { 989bf215546Sopenharmony_ci stype = TGSI_RETURN_TYPE_UINT; 990bf215546Sopenharmony_ci if (util_format_is_pure_uint(dst_format)) { 991bf215546Sopenharmony_ci dtype = TGSI_RETURN_TYPE_UINT; 992bf215546Sopenharmony_ci type = 0; 993bf215546Sopenharmony_ci } else { 994bf215546Sopenharmony_ci assert(util_format_is_pure_sint(dst_format)); 995bf215546Sopenharmony_ci dtype = TGSI_RETURN_TYPE_SINT; 996bf215546Sopenharmony_ci type = 1; 997bf215546Sopenharmony_ci } 998bf215546Sopenharmony_ci } else if (util_format_is_pure_sint(src_format)) { 999bf215546Sopenharmony_ci stype = TGSI_RETURN_TYPE_SINT; 1000bf215546Sopenharmony_ci if (util_format_is_pure_sint(dst_format)) { 1001bf215546Sopenharmony_ci dtype = TGSI_RETURN_TYPE_SINT; 1002bf215546Sopenharmony_ci type = 2; 1003bf215546Sopenharmony_ci } else { 1004bf215546Sopenharmony_ci assert(util_format_is_pure_uint(dst_format)); 1005bf215546Sopenharmony_ci dtype = TGSI_RETURN_TYPE_UINT; 1006bf215546Sopenharmony_ci type = 3; 1007bf215546Sopenharmony_ci } 1008bf215546Sopenharmony_ci } else { 1009bf215546Sopenharmony_ci assert(!util_format_is_pure_uint(dst_format) && 1010bf215546Sopenharmony_ci !util_format_is_pure_sint(dst_format)); 1011bf215546Sopenharmony_ci dtype = stype = TGSI_RETURN_TYPE_FLOAT; 1012bf215546Sopenharmony_ci type = 4; 1013bf215546Sopenharmony_ci } 1014bf215546Sopenharmony_ci 1015bf215546Sopenharmony_ci if (src_nr_samples > 1) { 1016bf215546Sopenharmony_ci void **shader; 1017bf215546Sopenharmony_ci 1018bf215546Sopenharmony_ci /* OpenGL requires that integer textures just copy 1 sample instead 1019bf215546Sopenharmony_ci * of averaging. 1020bf215546Sopenharmony_ci */ 1021bf215546Sopenharmony_ci if (dst_nr_samples <= 1 && 1022bf215546Sopenharmony_ci stype != TGSI_RETURN_TYPE_UINT && 1023bf215546Sopenharmony_ci stype != TGSI_RETURN_TYPE_SINT) { 1024bf215546Sopenharmony_ci /* The destination has one sample, so we'll do color resolve. */ 1025bf215546Sopenharmony_ci unsigned index = GET_MSAA_RESOLVE_FS_IDX(src_nr_samples); 1026bf215546Sopenharmony_ci 1027bf215546Sopenharmony_ci assert(filter < 2); 1028bf215546Sopenharmony_ci 1029bf215546Sopenharmony_ci shader = &ctx->fs_resolve[target][index][filter]; 1030bf215546Sopenharmony_ci 1031bf215546Sopenharmony_ci if (!*shader) { 1032bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 1033bf215546Sopenharmony_ci if (filter == PIPE_TEX_FILTER_LINEAR) { 1034bf215546Sopenharmony_ci *shader = util_make_fs_msaa_resolve_bilinear(pipe, tgsi_tex, 1035bf215546Sopenharmony_ci src_nr_samples, 1036bf215546Sopenharmony_ci stype); 1037bf215546Sopenharmony_ci } 1038bf215546Sopenharmony_ci else { 1039bf215546Sopenharmony_ci *shader = util_make_fs_msaa_resolve(pipe, tgsi_tex, 1040bf215546Sopenharmony_ci src_nr_samples, 1041bf215546Sopenharmony_ci stype); 1042bf215546Sopenharmony_ci } 1043bf215546Sopenharmony_ci } 1044bf215546Sopenharmony_ci } 1045bf215546Sopenharmony_ci else { 1046bf215546Sopenharmony_ci /* The destination has multiple samples, we'll do 1047bf215546Sopenharmony_ci * an MSAA->MSAA copy. 1048bf215546Sopenharmony_ci */ 1049bf215546Sopenharmony_ci shader = &ctx->fs_texfetch_col_msaa[type][target]; 1050bf215546Sopenharmony_ci 1051bf215546Sopenharmony_ci /* Create the fragment shader on-demand. */ 1052bf215546Sopenharmony_ci if (!*shader) { 1053bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 1054bf215546Sopenharmony_ci *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex, stype, dtype, 1055bf215546Sopenharmony_ci ctx->has_sample_shading); 1056bf215546Sopenharmony_ci } 1057bf215546Sopenharmony_ci } 1058bf215546Sopenharmony_ci 1059bf215546Sopenharmony_ci return *shader; 1060bf215546Sopenharmony_ci } else { 1061bf215546Sopenharmony_ci void **shader; 1062bf215546Sopenharmony_ci 1063bf215546Sopenharmony_ci if (use_txf) 1064bf215546Sopenharmony_ci shader = &ctx->fs_texfetch_col[type][target][1]; 1065bf215546Sopenharmony_ci else 1066bf215546Sopenharmony_ci shader = &ctx->fs_texfetch_col[type][target][0]; 1067bf215546Sopenharmony_ci 1068bf215546Sopenharmony_ci /* Create the fragment shader on-demand. */ 1069bf215546Sopenharmony_ci if (!*shader) { 1070bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 1071bf215546Sopenharmony_ci *shader = util_make_fragment_tex_shader(pipe, tgsi_tex, 1072bf215546Sopenharmony_ci TGSI_INTERPOLATE_LINEAR, 1073bf215546Sopenharmony_ci stype, dtype, 1074bf215546Sopenharmony_ci ctx->has_tex_lz, use_txf); 1075bf215546Sopenharmony_ci } 1076bf215546Sopenharmony_ci 1077bf215546Sopenharmony_ci return *shader; 1078bf215546Sopenharmony_ci } 1079bf215546Sopenharmony_ci} 1080bf215546Sopenharmony_ci 1081bf215546Sopenharmony_cistatic inline 1082bf215546Sopenharmony_civoid *blitter_get_fs_pack_color_zs(struct blitter_context_priv *ctx, 1083bf215546Sopenharmony_ci enum pipe_texture_target target, 1084bf215546Sopenharmony_ci unsigned nr_samples, 1085bf215546Sopenharmony_ci enum pipe_format zs_format, 1086bf215546Sopenharmony_ci bool dst_is_color) 1087bf215546Sopenharmony_ci{ 1088bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 1089bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex = 1090bf215546Sopenharmony_ci util_pipe_tex_to_tgsi_tex(target, nr_samples); 1091bf215546Sopenharmony_ci int format_index = zs_format == PIPE_FORMAT_Z24_UNORM_S8_UINT ? 0 : 1092bf215546Sopenharmony_ci zs_format == PIPE_FORMAT_S8_UINT_Z24_UNORM ? 1 : 1093bf215546Sopenharmony_ci zs_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ? 2 : 1094bf215546Sopenharmony_ci zs_format == PIPE_FORMAT_Z24X8_UNORM ? 3 : 1095bf215546Sopenharmony_ci zs_format == PIPE_FORMAT_X8Z24_UNORM ? 4 : -1; 1096bf215546Sopenharmony_ci 1097bf215546Sopenharmony_ci if (format_index == -1) { 1098bf215546Sopenharmony_ci assert(0); 1099bf215546Sopenharmony_ci return NULL; 1100bf215546Sopenharmony_ci } 1101bf215546Sopenharmony_ci 1102bf215546Sopenharmony_ci /* The first 5 shaders pack ZS to color, the last 5 shaders unpack color 1103bf215546Sopenharmony_ci * to ZS. 1104bf215546Sopenharmony_ci */ 1105bf215546Sopenharmony_ci if (dst_is_color) 1106bf215546Sopenharmony_ci format_index += 5; 1107bf215546Sopenharmony_ci 1108bf215546Sopenharmony_ci void **shader = &ctx->fs_pack_color_zs[tgsi_tex][format_index]; 1109bf215546Sopenharmony_ci 1110bf215546Sopenharmony_ci /* Create the fragment shader on-demand. */ 1111bf215546Sopenharmony_ci if (!*shader) { 1112bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 1113bf215546Sopenharmony_ci *shader = util_make_fs_pack_color_zs(pipe, tgsi_tex, zs_format, 1114bf215546Sopenharmony_ci dst_is_color); 1115bf215546Sopenharmony_ci } 1116bf215546Sopenharmony_ci return *shader; 1117bf215546Sopenharmony_ci} 1118bf215546Sopenharmony_ci 1119bf215546Sopenharmony_cistatic inline 1120bf215546Sopenharmony_civoid *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx, 1121bf215546Sopenharmony_ci enum pipe_texture_target target, 1122bf215546Sopenharmony_ci unsigned src_samples, unsigned dst_samples, 1123bf215546Sopenharmony_ci bool use_txf) 1124bf215546Sopenharmony_ci{ 1125bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 1126bf215546Sopenharmony_ci 1127bf215546Sopenharmony_ci assert(target < PIPE_MAX_TEXTURE_TYPES); 1128bf215546Sopenharmony_ci 1129bf215546Sopenharmony_ci if (src_samples > 1) { 1130bf215546Sopenharmony_ci bool sample_shading = ctx->has_sample_shading && src_samples > 1 && 1131bf215546Sopenharmony_ci src_samples == dst_samples; 1132bf215546Sopenharmony_ci void **shader = &ctx->fs_texfetch_depth_msaa[target][sample_shading]; 1133bf215546Sopenharmony_ci 1134bf215546Sopenharmony_ci /* Create the fragment shader on-demand. */ 1135bf215546Sopenharmony_ci if (!*shader) { 1136bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex; 1137bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 1138bf215546Sopenharmony_ci tgsi_tex = util_pipe_tex_to_tgsi_tex(target, src_samples); 1139bf215546Sopenharmony_ci *shader = util_make_fs_blit_msaa_depth(pipe, tgsi_tex, sample_shading); 1140bf215546Sopenharmony_ci } 1141bf215546Sopenharmony_ci 1142bf215546Sopenharmony_ci return *shader; 1143bf215546Sopenharmony_ci } else { 1144bf215546Sopenharmony_ci void **shader; 1145bf215546Sopenharmony_ci 1146bf215546Sopenharmony_ci if (use_txf) 1147bf215546Sopenharmony_ci shader = &ctx->fs_texfetch_depth[target][1]; 1148bf215546Sopenharmony_ci else 1149bf215546Sopenharmony_ci shader = &ctx->fs_texfetch_depth[target][0]; 1150bf215546Sopenharmony_ci 1151bf215546Sopenharmony_ci /* Create the fragment shader on-demand. */ 1152bf215546Sopenharmony_ci if (!*shader) { 1153bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex; 1154bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 1155bf215546Sopenharmony_ci tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0); 1156bf215546Sopenharmony_ci *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_Z, tgsi_tex, 1157bf215546Sopenharmony_ci ctx->has_tex_lz, use_txf); 1158bf215546Sopenharmony_ci } 1159bf215546Sopenharmony_ci 1160bf215546Sopenharmony_ci return *shader; 1161bf215546Sopenharmony_ci } 1162bf215546Sopenharmony_ci} 1163bf215546Sopenharmony_ci 1164bf215546Sopenharmony_cistatic inline 1165bf215546Sopenharmony_civoid *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx, 1166bf215546Sopenharmony_ci enum pipe_texture_target target, 1167bf215546Sopenharmony_ci unsigned src_samples, 1168bf215546Sopenharmony_ci unsigned dst_samples, bool use_txf) 1169bf215546Sopenharmony_ci{ 1170bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 1171bf215546Sopenharmony_ci 1172bf215546Sopenharmony_ci assert(target < PIPE_MAX_TEXTURE_TYPES); 1173bf215546Sopenharmony_ci 1174bf215546Sopenharmony_ci if (src_samples > 1) { 1175bf215546Sopenharmony_ci bool sample_shading = ctx->has_sample_shading && src_samples > 1 && 1176bf215546Sopenharmony_ci src_samples == dst_samples; 1177bf215546Sopenharmony_ci void **shader = &ctx->fs_texfetch_depthstencil_msaa[target][sample_shading]; 1178bf215546Sopenharmony_ci 1179bf215546Sopenharmony_ci /* Create the fragment shader on-demand. */ 1180bf215546Sopenharmony_ci if (!*shader) { 1181bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex; 1182bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 1183bf215546Sopenharmony_ci tgsi_tex = util_pipe_tex_to_tgsi_tex(target, src_samples); 1184bf215546Sopenharmony_ci *shader = util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex, 1185bf215546Sopenharmony_ci sample_shading); 1186bf215546Sopenharmony_ci } 1187bf215546Sopenharmony_ci 1188bf215546Sopenharmony_ci return *shader; 1189bf215546Sopenharmony_ci } else { 1190bf215546Sopenharmony_ci void **shader; 1191bf215546Sopenharmony_ci 1192bf215546Sopenharmony_ci if (use_txf) 1193bf215546Sopenharmony_ci shader = &ctx->fs_texfetch_depthstencil[target][1]; 1194bf215546Sopenharmony_ci else 1195bf215546Sopenharmony_ci shader = &ctx->fs_texfetch_depthstencil[target][0]; 1196bf215546Sopenharmony_ci 1197bf215546Sopenharmony_ci /* Create the fragment shader on-demand. */ 1198bf215546Sopenharmony_ci if (!*shader) { 1199bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex; 1200bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 1201bf215546Sopenharmony_ci tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0); 1202bf215546Sopenharmony_ci *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_ZS, tgsi_tex, 1203bf215546Sopenharmony_ci ctx->has_tex_lz, use_txf); 1204bf215546Sopenharmony_ci } 1205bf215546Sopenharmony_ci 1206bf215546Sopenharmony_ci return *shader; 1207bf215546Sopenharmony_ci } 1208bf215546Sopenharmony_ci} 1209bf215546Sopenharmony_ci 1210bf215546Sopenharmony_cistatic inline 1211bf215546Sopenharmony_civoid *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx, 1212bf215546Sopenharmony_ci enum pipe_texture_target target, 1213bf215546Sopenharmony_ci unsigned src_samples, unsigned dst_samples, 1214bf215546Sopenharmony_ci bool use_txf) 1215bf215546Sopenharmony_ci{ 1216bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 1217bf215546Sopenharmony_ci 1218bf215546Sopenharmony_ci assert(target < PIPE_MAX_TEXTURE_TYPES); 1219bf215546Sopenharmony_ci 1220bf215546Sopenharmony_ci if (src_samples > 1) { 1221bf215546Sopenharmony_ci bool sample_shading = ctx->has_sample_shading && src_samples > 1 && 1222bf215546Sopenharmony_ci src_samples == dst_samples; 1223bf215546Sopenharmony_ci void **shader = &ctx->fs_texfetch_stencil_msaa[target][sample_shading]; 1224bf215546Sopenharmony_ci 1225bf215546Sopenharmony_ci /* Create the fragment shader on-demand. */ 1226bf215546Sopenharmony_ci if (!*shader) { 1227bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex; 1228bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 1229bf215546Sopenharmony_ci tgsi_tex = util_pipe_tex_to_tgsi_tex(target, src_samples); 1230bf215546Sopenharmony_ci *shader = util_make_fs_blit_msaa_stencil(pipe, tgsi_tex, 1231bf215546Sopenharmony_ci sample_shading); 1232bf215546Sopenharmony_ci } 1233bf215546Sopenharmony_ci 1234bf215546Sopenharmony_ci return *shader; 1235bf215546Sopenharmony_ci } else { 1236bf215546Sopenharmony_ci void **shader; 1237bf215546Sopenharmony_ci 1238bf215546Sopenharmony_ci if (use_txf) 1239bf215546Sopenharmony_ci shader = &ctx->fs_texfetch_stencil[target][1]; 1240bf215546Sopenharmony_ci else 1241bf215546Sopenharmony_ci shader = &ctx->fs_texfetch_stencil[target][0]; 1242bf215546Sopenharmony_ci 1243bf215546Sopenharmony_ci /* Create the fragment shader on-demand. */ 1244bf215546Sopenharmony_ci if (!*shader) { 1245bf215546Sopenharmony_ci enum tgsi_texture_type tgsi_tex; 1246bf215546Sopenharmony_ci assert(!ctx->cached_all_shaders); 1247bf215546Sopenharmony_ci tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0); 1248bf215546Sopenharmony_ci *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_S, tgsi_tex, 1249bf215546Sopenharmony_ci ctx->has_tex_lz, use_txf); 1250bf215546Sopenharmony_ci } 1251bf215546Sopenharmony_ci 1252bf215546Sopenharmony_ci return *shader; 1253bf215546Sopenharmony_ci } 1254bf215546Sopenharmony_ci} 1255bf215546Sopenharmony_ci 1256bf215546Sopenharmony_ci 1257bf215546Sopenharmony_ci/** 1258bf215546Sopenharmony_ci * Generate and save all fragment shaders that we will ever need for 1259bf215546Sopenharmony_ci * blitting. Drivers which use the 'draw' fallbacks will typically use 1260bf215546Sopenharmony_ci * this to make sure we generate/use shaders that don't go through the 1261bf215546Sopenharmony_ci * draw module's wrapper functions. 1262bf215546Sopenharmony_ci */ 1263bf215546Sopenharmony_civoid util_blitter_cache_all_shaders(struct blitter_context *blitter) 1264bf215546Sopenharmony_ci{ 1265bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1266bf215546Sopenharmony_ci struct pipe_context *pipe = blitter->pipe; 1267bf215546Sopenharmony_ci struct pipe_screen *screen = pipe->screen; 1268bf215546Sopenharmony_ci unsigned samples, j, f, target, max_samples, use_txf; 1269bf215546Sopenharmony_ci bool has_arraytex, has_cubearraytex; 1270bf215546Sopenharmony_ci 1271bf215546Sopenharmony_ci max_samples = ctx->has_texture_multisample ? 2 : 1; 1272bf215546Sopenharmony_ci has_arraytex = screen->get_param(screen, 1273bf215546Sopenharmony_ci PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) != 0; 1274bf215546Sopenharmony_ci has_cubearraytex = screen->get_param(screen, 1275bf215546Sopenharmony_ci PIPE_CAP_CUBE_MAP_ARRAY) != 0; 1276bf215546Sopenharmony_ci 1277bf215546Sopenharmony_ci /* It only matters if i <= 1 or > 1. */ 1278bf215546Sopenharmony_ci for (samples = 1; samples <= max_samples; samples++) { 1279bf215546Sopenharmony_ci for (target = PIPE_TEXTURE_1D; target < PIPE_MAX_TEXTURE_TYPES; target++) { 1280bf215546Sopenharmony_ci for (use_txf = 0; use_txf <= ctx->has_txf; use_txf++) { 1281bf215546Sopenharmony_ci if (!has_arraytex && 1282bf215546Sopenharmony_ci (target == PIPE_TEXTURE_1D_ARRAY || 1283bf215546Sopenharmony_ci target == PIPE_TEXTURE_2D_ARRAY)) { 1284bf215546Sopenharmony_ci continue; 1285bf215546Sopenharmony_ci } 1286bf215546Sopenharmony_ci if (!has_cubearraytex && 1287bf215546Sopenharmony_ci (target == PIPE_TEXTURE_CUBE_ARRAY)) 1288bf215546Sopenharmony_ci continue; 1289bf215546Sopenharmony_ci if (!ctx->has_texrect && 1290bf215546Sopenharmony_ci (target == PIPE_TEXTURE_RECT)) 1291bf215546Sopenharmony_ci continue; 1292bf215546Sopenharmony_ci 1293bf215546Sopenharmony_ci if (samples > 1 && 1294bf215546Sopenharmony_ci (target != PIPE_TEXTURE_2D && 1295bf215546Sopenharmony_ci target != PIPE_TEXTURE_2D_ARRAY)) 1296bf215546Sopenharmony_ci continue; 1297bf215546Sopenharmony_ci 1298bf215546Sopenharmony_ci if (samples > 1 && use_txf) 1299bf215546Sopenharmony_ci continue; /* TXF is the only option, use_txf has no effect */ 1300bf215546Sopenharmony_ci 1301bf215546Sopenharmony_ci /* If samples == 1, the shaders read one texel. If samples >= 1, 1302bf215546Sopenharmony_ci * they read one sample. 1303bf215546Sopenharmony_ci */ 1304bf215546Sopenharmony_ci blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT, 1305bf215546Sopenharmony_ci PIPE_FORMAT_R32_FLOAT, target, 1306bf215546Sopenharmony_ci samples, samples, 0, use_txf); 1307bf215546Sopenharmony_ci blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT, 1308bf215546Sopenharmony_ci PIPE_FORMAT_R32_UINT, target, 1309bf215546Sopenharmony_ci samples, samples, 0, use_txf); 1310bf215546Sopenharmony_ci blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT, 1311bf215546Sopenharmony_ci PIPE_FORMAT_R32_SINT, target, 1312bf215546Sopenharmony_ci samples, samples, 0, use_txf); 1313bf215546Sopenharmony_ci blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT, 1314bf215546Sopenharmony_ci PIPE_FORMAT_R32_SINT, target, 1315bf215546Sopenharmony_ci samples, samples, 0, use_txf); 1316bf215546Sopenharmony_ci blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT, 1317bf215546Sopenharmony_ci PIPE_FORMAT_R32_UINT, target, 1318bf215546Sopenharmony_ci samples, samples, 0, use_txf); 1319bf215546Sopenharmony_ci blitter_get_fs_texfetch_depth(ctx, target, samples, samples, use_txf); 1320bf215546Sopenharmony_ci if (ctx->has_stencil_export) { 1321bf215546Sopenharmony_ci blitter_get_fs_texfetch_depthstencil(ctx, target, samples, samples, use_txf); 1322bf215546Sopenharmony_ci blitter_get_fs_texfetch_stencil(ctx, target, samples, samples, use_txf); 1323bf215546Sopenharmony_ci } 1324bf215546Sopenharmony_ci 1325bf215546Sopenharmony_ci if (samples == 2) { 1326bf215546Sopenharmony_ci blitter_get_fs_texfetch_depth(ctx, target, samples, 1, use_txf); 1327bf215546Sopenharmony_ci if (ctx->has_stencil_export) { 1328bf215546Sopenharmony_ci blitter_get_fs_texfetch_depthstencil(ctx, target, samples, 1, use_txf); 1329bf215546Sopenharmony_ci blitter_get_fs_texfetch_stencil(ctx, target, samples, 1, use_txf); 1330bf215546Sopenharmony_ci } 1331bf215546Sopenharmony_ci } 1332bf215546Sopenharmony_ci 1333bf215546Sopenharmony_ci if (samples == 1) 1334bf215546Sopenharmony_ci continue; 1335bf215546Sopenharmony_ci 1336bf215546Sopenharmony_ci /* MSAA resolve shaders. */ 1337bf215546Sopenharmony_ci for (j = 2; j < 32; j++) { 1338bf215546Sopenharmony_ci if (!screen->is_format_supported(screen, PIPE_FORMAT_R32_FLOAT, 1339bf215546Sopenharmony_ci target, j, j, 1340bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW)) { 1341bf215546Sopenharmony_ci continue; 1342bf215546Sopenharmony_ci } 1343bf215546Sopenharmony_ci 1344bf215546Sopenharmony_ci for (f = 0; f < 2; f++) { 1345bf215546Sopenharmony_ci if (f != PIPE_TEX_FILTER_NEAREST && use_txf) 1346bf215546Sopenharmony_ci continue; 1347bf215546Sopenharmony_ci 1348bf215546Sopenharmony_ci blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT, 1349bf215546Sopenharmony_ci PIPE_FORMAT_R32_FLOAT, target, 1350bf215546Sopenharmony_ci j, 1, f, use_txf); 1351bf215546Sopenharmony_ci blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT, 1352bf215546Sopenharmony_ci PIPE_FORMAT_R32_UINT, target, 1353bf215546Sopenharmony_ci j, 1, f, use_txf); 1354bf215546Sopenharmony_ci blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT, 1355bf215546Sopenharmony_ci PIPE_FORMAT_R32_SINT, target, 1356bf215546Sopenharmony_ci j, 1, f, use_txf); 1357bf215546Sopenharmony_ci } 1358bf215546Sopenharmony_ci } 1359bf215546Sopenharmony_ci } 1360bf215546Sopenharmony_ci } 1361bf215546Sopenharmony_ci } 1362bf215546Sopenharmony_ci 1363bf215546Sopenharmony_ci ctx->fs_empty = util_make_empty_fragment_shader(pipe); 1364bf215546Sopenharmony_ci 1365bf215546Sopenharmony_ci ctx->fs_write_one_cbuf = 1366bf215546Sopenharmony_ci util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC, 1367bf215546Sopenharmony_ci TGSI_INTERPOLATE_CONSTANT, false); 1368bf215546Sopenharmony_ci 1369bf215546Sopenharmony_ci ctx->fs_clear_all_cbufs = util_make_fs_clear_all_cbufs(pipe); 1370bf215546Sopenharmony_ci 1371bf215546Sopenharmony_ci ctx->cached_all_shaders = true; 1372bf215546Sopenharmony_ci} 1373bf215546Sopenharmony_ci 1374bf215546Sopenharmony_cistatic void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx, 1375bf215546Sopenharmony_ci bool scissor, bool msaa) 1376bf215546Sopenharmony_ci{ 1377bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 1378bf215546Sopenharmony_ci 1379bf215546Sopenharmony_ci if (ctx->base.saved_num_window_rectangles) 1380bf215546Sopenharmony_ci pipe->set_window_rectangles(pipe, false, 0, NULL); 1381bf215546Sopenharmony_ci 1382bf215546Sopenharmony_ci pipe->bind_rasterizer_state(pipe, ctx->rs_state[scissor][msaa]); 1383bf215546Sopenharmony_ci 1384bf215546Sopenharmony_ci if (ctx->has_geometry_shader) 1385bf215546Sopenharmony_ci pipe->bind_gs_state(pipe, NULL); 1386bf215546Sopenharmony_ci if (ctx->has_tessellation) { 1387bf215546Sopenharmony_ci pipe->bind_tcs_state(pipe, NULL); 1388bf215546Sopenharmony_ci pipe->bind_tes_state(pipe, NULL); 1389bf215546Sopenharmony_ci } 1390bf215546Sopenharmony_ci if (ctx->has_stream_out) 1391bf215546Sopenharmony_ci pipe->set_stream_output_targets(pipe, 0, NULL, NULL); 1392bf215546Sopenharmony_ci} 1393bf215546Sopenharmony_ci 1394bf215546Sopenharmony_cistatic void blitter_draw(struct blitter_context_priv *ctx, 1395bf215546Sopenharmony_ci void *vertex_elements_cso, 1396bf215546Sopenharmony_ci blitter_get_vs_func get_vs, 1397bf215546Sopenharmony_ci int x1, int y1, int x2, int y2, float depth, 1398bf215546Sopenharmony_ci unsigned num_instances) 1399bf215546Sopenharmony_ci{ 1400bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 1401bf215546Sopenharmony_ci struct pipe_vertex_buffer vb = {0}; 1402bf215546Sopenharmony_ci 1403bf215546Sopenharmony_ci blitter_set_rectangle(ctx, x1, y1, x2, y2, depth); 1404bf215546Sopenharmony_ci 1405bf215546Sopenharmony_ci vb.stride = 8 * sizeof(float); 1406bf215546Sopenharmony_ci 1407bf215546Sopenharmony_ci u_upload_data(pipe->stream_uploader, 0, sizeof(ctx->vertices), 4, ctx->vertices, 1408bf215546Sopenharmony_ci &vb.buffer_offset, &vb.buffer.resource); 1409bf215546Sopenharmony_ci if (!vb.buffer.resource) 1410bf215546Sopenharmony_ci return; 1411bf215546Sopenharmony_ci u_upload_unmap(pipe->stream_uploader); 1412bf215546Sopenharmony_ci 1413bf215546Sopenharmony_ci pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, false, &vb); 1414bf215546Sopenharmony_ci pipe->bind_vertex_elements_state(pipe, vertex_elements_cso); 1415bf215546Sopenharmony_ci pipe->bind_vs_state(pipe, get_vs(&ctx->base)); 1416bf215546Sopenharmony_ci 1417bf215546Sopenharmony_ci if (ctx->base.use_index_buffer) { 1418bf215546Sopenharmony_ci /* Note that for V3D, 1419bf215546Sopenharmony_ci * dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_* require 1420bf215546Sopenharmony_ci * that the last vert of the two tris be the same. 1421bf215546Sopenharmony_ci */ 1422bf215546Sopenharmony_ci static uint8_t indices[6] = { 0, 1, 2, 0, 3, 2 }; 1423bf215546Sopenharmony_ci util_draw_elements_instanced(pipe, indices, 1, 0, 1424bf215546Sopenharmony_ci PIPE_PRIM_TRIANGLES, 0, 6, 1425bf215546Sopenharmony_ci 0, num_instances); 1426bf215546Sopenharmony_ci } else { 1427bf215546Sopenharmony_ci util_draw_arrays_instanced(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4, 1428bf215546Sopenharmony_ci 0, num_instances); 1429bf215546Sopenharmony_ci } 1430bf215546Sopenharmony_ci pipe_resource_reference(&vb.buffer.resource, NULL); 1431bf215546Sopenharmony_ci} 1432bf215546Sopenharmony_ci 1433bf215546Sopenharmony_civoid util_blitter_draw_rectangle(struct blitter_context *blitter, 1434bf215546Sopenharmony_ci void *vertex_elements_cso, 1435bf215546Sopenharmony_ci blitter_get_vs_func get_vs, 1436bf215546Sopenharmony_ci int x1, int y1, int x2, int y2, 1437bf215546Sopenharmony_ci float depth, unsigned num_instances, 1438bf215546Sopenharmony_ci enum blitter_attrib_type type, 1439bf215546Sopenharmony_ci const union blitter_attrib *attrib) 1440bf215546Sopenharmony_ci{ 1441bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1442bf215546Sopenharmony_ci unsigned i; 1443bf215546Sopenharmony_ci 1444bf215546Sopenharmony_ci switch (type) { 1445bf215546Sopenharmony_ci case UTIL_BLITTER_ATTRIB_COLOR: 1446bf215546Sopenharmony_ci blitter_set_clear_color(ctx, attrib->color); 1447bf215546Sopenharmony_ci break; 1448bf215546Sopenharmony_ci 1449bf215546Sopenharmony_ci case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW: 1450bf215546Sopenharmony_ci for (i = 0; i < 4; i++) { 1451bf215546Sopenharmony_ci ctx->vertices[i][1][2] = attrib->texcoord.z; 1452bf215546Sopenharmony_ci ctx->vertices[i][1][3] = attrib->texcoord.w; 1453bf215546Sopenharmony_ci } 1454bf215546Sopenharmony_ci set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8); 1455bf215546Sopenharmony_ci break; 1456bf215546Sopenharmony_ci case UTIL_BLITTER_ATTRIB_TEXCOORD_XY: 1457bf215546Sopenharmony_ci /* We clean-up the ZW components, just in case we used before XYZW, 1458bf215546Sopenharmony_ci * to avoid feeding in the shader with wrong values (like on the lod) 1459bf215546Sopenharmony_ci */ 1460bf215546Sopenharmony_ci for (i = 0; i < 4; i++) { 1461bf215546Sopenharmony_ci ctx->vertices[i][1][2] = 0; 1462bf215546Sopenharmony_ci ctx->vertices[i][1][3] = 0; 1463bf215546Sopenharmony_ci } 1464bf215546Sopenharmony_ci set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8); 1465bf215546Sopenharmony_ci break; 1466bf215546Sopenharmony_ci 1467bf215546Sopenharmony_ci default:; 1468bf215546Sopenharmony_ci } 1469bf215546Sopenharmony_ci 1470bf215546Sopenharmony_ci blitter_draw(ctx, vertex_elements_cso, get_vs, x1, y1, x2, y2, depth, 1471bf215546Sopenharmony_ci num_instances); 1472bf215546Sopenharmony_ci} 1473bf215546Sopenharmony_ci 1474bf215546Sopenharmony_cistatic void *get_clear_blend_state(struct blitter_context_priv *ctx, 1475bf215546Sopenharmony_ci unsigned clear_buffers) 1476bf215546Sopenharmony_ci{ 1477bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 1478bf215546Sopenharmony_ci int index; 1479bf215546Sopenharmony_ci 1480bf215546Sopenharmony_ci clear_buffers &= PIPE_CLEAR_COLOR; 1481bf215546Sopenharmony_ci 1482bf215546Sopenharmony_ci /* Return an existing blend state. */ 1483bf215546Sopenharmony_ci if (!clear_buffers) 1484bf215546Sopenharmony_ci return ctx->blend[0][0]; 1485bf215546Sopenharmony_ci 1486bf215546Sopenharmony_ci index = GET_CLEAR_BLEND_STATE_IDX(clear_buffers); 1487bf215546Sopenharmony_ci 1488bf215546Sopenharmony_ci if (ctx->blend_clear[index]) 1489bf215546Sopenharmony_ci return ctx->blend_clear[index]; 1490bf215546Sopenharmony_ci 1491bf215546Sopenharmony_ci /* Create a new one. */ 1492bf215546Sopenharmony_ci { 1493bf215546Sopenharmony_ci struct pipe_blend_state blend = {0}; 1494bf215546Sopenharmony_ci unsigned i; 1495bf215546Sopenharmony_ci 1496bf215546Sopenharmony_ci blend.independent_blend_enable = 1; 1497bf215546Sopenharmony_ci 1498bf215546Sopenharmony_ci for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { 1499bf215546Sopenharmony_ci if (clear_buffers & (PIPE_CLEAR_COLOR0 << i)) { 1500bf215546Sopenharmony_ci blend.rt[i].colormask = PIPE_MASK_RGBA; 1501bf215546Sopenharmony_ci blend.max_rt = i; 1502bf215546Sopenharmony_ci } 1503bf215546Sopenharmony_ci } 1504bf215546Sopenharmony_ci 1505bf215546Sopenharmony_ci ctx->blend_clear[index] = pipe->create_blend_state(pipe, &blend); 1506bf215546Sopenharmony_ci } 1507bf215546Sopenharmony_ci return ctx->blend_clear[index]; 1508bf215546Sopenharmony_ci} 1509bf215546Sopenharmony_ci 1510bf215546Sopenharmony_civoid util_blitter_common_clear_setup(struct blitter_context *blitter, 1511bf215546Sopenharmony_ci unsigned width, unsigned height, 1512bf215546Sopenharmony_ci unsigned clear_buffers, 1513bf215546Sopenharmony_ci void *custom_blend, void *custom_dsa) 1514bf215546Sopenharmony_ci{ 1515bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1516bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 1517bf215546Sopenharmony_ci 1518bf215546Sopenharmony_ci util_blitter_set_running_flag(blitter); 1519bf215546Sopenharmony_ci blitter_check_saved_vertex_states(ctx); 1520bf215546Sopenharmony_ci blitter_check_saved_fragment_states(ctx); 1521bf215546Sopenharmony_ci blitter_disable_render_cond(ctx); 1522bf215546Sopenharmony_ci 1523bf215546Sopenharmony_ci /* bind states */ 1524bf215546Sopenharmony_ci if (custom_blend) { 1525bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, custom_blend); 1526bf215546Sopenharmony_ci } else { 1527bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, get_clear_blend_state(ctx, clear_buffers)); 1528bf215546Sopenharmony_ci } 1529bf215546Sopenharmony_ci 1530bf215546Sopenharmony_ci if (custom_dsa) { 1531bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa); 1532bf215546Sopenharmony_ci } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { 1533bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 1534bf215546Sopenharmony_ci } else if (clear_buffers & PIPE_CLEAR_DEPTH) { 1535bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); 1536bf215546Sopenharmony_ci } else if (clear_buffers & PIPE_CLEAR_STENCIL) { 1537bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 1538bf215546Sopenharmony_ci } else { 1539bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 1540bf215546Sopenharmony_ci } 1541bf215546Sopenharmony_ci 1542bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, ~0); 1543bf215546Sopenharmony_ci if (pipe->set_min_samples) 1544bf215546Sopenharmony_ci pipe->set_min_samples(pipe, 1); 1545bf215546Sopenharmony_ci blitter_set_dst_dimensions(ctx, width, height); 1546bf215546Sopenharmony_ci} 1547bf215546Sopenharmony_ci 1548bf215546Sopenharmony_cistatic void util_blitter_clear_custom(struct blitter_context *blitter, 1549bf215546Sopenharmony_ci unsigned width, unsigned height, 1550bf215546Sopenharmony_ci unsigned num_layers, 1551bf215546Sopenharmony_ci unsigned clear_buffers, 1552bf215546Sopenharmony_ci const union pipe_color_union *color, 1553bf215546Sopenharmony_ci double depth, unsigned stencil, 1554bf215546Sopenharmony_ci void *custom_blend, void *custom_dsa, 1555bf215546Sopenharmony_ci bool msaa) 1556bf215546Sopenharmony_ci{ 1557bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1558bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 1559bf215546Sopenharmony_ci struct pipe_stencil_ref sr = { { 0 } }; 1560bf215546Sopenharmony_ci 1561bf215546Sopenharmony_ci assert(ctx->has_layered || num_layers <= 1); 1562bf215546Sopenharmony_ci 1563bf215546Sopenharmony_ci util_blitter_common_clear_setup(blitter, width, height, clear_buffers, 1564bf215546Sopenharmony_ci custom_blend, custom_dsa); 1565bf215546Sopenharmony_ci 1566bf215546Sopenharmony_ci sr.ref_value[0] = stencil & 0xff; 1567bf215546Sopenharmony_ci pipe->set_stencil_ref(pipe, sr); 1568bf215546Sopenharmony_ci 1569bf215546Sopenharmony_ci bool pass_generic = (clear_buffers & PIPE_CLEAR_COLOR) != 0; 1570bf215546Sopenharmony_ci enum blitter_attrib_type type = UTIL_BLITTER_ATTRIB_NONE; 1571bf215546Sopenharmony_ci 1572bf215546Sopenharmony_ci if (pass_generic) { 1573bf215546Sopenharmony_ci struct pipe_constant_buffer cb = { 1574bf215546Sopenharmony_ci .user_buffer = color->f, 1575bf215546Sopenharmony_ci .buffer_size = 4 * sizeof(float), 1576bf215546Sopenharmony_ci }; 1577bf215546Sopenharmony_ci pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot, 1578bf215546Sopenharmony_ci false, &cb); 1579bf215546Sopenharmony_ci bind_fs_clear_all_cbufs(ctx); 1580bf215546Sopenharmony_ci } else { 1581bf215546Sopenharmony_ci bind_fs_empty(ctx); 1582bf215546Sopenharmony_ci } 1583bf215546Sopenharmony_ci 1584bf215546Sopenharmony_ci if (num_layers > 1 && ctx->has_layered) { 1585bf215546Sopenharmony_ci blitter_get_vs_func get_vs = get_vs_layered; 1586bf215546Sopenharmony_ci 1587bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, false, msaa); 1588bf215546Sopenharmony_ci blitter->draw_rectangle(blitter, ctx->velem_state, get_vs, 1589bf215546Sopenharmony_ci 0, 0, width, height, 1590bf215546Sopenharmony_ci (float) depth, num_layers, type, NULL); 1591bf215546Sopenharmony_ci } else { 1592bf215546Sopenharmony_ci blitter_get_vs_func get_vs; 1593bf215546Sopenharmony_ci 1594bf215546Sopenharmony_ci if (pass_generic) 1595bf215546Sopenharmony_ci get_vs = get_vs_passthrough_pos_generic; 1596bf215546Sopenharmony_ci else 1597bf215546Sopenharmony_ci get_vs = get_vs_passthrough_pos; 1598bf215546Sopenharmony_ci 1599bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, false, msaa); 1600bf215546Sopenharmony_ci blitter->draw_rectangle(blitter, ctx->velem_state, get_vs, 1601bf215546Sopenharmony_ci 0, 0, width, height, 1602bf215546Sopenharmony_ci (float) depth, 1, type, NULL); 1603bf215546Sopenharmony_ci } 1604bf215546Sopenharmony_ci 1605bf215546Sopenharmony_ci util_blitter_restore_vertex_states(blitter); 1606bf215546Sopenharmony_ci util_blitter_restore_fragment_states(blitter); 1607bf215546Sopenharmony_ci util_blitter_restore_constant_buffer_state(blitter); 1608bf215546Sopenharmony_ci util_blitter_restore_render_cond(blitter); 1609bf215546Sopenharmony_ci util_blitter_unset_running_flag(blitter); 1610bf215546Sopenharmony_ci} 1611bf215546Sopenharmony_ci 1612bf215546Sopenharmony_civoid util_blitter_clear(struct blitter_context *blitter, 1613bf215546Sopenharmony_ci unsigned width, unsigned height, unsigned num_layers, 1614bf215546Sopenharmony_ci unsigned clear_buffers, 1615bf215546Sopenharmony_ci const union pipe_color_union *color, 1616bf215546Sopenharmony_ci double depth, unsigned stencil, 1617bf215546Sopenharmony_ci bool msaa) 1618bf215546Sopenharmony_ci{ 1619bf215546Sopenharmony_ci util_blitter_clear_custom(blitter, width, height, num_layers, 1620bf215546Sopenharmony_ci clear_buffers, color, depth, stencil, 1621bf215546Sopenharmony_ci NULL, NULL, msaa); 1622bf215546Sopenharmony_ci} 1623bf215546Sopenharmony_ci 1624bf215546Sopenharmony_civoid util_blitter_custom_clear_depth(struct blitter_context *blitter, 1625bf215546Sopenharmony_ci unsigned width, unsigned height, 1626bf215546Sopenharmony_ci double depth, void *custom_dsa) 1627bf215546Sopenharmony_ci{ 1628bf215546Sopenharmony_ci static const union pipe_color_union color; 1629bf215546Sopenharmony_ci util_blitter_clear_custom(blitter, width, height, 0, 0, &color, depth, 0, 1630bf215546Sopenharmony_ci NULL, custom_dsa, false); 1631bf215546Sopenharmony_ci} 1632bf215546Sopenharmony_ci 1633bf215546Sopenharmony_civoid util_blitter_default_dst_texture(struct pipe_surface *dst_templ, 1634bf215546Sopenharmony_ci struct pipe_resource *dst, 1635bf215546Sopenharmony_ci unsigned dstlevel, 1636bf215546Sopenharmony_ci unsigned dstz) 1637bf215546Sopenharmony_ci{ 1638bf215546Sopenharmony_ci memset(dst_templ, 0, sizeof(*dst_templ)); 1639bf215546Sopenharmony_ci dst_templ->format = util_format_linear(dst->format); 1640bf215546Sopenharmony_ci dst_templ->u.tex.level = dstlevel; 1641bf215546Sopenharmony_ci dst_templ->u.tex.first_layer = dstz; 1642bf215546Sopenharmony_ci dst_templ->u.tex.last_layer = dstz; 1643bf215546Sopenharmony_ci} 1644bf215546Sopenharmony_ci 1645bf215546Sopenharmony_cistatic struct pipe_surface * 1646bf215546Sopenharmony_ciutil_blitter_get_next_surface_layer(struct pipe_context *pipe, 1647bf215546Sopenharmony_ci struct pipe_surface *surf) 1648bf215546Sopenharmony_ci{ 1649bf215546Sopenharmony_ci struct pipe_surface dst_templ; 1650bf215546Sopenharmony_ci 1651bf215546Sopenharmony_ci memset(&dst_templ, 0, sizeof(dst_templ)); 1652bf215546Sopenharmony_ci dst_templ.format = surf->format; 1653bf215546Sopenharmony_ci dst_templ.u.tex.level = surf->u.tex.level; 1654bf215546Sopenharmony_ci dst_templ.u.tex.first_layer = surf->u.tex.first_layer + 1; 1655bf215546Sopenharmony_ci dst_templ.u.tex.last_layer = surf->u.tex.last_layer + 1; 1656bf215546Sopenharmony_ci 1657bf215546Sopenharmony_ci return pipe->create_surface(pipe, surf->texture, &dst_templ); 1658bf215546Sopenharmony_ci} 1659bf215546Sopenharmony_ci 1660bf215546Sopenharmony_civoid util_blitter_default_src_texture(struct blitter_context *blitter, 1661bf215546Sopenharmony_ci struct pipe_sampler_view *src_templ, 1662bf215546Sopenharmony_ci struct pipe_resource *src, 1663bf215546Sopenharmony_ci unsigned srclevel) 1664bf215546Sopenharmony_ci{ 1665bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1666bf215546Sopenharmony_ci 1667bf215546Sopenharmony_ci memset(src_templ, 0, sizeof(*src_templ)); 1668bf215546Sopenharmony_ci 1669bf215546Sopenharmony_ci if (ctx->cube_as_2darray && 1670bf215546Sopenharmony_ci (src->target == PIPE_TEXTURE_CUBE || 1671bf215546Sopenharmony_ci src->target == PIPE_TEXTURE_CUBE_ARRAY)) 1672bf215546Sopenharmony_ci src_templ->target = PIPE_TEXTURE_2D_ARRAY; 1673bf215546Sopenharmony_ci else 1674bf215546Sopenharmony_ci src_templ->target = src->target; 1675bf215546Sopenharmony_ci 1676bf215546Sopenharmony_ci src_templ->format = util_format_linear(src->format); 1677bf215546Sopenharmony_ci src_templ->u.tex.first_level = srclevel; 1678bf215546Sopenharmony_ci src_templ->u.tex.last_level = srclevel; 1679bf215546Sopenharmony_ci src_templ->u.tex.first_layer = 0; 1680bf215546Sopenharmony_ci src_templ->u.tex.last_layer = 1681bf215546Sopenharmony_ci src->target == PIPE_TEXTURE_3D ? u_minify(src->depth0, srclevel) - 1 1682bf215546Sopenharmony_ci : (unsigned)(src->array_size - 1); 1683bf215546Sopenharmony_ci src_templ->swizzle_r = PIPE_SWIZZLE_X; 1684bf215546Sopenharmony_ci src_templ->swizzle_g = PIPE_SWIZZLE_Y; 1685bf215546Sopenharmony_ci src_templ->swizzle_b = PIPE_SWIZZLE_Z; 1686bf215546Sopenharmony_ci src_templ->swizzle_a = PIPE_SWIZZLE_W; 1687bf215546Sopenharmony_ci} 1688bf215546Sopenharmony_ci 1689bf215546Sopenharmony_cistatic bool is_blit_generic_supported(struct blitter_context *blitter, 1690bf215546Sopenharmony_ci const struct pipe_resource *dst, 1691bf215546Sopenharmony_ci enum pipe_format dst_format, 1692bf215546Sopenharmony_ci const struct pipe_resource *src, 1693bf215546Sopenharmony_ci enum pipe_format src_format, 1694bf215546Sopenharmony_ci unsigned mask) 1695bf215546Sopenharmony_ci{ 1696bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1697bf215546Sopenharmony_ci struct pipe_screen *screen = ctx->base.pipe->screen; 1698bf215546Sopenharmony_ci 1699bf215546Sopenharmony_ci if (dst) { 1700bf215546Sopenharmony_ci unsigned bind; 1701bf215546Sopenharmony_ci const struct util_format_description *desc = 1702bf215546Sopenharmony_ci util_format_description(dst_format); 1703bf215546Sopenharmony_ci bool dst_has_stencil = util_format_has_stencil(desc); 1704bf215546Sopenharmony_ci 1705bf215546Sopenharmony_ci /* Stencil export must be supported for stencil copy. */ 1706bf215546Sopenharmony_ci if ((mask & PIPE_MASK_S) && dst_has_stencil && 1707bf215546Sopenharmony_ci !ctx->has_stencil_export) { 1708bf215546Sopenharmony_ci return false; 1709bf215546Sopenharmony_ci } 1710bf215546Sopenharmony_ci 1711bf215546Sopenharmony_ci if (dst_has_stencil || util_format_has_depth(desc)) 1712bf215546Sopenharmony_ci bind = PIPE_BIND_DEPTH_STENCIL; 1713bf215546Sopenharmony_ci else 1714bf215546Sopenharmony_ci bind = PIPE_BIND_RENDER_TARGET; 1715bf215546Sopenharmony_ci 1716bf215546Sopenharmony_ci if (!screen->is_format_supported(screen, dst_format, dst->target, 1717bf215546Sopenharmony_ci dst->nr_samples, dst->nr_storage_samples, 1718bf215546Sopenharmony_ci bind)) { 1719bf215546Sopenharmony_ci return false; 1720bf215546Sopenharmony_ci } 1721bf215546Sopenharmony_ci } 1722bf215546Sopenharmony_ci 1723bf215546Sopenharmony_ci if (src) { 1724bf215546Sopenharmony_ci if (src->nr_samples > 1 && !ctx->has_texture_multisample) { 1725bf215546Sopenharmony_ci return false; 1726bf215546Sopenharmony_ci } 1727bf215546Sopenharmony_ci 1728bf215546Sopenharmony_ci if (!screen->is_format_supported(screen, src_format, src->target, 1729bf215546Sopenharmony_ci src->nr_samples, src->nr_storage_samples, 1730bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW)) { 1731bf215546Sopenharmony_ci return false; 1732bf215546Sopenharmony_ci } 1733bf215546Sopenharmony_ci 1734bf215546Sopenharmony_ci /* Check stencil sampler support for stencil copy. */ 1735bf215546Sopenharmony_ci if (mask & PIPE_MASK_S) { 1736bf215546Sopenharmony_ci if (util_format_has_stencil(util_format_description(src_format))) { 1737bf215546Sopenharmony_ci enum pipe_format stencil_format = 1738bf215546Sopenharmony_ci util_format_stencil_only(src_format); 1739bf215546Sopenharmony_ci assert(stencil_format != PIPE_FORMAT_NONE); 1740bf215546Sopenharmony_ci 1741bf215546Sopenharmony_ci if (stencil_format != src_format && 1742bf215546Sopenharmony_ci !screen->is_format_supported(screen, stencil_format, 1743bf215546Sopenharmony_ci src->target, src->nr_samples, 1744bf215546Sopenharmony_ci src->nr_storage_samples, 1745bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW)) { 1746bf215546Sopenharmony_ci return false; 1747bf215546Sopenharmony_ci } 1748bf215546Sopenharmony_ci } 1749bf215546Sopenharmony_ci } 1750bf215546Sopenharmony_ci } 1751bf215546Sopenharmony_ci 1752bf215546Sopenharmony_ci return true; 1753bf215546Sopenharmony_ci} 1754bf215546Sopenharmony_ci 1755bf215546Sopenharmony_cibool util_blitter_is_copy_supported(struct blitter_context *blitter, 1756bf215546Sopenharmony_ci const struct pipe_resource *dst, 1757bf215546Sopenharmony_ci const struct pipe_resource *src) 1758bf215546Sopenharmony_ci{ 1759bf215546Sopenharmony_ci return is_blit_generic_supported(blitter, dst, dst->format, 1760bf215546Sopenharmony_ci src, src->format, PIPE_MASK_RGBAZS); 1761bf215546Sopenharmony_ci} 1762bf215546Sopenharmony_ci 1763bf215546Sopenharmony_cibool util_blitter_is_blit_supported(struct blitter_context *blitter, 1764bf215546Sopenharmony_ci const struct pipe_blit_info *info) 1765bf215546Sopenharmony_ci{ 1766bf215546Sopenharmony_ci return is_blit_generic_supported(blitter, 1767bf215546Sopenharmony_ci info->dst.resource, info->dst.format, 1768bf215546Sopenharmony_ci info->src.resource, info->src.format, 1769bf215546Sopenharmony_ci info->mask); 1770bf215546Sopenharmony_ci} 1771bf215546Sopenharmony_ci 1772bf215546Sopenharmony_civoid util_blitter_copy_texture(struct blitter_context *blitter, 1773bf215546Sopenharmony_ci struct pipe_resource *dst, 1774bf215546Sopenharmony_ci unsigned dst_level, 1775bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, unsigned dstz, 1776bf215546Sopenharmony_ci struct pipe_resource *src, 1777bf215546Sopenharmony_ci unsigned src_level, 1778bf215546Sopenharmony_ci const struct pipe_box *srcbox) 1779bf215546Sopenharmony_ci{ 1780bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1781bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 1782bf215546Sopenharmony_ci struct pipe_surface *dst_view, dst_templ; 1783bf215546Sopenharmony_ci struct pipe_sampler_view src_templ, *src_view; 1784bf215546Sopenharmony_ci struct pipe_box dstbox; 1785bf215546Sopenharmony_ci 1786bf215546Sopenharmony_ci assert(dst && src); 1787bf215546Sopenharmony_ci assert(src->target < PIPE_MAX_TEXTURE_TYPES); 1788bf215546Sopenharmony_ci 1789bf215546Sopenharmony_ci u_box_3d(dstx, dsty, dstz, abs(srcbox->width), abs(srcbox->height), 1790bf215546Sopenharmony_ci abs(srcbox->depth), &dstbox); 1791bf215546Sopenharmony_ci 1792bf215546Sopenharmony_ci /* Initialize the surface. */ 1793bf215546Sopenharmony_ci util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); 1794bf215546Sopenharmony_ci dst_view = pipe->create_surface(pipe, dst, &dst_templ); 1795bf215546Sopenharmony_ci 1796bf215546Sopenharmony_ci /* Initialize the sampler view. */ 1797bf215546Sopenharmony_ci util_blitter_default_src_texture(blitter, &src_templ, src, src_level); 1798bf215546Sopenharmony_ci src_view = pipe->create_sampler_view(pipe, src, &src_templ); 1799bf215546Sopenharmony_ci 1800bf215546Sopenharmony_ci /* Copy. */ 1801bf215546Sopenharmony_ci util_blitter_blit_generic(blitter, dst_view, &dstbox, 1802bf215546Sopenharmony_ci src_view, srcbox, src->width0, src->height0, 1803bf215546Sopenharmony_ci PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, 1804bf215546Sopenharmony_ci false, false, 0); 1805bf215546Sopenharmony_ci 1806bf215546Sopenharmony_ci pipe_surface_reference(&dst_view, NULL); 1807bf215546Sopenharmony_ci pipe_sampler_view_reference(&src_view, NULL); 1808bf215546Sopenharmony_ci} 1809bf215546Sopenharmony_ci 1810bf215546Sopenharmony_cistatic void 1811bf215546Sopenharmony_ciblitter_draw_tex(struct blitter_context_priv *ctx, 1812bf215546Sopenharmony_ci int dst_x1, int dst_y1, int dst_x2, int dst_y2, 1813bf215546Sopenharmony_ci struct pipe_sampler_view *src, 1814bf215546Sopenharmony_ci unsigned src_width0, unsigned src_height0, 1815bf215546Sopenharmony_ci int src_x1, int src_y1, int src_x2, int src_y2, 1816bf215546Sopenharmony_ci float layer, unsigned sample, 1817bf215546Sopenharmony_ci bool uses_txf, enum blitter_attrib_type type) 1818bf215546Sopenharmony_ci{ 1819bf215546Sopenharmony_ci union blitter_attrib coord; 1820bf215546Sopenharmony_ci blitter_get_vs_func get_vs = get_vs_passthrough_pos_generic; 1821bf215546Sopenharmony_ci 1822bf215546Sopenharmony_ci get_texcoords(src, src_width0, src_height0, 1823bf215546Sopenharmony_ci src_x1, src_y1, src_x2, src_y2, layer, sample, 1824bf215546Sopenharmony_ci uses_txf, &coord); 1825bf215546Sopenharmony_ci 1826bf215546Sopenharmony_ci if (src->target == PIPE_TEXTURE_CUBE || 1827bf215546Sopenharmony_ci src->target == PIPE_TEXTURE_CUBE_ARRAY) { 1828bf215546Sopenharmony_ci float face_coord[4][2]; 1829bf215546Sopenharmony_ci 1830bf215546Sopenharmony_ci set_texcoords_in_vertices(&coord, &face_coord[0][0], 2); 1831bf215546Sopenharmony_ci util_map_texcoords2d_onto_cubemap((unsigned)layer % 6, 1832bf215546Sopenharmony_ci /* pointer, stride in floats */ 1833bf215546Sopenharmony_ci &face_coord[0][0], 2, 1834bf215546Sopenharmony_ci &ctx->vertices[0][1][0], 8, 1835bf215546Sopenharmony_ci false); 1836bf215546Sopenharmony_ci for (unsigned i = 0; i < 4; i++) 1837bf215546Sopenharmony_ci ctx->vertices[i][1][3] = coord.texcoord.w; 1838bf215546Sopenharmony_ci 1839bf215546Sopenharmony_ci /* Cubemaps don't use draw_rectangle. */ 1840bf215546Sopenharmony_ci blitter_draw(ctx, ctx->velem_state, get_vs, 1841bf215546Sopenharmony_ci dst_x1, dst_y1, dst_x2, dst_y2, 0, 1); 1842bf215546Sopenharmony_ci } else { 1843bf215546Sopenharmony_ci ctx->base.draw_rectangle(&ctx->base, ctx->velem_state, get_vs, 1844bf215546Sopenharmony_ci dst_x1, dst_y1, dst_x2, dst_y2, 1845bf215546Sopenharmony_ci 0, 1, type, &coord); 1846bf215546Sopenharmony_ci } 1847bf215546Sopenharmony_ci} 1848bf215546Sopenharmony_ci 1849bf215546Sopenharmony_cistatic void do_blits(struct blitter_context_priv *ctx, 1850bf215546Sopenharmony_ci struct pipe_surface *dst, 1851bf215546Sopenharmony_ci const struct pipe_box *dstbox, 1852bf215546Sopenharmony_ci struct pipe_sampler_view *src, 1853bf215546Sopenharmony_ci unsigned src_width0, 1854bf215546Sopenharmony_ci unsigned src_height0, 1855bf215546Sopenharmony_ci const struct pipe_box *srcbox, 1856bf215546Sopenharmony_ci bool is_zsbuf, 1857bf215546Sopenharmony_ci bool uses_txf, bool sample0_only, 1858bf215546Sopenharmony_ci unsigned dst_sample) 1859bf215546Sopenharmony_ci{ 1860bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 1861bf215546Sopenharmony_ci unsigned src_samples = src->texture->nr_samples; 1862bf215546Sopenharmony_ci unsigned dst_samples = dst->texture->nr_samples; 1863bf215546Sopenharmony_ci bool sample_shading = ctx->has_sample_shading && src_samples > 1 && 1864bf215546Sopenharmony_ci src_samples == dst_samples && !sample0_only; 1865bf215546Sopenharmony_ci enum pipe_texture_target src_target = src->target; 1866bf215546Sopenharmony_ci struct pipe_framebuffer_state fb_state = {0}; 1867bf215546Sopenharmony_ci 1868bf215546Sopenharmony_ci /* Initialize framebuffer state. */ 1869bf215546Sopenharmony_ci fb_state.width = dst->width; 1870bf215546Sopenharmony_ci fb_state.height = dst->height; 1871bf215546Sopenharmony_ci fb_state.nr_cbufs = is_zsbuf ? 0 : 1; 1872bf215546Sopenharmony_ci 1873bf215546Sopenharmony_ci blitter_set_dst_dimensions(ctx, fb_state.width, fb_state.height); 1874bf215546Sopenharmony_ci 1875bf215546Sopenharmony_ci if ((src_target == PIPE_TEXTURE_1D || 1876bf215546Sopenharmony_ci src_target == PIPE_TEXTURE_2D || 1877bf215546Sopenharmony_ci src_target == PIPE_TEXTURE_RECT) && 1878bf215546Sopenharmony_ci (src_samples <= 1 || sample_shading)) { 1879bf215546Sopenharmony_ci /* Set framebuffer state. */ 1880bf215546Sopenharmony_ci if (is_zsbuf) { 1881bf215546Sopenharmony_ci fb_state.zsbuf = dst; 1882bf215546Sopenharmony_ci } else { 1883bf215546Sopenharmony_ci fb_state.cbufs[0] = dst; 1884bf215546Sopenharmony_ci } 1885bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &fb_state); 1886bf215546Sopenharmony_ci 1887bf215546Sopenharmony_ci /* Draw. */ 1888bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, dst_sample ? BITFIELD_BIT(dst_sample - 1) : ~0); 1889bf215546Sopenharmony_ci if (pipe->set_min_samples) 1890bf215546Sopenharmony_ci pipe->set_min_samples(pipe, sample_shading ? dst_samples : 1); 1891bf215546Sopenharmony_ci blitter_draw_tex(ctx, dstbox->x, dstbox->y, 1892bf215546Sopenharmony_ci dstbox->x + dstbox->width, 1893bf215546Sopenharmony_ci dstbox->y + dstbox->height, 1894bf215546Sopenharmony_ci src, src_width0, src_height0, srcbox->x, srcbox->y, 1895bf215546Sopenharmony_ci srcbox->x + srcbox->width, srcbox->y + srcbox->height, 1896bf215546Sopenharmony_ci 0, 0, uses_txf, UTIL_BLITTER_ATTRIB_TEXCOORD_XY); 1897bf215546Sopenharmony_ci } else { 1898bf215546Sopenharmony_ci /* Draw the quad with the generic codepath. */ 1899bf215546Sopenharmony_ci int dst_z; 1900bf215546Sopenharmony_ci for (dst_z = 0; dst_z < dstbox->depth; dst_z++) { 1901bf215546Sopenharmony_ci struct pipe_surface *old; 1902bf215546Sopenharmony_ci bool flipped = (srcbox->depth < 0); 1903bf215546Sopenharmony_ci float depth_center_offset = 0.0; 1904bf215546Sopenharmony_ci int src_depth = abs(srcbox->depth); 1905bf215546Sopenharmony_ci float src_z_step = src_depth / (float)dstbox->depth; 1906bf215546Sopenharmony_ci 1907bf215546Sopenharmony_ci /* Scale Z properly if the blit is scaled. 1908bf215546Sopenharmony_ci * 1909bf215546Sopenharmony_ci * When downscaling, we want the coordinates centered, so that 1910bf215546Sopenharmony_ci * mipmapping works for 3D textures. For example, when generating 1911bf215546Sopenharmony_ci * a 4x4x4 level, this wouldn't average the pixels: 1912bf215546Sopenharmony_ci * 1913bf215546Sopenharmony_ci * src Z: 0 1 2 3 4 5 6 7 1914bf215546Sopenharmony_ci * dst Z: 0 1 2 3 1915bf215546Sopenharmony_ci * 1916bf215546Sopenharmony_ci * Because the pixels are not centered below the pixels of the higher 1917bf215546Sopenharmony_ci * level. Therefore, we want this: 1918bf215546Sopenharmony_ci * src Z: 0 1 2 3 4 5 6 7 1919bf215546Sopenharmony_ci * dst Z: 0 1 2 3 1920bf215546Sopenharmony_ci * 1921bf215546Sopenharmony_ci * This calculation is taken from the radv driver. 1922bf215546Sopenharmony_ci */ 1923bf215546Sopenharmony_ci if (src_target == PIPE_TEXTURE_3D) 1924bf215546Sopenharmony_ci depth_center_offset = 0.5 / dstbox->depth * src_depth; 1925bf215546Sopenharmony_ci 1926bf215546Sopenharmony_ci if (flipped) { 1927bf215546Sopenharmony_ci src_z_step *= - 1; 1928bf215546Sopenharmony_ci depth_center_offset *= -1; 1929bf215546Sopenharmony_ci } 1930bf215546Sopenharmony_ci 1931bf215546Sopenharmony_ci float src_z = dst_z * src_z_step + depth_center_offset; 1932bf215546Sopenharmony_ci 1933bf215546Sopenharmony_ci /* Set framebuffer state. */ 1934bf215546Sopenharmony_ci if (is_zsbuf) { 1935bf215546Sopenharmony_ci fb_state.zsbuf = dst; 1936bf215546Sopenharmony_ci } else { 1937bf215546Sopenharmony_ci fb_state.cbufs[0] = dst; 1938bf215546Sopenharmony_ci } 1939bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &fb_state); 1940bf215546Sopenharmony_ci 1941bf215546Sopenharmony_ci /* See if we need to blit a multisample or singlesample buffer. */ 1942bf215546Sopenharmony_ci if (sample0_only || (src_samples == dst_samples && dst_samples > 1)) { 1943bf215546Sopenharmony_ci /* MSAA copy. */ 1944bf215546Sopenharmony_ci unsigned i, max_sample = sample0_only ? 0 : dst_samples - 1; 1945bf215546Sopenharmony_ci 1946bf215546Sopenharmony_ci if (sample_shading) { 1947bf215546Sopenharmony_ci assert(dst_sample == 0); 1948bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, ~0); 1949bf215546Sopenharmony_ci if (pipe->set_min_samples) 1950bf215546Sopenharmony_ci pipe->set_min_samples(pipe, max_sample); 1951bf215546Sopenharmony_ci blitter_draw_tex(ctx, dstbox->x, dstbox->y, 1952bf215546Sopenharmony_ci dstbox->x + dstbox->width, 1953bf215546Sopenharmony_ci dstbox->y + dstbox->height, 1954bf215546Sopenharmony_ci src, src_width0, src_height0, 1955bf215546Sopenharmony_ci srcbox->x, srcbox->y, 1956bf215546Sopenharmony_ci srcbox->x + srcbox->width, 1957bf215546Sopenharmony_ci srcbox->y + srcbox->height, 1958bf215546Sopenharmony_ci srcbox->z + src_z, 0, uses_txf, 1959bf215546Sopenharmony_ci UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW); 1960bf215546Sopenharmony_ci } else { 1961bf215546Sopenharmony_ci if (pipe->set_min_samples) 1962bf215546Sopenharmony_ci pipe->set_min_samples(pipe, 1); 1963bf215546Sopenharmony_ci 1964bf215546Sopenharmony_ci for (i = 0; i <= max_sample; i++) { 1965bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, 1 << i); 1966bf215546Sopenharmony_ci blitter_draw_tex(ctx, dstbox->x, dstbox->y, 1967bf215546Sopenharmony_ci dstbox->x + dstbox->width, 1968bf215546Sopenharmony_ci dstbox->y + dstbox->height, 1969bf215546Sopenharmony_ci src, src_width0, src_height0, 1970bf215546Sopenharmony_ci srcbox->x, srcbox->y, 1971bf215546Sopenharmony_ci srcbox->x + srcbox->width, 1972bf215546Sopenharmony_ci srcbox->y + srcbox->height, 1973bf215546Sopenharmony_ci srcbox->z + src_z, i, uses_txf, 1974bf215546Sopenharmony_ci UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW); 1975bf215546Sopenharmony_ci } 1976bf215546Sopenharmony_ci } 1977bf215546Sopenharmony_ci } else { 1978bf215546Sopenharmony_ci /* Normal copy, MSAA upsampling, or MSAA resolve. */ 1979bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, dst_sample ? BITFIELD_BIT(dst_sample - 1) : ~0); 1980bf215546Sopenharmony_ci if (pipe->set_min_samples) 1981bf215546Sopenharmony_ci pipe->set_min_samples(pipe, 1); 1982bf215546Sopenharmony_ci blitter_draw_tex(ctx, dstbox->x, dstbox->y, 1983bf215546Sopenharmony_ci dstbox->x + dstbox->width, 1984bf215546Sopenharmony_ci dstbox->y + dstbox->height, 1985bf215546Sopenharmony_ci src, src_width0, src_height0, 1986bf215546Sopenharmony_ci srcbox->x, srcbox->y, 1987bf215546Sopenharmony_ci srcbox->x + srcbox->width, 1988bf215546Sopenharmony_ci srcbox->y + srcbox->height, 1989bf215546Sopenharmony_ci srcbox->z + src_z, 0, uses_txf, 1990bf215546Sopenharmony_ci UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW); 1991bf215546Sopenharmony_ci } 1992bf215546Sopenharmony_ci 1993bf215546Sopenharmony_ci /* Get the next surface or (if this is the last iteration) 1994bf215546Sopenharmony_ci * just unreference the last one. */ 1995bf215546Sopenharmony_ci old = dst; 1996bf215546Sopenharmony_ci if (dst_z < dstbox->depth-1) { 1997bf215546Sopenharmony_ci dst = util_blitter_get_next_surface_layer(ctx->base.pipe, dst); 1998bf215546Sopenharmony_ci } 1999bf215546Sopenharmony_ci if (dst_z) { 2000bf215546Sopenharmony_ci pipe_surface_reference(&old, NULL); 2001bf215546Sopenharmony_ci } 2002bf215546Sopenharmony_ci } 2003bf215546Sopenharmony_ci } 2004bf215546Sopenharmony_ci} 2005bf215546Sopenharmony_ci 2006bf215546Sopenharmony_civoid util_blitter_blit_generic(struct blitter_context *blitter, 2007bf215546Sopenharmony_ci struct pipe_surface *dst, 2008bf215546Sopenharmony_ci const struct pipe_box *dstbox, 2009bf215546Sopenharmony_ci struct pipe_sampler_view *src, 2010bf215546Sopenharmony_ci const struct pipe_box *srcbox, 2011bf215546Sopenharmony_ci unsigned src_width0, unsigned src_height0, 2012bf215546Sopenharmony_ci unsigned mask, unsigned filter, 2013bf215546Sopenharmony_ci const struct pipe_scissor_state *scissor, 2014bf215546Sopenharmony_ci bool alpha_blend, bool sample0_only, 2015bf215546Sopenharmony_ci unsigned dst_sample) 2016bf215546Sopenharmony_ci{ 2017bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2018bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 2019bf215546Sopenharmony_ci enum pipe_texture_target src_target = src->target; 2020bf215546Sopenharmony_ci unsigned src_samples = src->texture->nr_samples; 2021bf215546Sopenharmony_ci unsigned dst_samples = dst->texture->nr_samples; 2022bf215546Sopenharmony_ci void *sampler_state; 2023bf215546Sopenharmony_ci const struct util_format_description *src_desc = 2024bf215546Sopenharmony_ci util_format_description(src->format); 2025bf215546Sopenharmony_ci const struct util_format_description *dst_desc = 2026bf215546Sopenharmony_ci util_format_description(dst->format); 2027bf215546Sopenharmony_ci 2028bf215546Sopenharmony_ci bool src_has_color = src_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS; 2029bf215546Sopenharmony_ci bool src_has_depth = util_format_has_depth(src_desc); 2030bf215546Sopenharmony_ci bool src_has_stencil = util_format_has_stencil(src_desc); 2031bf215546Sopenharmony_ci 2032bf215546Sopenharmony_ci bool dst_has_color = mask & PIPE_MASK_RGBA && 2033bf215546Sopenharmony_ci dst_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS; 2034bf215546Sopenharmony_ci bool dst_has_depth = mask & PIPE_MASK_Z && 2035bf215546Sopenharmony_ci util_format_has_depth(dst_desc); 2036bf215546Sopenharmony_ci bool dst_has_stencil = ctx->has_stencil_export && 2037bf215546Sopenharmony_ci mask & PIPE_MASK_S && 2038bf215546Sopenharmony_ci util_format_has_stencil(dst_desc); 2039bf215546Sopenharmony_ci 2040bf215546Sopenharmony_ci /* Return if there is nothing to do. */ 2041bf215546Sopenharmony_ci if (!dst_has_color && !dst_has_depth && !dst_has_stencil) { 2042bf215546Sopenharmony_ci return; 2043bf215546Sopenharmony_ci } 2044bf215546Sopenharmony_ci 2045bf215546Sopenharmony_ci bool is_scaled = dstbox->width != abs(srcbox->width) || 2046bf215546Sopenharmony_ci dstbox->height != abs(srcbox->height); 2047bf215546Sopenharmony_ci 2048bf215546Sopenharmony_ci if (src_has_stencil || !is_scaled) 2049bf215546Sopenharmony_ci filter = PIPE_TEX_FILTER_NEAREST; 2050bf215546Sopenharmony_ci 2051bf215546Sopenharmony_ci bool use_txf = false; 2052bf215546Sopenharmony_ci 2053bf215546Sopenharmony_ci /* Don't support scaled blits. The TXF shader uses F2I for rounding. */ 2054bf215546Sopenharmony_ci if (ctx->has_txf && 2055bf215546Sopenharmony_ci !is_scaled && 2056bf215546Sopenharmony_ci filter == PIPE_TEX_FILTER_NEAREST && 2057bf215546Sopenharmony_ci src->target != PIPE_TEXTURE_CUBE && 2058bf215546Sopenharmony_ci src->target != PIPE_TEXTURE_CUBE_ARRAY) { 2059bf215546Sopenharmony_ci int src_width = u_minify(src_width0, src->u.tex.first_level); 2060bf215546Sopenharmony_ci int src_height = u_minify(src_height0, src->u.tex.first_level); 2061bf215546Sopenharmony_ci int src_depth = src->u.tex.last_layer + 1; 2062bf215546Sopenharmony_ci struct pipe_box box = *srcbox; 2063bf215546Sopenharmony_ci 2064bf215546Sopenharmony_ci /* Eliminate negative width/height/depth. */ 2065bf215546Sopenharmony_ci if (box.width < 0) { 2066bf215546Sopenharmony_ci box.x += box.width; 2067bf215546Sopenharmony_ci box.width *= -1; 2068bf215546Sopenharmony_ci } 2069bf215546Sopenharmony_ci if (box.height < 0) { 2070bf215546Sopenharmony_ci box.y += box.height; 2071bf215546Sopenharmony_ci box.height *= -1; 2072bf215546Sopenharmony_ci } 2073bf215546Sopenharmony_ci if (box.depth < 0) { 2074bf215546Sopenharmony_ci box.z += box.depth; 2075bf215546Sopenharmony_ci box.depth *= -1; 2076bf215546Sopenharmony_ci } 2077bf215546Sopenharmony_ci 2078bf215546Sopenharmony_ci /* See if srcbox is in bounds. TXF doesn't clamp the coordinates. */ 2079bf215546Sopenharmony_ci use_txf = 2080bf215546Sopenharmony_ci box.x >= 0 && box.x < src_width && 2081bf215546Sopenharmony_ci box.y >= 0 && box.y < src_height && 2082bf215546Sopenharmony_ci box.z >= 0 && box.z < src_depth && 2083bf215546Sopenharmony_ci box.x + box.width > 0 && box.x + box.width <= src_width && 2084bf215546Sopenharmony_ci box.y + box.height > 0 && box.y + box.height <= src_height && 2085bf215546Sopenharmony_ci box.z + box.depth > 0 && box.z + box.depth <= src_depth; 2086bf215546Sopenharmony_ci } 2087bf215546Sopenharmony_ci 2088bf215546Sopenharmony_ci /* Check whether the states are properly saved. */ 2089bf215546Sopenharmony_ci util_blitter_set_running_flag(blitter); 2090bf215546Sopenharmony_ci blitter_check_saved_vertex_states(ctx); 2091bf215546Sopenharmony_ci blitter_check_saved_fragment_states(ctx); 2092bf215546Sopenharmony_ci blitter_check_saved_textures(ctx); 2093bf215546Sopenharmony_ci blitter_check_saved_fb_state(ctx); 2094bf215546Sopenharmony_ci blitter_disable_render_cond(ctx); 2095bf215546Sopenharmony_ci 2096bf215546Sopenharmony_ci /* Blend, DSA, fragment shader. */ 2097bf215546Sopenharmony_ci if (dst_has_depth && dst_has_stencil) { 2098bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, ctx->blend[0][0]); 2099bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, 2100bf215546Sopenharmony_ci ctx->dsa_write_depth_stencil); 2101bf215546Sopenharmony_ci if (src_has_color) { 2102bf215546Sopenharmony_ci assert(use_txf); 2103bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, 2104bf215546Sopenharmony_ci blitter_get_fs_pack_color_zs(ctx, src_target, 2105bf215546Sopenharmony_ci src_samples, dst->format, false)); 2106bf215546Sopenharmony_ci } else { 2107bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, 2108bf215546Sopenharmony_ci blitter_get_fs_texfetch_depthstencil(ctx, src_target, src_samples, 2109bf215546Sopenharmony_ci dst_samples, use_txf)); 2110bf215546Sopenharmony_ci } 2111bf215546Sopenharmony_ci } else if (dst_has_depth) { 2112bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, ctx->blend[0][0]); 2113bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, 2114bf215546Sopenharmony_ci ctx->dsa_write_depth_keep_stencil); 2115bf215546Sopenharmony_ci if (src_has_color && 2116bf215546Sopenharmony_ci (src->format == PIPE_FORMAT_R32_UINT || 2117bf215546Sopenharmony_ci src->format == PIPE_FORMAT_R32G32_UINT)) { 2118bf215546Sopenharmony_ci assert(use_txf); 2119bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, 2120bf215546Sopenharmony_ci blitter_get_fs_pack_color_zs(ctx, src_target, 2121bf215546Sopenharmony_ci src_samples, dst->format, false)); 2122bf215546Sopenharmony_ci } else { 2123bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, 2124bf215546Sopenharmony_ci blitter_get_fs_texfetch_depth(ctx, src_target, src_samples, 2125bf215546Sopenharmony_ci dst_samples, use_txf)); 2126bf215546Sopenharmony_ci } 2127bf215546Sopenharmony_ci } else if (dst_has_stencil) { 2128bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, ctx->blend[0][0]); 2129bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, 2130bf215546Sopenharmony_ci ctx->dsa_keep_depth_write_stencil); 2131bf215546Sopenharmony_ci 2132bf215546Sopenharmony_ci assert(src_has_stencil); /* unpacking from color is unsupported */ 2133bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, 2134bf215546Sopenharmony_ci blitter_get_fs_texfetch_stencil(ctx, src_target, src_samples, 2135bf215546Sopenharmony_ci dst_samples, use_txf)); 2136bf215546Sopenharmony_ci } else { 2137bf215546Sopenharmony_ci unsigned colormask = mask & PIPE_MASK_RGBA; 2138bf215546Sopenharmony_ci 2139bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, ctx->blend[colormask][alpha_blend]); 2140bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2141bf215546Sopenharmony_ci 2142bf215546Sopenharmony_ci if (src_has_depth && 2143bf215546Sopenharmony_ci (dst->format == PIPE_FORMAT_R32_UINT || 2144bf215546Sopenharmony_ci dst->format == PIPE_FORMAT_R32G32_UINT)) { 2145bf215546Sopenharmony_ci assert(use_txf); 2146bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, 2147bf215546Sopenharmony_ci blitter_get_fs_pack_color_zs(ctx, src_target, 2148bf215546Sopenharmony_ci src_samples, src->format, true)); 2149bf215546Sopenharmony_ci } else { 2150bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, 2151bf215546Sopenharmony_ci blitter_get_fs_texfetch_col(ctx, src->format, dst->format, src_target, 2152bf215546Sopenharmony_ci src_samples, dst_samples, filter, 2153bf215546Sopenharmony_ci use_txf)); 2154bf215546Sopenharmony_ci } 2155bf215546Sopenharmony_ci } 2156bf215546Sopenharmony_ci 2157bf215546Sopenharmony_ci /* Set the linear filter only for scaled color non-MSAA blits. */ 2158bf215546Sopenharmony_ci if (filter == PIPE_TEX_FILTER_LINEAR) { 2159bf215546Sopenharmony_ci if (src_target == PIPE_TEXTURE_RECT && ctx->has_texrect) { 2160bf215546Sopenharmony_ci sampler_state = ctx->sampler_state_rect_linear; 2161bf215546Sopenharmony_ci } else { 2162bf215546Sopenharmony_ci sampler_state = ctx->sampler_state_linear; 2163bf215546Sopenharmony_ci } 2164bf215546Sopenharmony_ci } else { 2165bf215546Sopenharmony_ci if (src_target == PIPE_TEXTURE_RECT && ctx->has_texrect) { 2166bf215546Sopenharmony_ci sampler_state = ctx->sampler_state_rect; 2167bf215546Sopenharmony_ci } else { 2168bf215546Sopenharmony_ci sampler_state = ctx->sampler_state; 2169bf215546Sopenharmony_ci } 2170bf215546Sopenharmony_ci } 2171bf215546Sopenharmony_ci 2172bf215546Sopenharmony_ci /* Set samplers. */ 2173bf215546Sopenharmony_ci unsigned count = 0; 2174bf215546Sopenharmony_ci if (src_has_depth && src_has_stencil && 2175bf215546Sopenharmony_ci (dst_has_color || (dst_has_depth && dst_has_stencil))) { 2176bf215546Sopenharmony_ci /* Setup two samplers, one for depth and the other one for stencil. */ 2177bf215546Sopenharmony_ci struct pipe_sampler_view templ; 2178bf215546Sopenharmony_ci struct pipe_sampler_view *views[2]; 2179bf215546Sopenharmony_ci void *samplers[2] = {sampler_state, sampler_state}; 2180bf215546Sopenharmony_ci 2181bf215546Sopenharmony_ci templ = *src; 2182bf215546Sopenharmony_ci templ.format = util_format_stencil_only(templ.format); 2183bf215546Sopenharmony_ci assert(templ.format != PIPE_FORMAT_NONE); 2184bf215546Sopenharmony_ci 2185bf215546Sopenharmony_ci views[0] = src; 2186bf215546Sopenharmony_ci views[1] = pipe->create_sampler_view(pipe, src->texture, &templ); 2187bf215546Sopenharmony_ci 2188bf215546Sopenharmony_ci count = 2; 2189bf215546Sopenharmony_ci pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 2, 0, false, views); 2190bf215546Sopenharmony_ci pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 2, samplers); 2191bf215546Sopenharmony_ci 2192bf215546Sopenharmony_ci pipe_sampler_view_reference(&views[1], NULL); 2193bf215546Sopenharmony_ci } else if (src_has_stencil && dst_has_stencil) { 2194bf215546Sopenharmony_ci /* Set a stencil-only sampler view for it not to sample depth instead. */ 2195bf215546Sopenharmony_ci struct pipe_sampler_view templ; 2196bf215546Sopenharmony_ci struct pipe_sampler_view *view; 2197bf215546Sopenharmony_ci 2198bf215546Sopenharmony_ci templ = *src; 2199bf215546Sopenharmony_ci templ.format = util_format_stencil_only(templ.format); 2200bf215546Sopenharmony_ci assert(templ.format != PIPE_FORMAT_NONE); 2201bf215546Sopenharmony_ci 2202bf215546Sopenharmony_ci view = pipe->create_sampler_view(pipe, src->texture, &templ); 2203bf215546Sopenharmony_ci 2204bf215546Sopenharmony_ci count = 1; 2205bf215546Sopenharmony_ci pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &view); 2206bf215546Sopenharmony_ci pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 2207bf215546Sopenharmony_ci 0, 1, &sampler_state); 2208bf215546Sopenharmony_ci 2209bf215546Sopenharmony_ci pipe_sampler_view_reference(&view, NULL); 2210bf215546Sopenharmony_ci } else { 2211bf215546Sopenharmony_ci count = 1; 2212bf215546Sopenharmony_ci pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src); 2213bf215546Sopenharmony_ci pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 2214bf215546Sopenharmony_ci 0, 1, &sampler_state); 2215bf215546Sopenharmony_ci } 2216bf215546Sopenharmony_ci 2217bf215546Sopenharmony_ci if (scissor) { 2218bf215546Sopenharmony_ci pipe->set_scissor_states(pipe, 0, 1, scissor); 2219bf215546Sopenharmony_ci } 2220bf215546Sopenharmony_ci 2221bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, scissor != NULL, dst_samples > 1); 2222bf215546Sopenharmony_ci 2223bf215546Sopenharmony_ci do_blits(ctx, dst, dstbox, src, src_width0, src_height0, 2224bf215546Sopenharmony_ci srcbox, dst_has_depth || dst_has_stencil, use_txf, sample0_only, 2225bf215546Sopenharmony_ci dst_sample); 2226bf215546Sopenharmony_ci 2227bf215546Sopenharmony_ci util_blitter_restore_vertex_states(blitter); 2228bf215546Sopenharmony_ci util_blitter_restore_fragment_states(blitter); 2229bf215546Sopenharmony_ci util_blitter_restore_textures_internal(blitter, count); 2230bf215546Sopenharmony_ci util_blitter_restore_fb_state(blitter); 2231bf215546Sopenharmony_ci if (scissor) { 2232bf215546Sopenharmony_ci pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor); 2233bf215546Sopenharmony_ci } 2234bf215546Sopenharmony_ci util_blitter_restore_render_cond(blitter); 2235bf215546Sopenharmony_ci util_blitter_unset_running_flag(blitter); 2236bf215546Sopenharmony_ci} 2237bf215546Sopenharmony_ci 2238bf215546Sopenharmony_civoid 2239bf215546Sopenharmony_ciutil_blitter_blit(struct blitter_context *blitter, 2240bf215546Sopenharmony_ci const struct pipe_blit_info *info) 2241bf215546Sopenharmony_ci{ 2242bf215546Sopenharmony_ci struct pipe_resource *dst = info->dst.resource; 2243bf215546Sopenharmony_ci struct pipe_resource *src = info->src.resource; 2244bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2245bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 2246bf215546Sopenharmony_ci struct pipe_surface *dst_view, dst_templ; 2247bf215546Sopenharmony_ci struct pipe_sampler_view src_templ, *src_view; 2248bf215546Sopenharmony_ci 2249bf215546Sopenharmony_ci /* Initialize the surface. */ 2250bf215546Sopenharmony_ci util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level, 2251bf215546Sopenharmony_ci info->dst.box.z); 2252bf215546Sopenharmony_ci dst_templ.format = info->dst.format; 2253bf215546Sopenharmony_ci dst_view = pipe->create_surface(pipe, dst, &dst_templ); 2254bf215546Sopenharmony_ci 2255bf215546Sopenharmony_ci /* Initialize the sampler view. */ 2256bf215546Sopenharmony_ci util_blitter_default_src_texture(blitter, &src_templ, src, info->src.level); 2257bf215546Sopenharmony_ci src_templ.format = info->src.format; 2258bf215546Sopenharmony_ci src_view = pipe->create_sampler_view(pipe, src, &src_templ); 2259bf215546Sopenharmony_ci 2260bf215546Sopenharmony_ci /* Copy. */ 2261bf215546Sopenharmony_ci util_blitter_blit_generic(blitter, dst_view, &info->dst.box, 2262bf215546Sopenharmony_ci src_view, &info->src.box, src->width0, src->height0, 2263bf215546Sopenharmony_ci info->mask, info->filter, 2264bf215546Sopenharmony_ci info->scissor_enable ? &info->scissor : NULL, 2265bf215546Sopenharmony_ci info->alpha_blend, info->sample0_only, 2266bf215546Sopenharmony_ci info->dst_sample); 2267bf215546Sopenharmony_ci 2268bf215546Sopenharmony_ci pipe_surface_reference(&dst_view, NULL); 2269bf215546Sopenharmony_ci pipe_sampler_view_reference(&src_view, NULL); 2270bf215546Sopenharmony_ci} 2271bf215546Sopenharmony_ci 2272bf215546Sopenharmony_civoid util_blitter_generate_mipmap(struct blitter_context *blitter, 2273bf215546Sopenharmony_ci struct pipe_resource *tex, 2274bf215546Sopenharmony_ci enum pipe_format format, 2275bf215546Sopenharmony_ci unsigned base_level, unsigned last_level, 2276bf215546Sopenharmony_ci unsigned first_layer, unsigned last_layer) 2277bf215546Sopenharmony_ci{ 2278bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2279bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 2280bf215546Sopenharmony_ci struct pipe_surface dst_templ, *dst_view; 2281bf215546Sopenharmony_ci struct pipe_sampler_view src_templ, *src_view; 2282bf215546Sopenharmony_ci bool is_depth; 2283bf215546Sopenharmony_ci void *sampler_state; 2284bf215546Sopenharmony_ci const struct util_format_description *desc = 2285bf215546Sopenharmony_ci util_format_description(format); 2286bf215546Sopenharmony_ci unsigned src_level; 2287bf215546Sopenharmony_ci unsigned target = tex->target; 2288bf215546Sopenharmony_ci 2289bf215546Sopenharmony_ci if (ctx->cube_as_2darray && 2290bf215546Sopenharmony_ci (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY)) 2291bf215546Sopenharmony_ci target = PIPE_TEXTURE_2D_ARRAY; 2292bf215546Sopenharmony_ci 2293bf215546Sopenharmony_ci assert(tex->nr_samples <= 1); 2294bf215546Sopenharmony_ci /* Disallow stencil formats without depth. */ 2295bf215546Sopenharmony_ci assert(!util_format_has_stencil(desc) || util_format_has_depth(desc)); 2296bf215546Sopenharmony_ci 2297bf215546Sopenharmony_ci is_depth = desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS; 2298bf215546Sopenharmony_ci 2299bf215546Sopenharmony_ci /* Check whether the states are properly saved. */ 2300bf215546Sopenharmony_ci util_blitter_set_running_flag(blitter); 2301bf215546Sopenharmony_ci blitter_check_saved_vertex_states(ctx); 2302bf215546Sopenharmony_ci blitter_check_saved_fragment_states(ctx); 2303bf215546Sopenharmony_ci blitter_check_saved_textures(ctx); 2304bf215546Sopenharmony_ci blitter_check_saved_fb_state(ctx); 2305bf215546Sopenharmony_ci blitter_disable_render_cond(ctx); 2306bf215546Sopenharmony_ci 2307bf215546Sopenharmony_ci /* Set states. */ 2308bf215546Sopenharmony_ci if (is_depth) { 2309bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, ctx->blend[0][0]); 2310bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, 2311bf215546Sopenharmony_ci ctx->dsa_write_depth_keep_stencil); 2312bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, 2313bf215546Sopenharmony_ci blitter_get_fs_texfetch_depth(ctx, target, 1, 1, false)); 2314bf215546Sopenharmony_ci } else { 2315bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]); 2316bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2317bf215546Sopenharmony_ci ctx->bind_fs_state(pipe, 2318bf215546Sopenharmony_ci blitter_get_fs_texfetch_col(ctx, tex->format, tex->format, target, 2319bf215546Sopenharmony_ci 1, 1, PIPE_TEX_FILTER_LINEAR, false)); 2320bf215546Sopenharmony_ci } 2321bf215546Sopenharmony_ci 2322bf215546Sopenharmony_ci if (target == PIPE_TEXTURE_RECT) { 2323bf215546Sopenharmony_ci sampler_state = ctx->sampler_state_rect_linear; 2324bf215546Sopenharmony_ci } else { 2325bf215546Sopenharmony_ci sampler_state = ctx->sampler_state_linear; 2326bf215546Sopenharmony_ci } 2327bf215546Sopenharmony_ci pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 2328bf215546Sopenharmony_ci 0, 1, &sampler_state); 2329bf215546Sopenharmony_ci 2330bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, false, false); 2331bf215546Sopenharmony_ci 2332bf215546Sopenharmony_ci for (src_level = base_level; src_level < last_level; src_level++) { 2333bf215546Sopenharmony_ci struct pipe_box dstbox = {0}, srcbox = {0}; 2334bf215546Sopenharmony_ci unsigned dst_level = src_level + 1; 2335bf215546Sopenharmony_ci 2336bf215546Sopenharmony_ci dstbox.width = u_minify(tex->width0, dst_level); 2337bf215546Sopenharmony_ci dstbox.height = u_minify(tex->height0, dst_level); 2338bf215546Sopenharmony_ci 2339bf215546Sopenharmony_ci srcbox.width = u_minify(tex->width0, src_level); 2340bf215546Sopenharmony_ci srcbox.height = u_minify(tex->height0, src_level); 2341bf215546Sopenharmony_ci 2342bf215546Sopenharmony_ci if (target == PIPE_TEXTURE_3D) { 2343bf215546Sopenharmony_ci dstbox.depth = util_num_layers(tex, dst_level); 2344bf215546Sopenharmony_ci srcbox.depth = util_num_layers(tex, src_level); 2345bf215546Sopenharmony_ci } else { 2346bf215546Sopenharmony_ci dstbox.z = srcbox.z = first_layer; 2347bf215546Sopenharmony_ci dstbox.depth = srcbox.depth = last_layer - first_layer + 1; 2348bf215546Sopenharmony_ci } 2349bf215546Sopenharmony_ci 2350bf215546Sopenharmony_ci /* Initialize the surface. */ 2351bf215546Sopenharmony_ci util_blitter_default_dst_texture(&dst_templ, tex, dst_level, 2352bf215546Sopenharmony_ci first_layer); 2353bf215546Sopenharmony_ci dst_templ.format = format; 2354bf215546Sopenharmony_ci dst_view = pipe->create_surface(pipe, tex, &dst_templ); 2355bf215546Sopenharmony_ci 2356bf215546Sopenharmony_ci /* Initialize the sampler view. */ 2357bf215546Sopenharmony_ci util_blitter_default_src_texture(blitter, &src_templ, tex, src_level); 2358bf215546Sopenharmony_ci src_templ.format = format; 2359bf215546Sopenharmony_ci src_view = pipe->create_sampler_view(pipe, tex, &src_templ); 2360bf215546Sopenharmony_ci 2361bf215546Sopenharmony_ci pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src_view); 2362bf215546Sopenharmony_ci 2363bf215546Sopenharmony_ci do_blits(ctx, dst_view, &dstbox, src_view, tex->width0, tex->height0, 2364bf215546Sopenharmony_ci &srcbox, is_depth, false, false, 0); 2365bf215546Sopenharmony_ci 2366bf215546Sopenharmony_ci pipe_surface_reference(&dst_view, NULL); 2367bf215546Sopenharmony_ci pipe_sampler_view_reference(&src_view, NULL); 2368bf215546Sopenharmony_ci } 2369bf215546Sopenharmony_ci 2370bf215546Sopenharmony_ci util_blitter_restore_vertex_states(blitter); 2371bf215546Sopenharmony_ci util_blitter_restore_fragment_states(blitter); 2372bf215546Sopenharmony_ci util_blitter_restore_textures_internal(blitter, 1); 2373bf215546Sopenharmony_ci util_blitter_restore_fb_state(blitter); 2374bf215546Sopenharmony_ci util_blitter_restore_render_cond(blitter); 2375bf215546Sopenharmony_ci util_blitter_unset_running_flag(blitter); 2376bf215546Sopenharmony_ci} 2377bf215546Sopenharmony_ci 2378bf215546Sopenharmony_ci/* Clear a region of a color surface to a constant value. */ 2379bf215546Sopenharmony_civoid util_blitter_clear_render_target(struct blitter_context *blitter, 2380bf215546Sopenharmony_ci struct pipe_surface *dstsurf, 2381bf215546Sopenharmony_ci const union pipe_color_union *color, 2382bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, 2383bf215546Sopenharmony_ci unsigned width, unsigned height) 2384bf215546Sopenharmony_ci{ 2385bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2386bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 2387bf215546Sopenharmony_ci struct pipe_framebuffer_state fb_state; 2388bf215546Sopenharmony_ci bool msaa; 2389bf215546Sopenharmony_ci unsigned num_layers; 2390bf215546Sopenharmony_ci 2391bf215546Sopenharmony_ci assert(dstsurf->texture); 2392bf215546Sopenharmony_ci if (!dstsurf->texture) 2393bf215546Sopenharmony_ci return; 2394bf215546Sopenharmony_ci 2395bf215546Sopenharmony_ci /* check the saved state */ 2396bf215546Sopenharmony_ci util_blitter_set_running_flag(blitter); 2397bf215546Sopenharmony_ci blitter_check_saved_vertex_states(ctx); 2398bf215546Sopenharmony_ci blitter_check_saved_fragment_states(ctx); 2399bf215546Sopenharmony_ci blitter_check_saved_fb_state(ctx); 2400bf215546Sopenharmony_ci blitter_disable_render_cond(ctx); 2401bf215546Sopenharmony_ci 2402bf215546Sopenharmony_ci /* bind states */ 2403bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]); 2404bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2405bf215546Sopenharmony_ci bind_fs_write_one_cbuf(ctx); 2406bf215546Sopenharmony_ci 2407bf215546Sopenharmony_ci /* set a framebuffer state */ 2408bf215546Sopenharmony_ci fb_state.width = dstsurf->width; 2409bf215546Sopenharmony_ci fb_state.height = dstsurf->height; 2410bf215546Sopenharmony_ci fb_state.nr_cbufs = 1; 2411bf215546Sopenharmony_ci fb_state.cbufs[0] = dstsurf; 2412bf215546Sopenharmony_ci fb_state.zsbuf = NULL; 2413bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &fb_state); 2414bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, ~0); 2415bf215546Sopenharmony_ci if (pipe->set_min_samples) 2416bf215546Sopenharmony_ci pipe->set_min_samples(pipe, 1); 2417bf215546Sopenharmony_ci msaa = util_framebuffer_get_num_samples(&fb_state) > 1; 2418bf215546Sopenharmony_ci 2419bf215546Sopenharmony_ci blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 2420bf215546Sopenharmony_ci 2421bf215546Sopenharmony_ci union blitter_attrib attrib; 2422bf215546Sopenharmony_ci memcpy(attrib.color, color->ui, sizeof(color->ui)); 2423bf215546Sopenharmony_ci 2424bf215546Sopenharmony_ci num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1; 2425bf215546Sopenharmony_ci if (num_layers > 1 && ctx->has_layered) { 2426bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, false, msaa); 2427bf215546Sopenharmony_ci blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_layered, 2428bf215546Sopenharmony_ci dstx, dsty, dstx+width, dsty+height, 0, 2429bf215546Sopenharmony_ci num_layers, UTIL_BLITTER_ATTRIB_COLOR, &attrib); 2430bf215546Sopenharmony_ci } else { 2431bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, false, msaa); 2432bf215546Sopenharmony_ci blitter->draw_rectangle(blitter, ctx->velem_state, 2433bf215546Sopenharmony_ci get_vs_passthrough_pos_generic, 2434bf215546Sopenharmony_ci dstx, dsty, dstx+width, dsty+height, 0, 2435bf215546Sopenharmony_ci 1, UTIL_BLITTER_ATTRIB_COLOR, &attrib); 2436bf215546Sopenharmony_ci } 2437bf215546Sopenharmony_ci 2438bf215546Sopenharmony_ci util_blitter_restore_vertex_states(blitter); 2439bf215546Sopenharmony_ci util_blitter_restore_fragment_states(blitter); 2440bf215546Sopenharmony_ci util_blitter_restore_fb_state(blitter); 2441bf215546Sopenharmony_ci util_blitter_restore_render_cond(blitter); 2442bf215546Sopenharmony_ci util_blitter_unset_running_flag(blitter); 2443bf215546Sopenharmony_ci} 2444bf215546Sopenharmony_ci 2445bf215546Sopenharmony_ci/* Clear a region of a depth stencil surface. */ 2446bf215546Sopenharmony_civoid util_blitter_clear_depth_stencil(struct blitter_context *blitter, 2447bf215546Sopenharmony_ci struct pipe_surface *dstsurf, 2448bf215546Sopenharmony_ci unsigned clear_flags, 2449bf215546Sopenharmony_ci double depth, 2450bf215546Sopenharmony_ci unsigned stencil, 2451bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, 2452bf215546Sopenharmony_ci unsigned width, unsigned height) 2453bf215546Sopenharmony_ci{ 2454bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2455bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 2456bf215546Sopenharmony_ci struct pipe_framebuffer_state fb_state; 2457bf215546Sopenharmony_ci struct pipe_stencil_ref sr = { { 0 } }; 2458bf215546Sopenharmony_ci unsigned num_layers; 2459bf215546Sopenharmony_ci 2460bf215546Sopenharmony_ci assert(dstsurf->texture); 2461bf215546Sopenharmony_ci if (!dstsurf->texture) 2462bf215546Sopenharmony_ci return; 2463bf215546Sopenharmony_ci 2464bf215546Sopenharmony_ci /* check the saved state */ 2465bf215546Sopenharmony_ci util_blitter_set_running_flag(blitter); 2466bf215546Sopenharmony_ci blitter_check_saved_vertex_states(ctx); 2467bf215546Sopenharmony_ci blitter_check_saved_fragment_states(ctx); 2468bf215546Sopenharmony_ci blitter_check_saved_fb_state(ctx); 2469bf215546Sopenharmony_ci blitter_disable_render_cond(ctx); 2470bf215546Sopenharmony_ci 2471bf215546Sopenharmony_ci /* bind states */ 2472bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, ctx->blend[0][0]); 2473bf215546Sopenharmony_ci if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { 2474bf215546Sopenharmony_ci sr.ref_value[0] = stencil & 0xff; 2475bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 2476bf215546Sopenharmony_ci pipe->set_stencil_ref(pipe, sr); 2477bf215546Sopenharmony_ci } 2478bf215546Sopenharmony_ci else if (clear_flags & PIPE_CLEAR_DEPTH) { 2479bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); 2480bf215546Sopenharmony_ci } 2481bf215546Sopenharmony_ci else if (clear_flags & PIPE_CLEAR_STENCIL) { 2482bf215546Sopenharmony_ci sr.ref_value[0] = stencil & 0xff; 2483bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 2484bf215546Sopenharmony_ci pipe->set_stencil_ref(pipe, sr); 2485bf215546Sopenharmony_ci } 2486bf215546Sopenharmony_ci else 2487bf215546Sopenharmony_ci /* hmm that should be illegal probably, or make it a no-op somewhere */ 2488bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2489bf215546Sopenharmony_ci 2490bf215546Sopenharmony_ci bind_fs_empty(ctx); 2491bf215546Sopenharmony_ci 2492bf215546Sopenharmony_ci /* set a framebuffer state */ 2493bf215546Sopenharmony_ci fb_state.width = dstsurf->width; 2494bf215546Sopenharmony_ci fb_state.height = dstsurf->height; 2495bf215546Sopenharmony_ci fb_state.nr_cbufs = 0; 2496bf215546Sopenharmony_ci fb_state.cbufs[0] = NULL; 2497bf215546Sopenharmony_ci fb_state.zsbuf = dstsurf; 2498bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &fb_state); 2499bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, ~0); 2500bf215546Sopenharmony_ci if (pipe->set_min_samples) 2501bf215546Sopenharmony_ci pipe->set_min_samples(pipe, 1); 2502bf215546Sopenharmony_ci 2503bf215546Sopenharmony_ci blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 2504bf215546Sopenharmony_ci 2505bf215546Sopenharmony_ci num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1; 2506bf215546Sopenharmony_ci if (num_layers > 1 && ctx->has_layered) { 2507bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, false, false); 2508bf215546Sopenharmony_ci blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_layered, 2509bf215546Sopenharmony_ci dstx, dsty, dstx+width, dsty+height, depth, 2510bf215546Sopenharmony_ci num_layers, UTIL_BLITTER_ATTRIB_NONE, NULL); 2511bf215546Sopenharmony_ci } else { 2512bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, false, false); 2513bf215546Sopenharmony_ci blitter->draw_rectangle(blitter, ctx->velem_state, 2514bf215546Sopenharmony_ci get_vs_passthrough_pos, 2515bf215546Sopenharmony_ci dstx, dsty, dstx+width, dsty+height, depth, 1, 2516bf215546Sopenharmony_ci UTIL_BLITTER_ATTRIB_NONE, NULL); 2517bf215546Sopenharmony_ci } 2518bf215546Sopenharmony_ci 2519bf215546Sopenharmony_ci util_blitter_restore_vertex_states(blitter); 2520bf215546Sopenharmony_ci util_blitter_restore_fragment_states(blitter); 2521bf215546Sopenharmony_ci util_blitter_restore_fb_state(blitter); 2522bf215546Sopenharmony_ci util_blitter_restore_render_cond(blitter); 2523bf215546Sopenharmony_ci util_blitter_unset_running_flag(blitter); 2524bf215546Sopenharmony_ci} 2525bf215546Sopenharmony_ci 2526bf215546Sopenharmony_ci/* draw a rectangle across a region using a custom dsa stage - for r600g */ 2527bf215546Sopenharmony_civoid util_blitter_custom_depth_stencil(struct blitter_context *blitter, 2528bf215546Sopenharmony_ci struct pipe_surface *zsurf, 2529bf215546Sopenharmony_ci struct pipe_surface *cbsurf, 2530bf215546Sopenharmony_ci unsigned sample_mask, 2531bf215546Sopenharmony_ci void *dsa_stage, float depth) 2532bf215546Sopenharmony_ci{ 2533bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2534bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 2535bf215546Sopenharmony_ci struct pipe_framebuffer_state fb_state; 2536bf215546Sopenharmony_ci 2537bf215546Sopenharmony_ci assert(zsurf->texture); 2538bf215546Sopenharmony_ci if (!zsurf->texture) 2539bf215546Sopenharmony_ci return; 2540bf215546Sopenharmony_ci 2541bf215546Sopenharmony_ci /* check the saved state */ 2542bf215546Sopenharmony_ci util_blitter_set_running_flag(blitter); 2543bf215546Sopenharmony_ci blitter_check_saved_vertex_states(ctx); 2544bf215546Sopenharmony_ci blitter_check_saved_fragment_states(ctx); 2545bf215546Sopenharmony_ci blitter_check_saved_fb_state(ctx); 2546bf215546Sopenharmony_ci blitter_disable_render_cond(ctx); 2547bf215546Sopenharmony_ci 2548bf215546Sopenharmony_ci /* bind states */ 2549bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA][0] : 2550bf215546Sopenharmony_ci ctx->blend[0][0]); 2551bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage); 2552bf215546Sopenharmony_ci if (cbsurf) 2553bf215546Sopenharmony_ci bind_fs_write_one_cbuf(ctx); 2554bf215546Sopenharmony_ci else 2555bf215546Sopenharmony_ci bind_fs_empty(ctx); 2556bf215546Sopenharmony_ci 2557bf215546Sopenharmony_ci /* set a framebuffer state */ 2558bf215546Sopenharmony_ci fb_state.width = zsurf->width; 2559bf215546Sopenharmony_ci fb_state.height = zsurf->height; 2560bf215546Sopenharmony_ci fb_state.nr_cbufs = 1; 2561bf215546Sopenharmony_ci if (cbsurf) { 2562bf215546Sopenharmony_ci fb_state.cbufs[0] = cbsurf; 2563bf215546Sopenharmony_ci fb_state.nr_cbufs = 1; 2564bf215546Sopenharmony_ci } else { 2565bf215546Sopenharmony_ci fb_state.cbufs[0] = NULL; 2566bf215546Sopenharmony_ci fb_state.nr_cbufs = 0; 2567bf215546Sopenharmony_ci } 2568bf215546Sopenharmony_ci fb_state.zsbuf = zsurf; 2569bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &fb_state); 2570bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, sample_mask); 2571bf215546Sopenharmony_ci if (pipe->set_min_samples) 2572bf215546Sopenharmony_ci pipe->set_min_samples(pipe, 1); 2573bf215546Sopenharmony_ci 2574bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, false, 2575bf215546Sopenharmony_ci util_framebuffer_get_num_samples(&fb_state) > 1); 2576bf215546Sopenharmony_ci blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height); 2577bf215546Sopenharmony_ci blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos, 2578bf215546Sopenharmony_ci 0, 0, zsurf->width, zsurf->height, depth, 2579bf215546Sopenharmony_ci 1, UTIL_BLITTER_ATTRIB_NONE, NULL); 2580bf215546Sopenharmony_ci 2581bf215546Sopenharmony_ci util_blitter_restore_vertex_states(blitter); 2582bf215546Sopenharmony_ci util_blitter_restore_fragment_states(blitter); 2583bf215546Sopenharmony_ci util_blitter_restore_fb_state(blitter); 2584bf215546Sopenharmony_ci util_blitter_restore_render_cond(blitter); 2585bf215546Sopenharmony_ci util_blitter_unset_running_flag(blitter); 2586bf215546Sopenharmony_ci} 2587bf215546Sopenharmony_ci 2588bf215546Sopenharmony_civoid util_blitter_clear_buffer(struct blitter_context *blitter, 2589bf215546Sopenharmony_ci struct pipe_resource *dst, 2590bf215546Sopenharmony_ci unsigned offset, unsigned size, 2591bf215546Sopenharmony_ci unsigned num_channels, 2592bf215546Sopenharmony_ci const union pipe_color_union *clear_value) 2593bf215546Sopenharmony_ci{ 2594bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2595bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 2596bf215546Sopenharmony_ci struct pipe_vertex_buffer vb = {0}; 2597bf215546Sopenharmony_ci struct pipe_stream_output_target *so_target = NULL; 2598bf215546Sopenharmony_ci unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0}; 2599bf215546Sopenharmony_ci 2600bf215546Sopenharmony_ci assert(num_channels >= 1); 2601bf215546Sopenharmony_ci assert(num_channels <= 4); 2602bf215546Sopenharmony_ci 2603bf215546Sopenharmony_ci /* IMPORTANT: DON'T DO ANY BOUNDS CHECKING HERE! 2604bf215546Sopenharmony_ci * 2605bf215546Sopenharmony_ci * R600 uses this to initialize texture resources, so width0 might not be 2606bf215546Sopenharmony_ci * what you think it is. 2607bf215546Sopenharmony_ci */ 2608bf215546Sopenharmony_ci 2609bf215546Sopenharmony_ci /* Streamout is required. */ 2610bf215546Sopenharmony_ci if (!ctx->has_stream_out) { 2611bf215546Sopenharmony_ci assert(!"Streamout unsupported in util_blitter_clear_buffer()"); 2612bf215546Sopenharmony_ci return; 2613bf215546Sopenharmony_ci } 2614bf215546Sopenharmony_ci 2615bf215546Sopenharmony_ci /* Some alignment is required. */ 2616bf215546Sopenharmony_ci if (offset % 4 != 0 || size % 4 != 0) { 2617bf215546Sopenharmony_ci assert(!"Bad alignment in util_blitter_clear_buffer()"); 2618bf215546Sopenharmony_ci return; 2619bf215546Sopenharmony_ci } 2620bf215546Sopenharmony_ci 2621bf215546Sopenharmony_ci u_upload_data(pipe->stream_uploader, 0, num_channels*4, 4, clear_value, 2622bf215546Sopenharmony_ci &vb.buffer_offset, &vb.buffer.resource); 2623bf215546Sopenharmony_ci if (!vb.buffer.resource) 2624bf215546Sopenharmony_ci goto out; 2625bf215546Sopenharmony_ci 2626bf215546Sopenharmony_ci vb.stride = 0; 2627bf215546Sopenharmony_ci 2628bf215546Sopenharmony_ci util_blitter_set_running_flag(blitter); 2629bf215546Sopenharmony_ci blitter_check_saved_vertex_states(ctx); 2630bf215546Sopenharmony_ci blitter_disable_render_cond(ctx); 2631bf215546Sopenharmony_ci 2632bf215546Sopenharmony_ci pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, false, &vb); 2633bf215546Sopenharmony_ci pipe->bind_vertex_elements_state(pipe, 2634bf215546Sopenharmony_ci ctx->velem_state_readbuf[num_channels-1]); 2635bf215546Sopenharmony_ci bind_vs_pos_only(ctx, num_channels); 2636bf215546Sopenharmony_ci if (ctx->has_geometry_shader) 2637bf215546Sopenharmony_ci pipe->bind_gs_state(pipe, NULL); 2638bf215546Sopenharmony_ci if (ctx->has_tessellation) { 2639bf215546Sopenharmony_ci pipe->bind_tcs_state(pipe, NULL); 2640bf215546Sopenharmony_ci pipe->bind_tes_state(pipe, NULL); 2641bf215546Sopenharmony_ci } 2642bf215546Sopenharmony_ci pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state); 2643bf215546Sopenharmony_ci 2644bf215546Sopenharmony_ci so_target = pipe->create_stream_output_target(pipe, dst, offset, size); 2645bf215546Sopenharmony_ci pipe->set_stream_output_targets(pipe, 1, &so_target, offsets); 2646bf215546Sopenharmony_ci 2647bf215546Sopenharmony_ci util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4); 2648bf215546Sopenharmony_ci 2649bf215546Sopenharmony_ciout: 2650bf215546Sopenharmony_ci util_blitter_restore_vertex_states(blitter); 2651bf215546Sopenharmony_ci util_blitter_restore_render_cond(blitter); 2652bf215546Sopenharmony_ci util_blitter_unset_running_flag(blitter); 2653bf215546Sopenharmony_ci pipe_so_target_reference(&so_target, NULL); 2654bf215546Sopenharmony_ci pipe_resource_reference(&vb.buffer.resource, NULL); 2655bf215546Sopenharmony_ci} 2656bf215546Sopenharmony_ci 2657bf215546Sopenharmony_ci/* probably radeon specific */ 2658bf215546Sopenharmony_civoid util_blitter_custom_resolve_color(struct blitter_context *blitter, 2659bf215546Sopenharmony_ci struct pipe_resource *dst, 2660bf215546Sopenharmony_ci unsigned dst_level, 2661bf215546Sopenharmony_ci unsigned dst_layer, 2662bf215546Sopenharmony_ci struct pipe_resource *src, 2663bf215546Sopenharmony_ci unsigned src_layer, 2664bf215546Sopenharmony_ci unsigned sample_mask, 2665bf215546Sopenharmony_ci void *custom_blend, 2666bf215546Sopenharmony_ci enum pipe_format format) 2667bf215546Sopenharmony_ci{ 2668bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2669bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 2670bf215546Sopenharmony_ci struct pipe_framebuffer_state fb_state; 2671bf215546Sopenharmony_ci struct pipe_surface *srcsurf, *dstsurf, surf_tmpl; 2672bf215546Sopenharmony_ci 2673bf215546Sopenharmony_ci util_blitter_set_running_flag(blitter); 2674bf215546Sopenharmony_ci blitter_check_saved_vertex_states(ctx); 2675bf215546Sopenharmony_ci blitter_check_saved_fragment_states(ctx); 2676bf215546Sopenharmony_ci blitter_disable_render_cond(ctx); 2677bf215546Sopenharmony_ci 2678bf215546Sopenharmony_ci /* bind states */ 2679bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, custom_blend); 2680bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2681bf215546Sopenharmony_ci bind_fs_write_one_cbuf(ctx); 2682bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, sample_mask); 2683bf215546Sopenharmony_ci if (pipe->set_min_samples) 2684bf215546Sopenharmony_ci pipe->set_min_samples(pipe, 1); 2685bf215546Sopenharmony_ci 2686bf215546Sopenharmony_ci memset(&surf_tmpl, 0, sizeof(surf_tmpl)); 2687bf215546Sopenharmony_ci surf_tmpl.format = format; 2688bf215546Sopenharmony_ci surf_tmpl.u.tex.level = dst_level; 2689bf215546Sopenharmony_ci surf_tmpl.u.tex.first_layer = dst_layer; 2690bf215546Sopenharmony_ci surf_tmpl.u.tex.last_layer = dst_layer; 2691bf215546Sopenharmony_ci 2692bf215546Sopenharmony_ci dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl); 2693bf215546Sopenharmony_ci 2694bf215546Sopenharmony_ci surf_tmpl.u.tex.level = 0; 2695bf215546Sopenharmony_ci surf_tmpl.u.tex.first_layer = src_layer; 2696bf215546Sopenharmony_ci surf_tmpl.u.tex.last_layer = src_layer; 2697bf215546Sopenharmony_ci 2698bf215546Sopenharmony_ci srcsurf = pipe->create_surface(pipe, src, &surf_tmpl); 2699bf215546Sopenharmony_ci 2700bf215546Sopenharmony_ci /* set a framebuffer state */ 2701bf215546Sopenharmony_ci fb_state.width = src->width0; 2702bf215546Sopenharmony_ci fb_state.height = src->height0; 2703bf215546Sopenharmony_ci fb_state.nr_cbufs = 2; 2704bf215546Sopenharmony_ci fb_state.cbufs[0] = srcsurf; 2705bf215546Sopenharmony_ci fb_state.cbufs[1] = dstsurf; 2706bf215546Sopenharmony_ci fb_state.zsbuf = NULL; 2707bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &fb_state); 2708bf215546Sopenharmony_ci 2709bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, false, 2710bf215546Sopenharmony_ci util_framebuffer_get_num_samples(&fb_state) > 1); 2711bf215546Sopenharmony_ci blitter_set_dst_dimensions(ctx, src->width0, src->height0); 2712bf215546Sopenharmony_ci blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos, 2713bf215546Sopenharmony_ci 0, 0, src->width0, src->height0, 2714bf215546Sopenharmony_ci 0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL); 2715bf215546Sopenharmony_ci util_blitter_restore_fb_state(blitter); 2716bf215546Sopenharmony_ci util_blitter_restore_vertex_states(blitter); 2717bf215546Sopenharmony_ci util_blitter_restore_fragment_states(blitter); 2718bf215546Sopenharmony_ci util_blitter_restore_render_cond(blitter); 2719bf215546Sopenharmony_ci util_blitter_unset_running_flag(blitter); 2720bf215546Sopenharmony_ci 2721bf215546Sopenharmony_ci pipe_surface_reference(&srcsurf, NULL); 2722bf215546Sopenharmony_ci pipe_surface_reference(&dstsurf, NULL); 2723bf215546Sopenharmony_ci} 2724bf215546Sopenharmony_ci 2725bf215546Sopenharmony_civoid util_blitter_custom_color(struct blitter_context *blitter, 2726bf215546Sopenharmony_ci struct pipe_surface *dstsurf, 2727bf215546Sopenharmony_ci void *custom_blend) 2728bf215546Sopenharmony_ci{ 2729bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2730bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 2731bf215546Sopenharmony_ci struct pipe_framebuffer_state fb_state; 2732bf215546Sopenharmony_ci 2733bf215546Sopenharmony_ci assert(dstsurf->texture); 2734bf215546Sopenharmony_ci if (!dstsurf->texture) 2735bf215546Sopenharmony_ci return; 2736bf215546Sopenharmony_ci 2737bf215546Sopenharmony_ci /* check the saved state */ 2738bf215546Sopenharmony_ci util_blitter_set_running_flag(blitter); 2739bf215546Sopenharmony_ci blitter_check_saved_vertex_states(ctx); 2740bf215546Sopenharmony_ci blitter_check_saved_fragment_states(ctx); 2741bf215546Sopenharmony_ci blitter_check_saved_fb_state(ctx); 2742bf215546Sopenharmony_ci blitter_disable_render_cond(ctx); 2743bf215546Sopenharmony_ci 2744bf215546Sopenharmony_ci /* bind states */ 2745bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, custom_blend ? custom_blend 2746bf215546Sopenharmony_ci : ctx->blend[PIPE_MASK_RGBA][0]); 2747bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2748bf215546Sopenharmony_ci bind_fs_write_one_cbuf(ctx); 2749bf215546Sopenharmony_ci 2750bf215546Sopenharmony_ci /* set a framebuffer state */ 2751bf215546Sopenharmony_ci fb_state.width = dstsurf->width; 2752bf215546Sopenharmony_ci fb_state.height = dstsurf->height; 2753bf215546Sopenharmony_ci fb_state.nr_cbufs = 1; 2754bf215546Sopenharmony_ci fb_state.cbufs[0] = dstsurf; 2755bf215546Sopenharmony_ci fb_state.zsbuf = NULL; 2756bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &fb_state); 2757bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, ~0); 2758bf215546Sopenharmony_ci if (pipe->set_min_samples) 2759bf215546Sopenharmony_ci pipe->set_min_samples(pipe, 1); 2760bf215546Sopenharmony_ci 2761bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, false, 2762bf215546Sopenharmony_ci util_framebuffer_get_num_samples(&fb_state) > 1); 2763bf215546Sopenharmony_ci blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 2764bf215546Sopenharmony_ci blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos, 2765bf215546Sopenharmony_ci 0, 0, dstsurf->width, dstsurf->height, 2766bf215546Sopenharmony_ci 0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL); 2767bf215546Sopenharmony_ci 2768bf215546Sopenharmony_ci util_blitter_restore_vertex_states(blitter); 2769bf215546Sopenharmony_ci util_blitter_restore_fragment_states(blitter); 2770bf215546Sopenharmony_ci util_blitter_restore_fb_state(blitter); 2771bf215546Sopenharmony_ci util_blitter_restore_render_cond(blitter); 2772bf215546Sopenharmony_ci util_blitter_unset_running_flag(blitter); 2773bf215546Sopenharmony_ci} 2774bf215546Sopenharmony_ci 2775bf215546Sopenharmony_cistatic void *get_custom_vs(struct blitter_context *blitter) 2776bf215546Sopenharmony_ci{ 2777bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2778bf215546Sopenharmony_ci 2779bf215546Sopenharmony_ci return ctx->custom_vs; 2780bf215546Sopenharmony_ci} 2781bf215546Sopenharmony_ci 2782bf215546Sopenharmony_ci/** 2783bf215546Sopenharmony_ci * Performs a custom blit to the destination surface, using the VS and FS 2784bf215546Sopenharmony_ci * provided. 2785bf215546Sopenharmony_ci * 2786bf215546Sopenharmony_ci * Used by vc4 for the 8-bit linear-to-tiled blit. 2787bf215546Sopenharmony_ci */ 2788bf215546Sopenharmony_civoid util_blitter_custom_shader(struct blitter_context *blitter, 2789bf215546Sopenharmony_ci struct pipe_surface *dstsurf, 2790bf215546Sopenharmony_ci void *custom_vs, void *custom_fs) 2791bf215546Sopenharmony_ci{ 2792bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2793bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 2794bf215546Sopenharmony_ci struct pipe_framebuffer_state fb_state = { 0 }; 2795bf215546Sopenharmony_ci 2796bf215546Sopenharmony_ci ctx->custom_vs = custom_vs; 2797bf215546Sopenharmony_ci 2798bf215546Sopenharmony_ci assert(dstsurf->texture); 2799bf215546Sopenharmony_ci if (!dstsurf->texture) 2800bf215546Sopenharmony_ci return; 2801bf215546Sopenharmony_ci 2802bf215546Sopenharmony_ci /* check the saved state */ 2803bf215546Sopenharmony_ci util_blitter_set_running_flag(blitter); 2804bf215546Sopenharmony_ci blitter_check_saved_vertex_states(ctx); 2805bf215546Sopenharmony_ci blitter_check_saved_fragment_states(ctx); 2806bf215546Sopenharmony_ci blitter_check_saved_fb_state(ctx); 2807bf215546Sopenharmony_ci blitter_disable_render_cond(ctx); 2808bf215546Sopenharmony_ci 2809bf215546Sopenharmony_ci /* bind states */ 2810bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]); 2811bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2812bf215546Sopenharmony_ci pipe->bind_fs_state(pipe, custom_fs); 2813bf215546Sopenharmony_ci 2814bf215546Sopenharmony_ci /* set a framebuffer state */ 2815bf215546Sopenharmony_ci fb_state.width = dstsurf->width; 2816bf215546Sopenharmony_ci fb_state.height = dstsurf->height; 2817bf215546Sopenharmony_ci fb_state.nr_cbufs = 1; 2818bf215546Sopenharmony_ci fb_state.cbufs[0] = dstsurf; 2819bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &fb_state); 2820bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, ~0); 2821bf215546Sopenharmony_ci if (pipe->set_min_samples) 2822bf215546Sopenharmony_ci pipe->set_min_samples(pipe, 1); 2823bf215546Sopenharmony_ci 2824bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, false, 2825bf215546Sopenharmony_ci util_framebuffer_get_num_samples(&fb_state) > 1); 2826bf215546Sopenharmony_ci blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 2827bf215546Sopenharmony_ci blitter->draw_rectangle(blitter, ctx->velem_state, get_custom_vs, 2828bf215546Sopenharmony_ci 0, 0, dstsurf->width, dstsurf->height, 2829bf215546Sopenharmony_ci 0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL); 2830bf215546Sopenharmony_ci 2831bf215546Sopenharmony_ci util_blitter_restore_vertex_states(blitter); 2832bf215546Sopenharmony_ci util_blitter_restore_fragment_states(blitter); 2833bf215546Sopenharmony_ci util_blitter_restore_fb_state(blitter); 2834bf215546Sopenharmony_ci util_blitter_restore_render_cond(blitter); 2835bf215546Sopenharmony_ci util_blitter_unset_running_flag(blitter); 2836bf215546Sopenharmony_ci} 2837bf215546Sopenharmony_ci 2838bf215546Sopenharmony_cistatic void * 2839bf215546Sopenharmony_ciget_stencil_blit_fallback_fs(struct blitter_context_priv *ctx, bool msaa_src) 2840bf215546Sopenharmony_ci{ 2841bf215546Sopenharmony_ci if (!ctx->fs_stencil_blit_fallback[msaa_src]) { 2842bf215546Sopenharmony_ci ctx->fs_stencil_blit_fallback[msaa_src] = 2843bf215546Sopenharmony_ci util_make_fs_stencil_blit(ctx->base.pipe, msaa_src); 2844bf215546Sopenharmony_ci } 2845bf215546Sopenharmony_ci 2846bf215546Sopenharmony_ci return ctx->fs_stencil_blit_fallback[msaa_src]; 2847bf215546Sopenharmony_ci} 2848bf215546Sopenharmony_ci 2849bf215546Sopenharmony_cistatic void * 2850bf215546Sopenharmony_ciget_stencil_blit_fallback_dsa(struct blitter_context_priv *ctx, unsigned i) 2851bf215546Sopenharmony_ci{ 2852bf215546Sopenharmony_ci assert(i < ARRAY_SIZE(ctx->dsa_replicate_stencil_bit)); 2853bf215546Sopenharmony_ci if (!ctx->dsa_replicate_stencil_bit[i]) { 2854bf215546Sopenharmony_ci struct pipe_depth_stencil_alpha_state dsa = { 0 }; 2855bf215546Sopenharmony_ci dsa.depth_func = PIPE_FUNC_ALWAYS; 2856bf215546Sopenharmony_ci dsa.stencil[0].enabled = 1; 2857bf215546Sopenharmony_ci dsa.stencil[0].func = PIPE_FUNC_ALWAYS; 2858bf215546Sopenharmony_ci dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; 2859bf215546Sopenharmony_ci dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; 2860bf215546Sopenharmony_ci dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; 2861bf215546Sopenharmony_ci dsa.stencil[0].valuemask = 0xff; 2862bf215546Sopenharmony_ci dsa.stencil[0].writemask = 1u << i; 2863bf215546Sopenharmony_ci 2864bf215546Sopenharmony_ci ctx->dsa_replicate_stencil_bit[i] = 2865bf215546Sopenharmony_ci ctx->base.pipe->create_depth_stencil_alpha_state(ctx->base.pipe, &dsa); 2866bf215546Sopenharmony_ci } 2867bf215546Sopenharmony_ci return ctx->dsa_replicate_stencil_bit[i]; 2868bf215546Sopenharmony_ci} 2869bf215546Sopenharmony_ci 2870bf215546Sopenharmony_ci/** 2871bf215546Sopenharmony_ci * Performs a series of draws to implement stencil blits texture without 2872bf215546Sopenharmony_ci * requiring stencil writes, updating a single bit per pixel at the time. 2873bf215546Sopenharmony_ci */ 2874bf215546Sopenharmony_civoid 2875bf215546Sopenharmony_ciutil_blitter_stencil_fallback(struct blitter_context *blitter, 2876bf215546Sopenharmony_ci struct pipe_resource *dst, 2877bf215546Sopenharmony_ci unsigned dst_level, 2878bf215546Sopenharmony_ci const struct pipe_box *dstbox, 2879bf215546Sopenharmony_ci struct pipe_resource *src, 2880bf215546Sopenharmony_ci unsigned src_level, 2881bf215546Sopenharmony_ci const struct pipe_box *srcbox, 2882bf215546Sopenharmony_ci const struct pipe_scissor_state *scissor) 2883bf215546Sopenharmony_ci{ 2884bf215546Sopenharmony_ci struct blitter_context_priv *ctx = (struct blitter_context_priv *)blitter; 2885bf215546Sopenharmony_ci struct pipe_context *pipe = ctx->base.pipe; 2886bf215546Sopenharmony_ci 2887bf215546Sopenharmony_ci /* check the saved state */ 2888bf215546Sopenharmony_ci util_blitter_set_running_flag(blitter); 2889bf215546Sopenharmony_ci blitter_check_saved_vertex_states(ctx); 2890bf215546Sopenharmony_ci blitter_check_saved_fragment_states(ctx); 2891bf215546Sopenharmony_ci blitter_check_saved_fb_state(ctx); 2892bf215546Sopenharmony_ci blitter_disable_render_cond(ctx); 2893bf215546Sopenharmony_ci 2894bf215546Sopenharmony_ci /* Initialize the surface. */ 2895bf215546Sopenharmony_ci struct pipe_surface *dst_view, dst_templ; 2896bf215546Sopenharmony_ci util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstbox->z); 2897bf215546Sopenharmony_ci dst_view = pipe->create_surface(pipe, dst, &dst_templ); 2898bf215546Sopenharmony_ci 2899bf215546Sopenharmony_ci /* Initialize the sampler view. */ 2900bf215546Sopenharmony_ci struct pipe_sampler_view src_templ, *src_view; 2901bf215546Sopenharmony_ci util_blitter_default_src_texture(blitter, &src_templ, src, src_level); 2902bf215546Sopenharmony_ci src_templ.format = util_format_stencil_only(src_templ.format); 2903bf215546Sopenharmony_ci src_view = pipe->create_sampler_view(pipe, src, &src_templ); 2904bf215546Sopenharmony_ci 2905bf215546Sopenharmony_ci /* bind states */ 2906bf215546Sopenharmony_ci pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]); 2907bf215546Sopenharmony_ci pipe->bind_fs_state(pipe, 2908bf215546Sopenharmony_ci get_stencil_blit_fallback_fs(ctx, src->nr_samples > 1)); 2909bf215546Sopenharmony_ci 2910bf215546Sopenharmony_ci /* set a framebuffer state */ 2911bf215546Sopenharmony_ci struct pipe_framebuffer_state fb_state = { 0 }; 2912bf215546Sopenharmony_ci fb_state.width = dstbox->x + dstbox->width; 2913bf215546Sopenharmony_ci fb_state.height = dstbox->y + dstbox->height; 2914bf215546Sopenharmony_ci fb_state.zsbuf = dst_view; 2915bf215546Sopenharmony_ci pipe->set_framebuffer_state(pipe, &fb_state); 2916bf215546Sopenharmony_ci pipe->set_sample_mask(pipe, ~0); 2917bf215546Sopenharmony_ci if (pipe->set_min_samples) 2918bf215546Sopenharmony_ci pipe->set_min_samples(pipe, 1); 2919bf215546Sopenharmony_ci 2920bf215546Sopenharmony_ci blitter_set_common_draw_rect_state(ctx, scissor != NULL, 2921bf215546Sopenharmony_ci util_framebuffer_get_num_samples(&fb_state) > 1); 2922bf215546Sopenharmony_ci blitter_set_dst_dimensions(ctx, dst_view->width, dst_view->height); 2923bf215546Sopenharmony_ci 2924bf215546Sopenharmony_ci if (scissor) { 2925bf215546Sopenharmony_ci pipe->clear_depth_stencil(pipe, dst_view, PIPE_CLEAR_STENCIL, 0.0, 0, 2926bf215546Sopenharmony_ci MAX2(dstbox->x, scissor->minx), 2927bf215546Sopenharmony_ci MAX2(dstbox->y, scissor->miny), 2928bf215546Sopenharmony_ci MIN2(dstbox->x + dstbox->width, scissor->maxx) - dstbox->x, 2929bf215546Sopenharmony_ci MIN2(dstbox->y + dstbox->height, scissor->maxy) - dstbox->y, 2930bf215546Sopenharmony_ci true); 2931bf215546Sopenharmony_ci pipe->set_scissor_states(pipe, 0, 1, scissor); 2932bf215546Sopenharmony_ci } else { 2933bf215546Sopenharmony_ci pipe->clear_depth_stencil(pipe, dst_view, PIPE_CLEAR_STENCIL, 0.0, 0, 2934bf215546Sopenharmony_ci dstbox->x, dstbox->y, 2935bf215546Sopenharmony_ci dstbox->width, dstbox->height, 2936bf215546Sopenharmony_ci true); 2937bf215546Sopenharmony_ci } 2938bf215546Sopenharmony_ci 2939bf215546Sopenharmony_ci pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src_view); 2940bf215546Sopenharmony_ci pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &ctx->sampler_state); 2941bf215546Sopenharmony_ci 2942bf215546Sopenharmony_ci unsigned stencil_bits = 2943bf215546Sopenharmony_ci util_format_get_component_bits(dst->format, 2944bf215546Sopenharmony_ci UTIL_FORMAT_COLORSPACE_ZS, 1); 2945bf215546Sopenharmony_ci 2946bf215546Sopenharmony_ci struct pipe_stencil_ref sr = { { (1u << stencil_bits) - 1 } }; 2947bf215546Sopenharmony_ci pipe->set_stencil_ref(pipe, sr); 2948bf215546Sopenharmony_ci 2949bf215546Sopenharmony_ci union blitter_attrib coord; 2950bf215546Sopenharmony_ci get_texcoords(src_view, src->width0, src->height0, 2951bf215546Sopenharmony_ci srcbox->x, srcbox->y, 2952bf215546Sopenharmony_ci srcbox->x + srcbox->width, srcbox->y + srcbox->height, 2953bf215546Sopenharmony_ci srcbox->z, 0, true, 2954bf215546Sopenharmony_ci &coord); 2955bf215546Sopenharmony_ci 2956bf215546Sopenharmony_ci for (int i = 0; i < stencil_bits; ++i) { 2957bf215546Sopenharmony_ci uint32_t mask = 1 << i; 2958bf215546Sopenharmony_ci struct pipe_constant_buffer cb = { 2959bf215546Sopenharmony_ci .user_buffer = &mask, 2960bf215546Sopenharmony_ci .buffer_size = sizeof(mask), 2961bf215546Sopenharmony_ci }; 2962bf215546Sopenharmony_ci pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot, 2963bf215546Sopenharmony_ci false, &cb); 2964bf215546Sopenharmony_ci 2965bf215546Sopenharmony_ci pipe->bind_depth_stencil_alpha_state(pipe, 2966bf215546Sopenharmony_ci get_stencil_blit_fallback_dsa(ctx, i)); 2967bf215546Sopenharmony_ci 2968bf215546Sopenharmony_ci blitter->draw_rectangle(blitter, ctx->velem_state, 2969bf215546Sopenharmony_ci get_vs_passthrough_pos_generic, 2970bf215546Sopenharmony_ci dstbox->x, dstbox->y, 2971bf215546Sopenharmony_ci dstbox->x + dstbox->width, 2972bf215546Sopenharmony_ci dstbox->y + dstbox->height, 2973bf215546Sopenharmony_ci 0, 1, 2974bf215546Sopenharmony_ci UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW, 2975bf215546Sopenharmony_ci &coord); 2976bf215546Sopenharmony_ci } 2977bf215546Sopenharmony_ci 2978bf215546Sopenharmony_ci if (scissor) 2979bf215546Sopenharmony_ci pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor); 2980bf215546Sopenharmony_ci 2981bf215546Sopenharmony_ci util_blitter_restore_vertex_states(blitter); 2982bf215546Sopenharmony_ci util_blitter_restore_fragment_states(blitter); 2983bf215546Sopenharmony_ci util_blitter_restore_textures_internal(blitter, 1); 2984bf215546Sopenharmony_ci util_blitter_restore_fb_state(blitter); 2985bf215546Sopenharmony_ci util_blitter_restore_render_cond(blitter); 2986bf215546Sopenharmony_ci util_blitter_restore_constant_buffer_state(blitter); 2987bf215546Sopenharmony_ci util_blitter_unset_running_flag(blitter); 2988bf215546Sopenharmony_ci 2989bf215546Sopenharmony_ci pipe_surface_reference(&dst_view, NULL); 2990bf215546Sopenharmony_ci pipe_sampler_view_reference(&src_view, NULL); 2991bf215546Sopenharmony_ci} 2992