1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2014 Broadcom 3bf215546Sopenharmony_ci * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> 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 "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22bf215546Sopenharmony_ci * IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#include "pipe/p_state.h" 26bf215546Sopenharmony_ci#include "util/u_framebuffer.h" 27bf215546Sopenharmony_ci#include "util/u_inlines.h" 28bf215546Sopenharmony_ci#include "util/u_math.h" 29bf215546Sopenharmony_ci#include "util/u_memory.h" 30bf215546Sopenharmony_ci#include "util/u_helpers.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "vc4_context.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_cistatic void * 35bf215546Sopenharmony_civc4_generic_cso_state_create(const void *src, uint32_t size) 36bf215546Sopenharmony_ci{ 37bf215546Sopenharmony_ci void *dst = calloc(1, size); 38bf215546Sopenharmony_ci if (!dst) 39bf215546Sopenharmony_ci return NULL; 40bf215546Sopenharmony_ci memcpy(dst, src, size); 41bf215546Sopenharmony_ci return dst; 42bf215546Sopenharmony_ci} 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_cistatic void 45bf215546Sopenharmony_civc4_generic_cso_state_delete(struct pipe_context *pctx, void *hwcso) 46bf215546Sopenharmony_ci{ 47bf215546Sopenharmony_ci free(hwcso); 48bf215546Sopenharmony_ci} 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_cistatic void 51bf215546Sopenharmony_civc4_set_blend_color(struct pipe_context *pctx, 52bf215546Sopenharmony_ci const struct pipe_blend_color *blend_color) 53bf215546Sopenharmony_ci{ 54bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 55bf215546Sopenharmony_ci vc4->blend_color.f = *blend_color; 56bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 57bf215546Sopenharmony_ci vc4->blend_color.ub[i] = float_to_ubyte(blend_color->color[i]); 58bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_BLEND_COLOR; 59bf215546Sopenharmony_ci} 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_cistatic void 62bf215546Sopenharmony_civc4_set_stencil_ref(struct pipe_context *pctx, 63bf215546Sopenharmony_ci const struct pipe_stencil_ref stencil_ref) 64bf215546Sopenharmony_ci{ 65bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 66bf215546Sopenharmony_ci vc4->stencil_ref = stencil_ref; 67bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_STENCIL_REF; 68bf215546Sopenharmony_ci} 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_cistatic void 71bf215546Sopenharmony_civc4_set_clip_state(struct pipe_context *pctx, 72bf215546Sopenharmony_ci const struct pipe_clip_state *clip) 73bf215546Sopenharmony_ci{ 74bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 75bf215546Sopenharmony_ci vc4->clip = *clip; 76bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_CLIP; 77bf215546Sopenharmony_ci} 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_cistatic void 80bf215546Sopenharmony_civc4_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask) 81bf215546Sopenharmony_ci{ 82bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 83bf215546Sopenharmony_ci vc4->sample_mask = sample_mask & ((1 << VC4_MAX_SAMPLES) - 1); 84bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_SAMPLE_MASK; 85bf215546Sopenharmony_ci} 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_cistatic uint16_t 88bf215546Sopenharmony_cifloat_to_187_half(float f) 89bf215546Sopenharmony_ci{ 90bf215546Sopenharmony_ci return fui(f) >> 16; 91bf215546Sopenharmony_ci} 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_cistatic void * 94bf215546Sopenharmony_civc4_create_rasterizer_state(struct pipe_context *pctx, 95bf215546Sopenharmony_ci const struct pipe_rasterizer_state *cso) 96bf215546Sopenharmony_ci{ 97bf215546Sopenharmony_ci struct vc4_rasterizer_state *so; 98bf215546Sopenharmony_ci struct V3D21_DEPTH_OFFSET depth_offset = { V3D21_DEPTH_OFFSET_header }; 99bf215546Sopenharmony_ci struct V3D21_POINT_SIZE point_size = { V3D21_POINT_SIZE_header }; 100bf215546Sopenharmony_ci struct V3D21_LINE_WIDTH line_width = { V3D21_LINE_WIDTH_header }; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci so = CALLOC_STRUCT(vc4_rasterizer_state); 103bf215546Sopenharmony_ci if (!so) 104bf215546Sopenharmony_ci return NULL; 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci so->base = *cso; 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci if (!(cso->cull_face & PIPE_FACE_FRONT)) 109bf215546Sopenharmony_ci so->config_bits[0] |= VC4_CONFIG_BITS_ENABLE_PRIM_FRONT; 110bf215546Sopenharmony_ci if (!(cso->cull_face & PIPE_FACE_BACK)) 111bf215546Sopenharmony_ci so->config_bits[0] |= VC4_CONFIG_BITS_ENABLE_PRIM_BACK; 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci /* Workaround: HW-2726 PTB does not handle zero-size points (BCM2835, 114bf215546Sopenharmony_ci * BCM21553). 115bf215546Sopenharmony_ci */ 116bf215546Sopenharmony_ci point_size.point_size = MAX2(cso->point_size, .125f); 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci line_width.line_width = cso->line_width; 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci if (cso->front_ccw) 121bf215546Sopenharmony_ci so->config_bits[0] |= VC4_CONFIG_BITS_CW_PRIMITIVES; 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci if (cso->offset_tri) { 124bf215546Sopenharmony_ci so->config_bits[0] |= VC4_CONFIG_BITS_ENABLE_DEPTH_OFFSET; 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci depth_offset.depth_offset_units = 127bf215546Sopenharmony_ci float_to_187_half(cso->offset_units); 128bf215546Sopenharmony_ci depth_offset.depth_offset_factor = 129bf215546Sopenharmony_ci float_to_187_half(cso->offset_scale); 130bf215546Sopenharmony_ci } 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci if (cso->multisample) 133bf215546Sopenharmony_ci so->config_bits[0] |= VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_4X; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci V3D21_DEPTH_OFFSET_pack(NULL, so->packed.depth_offset, &depth_offset); 136bf215546Sopenharmony_ci V3D21_POINT_SIZE_pack(NULL, so->packed.point_size, &point_size); 137bf215546Sopenharmony_ci V3D21_LINE_WIDTH_pack(NULL, so->packed.line_width, &line_width); 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci if (cso->tile_raster_order_fixed) { 140bf215546Sopenharmony_ci so->tile_raster_order_flags |= VC4_SUBMIT_CL_FIXED_RCL_ORDER; 141bf215546Sopenharmony_ci if (cso->tile_raster_order_increasing_x) { 142bf215546Sopenharmony_ci so->tile_raster_order_flags |= 143bf215546Sopenharmony_ci VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X; 144bf215546Sopenharmony_ci } 145bf215546Sopenharmony_ci if (cso->tile_raster_order_increasing_y) { 146bf215546Sopenharmony_ci so->tile_raster_order_flags |= 147bf215546Sopenharmony_ci VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y; 148bf215546Sopenharmony_ci } 149bf215546Sopenharmony_ci } 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci return so; 152bf215546Sopenharmony_ci} 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci/* Blend state is baked into shaders. */ 155bf215546Sopenharmony_cistatic void * 156bf215546Sopenharmony_civc4_create_blend_state(struct pipe_context *pctx, 157bf215546Sopenharmony_ci const struct pipe_blend_state *cso) 158bf215546Sopenharmony_ci{ 159bf215546Sopenharmony_ci return vc4_generic_cso_state_create(cso, sizeof(*cso)); 160bf215546Sopenharmony_ci} 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci/** 163bf215546Sopenharmony_ci * The TLB_STENCIL_SETUP data has a little bitfield for common writemask 164bf215546Sopenharmony_ci * values, so you don't have to do a separate writemask setup. 165bf215546Sopenharmony_ci */ 166bf215546Sopenharmony_cistatic uint8_t 167bf215546Sopenharmony_citlb_stencil_setup_writemask(uint8_t mask) 168bf215546Sopenharmony_ci{ 169bf215546Sopenharmony_ci switch (mask) { 170bf215546Sopenharmony_ci case 0x1: return 0; 171bf215546Sopenharmony_ci case 0x3: return 1; 172bf215546Sopenharmony_ci case 0xf: return 2; 173bf215546Sopenharmony_ci case 0xff: return 3; 174bf215546Sopenharmony_ci default: return 0xff; 175bf215546Sopenharmony_ci } 176bf215546Sopenharmony_ci} 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_cistatic uint32_t 179bf215546Sopenharmony_citlb_stencil_setup_bits(const struct pipe_stencil_state *state, 180bf215546Sopenharmony_ci uint8_t writemask_bits) 181bf215546Sopenharmony_ci{ 182bf215546Sopenharmony_ci static const uint8_t op_map[] = { 183bf215546Sopenharmony_ci [PIPE_STENCIL_OP_ZERO] = 0, 184bf215546Sopenharmony_ci [PIPE_STENCIL_OP_KEEP] = 1, 185bf215546Sopenharmony_ci [PIPE_STENCIL_OP_REPLACE] = 2, 186bf215546Sopenharmony_ci [PIPE_STENCIL_OP_INCR] = 3, 187bf215546Sopenharmony_ci [PIPE_STENCIL_OP_DECR] = 4, 188bf215546Sopenharmony_ci [PIPE_STENCIL_OP_INVERT] = 5, 189bf215546Sopenharmony_ci [PIPE_STENCIL_OP_INCR_WRAP] = 6, 190bf215546Sopenharmony_ci [PIPE_STENCIL_OP_DECR_WRAP] = 7, 191bf215546Sopenharmony_ci }; 192bf215546Sopenharmony_ci uint32_t bits = 0; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci if (writemask_bits != 0xff) 195bf215546Sopenharmony_ci bits |= writemask_bits << 28; 196bf215546Sopenharmony_ci bits |= op_map[state->zfail_op] << 25; 197bf215546Sopenharmony_ci bits |= op_map[state->zpass_op] << 22; 198bf215546Sopenharmony_ci bits |= op_map[state->fail_op] << 19; 199bf215546Sopenharmony_ci bits |= state->func << 16; 200bf215546Sopenharmony_ci /* Ref is filled in at uniform upload time */ 201bf215546Sopenharmony_ci bits |= state->valuemask << 0; 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci return bits; 204bf215546Sopenharmony_ci} 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_cistatic void * 207bf215546Sopenharmony_civc4_create_depth_stencil_alpha_state(struct pipe_context *pctx, 208bf215546Sopenharmony_ci const struct pipe_depth_stencil_alpha_state *cso) 209bf215546Sopenharmony_ci{ 210bf215546Sopenharmony_ci struct vc4_depth_stencil_alpha_state *so; 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci so = CALLOC_STRUCT(vc4_depth_stencil_alpha_state); 213bf215546Sopenharmony_ci if (!so) 214bf215546Sopenharmony_ci return NULL; 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci so->base = *cso; 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci /* We always keep the early Z state correct, since a later state using 219bf215546Sopenharmony_ci * early Z may want it. 220bf215546Sopenharmony_ci */ 221bf215546Sopenharmony_ci so->config_bits[2] |= VC4_CONFIG_BITS_EARLY_Z_UPDATE; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci if (cso->depth_enabled) { 224bf215546Sopenharmony_ci if (cso->depth_writemask) { 225bf215546Sopenharmony_ci so->config_bits[1] |= VC4_CONFIG_BITS_Z_UPDATE; 226bf215546Sopenharmony_ci } 227bf215546Sopenharmony_ci so->config_bits[1] |= (cso->depth_func << 228bf215546Sopenharmony_ci VC4_CONFIG_BITS_DEPTH_FUNC_SHIFT); 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci /* We only handle early Z in the < direction because otherwise 231bf215546Sopenharmony_ci * we'd have to runtime guess which direction to set in the 232bf215546Sopenharmony_ci * render config. 233bf215546Sopenharmony_ci */ 234bf215546Sopenharmony_ci if ((cso->depth_func == PIPE_FUNC_LESS || 235bf215546Sopenharmony_ci cso->depth_func == PIPE_FUNC_LEQUAL) && 236bf215546Sopenharmony_ci (!cso->stencil[0].enabled || 237bf215546Sopenharmony_ci (cso->stencil[0].zfail_op == PIPE_STENCIL_OP_KEEP && 238bf215546Sopenharmony_ci (!cso->stencil[1].enabled || 239bf215546Sopenharmony_ci cso->stencil[1].zfail_op == PIPE_STENCIL_OP_KEEP)))) { 240bf215546Sopenharmony_ci so->config_bits[2] |= VC4_CONFIG_BITS_EARLY_Z; 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci } else { 243bf215546Sopenharmony_ci so->config_bits[1] |= (PIPE_FUNC_ALWAYS << 244bf215546Sopenharmony_ci VC4_CONFIG_BITS_DEPTH_FUNC_SHIFT); 245bf215546Sopenharmony_ci } 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci if (cso->stencil[0].enabled) { 248bf215546Sopenharmony_ci const struct pipe_stencil_state *front = &cso->stencil[0]; 249bf215546Sopenharmony_ci const struct pipe_stencil_state *back = &cso->stencil[1]; 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci uint8_t front_writemask_bits = 252bf215546Sopenharmony_ci tlb_stencil_setup_writemask(front->writemask); 253bf215546Sopenharmony_ci uint8_t back_writemask = front->writemask; 254bf215546Sopenharmony_ci uint8_t back_writemask_bits = front_writemask_bits; 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci so->stencil_uniforms[0] = 257bf215546Sopenharmony_ci tlb_stencil_setup_bits(front, front_writemask_bits); 258bf215546Sopenharmony_ci if (back->enabled) { 259bf215546Sopenharmony_ci back_writemask = back->writemask; 260bf215546Sopenharmony_ci back_writemask_bits = 261bf215546Sopenharmony_ci tlb_stencil_setup_writemask(back->writemask); 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci so->stencil_uniforms[0] |= (1 << 30); 264bf215546Sopenharmony_ci so->stencil_uniforms[1] = 265bf215546Sopenharmony_ci tlb_stencil_setup_bits(back, back_writemask_bits); 266bf215546Sopenharmony_ci so->stencil_uniforms[1] |= (2 << 30); 267bf215546Sopenharmony_ci } else { 268bf215546Sopenharmony_ci so->stencil_uniforms[0] |= (3 << 30); 269bf215546Sopenharmony_ci } 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci if (front_writemask_bits == 0xff || 272bf215546Sopenharmony_ci back_writemask_bits == 0xff) { 273bf215546Sopenharmony_ci so->stencil_uniforms[2] = (front->writemask | 274bf215546Sopenharmony_ci (back_writemask << 8)); 275bf215546Sopenharmony_ci } 276bf215546Sopenharmony_ci } 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci return so; 279bf215546Sopenharmony_ci} 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_cistatic void 282bf215546Sopenharmony_civc4_set_polygon_stipple(struct pipe_context *pctx, 283bf215546Sopenharmony_ci const struct pipe_poly_stipple *stipple) 284bf215546Sopenharmony_ci{ 285bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 286bf215546Sopenharmony_ci vc4->stipple = *stipple; 287bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_STIPPLE; 288bf215546Sopenharmony_ci} 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_cistatic void 291bf215546Sopenharmony_civc4_set_scissor_states(struct pipe_context *pctx, 292bf215546Sopenharmony_ci unsigned start_slot, 293bf215546Sopenharmony_ci unsigned num_scissors, 294bf215546Sopenharmony_ci const struct pipe_scissor_state *scissor) 295bf215546Sopenharmony_ci{ 296bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci vc4->scissor = *scissor; 299bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_SCISSOR; 300bf215546Sopenharmony_ci} 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_cistatic void 303bf215546Sopenharmony_civc4_set_viewport_states(struct pipe_context *pctx, 304bf215546Sopenharmony_ci unsigned start_slot, 305bf215546Sopenharmony_ci unsigned num_viewports, 306bf215546Sopenharmony_ci const struct pipe_viewport_state *viewport) 307bf215546Sopenharmony_ci{ 308bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 309bf215546Sopenharmony_ci vc4->viewport = *viewport; 310bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_VIEWPORT; 311bf215546Sopenharmony_ci} 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_cistatic void 314bf215546Sopenharmony_civc4_set_vertex_buffers(struct pipe_context *pctx, 315bf215546Sopenharmony_ci unsigned start_slot, unsigned count, 316bf215546Sopenharmony_ci unsigned unbind_num_trailing_slots, 317bf215546Sopenharmony_ci bool take_ownership, 318bf215546Sopenharmony_ci const struct pipe_vertex_buffer *vb) 319bf215546Sopenharmony_ci{ 320bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 321bf215546Sopenharmony_ci struct vc4_vertexbuf_stateobj *so = &vc4->vertexbuf; 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, vb, 324bf215546Sopenharmony_ci start_slot, count, 325bf215546Sopenharmony_ci unbind_num_trailing_slots, 326bf215546Sopenharmony_ci take_ownership); 327bf215546Sopenharmony_ci so->count = util_last_bit(so->enabled_mask); 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_VTXBUF; 330bf215546Sopenharmony_ci} 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_cistatic void 333bf215546Sopenharmony_civc4_blend_state_bind(struct pipe_context *pctx, void *hwcso) 334bf215546Sopenharmony_ci{ 335bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 336bf215546Sopenharmony_ci vc4->blend = hwcso; 337bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_BLEND; 338bf215546Sopenharmony_ci} 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_cistatic void 341bf215546Sopenharmony_civc4_rasterizer_state_bind(struct pipe_context *pctx, void *hwcso) 342bf215546Sopenharmony_ci{ 343bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 344bf215546Sopenharmony_ci struct vc4_rasterizer_state *rast = hwcso; 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci if (vc4->rasterizer && rast && 347bf215546Sopenharmony_ci vc4->rasterizer->base.flatshade != rast->base.flatshade) { 348bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_FLAT_SHADE_FLAGS; 349bf215546Sopenharmony_ci } 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci vc4->rasterizer = hwcso; 352bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_RASTERIZER; 353bf215546Sopenharmony_ci} 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_cistatic void 356bf215546Sopenharmony_civc4_zsa_state_bind(struct pipe_context *pctx, void *hwcso) 357bf215546Sopenharmony_ci{ 358bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 359bf215546Sopenharmony_ci vc4->zsa = hwcso; 360bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_ZSA; 361bf215546Sopenharmony_ci} 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_cistatic void * 364bf215546Sopenharmony_civc4_vertex_state_create(struct pipe_context *pctx, unsigned num_elements, 365bf215546Sopenharmony_ci const struct pipe_vertex_element *elements) 366bf215546Sopenharmony_ci{ 367bf215546Sopenharmony_ci struct vc4_vertex_stateobj *so = CALLOC_STRUCT(vc4_vertex_stateobj); 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci if (!so) 370bf215546Sopenharmony_ci return NULL; 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci memcpy(so->pipe, elements, sizeof(*elements) * num_elements); 373bf215546Sopenharmony_ci so->num_elements = num_elements; 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci return so; 376bf215546Sopenharmony_ci} 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_cistatic void 379bf215546Sopenharmony_civc4_vertex_state_bind(struct pipe_context *pctx, void *hwcso) 380bf215546Sopenharmony_ci{ 381bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 382bf215546Sopenharmony_ci vc4->vtx = hwcso; 383bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_VTXSTATE; 384bf215546Sopenharmony_ci} 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_cistatic void 387bf215546Sopenharmony_civc4_set_constant_buffer(struct pipe_context *pctx, 388bf215546Sopenharmony_ci enum pipe_shader_type shader, uint index, 389bf215546Sopenharmony_ci bool take_ownership, 390bf215546Sopenharmony_ci const struct pipe_constant_buffer *cb) 391bf215546Sopenharmony_ci{ 392bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 393bf215546Sopenharmony_ci struct vc4_constbuf_stateobj *so = &vc4->constbuf[shader]; 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci /* Note that the gallium frontend can unbind constant buffers by 396bf215546Sopenharmony_ci * passing NULL here. 397bf215546Sopenharmony_ci */ 398bf215546Sopenharmony_ci if (unlikely(!cb)) { 399bf215546Sopenharmony_ci so->enabled_mask &= ~(1 << index); 400bf215546Sopenharmony_ci so->dirty_mask &= ~(1 << index); 401bf215546Sopenharmony_ci return; 402bf215546Sopenharmony_ci } 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci if (index == 1 && so->cb[index].buffer_size != cb->buffer_size) 405bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_UBO_1_SIZE; 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci util_copy_constant_buffer(&so->cb[index], cb, take_ownership); 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci so->enabled_mask |= 1 << index; 410bf215546Sopenharmony_ci so->dirty_mask |= 1 << index; 411bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_CONSTBUF; 412bf215546Sopenharmony_ci} 413bf215546Sopenharmony_ci 414bf215546Sopenharmony_cistatic void 415bf215546Sopenharmony_civc4_set_framebuffer_state(struct pipe_context *pctx, 416bf215546Sopenharmony_ci const struct pipe_framebuffer_state *framebuffer) 417bf215546Sopenharmony_ci{ 418bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 419bf215546Sopenharmony_ci struct pipe_framebuffer_state *cso = &vc4->framebuffer; 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci vc4->job = NULL; 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci util_copy_framebuffer_state(cso, framebuffer); 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci /* Nonzero texture mipmap levels are laid out as if they were in 426bf215546Sopenharmony_ci * power-of-two-sized spaces. The renderbuffer config infers its 427bf215546Sopenharmony_ci * stride from the width parameter, so we need to configure our 428bf215546Sopenharmony_ci * framebuffer. Note that if the z/color buffers were mismatched 429bf215546Sopenharmony_ci * sizes, we wouldn't be able to do this. 430bf215546Sopenharmony_ci */ 431bf215546Sopenharmony_ci if (cso->cbufs[0] && cso->cbufs[0]->u.tex.level) { 432bf215546Sopenharmony_ci struct vc4_resource *rsc = 433bf215546Sopenharmony_ci vc4_resource(cso->cbufs[0]->texture); 434bf215546Sopenharmony_ci cso->width = 435bf215546Sopenharmony_ci (rsc->slices[cso->cbufs[0]->u.tex.level].stride / 436bf215546Sopenharmony_ci rsc->cpp); 437bf215546Sopenharmony_ci } else if (cso->zsbuf && cso->zsbuf->u.tex.level){ 438bf215546Sopenharmony_ci struct vc4_resource *rsc = 439bf215546Sopenharmony_ci vc4_resource(cso->zsbuf->texture); 440bf215546Sopenharmony_ci cso->width = 441bf215546Sopenharmony_ci (rsc->slices[cso->zsbuf->u.tex.level].stride / 442bf215546Sopenharmony_ci rsc->cpp); 443bf215546Sopenharmony_ci } 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_FRAMEBUFFER; 446bf215546Sopenharmony_ci} 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_cistatic struct vc4_texture_stateobj * 449bf215546Sopenharmony_civc4_get_stage_tex(struct vc4_context *vc4, enum pipe_shader_type shader) 450bf215546Sopenharmony_ci{ 451bf215546Sopenharmony_ci switch (shader) { 452bf215546Sopenharmony_ci case PIPE_SHADER_FRAGMENT: 453bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_FRAGTEX; 454bf215546Sopenharmony_ci return &vc4->fragtex; 455bf215546Sopenharmony_ci break; 456bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 457bf215546Sopenharmony_ci vc4->dirty |= VC4_DIRTY_VERTTEX; 458bf215546Sopenharmony_ci return &vc4->verttex; 459bf215546Sopenharmony_ci break; 460bf215546Sopenharmony_ci default: 461bf215546Sopenharmony_ci fprintf(stderr, "Unknown shader target %d\n", shader); 462bf215546Sopenharmony_ci abort(); 463bf215546Sopenharmony_ci } 464bf215546Sopenharmony_ci} 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_cistatic uint32_t translate_wrap(uint32_t p_wrap, bool using_nearest) 467bf215546Sopenharmony_ci{ 468bf215546Sopenharmony_ci switch (p_wrap) { 469bf215546Sopenharmony_ci case PIPE_TEX_WRAP_REPEAT: 470bf215546Sopenharmony_ci return 0; 471bf215546Sopenharmony_ci case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 472bf215546Sopenharmony_ci return 1; 473bf215546Sopenharmony_ci case PIPE_TEX_WRAP_MIRROR_REPEAT: 474bf215546Sopenharmony_ci return 2; 475bf215546Sopenharmony_ci case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 476bf215546Sopenharmony_ci return 3; 477bf215546Sopenharmony_ci case PIPE_TEX_WRAP_CLAMP: 478bf215546Sopenharmony_ci return (using_nearest ? 1 : 3); 479bf215546Sopenharmony_ci default: 480bf215546Sopenharmony_ci fprintf(stderr, "Unknown wrap mode %d\n", p_wrap); 481bf215546Sopenharmony_ci assert(!"not reached"); 482bf215546Sopenharmony_ci return 0; 483bf215546Sopenharmony_ci } 484bf215546Sopenharmony_ci} 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_cistatic void * 487bf215546Sopenharmony_civc4_create_sampler_state(struct pipe_context *pctx, 488bf215546Sopenharmony_ci const struct pipe_sampler_state *cso) 489bf215546Sopenharmony_ci{ 490bf215546Sopenharmony_ci static const uint8_t minfilter_map[6] = { 491bf215546Sopenharmony_ci VC4_TEX_P1_MINFILT_NEAR_MIP_NEAR, 492bf215546Sopenharmony_ci VC4_TEX_P1_MINFILT_LIN_MIP_NEAR, 493bf215546Sopenharmony_ci VC4_TEX_P1_MINFILT_NEAR_MIP_LIN, 494bf215546Sopenharmony_ci VC4_TEX_P1_MINFILT_LIN_MIP_LIN, 495bf215546Sopenharmony_ci VC4_TEX_P1_MINFILT_NEAREST, 496bf215546Sopenharmony_ci VC4_TEX_P1_MINFILT_LINEAR, 497bf215546Sopenharmony_ci }; 498bf215546Sopenharmony_ci static const uint32_t magfilter_map[] = { 499bf215546Sopenharmony_ci [PIPE_TEX_FILTER_NEAREST] = VC4_TEX_P1_MAGFILT_NEAREST, 500bf215546Sopenharmony_ci [PIPE_TEX_FILTER_LINEAR] = VC4_TEX_P1_MAGFILT_LINEAR, 501bf215546Sopenharmony_ci }; 502bf215546Sopenharmony_ci bool either_nearest = 503bf215546Sopenharmony_ci (cso->mag_img_filter == PIPE_TEX_MIPFILTER_NEAREST || 504bf215546Sopenharmony_ci cso->min_img_filter == PIPE_TEX_MIPFILTER_NEAREST); 505bf215546Sopenharmony_ci struct vc4_sampler_state *so = CALLOC_STRUCT(vc4_sampler_state); 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci if (!so) 508bf215546Sopenharmony_ci return NULL; 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci memcpy(so, cso, sizeof(*cso)); 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci so->texture_p1 = 513bf215546Sopenharmony_ci (VC4_SET_FIELD(magfilter_map[cso->mag_img_filter], 514bf215546Sopenharmony_ci VC4_TEX_P1_MAGFILT) | 515bf215546Sopenharmony_ci VC4_SET_FIELD(minfilter_map[cso->min_mip_filter * 2 + 516bf215546Sopenharmony_ci cso->min_img_filter], 517bf215546Sopenharmony_ci VC4_TEX_P1_MINFILT) | 518bf215546Sopenharmony_ci VC4_SET_FIELD(translate_wrap(cso->wrap_s, either_nearest), 519bf215546Sopenharmony_ci VC4_TEX_P1_WRAP_S) | 520bf215546Sopenharmony_ci VC4_SET_FIELD(translate_wrap(cso->wrap_t, either_nearest), 521bf215546Sopenharmony_ci VC4_TEX_P1_WRAP_T)); 522bf215546Sopenharmony_ci 523bf215546Sopenharmony_ci return so; 524bf215546Sopenharmony_ci} 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_cistatic void 527bf215546Sopenharmony_civc4_sampler_states_bind(struct pipe_context *pctx, 528bf215546Sopenharmony_ci enum pipe_shader_type shader, unsigned start, 529bf215546Sopenharmony_ci unsigned nr, void **hwcso) 530bf215546Sopenharmony_ci{ 531bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 532bf215546Sopenharmony_ci struct vc4_texture_stateobj *stage_tex = vc4_get_stage_tex(vc4, shader); 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_ci assert(start == 0); 535bf215546Sopenharmony_ci unsigned i; 536bf215546Sopenharmony_ci unsigned new_nr = 0; 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci for (i = 0; i < nr; i++) { 539bf215546Sopenharmony_ci if (hwcso[i]) 540bf215546Sopenharmony_ci new_nr = i + 1; 541bf215546Sopenharmony_ci stage_tex->samplers[i] = hwcso[i]; 542bf215546Sopenharmony_ci } 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci for (; i < stage_tex->num_samplers; i++) { 545bf215546Sopenharmony_ci stage_tex->samplers[i] = NULL; 546bf215546Sopenharmony_ci } 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci stage_tex->num_samplers = new_nr; 549bf215546Sopenharmony_ci} 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_cistatic struct pipe_sampler_view * 552bf215546Sopenharmony_civc4_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, 553bf215546Sopenharmony_ci const struct pipe_sampler_view *cso) 554bf215546Sopenharmony_ci{ 555bf215546Sopenharmony_ci struct vc4_sampler_view *so = CALLOC_STRUCT(vc4_sampler_view); 556bf215546Sopenharmony_ci struct vc4_resource *rsc = vc4_resource(prsc); 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci if (!so) 559bf215546Sopenharmony_ci return NULL; 560bf215546Sopenharmony_ci 561bf215546Sopenharmony_ci so->base = *cso; 562bf215546Sopenharmony_ci 563bf215546Sopenharmony_ci so->base.texture = NULL; 564bf215546Sopenharmony_ci pipe_resource_reference(&so->base.texture, prsc); 565bf215546Sopenharmony_ci so->base.reference.count = 1; 566bf215546Sopenharmony_ci so->base.context = pctx; 567bf215546Sopenharmony_ci 568bf215546Sopenharmony_ci /* There is no hardware level clamping, and the start address of a 569bf215546Sopenharmony_ci * texture may be misaligned, so in that case we have to copy to a 570bf215546Sopenharmony_ci * temporary. 571bf215546Sopenharmony_ci * 572bf215546Sopenharmony_ci * Also, Raspberry Pi doesn't support sampling from raster textures, 573bf215546Sopenharmony_ci * so we also have to copy to a temporary then. 574bf215546Sopenharmony_ci */ 575bf215546Sopenharmony_ci if ((cso->u.tex.first_level && 576bf215546Sopenharmony_ci (cso->u.tex.first_level != cso->u.tex.last_level)) || 577bf215546Sopenharmony_ci rsc->vc4_format == VC4_TEXTURE_TYPE_RGBA32R || 578bf215546Sopenharmony_ci rsc->vc4_format == ~0) { 579bf215546Sopenharmony_ci struct vc4_resource *shadow_parent = rsc; 580bf215546Sopenharmony_ci struct pipe_resource tmpl = { 581bf215546Sopenharmony_ci .target = prsc->target, 582bf215546Sopenharmony_ci .format = prsc->format, 583bf215546Sopenharmony_ci .width0 = u_minify(prsc->width0, 584bf215546Sopenharmony_ci cso->u.tex.first_level), 585bf215546Sopenharmony_ci .height0 = u_minify(prsc->height0, 586bf215546Sopenharmony_ci cso->u.tex.first_level), 587bf215546Sopenharmony_ci .bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET, 588bf215546Sopenharmony_ci .last_level = cso->u.tex.last_level - cso->u.tex.first_level, 589bf215546Sopenharmony_ci .nr_samples = prsc->nr_samples, 590bf215546Sopenharmony_ci }; 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci /* Create the shadow texture. The rest of the texture 593bf215546Sopenharmony_ci * parameter setup will use the shadow. 594bf215546Sopenharmony_ci */ 595bf215546Sopenharmony_ci prsc = vc4_resource_create(pctx->screen, &tmpl); 596bf215546Sopenharmony_ci if (!prsc) { 597bf215546Sopenharmony_ci free(so); 598bf215546Sopenharmony_ci return NULL; 599bf215546Sopenharmony_ci } 600bf215546Sopenharmony_ci rsc = vc4_resource(prsc); 601bf215546Sopenharmony_ci vc4_bo_label(vc4_screen(pctx->screen), rsc->bo, 602bf215546Sopenharmony_ci "tiling shadow %dx%d", 603bf215546Sopenharmony_ci tmpl.width0, tmpl.height0); 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_ci /* Flag it as needing update of the contents from the parent. */ 606bf215546Sopenharmony_ci rsc->writes = shadow_parent->writes - 1; 607bf215546Sopenharmony_ci assert(rsc->vc4_format != VC4_TEXTURE_TYPE_RGBA32R); 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci so->texture = prsc; 610bf215546Sopenharmony_ci } else { 611bf215546Sopenharmony_ci pipe_resource_reference(&so->texture, prsc); 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_ci if (cso->u.tex.first_level) { 614bf215546Sopenharmony_ci so->force_first_level = true; 615bf215546Sopenharmony_ci } 616bf215546Sopenharmony_ci } 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_ci so->texture_p0 = 619bf215546Sopenharmony_ci (VC4_SET_FIELD((rsc->slices[0].offset + 620bf215546Sopenharmony_ci cso->u.tex.first_layer * 621bf215546Sopenharmony_ci rsc->cube_map_stride) >> 12, VC4_TEX_P0_OFFSET) | 622bf215546Sopenharmony_ci VC4_SET_FIELD(rsc->vc4_format & 15, VC4_TEX_P0_TYPE) | 623bf215546Sopenharmony_ci VC4_SET_FIELD(so->force_first_level ? 624bf215546Sopenharmony_ci cso->u.tex.last_level : 625bf215546Sopenharmony_ci cso->u.tex.last_level - 626bf215546Sopenharmony_ci cso->u.tex.first_level, VC4_TEX_P0_MIPLVLS) | 627bf215546Sopenharmony_ci VC4_SET_FIELD(cso->target == PIPE_TEXTURE_CUBE, 628bf215546Sopenharmony_ci VC4_TEX_P0_CMMODE)); 629bf215546Sopenharmony_ci so->texture_p1 = 630bf215546Sopenharmony_ci (VC4_SET_FIELD(rsc->vc4_format >> 4, VC4_TEX_P1_TYPE4) | 631bf215546Sopenharmony_ci VC4_SET_FIELD(prsc->height0 & 2047, VC4_TEX_P1_HEIGHT) | 632bf215546Sopenharmony_ci VC4_SET_FIELD(prsc->width0 & 2047, VC4_TEX_P1_WIDTH)); 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_ci if (prsc->format == PIPE_FORMAT_ETC1_RGB8) 635bf215546Sopenharmony_ci so->texture_p1 |= VC4_TEX_P1_ETCFLIP_MASK; 636bf215546Sopenharmony_ci 637bf215546Sopenharmony_ci return &so->base; 638bf215546Sopenharmony_ci} 639bf215546Sopenharmony_ci 640bf215546Sopenharmony_cistatic void 641bf215546Sopenharmony_civc4_sampler_view_destroy(struct pipe_context *pctx, 642bf215546Sopenharmony_ci struct pipe_sampler_view *pview) 643bf215546Sopenharmony_ci{ 644bf215546Sopenharmony_ci struct vc4_sampler_view *view = vc4_sampler_view(pview); 645bf215546Sopenharmony_ci pipe_resource_reference(&pview->texture, NULL); 646bf215546Sopenharmony_ci pipe_resource_reference(&view->texture, NULL); 647bf215546Sopenharmony_ci free(view); 648bf215546Sopenharmony_ci} 649bf215546Sopenharmony_ci 650bf215546Sopenharmony_cistatic void 651bf215546Sopenharmony_civc4_set_sampler_views(struct pipe_context *pctx, 652bf215546Sopenharmony_ci enum pipe_shader_type shader, 653bf215546Sopenharmony_ci unsigned start, unsigned nr, 654bf215546Sopenharmony_ci unsigned unbind_num_trailing_slots, 655bf215546Sopenharmony_ci bool take_ownership, 656bf215546Sopenharmony_ci struct pipe_sampler_view **views) 657bf215546Sopenharmony_ci{ 658bf215546Sopenharmony_ci struct vc4_context *vc4 = vc4_context(pctx); 659bf215546Sopenharmony_ci struct vc4_texture_stateobj *stage_tex = vc4_get_stage_tex(vc4, shader); 660bf215546Sopenharmony_ci unsigned i; 661bf215546Sopenharmony_ci unsigned new_nr = 0; 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci assert(start == 0); 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_ci for (i = 0; i < nr; i++) { 666bf215546Sopenharmony_ci if (views[i]) 667bf215546Sopenharmony_ci new_nr = i + 1; 668bf215546Sopenharmony_ci if (take_ownership) { 669bf215546Sopenharmony_ci pipe_sampler_view_reference(&stage_tex->textures[i], NULL); 670bf215546Sopenharmony_ci stage_tex->textures[i] = views[i]; 671bf215546Sopenharmony_ci } else { 672bf215546Sopenharmony_ci pipe_sampler_view_reference(&stage_tex->textures[i], views[i]); 673bf215546Sopenharmony_ci } 674bf215546Sopenharmony_ci } 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci for (; i < stage_tex->num_textures; i++) { 677bf215546Sopenharmony_ci pipe_sampler_view_reference(&stage_tex->textures[i], NULL); 678bf215546Sopenharmony_ci } 679bf215546Sopenharmony_ci 680bf215546Sopenharmony_ci stage_tex->num_textures = new_nr; 681bf215546Sopenharmony_ci} 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_civoid 684bf215546Sopenharmony_civc4_state_init(struct pipe_context *pctx) 685bf215546Sopenharmony_ci{ 686bf215546Sopenharmony_ci pctx->set_blend_color = vc4_set_blend_color; 687bf215546Sopenharmony_ci pctx->set_stencil_ref = vc4_set_stencil_ref; 688bf215546Sopenharmony_ci pctx->set_clip_state = vc4_set_clip_state; 689bf215546Sopenharmony_ci pctx->set_sample_mask = vc4_set_sample_mask; 690bf215546Sopenharmony_ci pctx->set_constant_buffer = vc4_set_constant_buffer; 691bf215546Sopenharmony_ci pctx->set_framebuffer_state = vc4_set_framebuffer_state; 692bf215546Sopenharmony_ci pctx->set_polygon_stipple = vc4_set_polygon_stipple; 693bf215546Sopenharmony_ci pctx->set_scissor_states = vc4_set_scissor_states; 694bf215546Sopenharmony_ci pctx->set_viewport_states = vc4_set_viewport_states; 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci pctx->set_vertex_buffers = vc4_set_vertex_buffers; 697bf215546Sopenharmony_ci 698bf215546Sopenharmony_ci pctx->create_blend_state = vc4_create_blend_state; 699bf215546Sopenharmony_ci pctx->bind_blend_state = vc4_blend_state_bind; 700bf215546Sopenharmony_ci pctx->delete_blend_state = vc4_generic_cso_state_delete; 701bf215546Sopenharmony_ci 702bf215546Sopenharmony_ci pctx->create_rasterizer_state = vc4_create_rasterizer_state; 703bf215546Sopenharmony_ci pctx->bind_rasterizer_state = vc4_rasterizer_state_bind; 704bf215546Sopenharmony_ci pctx->delete_rasterizer_state = vc4_generic_cso_state_delete; 705bf215546Sopenharmony_ci 706bf215546Sopenharmony_ci pctx->create_depth_stencil_alpha_state = vc4_create_depth_stencil_alpha_state; 707bf215546Sopenharmony_ci pctx->bind_depth_stencil_alpha_state = vc4_zsa_state_bind; 708bf215546Sopenharmony_ci pctx->delete_depth_stencil_alpha_state = vc4_generic_cso_state_delete; 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_ci pctx->create_vertex_elements_state = vc4_vertex_state_create; 711bf215546Sopenharmony_ci pctx->delete_vertex_elements_state = vc4_generic_cso_state_delete; 712bf215546Sopenharmony_ci pctx->bind_vertex_elements_state = vc4_vertex_state_bind; 713bf215546Sopenharmony_ci 714bf215546Sopenharmony_ci pctx->create_sampler_state = vc4_create_sampler_state; 715bf215546Sopenharmony_ci pctx->delete_sampler_state = vc4_generic_cso_state_delete; 716bf215546Sopenharmony_ci pctx->bind_sampler_states = vc4_sampler_states_bind; 717bf215546Sopenharmony_ci 718bf215546Sopenharmony_ci pctx->create_sampler_view = vc4_create_sampler_view; 719bf215546Sopenharmony_ci pctx->sampler_view_destroy = vc4_sampler_view_destroy; 720bf215546Sopenharmony_ci pctx->set_sampler_views = vc4_set_sampler_views; 721bf215546Sopenharmony_ci} 722