Path: blob/21.2-virgl/src/gallium/drivers/v3d/v3dx_state.c
4570 views
/*1* Copyright © 2014-2017 Broadcom2* Copyright (C) 2012 Rob Clark <[email protected]>3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the "Software"),6* to deal in the Software without restriction, including without limitation7* the rights to use, copy, modify, merge, publish, distribute, sublicense,8* and/or sell copies of the Software, and to permit persons to whom the9* Software is furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice (including the next12* paragraph) shall be included in all copies or substantial portions of the13* Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING20* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS21* IN THE SOFTWARE.22*/2324#include "pipe/p_state.h"25#include "util/format/u_format.h"26#include "util/u_framebuffer.h"27#include "util/u_inlines.h"28#include "util/u_math.h"29#include "util/u_memory.h"30#include "util/half_float.h"31#include "util/u_helpers.h"32#include "util/u_upload_mgr.h"3334#include "v3d_context.h"35#include "broadcom/common/v3d_tiling.h"36#include "broadcom/common/v3d_macros.h"37#include "broadcom/compiler/v3d_compiler.h"38#include "broadcom/cle/v3dx_pack.h"3940static void41v3d_generic_cso_state_delete(struct pipe_context *pctx, void *hwcso)42{43free(hwcso);44}4546static void47v3d_set_blend_color(struct pipe_context *pctx,48const struct pipe_blend_color *blend_color)49{50struct v3d_context *v3d = v3d_context(pctx);51v3d->blend_color.f = *blend_color;52for (int i = 0; i < 4; i++) {53v3d->blend_color.hf[i] =54_mesa_float_to_half(blend_color->color[i]);55}56v3d->dirty |= V3D_DIRTY_BLEND_COLOR;57}5859static void60v3d_set_stencil_ref(struct pipe_context *pctx,61const struct pipe_stencil_ref stencil_ref)62{63struct v3d_context *v3d = v3d_context(pctx);64v3d->stencil_ref = stencil_ref;65v3d->dirty |= V3D_DIRTY_STENCIL_REF;66}6768static void69v3d_set_clip_state(struct pipe_context *pctx,70const struct pipe_clip_state *clip)71{72struct v3d_context *v3d = v3d_context(pctx);73v3d->clip = *clip;74v3d->dirty |= V3D_DIRTY_CLIP;75}7677static void78v3d_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask)79{80struct v3d_context *v3d = v3d_context(pctx);81v3d->sample_mask = sample_mask & ((1 << V3D_MAX_SAMPLES) - 1);82v3d->dirty |= V3D_DIRTY_SAMPLE_STATE;83}8485static void *86v3d_create_rasterizer_state(struct pipe_context *pctx,87const struct pipe_rasterizer_state *cso)88{89struct v3d_rasterizer_state *so;9091so = CALLOC_STRUCT(v3d_rasterizer_state);92if (!so)93return NULL;9495so->base = *cso;9697/* Workaround: HW-2726 PTB does not handle zero-size points (BCM2835,98* BCM21553).99*/100so->point_size = MAX2(cso->point_size, .125f);101102STATIC_ASSERT(sizeof(so->depth_offset) >=103cl_packet_length(DEPTH_OFFSET));104v3dx_pack(&so->depth_offset, DEPTH_OFFSET, depth) {105depth.depth_offset_factor = cso->offset_scale;106depth.depth_offset_units = cso->offset_units;107}108109/* The HW treats polygon offset units based on a Z24 buffer, so we110* need to scale up offset_units if we're only Z16.111*/112v3dx_pack(&so->depth_offset_z16, DEPTH_OFFSET, depth) {113depth.depth_offset_factor = cso->offset_scale;114depth.depth_offset_units = cso->offset_units * 256.0;115}116117return so;118}119120/* Blend state is baked into shaders. */121static void *122v3d_create_blend_state(struct pipe_context *pctx,123const struct pipe_blend_state *cso)124{125struct v3d_blend_state *so;126127so = CALLOC_STRUCT(v3d_blend_state);128if (!so)129return NULL;130131so->base = *cso;132133if (cso->independent_blend_enable) {134for (int i = 0; i < V3D_MAX_DRAW_BUFFERS; i++) {135so->blend_enables |= cso->rt[i].blend_enable << i;136137/* V3D 4.x is when we got independent blend enables. */138assert(V3D_VERSION >= 40 ||139cso->rt[i].blend_enable == cso->rt[0].blend_enable);140}141} else {142if (cso->rt[0].blend_enable)143so->blend_enables = (1 << V3D_MAX_DRAW_BUFFERS) - 1;144}145146return so;147}148149static uint32_t150translate_stencil_op(enum pipe_stencil_op op)151{152switch (op) {153case PIPE_STENCIL_OP_KEEP: return V3D_STENCIL_OP_KEEP;154case PIPE_STENCIL_OP_ZERO: return V3D_STENCIL_OP_ZERO;155case PIPE_STENCIL_OP_REPLACE: return V3D_STENCIL_OP_REPLACE;156case PIPE_STENCIL_OP_INCR: return V3D_STENCIL_OP_INCR;157case PIPE_STENCIL_OP_DECR: return V3D_STENCIL_OP_DECR;158case PIPE_STENCIL_OP_INCR_WRAP: return V3D_STENCIL_OP_INCWRAP;159case PIPE_STENCIL_OP_DECR_WRAP: return V3D_STENCIL_OP_DECWRAP;160case PIPE_STENCIL_OP_INVERT: return V3D_STENCIL_OP_INVERT;161}162unreachable("bad stencil op");163}164165static void *166v3d_create_depth_stencil_alpha_state(struct pipe_context *pctx,167const struct pipe_depth_stencil_alpha_state *cso)168{169struct v3d_depth_stencil_alpha_state *so;170171so = CALLOC_STRUCT(v3d_depth_stencil_alpha_state);172if (!so)173return NULL;174175so->base = *cso;176177if (cso->depth_enabled) {178switch (cso->depth_func) {179case PIPE_FUNC_LESS:180case PIPE_FUNC_LEQUAL:181so->ez_state = V3D_EZ_LT_LE;182break;183case PIPE_FUNC_GREATER:184case PIPE_FUNC_GEQUAL:185so->ez_state = V3D_EZ_GT_GE;186break;187case PIPE_FUNC_NEVER:188case PIPE_FUNC_EQUAL:189so->ez_state = V3D_EZ_UNDECIDED;190break;191default:192so->ez_state = V3D_EZ_DISABLED;193break;194}195196/* If stencil is enabled and it's not a no-op, then it would197* break EZ updates.198*/199if (cso->stencil[0].enabled &&200(cso->stencil[0].zfail_op != PIPE_STENCIL_OP_KEEP ||201cso->stencil[0].func != PIPE_FUNC_ALWAYS ||202(cso->stencil[1].enabled &&203(cso->stencil[1].zfail_op != PIPE_STENCIL_OP_KEEP &&204cso->stencil[1].func != PIPE_FUNC_ALWAYS)))) {205so->ez_state = V3D_EZ_DISABLED;206}207}208209const struct pipe_stencil_state *front = &cso->stencil[0];210const struct pipe_stencil_state *back = &cso->stencil[1];211212if (front->enabled) {213STATIC_ASSERT(sizeof(so->stencil_front) >=214cl_packet_length(STENCIL_CFG));215v3dx_pack(&so->stencil_front, STENCIL_CFG, config) {216config.front_config = true;217/* If !back->enabled, then the front values should be218* used for both front and back-facing primitives.219*/220config.back_config = !back->enabled;221222config.stencil_write_mask = front->writemask;223config.stencil_test_mask = front->valuemask;224225config.stencil_test_function = front->func;226config.stencil_pass_op =227translate_stencil_op(front->zpass_op);228config.depth_test_fail_op =229translate_stencil_op(front->zfail_op);230config.stencil_test_fail_op =231translate_stencil_op(front->fail_op);232}233}234if (back->enabled) {235STATIC_ASSERT(sizeof(so->stencil_back) >=236cl_packet_length(STENCIL_CFG));237v3dx_pack(&so->stencil_back, STENCIL_CFG, config) {238config.front_config = false;239config.back_config = true;240241config.stencil_write_mask = back->writemask;242config.stencil_test_mask = back->valuemask;243244config.stencil_test_function = back->func;245config.stencil_pass_op =246translate_stencil_op(back->zpass_op);247config.depth_test_fail_op =248translate_stencil_op(back->zfail_op);249config.stencil_test_fail_op =250translate_stencil_op(back->fail_op);251}252}253254return so;255}256257static void258v3d_set_polygon_stipple(struct pipe_context *pctx,259const struct pipe_poly_stipple *stipple)260{261struct v3d_context *v3d = v3d_context(pctx);262v3d->stipple = *stipple;263v3d->dirty |= V3D_DIRTY_STIPPLE;264}265266static void267v3d_set_scissor_states(struct pipe_context *pctx,268unsigned start_slot,269unsigned num_scissors,270const struct pipe_scissor_state *scissor)271{272struct v3d_context *v3d = v3d_context(pctx);273274v3d->scissor = *scissor;275v3d->dirty |= V3D_DIRTY_SCISSOR;276}277278static void279v3d_set_viewport_states(struct pipe_context *pctx,280unsigned start_slot,281unsigned num_viewports,282const struct pipe_viewport_state *viewport)283{284struct v3d_context *v3d = v3d_context(pctx);285v3d->viewport = *viewport;286v3d->dirty |= V3D_DIRTY_VIEWPORT;287}288289static void290v3d_set_vertex_buffers(struct pipe_context *pctx,291unsigned start_slot, unsigned count,292unsigned unbind_num_trailing_slots,293bool take_ownership,294const struct pipe_vertex_buffer *vb)295{296struct v3d_context *v3d = v3d_context(pctx);297struct v3d_vertexbuf_stateobj *so = &v3d->vertexbuf;298299util_set_vertex_buffers_mask(so->vb, &so->enabled_mask, vb,300start_slot, count,301unbind_num_trailing_slots,302take_ownership);303so->count = util_last_bit(so->enabled_mask);304305v3d->dirty |= V3D_DIRTY_VTXBUF;306}307308static void309v3d_blend_state_bind(struct pipe_context *pctx, void *hwcso)310{311struct v3d_context *v3d = v3d_context(pctx);312v3d->blend = hwcso;313v3d->dirty |= V3D_DIRTY_BLEND;314}315316static void317v3d_rasterizer_state_bind(struct pipe_context *pctx, void *hwcso)318{319struct v3d_context *v3d = v3d_context(pctx);320v3d->rasterizer = hwcso;321v3d->dirty |= V3D_DIRTY_RASTERIZER;322}323324static void325v3d_zsa_state_bind(struct pipe_context *pctx, void *hwcso)326{327struct v3d_context *v3d = v3d_context(pctx);328v3d->zsa = hwcso;329v3d->dirty |= V3D_DIRTY_ZSA;330}331332static void *333v3d_vertex_state_create(struct pipe_context *pctx, unsigned num_elements,334const struct pipe_vertex_element *elements)335{336struct v3d_context *v3d = v3d_context(pctx);337struct v3d_vertex_stateobj *so = CALLOC_STRUCT(v3d_vertex_stateobj);338339if (!so)340return NULL;341342memcpy(so->pipe, elements, sizeof(*elements) * num_elements);343so->num_elements = num_elements;344345for (int i = 0; i < so->num_elements; i++) {346const struct pipe_vertex_element *elem = &elements[i];347const struct util_format_description *desc =348util_format_description(elem->src_format);349uint32_t r_size = desc->channel[0].size;350351const uint32_t size =352cl_packet_length(GL_SHADER_STATE_ATTRIBUTE_RECORD);353354v3dx_pack(&so->attrs[i * size],355GL_SHADER_STATE_ATTRIBUTE_RECORD, attr) {356/* vec_size == 0 means 4 */357attr.vec_size = desc->nr_channels & 3;358attr.signed_int_type = (desc->channel[0].type ==359UTIL_FORMAT_TYPE_SIGNED);360361attr.normalized_int_type = desc->channel[0].normalized;362attr.read_as_int_uint = desc->channel[0].pure_integer;363attr.instance_divisor = MIN2(elem->instance_divisor,3640xffff);365366switch (desc->channel[0].type) {367case UTIL_FORMAT_TYPE_FLOAT:368if (r_size == 32) {369attr.type = ATTRIBUTE_FLOAT;370} else {371assert(r_size == 16);372attr.type = ATTRIBUTE_HALF_FLOAT;373}374break;375376case UTIL_FORMAT_TYPE_SIGNED:377case UTIL_FORMAT_TYPE_UNSIGNED:378switch (r_size) {379case 32:380attr.type = ATTRIBUTE_INT;381break;382case 16:383attr.type = ATTRIBUTE_SHORT;384break;385case 10:386attr.type = ATTRIBUTE_INT2_10_10_10;387break;388case 8:389attr.type = ATTRIBUTE_BYTE;390break;391default:392fprintf(stderr,393"format %s unsupported\n",394desc->name);395attr.type = ATTRIBUTE_BYTE;396abort();397}398break;399400default:401fprintf(stderr,402"format %s unsupported\n",403desc->name);404abort();405}406}407}408409/* Set up the default attribute values in case any of the vertex410* elements use them.411*/412uint32_t *attrs;413u_upload_alloc(v3d->state_uploader, 0,414V3D_MAX_VS_INPUTS * sizeof(float), 16,415&so->defaults_offset, &so->defaults, (void **)&attrs);416417for (int i = 0; i < V3D_MAX_VS_INPUTS / 4; i++) {418attrs[i * 4 + 0] = 0;419attrs[i * 4 + 1] = 0;420attrs[i * 4 + 2] = 0;421if (i < so->num_elements &&422util_format_is_pure_integer(so->pipe[i].src_format)) {423attrs[i * 4 + 3] = 1;424} else {425attrs[i * 4 + 3] = fui(1.0);426}427}428429u_upload_unmap(v3d->state_uploader);430return so;431}432433static void434v3d_vertex_state_delete(struct pipe_context *pctx, void *hwcso)435{436struct v3d_vertex_stateobj *so = hwcso;437438pipe_resource_reference(&so->defaults, NULL);439free(so);440}441442static void443v3d_vertex_state_bind(struct pipe_context *pctx, void *hwcso)444{445struct v3d_context *v3d = v3d_context(pctx);446v3d->vtx = hwcso;447v3d->dirty |= V3D_DIRTY_VTXSTATE;448}449450static void451v3d_set_constant_buffer(struct pipe_context *pctx, uint shader, uint index,452bool take_ownership,453const struct pipe_constant_buffer *cb)454{455struct v3d_context *v3d = v3d_context(pctx);456struct v3d_constbuf_stateobj *so = &v3d->constbuf[shader];457458util_copy_constant_buffer(&so->cb[index], cb, take_ownership);459460/* Note that the gallium frontend can unbind constant buffers by461* passing NULL here.462*/463if (unlikely(!cb)) {464so->enabled_mask &= ~(1 << index);465so->dirty_mask &= ~(1 << index);466return;467}468469so->enabled_mask |= 1 << index;470so->dirty_mask |= 1 << index;471v3d->dirty |= V3D_DIRTY_CONSTBUF;472}473474static void475v3d_set_framebuffer_state(struct pipe_context *pctx,476const struct pipe_framebuffer_state *framebuffer)477{478struct v3d_context *v3d = v3d_context(pctx);479struct pipe_framebuffer_state *cso = &v3d->framebuffer;480481v3d->job = NULL;482483util_copy_framebuffer_state(cso, framebuffer);484485v3d->swap_color_rb = 0;486v3d->blend_dst_alpha_one = 0;487for (int i = 0; i < v3d->framebuffer.nr_cbufs; i++) {488struct pipe_surface *cbuf = v3d->framebuffer.cbufs[i];489if (!cbuf)490continue;491struct v3d_surface *v3d_cbuf = v3d_surface(cbuf);492493const struct util_format_description *desc =494util_format_description(cbuf->format);495496/* For BGRA8 formats (DRI window system default format), we497* need to swap R and B, since the HW's format is RGBA8. On498* V3D 4.1+, the RCL can swap R and B on load/store.499*/500if (v3d->screen->devinfo.ver < 41 && v3d_cbuf->swap_rb)501v3d->swap_color_rb |= 1 << i;502503if (desc->swizzle[3] == PIPE_SWIZZLE_1)504v3d->blend_dst_alpha_one |= 1 << i;505}506507v3d->dirty |= V3D_DIRTY_FRAMEBUFFER;508}509510static enum V3DX(Wrap_Mode)511translate_wrap(uint32_t pipe_wrap)512{513switch (pipe_wrap) {514case PIPE_TEX_WRAP_REPEAT:515return V3D_WRAP_MODE_REPEAT;516case PIPE_TEX_WRAP_CLAMP_TO_EDGE:517return V3D_WRAP_MODE_CLAMP;518case PIPE_TEX_WRAP_MIRROR_REPEAT:519return V3D_WRAP_MODE_MIRROR;520case PIPE_TEX_WRAP_CLAMP_TO_BORDER:521return V3D_WRAP_MODE_BORDER;522default:523unreachable("Unknown wrap mode");524}525}526527#if V3D_VERSION >= 40528static void529v3d_upload_sampler_state_variant(void *map,530const struct pipe_sampler_state *cso,531enum v3d_sampler_state_variant variant)532{533v3dx_pack(map, SAMPLER_STATE, sampler) {534sampler.wrap_i_border = false;535536sampler.wrap_s = translate_wrap(cso->wrap_s);537sampler.wrap_t = translate_wrap(cso->wrap_t);538sampler.wrap_r = translate_wrap(cso->wrap_r);539540sampler.fixed_bias = cso->lod_bias;541sampler.depth_compare_function = cso->compare_func;542543sampler.min_filter_nearest =544cso->min_img_filter == PIPE_TEX_FILTER_NEAREST;545sampler.mag_filter_nearest =546cso->mag_img_filter == PIPE_TEX_FILTER_NEAREST;547sampler.mip_filter_nearest =548cso->min_mip_filter != PIPE_TEX_MIPFILTER_LINEAR;549550sampler.min_level_of_detail = MIN2(MAX2(0, cso->min_lod),55115);552sampler.max_level_of_detail = MIN2(MAX2(cso->max_lod,553cso->min_lod), 15);554555/* If we're not doing inter-miplevel filtering, we need to556* clamp the LOD so that we only sample from baselevel.557* However, we need to still allow the calculated LOD to be558* fractionally over the baselevel, so that the HW can decide559* between the min and mag filters.560*/561if (cso->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {562sampler.min_level_of_detail =563MIN2(sampler.min_level_of_detail, 1.0 / 256.0);564sampler.max_level_of_detail =565MIN2(sampler.max_level_of_detail, 1.0 / 256.0);566}567568if (cso->max_anisotropy) {569sampler.anisotropy_enable = true;570571if (cso->max_anisotropy > 8)572sampler.maximum_anisotropy = 3;573else if (cso->max_anisotropy > 4)574sampler.maximum_anisotropy = 2;575else if (cso->max_anisotropy > 2)576sampler.maximum_anisotropy = 1;577}578579if (variant == V3D_SAMPLER_STATE_BORDER_0) {580sampler.border_color_mode = V3D_BORDER_COLOR_0000;581} else {582sampler.border_color_mode = V3D_BORDER_COLOR_FOLLOWS;583584union pipe_color_union border;585586/* First, reswizzle the border color for any587* mismatching we're doing between the texture's588* channel order in hardware (R) versus what it is at589* the GL level (ALPHA)590*/591switch (variant) {592case V3D_SAMPLER_STATE_F16_BGRA:593case V3D_SAMPLER_STATE_F16_BGRA_UNORM:594case V3D_SAMPLER_STATE_F16_BGRA_SNORM:595border.i[0] = cso->border_color.i[2];596border.i[1] = cso->border_color.i[1];597border.i[2] = cso->border_color.i[0];598border.i[3] = cso->border_color.i[3];599break;600601case V3D_SAMPLER_STATE_F16_A:602case V3D_SAMPLER_STATE_F16_A_UNORM:603case V3D_SAMPLER_STATE_F16_A_SNORM:604case V3D_SAMPLER_STATE_32_A:605case V3D_SAMPLER_STATE_32_A_UNORM:606case V3D_SAMPLER_STATE_32_A_SNORM:607border.i[0] = cso->border_color.i[3];608border.i[1] = 0;609border.i[2] = 0;610border.i[3] = 0;611break;612613case V3D_SAMPLER_STATE_F16_LA:614case V3D_SAMPLER_STATE_F16_LA_UNORM:615case V3D_SAMPLER_STATE_F16_LA_SNORM:616border.i[0] = cso->border_color.i[0];617border.i[1] = cso->border_color.i[3];618border.i[2] = 0;619border.i[3] = 0;620break;621622default:623border = cso->border_color;624}625626/* Perform any clamping. */627switch (variant) {628case V3D_SAMPLER_STATE_F16_UNORM:629case V3D_SAMPLER_STATE_F16_BGRA_UNORM:630case V3D_SAMPLER_STATE_F16_A_UNORM:631case V3D_SAMPLER_STATE_F16_LA_UNORM:632case V3D_SAMPLER_STATE_32_UNORM:633case V3D_SAMPLER_STATE_32_A_UNORM:634for (int i = 0; i < 4; i++)635border.f[i] = CLAMP(border.f[i], 0, 1);636break;637638case V3D_SAMPLER_STATE_F16_SNORM:639case V3D_SAMPLER_STATE_F16_BGRA_SNORM:640case V3D_SAMPLER_STATE_F16_A_SNORM:641case V3D_SAMPLER_STATE_F16_LA_SNORM:642case V3D_SAMPLER_STATE_32_SNORM:643case V3D_SAMPLER_STATE_32_A_SNORM:644for (int i = 0; i < 4; i++)645border.f[i] = CLAMP(border.f[i], -1, 1);646break;647648case V3D_SAMPLER_STATE_1010102U:649border.ui[0] = CLAMP(border.ui[0],6500, (1 << 10) - 1);651border.ui[1] = CLAMP(border.ui[1],6520, (1 << 10) - 1);653border.ui[2] = CLAMP(border.ui[2],6540, (1 << 10) - 1);655border.ui[3] = CLAMP(border.ui[3],6560, 3);657break;658659case V3D_SAMPLER_STATE_16U:660for (int i = 0; i < 4; i++)661border.ui[i] = CLAMP(border.ui[i],6620, 0xffff);663break;664665case V3D_SAMPLER_STATE_16I:666for (int i = 0; i < 4; i++)667border.i[i] = CLAMP(border.i[i],668-32768, 32767);669break;670671case V3D_SAMPLER_STATE_8U:672for (int i = 0; i < 4; i++)673border.ui[i] = CLAMP(border.ui[i],6740, 0xff);675break;676677case V3D_SAMPLER_STATE_8I:678for (int i = 0; i < 4; i++)679border.i[i] = CLAMP(border.i[i],680-128, 127);681break;682683default:684break;685}686687if (variant >= V3D_SAMPLER_STATE_32) {688sampler.border_color_word_0 = border.ui[0];689sampler.border_color_word_1 = border.ui[1];690sampler.border_color_word_2 = border.ui[2];691sampler.border_color_word_3 = border.ui[3];692} else {693sampler.border_color_word_0 =694_mesa_float_to_half(border.f[0]);695sampler.border_color_word_1 =696_mesa_float_to_half(border.f[1]);697sampler.border_color_word_2 =698_mesa_float_to_half(border.f[2]);699sampler.border_color_word_3 =700_mesa_float_to_half(border.f[3]);701}702}703}704}705#endif706707static void *708v3d_create_sampler_state(struct pipe_context *pctx,709const struct pipe_sampler_state *cso)710{711UNUSED struct v3d_context *v3d = v3d_context(pctx);712struct v3d_sampler_state *so = CALLOC_STRUCT(v3d_sampler_state);713714if (!so)715return NULL;716717memcpy(so, cso, sizeof(*cso));718719enum V3DX(Wrap_Mode) wrap_s = translate_wrap(cso->wrap_s);720enum V3DX(Wrap_Mode) wrap_t = translate_wrap(cso->wrap_t);721enum V3DX(Wrap_Mode) wrap_r = translate_wrap(cso->wrap_r);722723bool uses_border_color = (wrap_s == V3D_WRAP_MODE_BORDER ||724wrap_t == V3D_WRAP_MODE_BORDER ||725wrap_r == V3D_WRAP_MODE_BORDER);726so->border_color_variants = (uses_border_color &&727(cso->border_color.ui[0] != 0 ||728cso->border_color.ui[1] != 0 ||729cso->border_color.ui[2] != 0 ||730cso->border_color.ui[3] != 0));731732#if V3D_VERSION >= 40733void *map;734int sampler_align = so->border_color_variants ? 32 : 8;735int sampler_size = align(cl_packet_length(SAMPLER_STATE), sampler_align);736int num_variants = (so->border_color_variants ? ARRAY_SIZE(so->sampler_state_offset) : 1);737u_upload_alloc(v3d->state_uploader, 0,738sampler_size * num_variants,739sampler_align,740&so->sampler_state_offset[0],741&so->sampler_state,742&map);743744for (int i = 0; i < num_variants; i++) {745so->sampler_state_offset[i] =746so->sampler_state_offset[0] + i * sampler_size;747v3d_upload_sampler_state_variant(map + i * sampler_size,748cso, i);749}750751#else /* V3D_VERSION < 40 */752v3dx_pack(&so->p0, TEXTURE_UNIFORM_PARAMETER_0_CFG_MODE1, p0) {753p0.s_wrap_mode = wrap_s;754p0.t_wrap_mode = wrap_t;755p0.r_wrap_mode = wrap_r;756}757758v3dx_pack(&so->texture_shader_state, TEXTURE_SHADER_STATE, tex) {759tex.depth_compare_function = cso->compare_func;760tex.fixed_bias = cso->lod_bias;761}762#endif /* V3D_VERSION < 40 */763return so;764}765766static void767v3d_sampler_states_bind(struct pipe_context *pctx,768enum pipe_shader_type shader, unsigned start,769unsigned nr, void **hwcso)770{771struct v3d_context *v3d = v3d_context(pctx);772struct v3d_texture_stateobj *stage_tex = &v3d->tex[shader];773774assert(start == 0);775unsigned i;776unsigned new_nr = 0;777778for (i = 0; i < nr; i++) {779if (hwcso[i])780new_nr = i + 1;781stage_tex->samplers[i] = hwcso[i];782}783784for (; i < stage_tex->num_samplers; i++) {785stage_tex->samplers[i] = NULL;786}787788stage_tex->num_samplers = new_nr;789790v3d_flag_dirty_sampler_state(v3d, shader);791}792793static void794v3d_sampler_state_delete(struct pipe_context *pctx,795void *hwcso)796{797struct pipe_sampler_state *psampler = hwcso;798struct v3d_sampler_state *sampler = v3d_sampler_state(psampler);799800pipe_resource_reference(&sampler->sampler_state, NULL);801free(psampler);802}803804#if V3D_VERSION >= 40805static uint32_t806translate_swizzle(unsigned char pipe_swizzle)807{808switch (pipe_swizzle) {809case PIPE_SWIZZLE_0:810return 0;811case PIPE_SWIZZLE_1:812return 1;813case PIPE_SWIZZLE_X:814case PIPE_SWIZZLE_Y:815case PIPE_SWIZZLE_Z:816case PIPE_SWIZZLE_W:817return 2 + pipe_swizzle;818default:819unreachable("unknown swizzle");820}821}822#endif823824static void825v3d_setup_texture_shader_state(struct V3DX(TEXTURE_SHADER_STATE) *tex,826struct pipe_resource *prsc,827int base_level, int last_level,828int first_layer, int last_layer)829{830struct v3d_resource *rsc = v3d_resource(prsc);831int msaa_scale = prsc->nr_samples > 1 ? 2 : 1;832833tex->image_width = prsc->width0 * msaa_scale;834tex->image_height = prsc->height0 * msaa_scale;835836#if V3D_VERSION >= 40837/* On 4.x, the height of a 1D texture is redefined to be the838* upper 14 bits of the width (which is only usable with txf).839*/840if (prsc->target == PIPE_TEXTURE_1D ||841prsc->target == PIPE_TEXTURE_1D_ARRAY) {842tex->image_height = tex->image_width >> 14;843}844845tex->image_width &= (1 << 14) - 1;846tex->image_height &= (1 << 14) - 1;847#endif848849if (prsc->target == PIPE_TEXTURE_3D) {850tex->image_depth = prsc->depth0;851} else {852tex->image_depth = (last_layer - first_layer) + 1;853}854855tex->base_level = base_level;856#if V3D_VERSION >= 40857tex->max_level = last_level;858/* Note that we don't have a job to reference the texture's sBO859* at state create time, so any time this sampler view is used860* we need to add the texture to the job.861*/862tex->texture_base_pointer =863cl_address(NULL,864rsc->bo->offset +865v3d_layer_offset(prsc, 0, first_layer));866#endif867tex->array_stride_64_byte_aligned = rsc->cube_map_stride / 64;868869/* Since other platform devices may produce UIF images even870* when they're not big enough for V3D to assume they're UIF,871* we force images with level 0 as UIF to be always treated872* that way.873*/874tex->level_0_is_strictly_uif =875(rsc->slices[0].tiling == V3D_TILING_UIF_XOR ||876rsc->slices[0].tiling == V3D_TILING_UIF_NO_XOR);877tex->level_0_xor_enable = (rsc->slices[0].tiling == V3D_TILING_UIF_XOR);878879if (tex->level_0_is_strictly_uif)880tex->level_0_ub_pad = rsc->slices[0].ub_pad;881882#if V3D_VERSION >= 40883if (tex->uif_xor_disable ||884tex->level_0_is_strictly_uif) {885tex->extended = true;886}887#endif /* V3D_VERSION >= 40 */888}889890void891v3dX(create_texture_shader_state_bo)(struct v3d_context *v3d,892struct v3d_sampler_view *so)893{894struct pipe_resource *prsc = so->texture;895const struct pipe_sampler_view *cso = &so->base;896struct v3d_screen *screen = v3d->screen;897898void *map;899900#if V3D_VERSION >= 40901v3d_bo_unreference(&so->bo);902so->bo = v3d_bo_alloc(v3d->screen,903cl_packet_length(TEXTURE_SHADER_STATE), "sampler");904map = v3d_bo_map(so->bo);905#else /* V3D_VERSION < 40 */906STATIC_ASSERT(sizeof(so->texture_shader_state) >=907cl_packet_length(TEXTURE_SHADER_STATE));908map = &so->texture_shader_state;909#endif910911v3dx_pack(map, TEXTURE_SHADER_STATE, tex) {912v3d_setup_texture_shader_state(&tex, prsc,913cso->u.tex.first_level,914cso->u.tex.last_level,915cso->u.tex.first_layer,916cso->u.tex.last_layer);917918tex.srgb = util_format_is_srgb(cso->format);919920#if V3D_VERSION >= 40921tex.swizzle_r = translate_swizzle(so->swizzle[0]);922tex.swizzle_g = translate_swizzle(so->swizzle[1]);923tex.swizzle_b = translate_swizzle(so->swizzle[2]);924tex.swizzle_a = translate_swizzle(so->swizzle[3]);925#endif926927if (prsc->nr_samples > 1 && V3D_VERSION < 40) {928/* Using texture views to reinterpret formats on our929* MSAA textures won't work, because we don't lay out930* the bits in memory as it's expected -- for example,931* RGBA8 and RGB10_A2 are compatible in the932* ARB_texture_view spec, but in HW we lay them out as933* 32bpp RGBA8 and 64bpp RGBA16F. Just assert for now934* to catch failures.935*936* We explicitly allow remapping S8Z24 to RGBA8888 for937* v3d_blit.c's stencil blits.938*/939assert((util_format_linear(cso->format) ==940util_format_linear(prsc->format)) ||941(prsc->format == PIPE_FORMAT_S8_UINT_Z24_UNORM &&942cso->format == PIPE_FORMAT_R8G8B8A8_UNORM));943uint32_t output_image_format =944v3d_get_rt_format(&screen->devinfo, cso->format);945uint32_t internal_type;946uint32_t internal_bpp;947v3d_get_internal_type_bpp_for_output_format(&screen->devinfo,948output_image_format,949&internal_type,950&internal_bpp);951952switch (internal_type) {953case V3D_INTERNAL_TYPE_8:954tex.texture_type = TEXTURE_DATA_FORMAT_RGBA8;955break;956case V3D_INTERNAL_TYPE_16F:957tex.texture_type = TEXTURE_DATA_FORMAT_RGBA16F;958break;959default:960unreachable("Bad MSAA texture type");961}962963/* sRGB was stored in the tile buffer as linear and964* would have been encoded to sRGB on resolved tile965* buffer store. Note that this means we would need966* shader code if we wanted to read an MSAA sRGB967* texture without sRGB decode.968*/969tex.srgb = false;970} else {971tex.texture_type = v3d_get_tex_format(&screen->devinfo,972cso->format);973}974};975}976977static struct pipe_sampler_view *978v3d_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,979const struct pipe_sampler_view *cso)980{981struct v3d_context *v3d = v3d_context(pctx);982struct v3d_screen *screen = v3d->screen;983struct v3d_sampler_view *so = CALLOC_STRUCT(v3d_sampler_view);984struct v3d_resource *rsc = v3d_resource(prsc);985986if (!so)987return NULL;988989so->base = *cso;990991pipe_reference(NULL, &prsc->reference);992993/* Compute the sampler view's swizzle up front. This will be plugged994* into either the sampler (for 16-bit returns) or the shader's995* texture key (for 32)996*/997uint8_t view_swizzle[4] = {998cso->swizzle_r,999cso->swizzle_g,1000cso->swizzle_b,1001cso->swizzle_a1002};1003const uint8_t *fmt_swizzle =1004v3d_get_format_swizzle(&screen->devinfo, so->base.format);1005util_format_compose_swizzles(fmt_swizzle, view_swizzle, so->swizzle);10061007so->base.texture = prsc;1008so->base.reference.count = 1;1009so->base.context = pctx;10101011if (rsc->separate_stencil &&1012cso->format == PIPE_FORMAT_X32_S8X24_UINT) {1013rsc = rsc->separate_stencil;1014prsc = &rsc->base;1015}10161017/* If we're sampling depth from depth/stencil, demote the format to1018* just depth. u_format will end up giving the answers for the1019* stencil channel, otherwise.1020*/1021enum pipe_format sample_format = cso->format;1022if (sample_format == PIPE_FORMAT_S8_UINT_Z24_UNORM)1023sample_format = PIPE_FORMAT_X8Z24_UNORM;10241025#if V3D_VERSION >= 401026const struct util_format_description *desc =1027util_format_description(sample_format);10281029if (util_format_is_pure_integer(sample_format) &&1030!util_format_has_depth(desc)) {1031int chan = util_format_get_first_non_void_channel(sample_format);1032if (util_format_is_pure_uint(sample_format)) {1033switch (desc->channel[chan].size) {1034case 32:1035so->sampler_variant = V3D_SAMPLER_STATE_32;1036break;1037case 16:1038so->sampler_variant = V3D_SAMPLER_STATE_16U;1039break;1040case 10:1041so->sampler_variant = V3D_SAMPLER_STATE_1010102U;1042break;1043case 8:1044so->sampler_variant = V3D_SAMPLER_STATE_8U;1045break;1046}1047} else {1048switch (desc->channel[chan].size) {1049case 32:1050so->sampler_variant = V3D_SAMPLER_STATE_32;1051break;1052case 16:1053so->sampler_variant = V3D_SAMPLER_STATE_16I;1054break;1055case 8:1056so->sampler_variant = V3D_SAMPLER_STATE_8I;1057break;1058}1059}1060} else {1061if (v3d_get_tex_return_size(&screen->devinfo, sample_format,1062PIPE_TEX_COMPARE_NONE) == 32) {1063if (util_format_is_alpha(sample_format))1064so->sampler_variant = V3D_SAMPLER_STATE_32_A;1065else1066so->sampler_variant = V3D_SAMPLER_STATE_32;1067} else {1068if (util_format_is_luminance_alpha(sample_format))1069so->sampler_variant = V3D_SAMPLER_STATE_F16_LA;1070else if (util_format_is_alpha(sample_format))1071so->sampler_variant = V3D_SAMPLER_STATE_F16_A;1072else if (fmt_swizzle[0] == PIPE_SWIZZLE_Z)1073so->sampler_variant = V3D_SAMPLER_STATE_F16_BGRA;1074else1075so->sampler_variant = V3D_SAMPLER_STATE_F16;10761077}10781079if (util_format_is_unorm(sample_format)) {1080so->sampler_variant += (V3D_SAMPLER_STATE_F16_UNORM -1081V3D_SAMPLER_STATE_F16);1082} else if (util_format_is_snorm(sample_format)){1083so->sampler_variant += (V3D_SAMPLER_STATE_F16_SNORM -1084V3D_SAMPLER_STATE_F16);1085}1086}1087#endif10881089/* V3D still doesn't support sampling from raster textures, so we will1090* have to copy to a temporary tiled texture.1091*/1092if (!rsc->tiled && !(prsc->target == PIPE_TEXTURE_1D ||1093prsc->target == PIPE_TEXTURE_1D_ARRAY)) {1094struct v3d_resource *shadow_parent = rsc;1095struct pipe_resource tmpl = {1096.target = prsc->target,1097.format = prsc->format,1098.width0 = u_minify(prsc->width0,1099cso->u.tex.first_level),1100.height0 = u_minify(prsc->height0,1101cso->u.tex.first_level),1102.depth0 = 1,1103.array_size = 1,1104.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,1105.last_level = cso->u.tex.last_level - cso->u.tex.first_level,1106.nr_samples = prsc->nr_samples,1107};11081109/* Create the shadow texture. The rest of the sampler view1110* setup will use the shadow.1111*/1112prsc = v3d_resource_create(pctx->screen, &tmpl);1113if (!prsc) {1114free(so);1115return NULL;1116}1117rsc = v3d_resource(prsc);11181119/* Flag it as needing update of the contents from the parent. */1120rsc->writes = shadow_parent->writes - 1;1121assert(rsc->tiled);11221123so->texture = prsc;1124} else {1125pipe_resource_reference(&so->texture, prsc);1126}11271128v3d_create_texture_shader_state_bo(v3d, so);11291130return &so->base;1131}11321133static void1134v3d_sampler_view_destroy(struct pipe_context *pctx,1135struct pipe_sampler_view *psview)1136{1137struct v3d_sampler_view *sview = v3d_sampler_view(psview);11381139v3d_bo_unreference(&sview->bo);1140pipe_resource_reference(&psview->texture, NULL);1141pipe_resource_reference(&sview->texture, NULL);1142free(psview);1143}11441145static void1146v3d_set_sampler_views(struct pipe_context *pctx,1147enum pipe_shader_type shader,1148unsigned start, unsigned nr,1149unsigned unbind_num_trailing_slots,1150struct pipe_sampler_view **views)1151{1152struct v3d_context *v3d = v3d_context(pctx);1153struct v3d_texture_stateobj *stage_tex = &v3d->tex[shader];1154unsigned i;1155unsigned new_nr = 0;11561157assert(start == 0);11581159for (i = 0; i < nr; i++) {1160if (views[i])1161new_nr = i + 1;1162pipe_sampler_view_reference(&stage_tex->textures[i], views[i]);1163}11641165for (; i < stage_tex->num_textures; i++) {1166pipe_sampler_view_reference(&stage_tex->textures[i], NULL);1167}11681169stage_tex->num_textures = new_nr;11701171v3d_flag_dirty_sampler_state(v3d, shader);1172}11731174static struct pipe_stream_output_target *1175v3d_create_stream_output_target(struct pipe_context *pctx,1176struct pipe_resource *prsc,1177unsigned buffer_offset,1178unsigned buffer_size)1179{1180struct v3d_stream_output_target *target;11811182target = CALLOC_STRUCT(v3d_stream_output_target);1183if (!target)1184return NULL;11851186pipe_reference_init(&target->base.reference, 1);1187pipe_resource_reference(&target->base.buffer, prsc);11881189target->base.context = pctx;1190target->base.buffer_offset = buffer_offset;1191target->base.buffer_size = buffer_size;11921193return &target->base;1194}11951196static void1197v3d_stream_output_target_destroy(struct pipe_context *pctx,1198struct pipe_stream_output_target *target)1199{1200pipe_resource_reference(&target->buffer, NULL);1201free(target);1202}12031204static void1205v3d_set_stream_output_targets(struct pipe_context *pctx,1206unsigned num_targets,1207struct pipe_stream_output_target **targets,1208const unsigned *offsets)1209{1210struct v3d_context *ctx = v3d_context(pctx);1211struct v3d_streamout_stateobj *so = &ctx->streamout;1212unsigned i;12131214assert(num_targets <= ARRAY_SIZE(so->targets));12151216/* Update recorded vertex counts when we are ending the recording of1217* transform feedback. We do this when we switch primitive types1218* at draw time, but if we haven't switched primitives in our last1219* draw we need to do it here as well.1220*/1221if (num_targets == 0 && so->num_targets > 0)1222v3d_update_primitive_counters(ctx);12231224for (i = 0; i < num_targets; i++) {1225if (offsets[i] != -1)1226so->offsets[i] = offsets[i];12271228pipe_so_target_reference(&so->targets[i], targets[i]);1229}12301231for (; i < so->num_targets; i++)1232pipe_so_target_reference(&so->targets[i], NULL);12331234so->num_targets = num_targets;12351236/* Create primitive counters BO if needed */1237if (num_targets > 0 && !ctx->prim_counts) {1238/* Init all 7 counters and 1 padding to 0 */1239uint32_t zeroes[8] = { 0 };1240u_upload_data(ctx->uploader,12410, sizeof(zeroes), 32, zeroes,1242&ctx->prim_counts_offset,1243&ctx->prim_counts);1244}12451246ctx->dirty |= V3D_DIRTY_STREAMOUT;1247}12481249static void1250v3d_set_shader_buffers(struct pipe_context *pctx,1251enum pipe_shader_type shader,1252unsigned start, unsigned count,1253const struct pipe_shader_buffer *buffers,1254unsigned writable_bitmask)1255{1256struct v3d_context *v3d = v3d_context(pctx);1257struct v3d_ssbo_stateobj *so = &v3d->ssbo[shader];1258unsigned mask = 0;12591260if (buffers) {1261for (unsigned i = 0; i < count; i++) {1262unsigned n = i + start;1263struct pipe_shader_buffer *buf = &so->sb[n];12641265if ((buf->buffer == buffers[i].buffer) &&1266(buf->buffer_offset == buffers[i].buffer_offset) &&1267(buf->buffer_size == buffers[i].buffer_size))1268continue;12691270mask |= 1 << n;12711272buf->buffer_offset = buffers[i].buffer_offset;1273buf->buffer_size = buffers[i].buffer_size;1274pipe_resource_reference(&buf->buffer, buffers[i].buffer);12751276if (buf->buffer)1277so->enabled_mask |= 1 << n;1278else1279so->enabled_mask &= ~(1 << n);1280}1281} else {1282mask = ((1 << count) - 1) << start;12831284for (unsigned i = 0; i < count; i++) {1285unsigned n = i + start;1286struct pipe_shader_buffer *buf = &so->sb[n];12871288pipe_resource_reference(&buf->buffer, NULL);1289}12901291so->enabled_mask &= ~mask;1292}12931294v3d->dirty |= V3D_DIRTY_SSBO;1295}12961297static void1298v3d_create_image_view_texture_shader_state(struct v3d_context *v3d,1299struct v3d_shaderimg_stateobj *so,1300int img)1301{1302#if V3D_VERSION >= 401303struct v3d_image_view *iview = &so->si[img];13041305void *map;1306u_upload_alloc(v3d->uploader, 0, cl_packet_length(TEXTURE_SHADER_STATE),130732,1308&iview->tex_state_offset,1309&iview->tex_state,1310&map);13111312struct pipe_resource *prsc = iview->base.resource;13131314v3dx_pack(map, TEXTURE_SHADER_STATE, tex) {1315v3d_setup_texture_shader_state(&tex, prsc,1316iview->base.u.tex.level,1317iview->base.u.tex.level,1318iview->base.u.tex.first_layer,1319iview->base.u.tex.last_layer);13201321tex.swizzle_r = translate_swizzle(PIPE_SWIZZLE_X);1322tex.swizzle_g = translate_swizzle(PIPE_SWIZZLE_Y);1323tex.swizzle_b = translate_swizzle(PIPE_SWIZZLE_Z);1324tex.swizzle_a = translate_swizzle(PIPE_SWIZZLE_W);13251326tex.texture_type = v3d_get_tex_format(&v3d->screen->devinfo,1327iview->base.format);1328};1329#else /* V3D_VERSION < 40 */1330/* V3D 3.x doesn't use support shader image load/store operations on1331* textures, so it would get lowered in the shader to general memory1332* acceses.1333*/1334#endif1335}13361337static void1338v3d_set_shader_images(struct pipe_context *pctx,1339enum pipe_shader_type shader,1340unsigned start, unsigned count,1341unsigned unbind_num_trailing_slots,1342const struct pipe_image_view *images)1343{1344struct v3d_context *v3d = v3d_context(pctx);1345struct v3d_shaderimg_stateobj *so = &v3d->shaderimg[shader];13461347if (images) {1348for (unsigned i = 0; i < count; i++) {1349unsigned n = i + start;1350struct v3d_image_view *iview = &so->si[n];13511352if ((iview->base.resource == images[i].resource) &&1353(iview->base.format == images[i].format) &&1354(iview->base.access == images[i].access) &&1355!memcmp(&iview->base.u, &images[i].u,1356sizeof(iview->base.u)))1357continue;13581359util_copy_image_view(&iview->base, &images[i]);13601361if (iview->base.resource) {1362so->enabled_mask |= 1 << n;1363v3d_create_image_view_texture_shader_state(v3d,1364so,1365n);1366} else {1367so->enabled_mask &= ~(1 << n);1368pipe_resource_reference(&iview->tex_state, NULL);1369}1370}1371} else {1372for (unsigned i = 0; i < count; i++) {1373unsigned n = i + start;1374struct v3d_image_view *iview = &so->si[n];13751376pipe_resource_reference(&iview->base.resource, NULL);1377pipe_resource_reference(&iview->tex_state, NULL);1378}13791380if (count == 32)1381so->enabled_mask = 0;1382else1383so->enabled_mask &= ~(((1 << count) - 1) << start);1384}13851386v3d->dirty |= V3D_DIRTY_SHADER_IMAGE;13871388if (unbind_num_trailing_slots) {1389v3d_set_shader_images(pctx, shader, start + count,1390unbind_num_trailing_slots, 0, NULL);1391}1392}13931394void1395v3dX(state_init)(struct pipe_context *pctx)1396{1397pctx->set_blend_color = v3d_set_blend_color;1398pctx->set_stencil_ref = v3d_set_stencil_ref;1399pctx->set_clip_state = v3d_set_clip_state;1400pctx->set_sample_mask = v3d_set_sample_mask;1401pctx->set_constant_buffer = v3d_set_constant_buffer;1402pctx->set_framebuffer_state = v3d_set_framebuffer_state;1403pctx->set_polygon_stipple = v3d_set_polygon_stipple;1404pctx->set_scissor_states = v3d_set_scissor_states;1405pctx->set_viewport_states = v3d_set_viewport_states;14061407pctx->set_vertex_buffers = v3d_set_vertex_buffers;14081409pctx->create_blend_state = v3d_create_blend_state;1410pctx->bind_blend_state = v3d_blend_state_bind;1411pctx->delete_blend_state = v3d_generic_cso_state_delete;14121413pctx->create_rasterizer_state = v3d_create_rasterizer_state;1414pctx->bind_rasterizer_state = v3d_rasterizer_state_bind;1415pctx->delete_rasterizer_state = v3d_generic_cso_state_delete;14161417pctx->create_depth_stencil_alpha_state = v3d_create_depth_stencil_alpha_state;1418pctx->bind_depth_stencil_alpha_state = v3d_zsa_state_bind;1419pctx->delete_depth_stencil_alpha_state = v3d_generic_cso_state_delete;14201421pctx->create_vertex_elements_state = v3d_vertex_state_create;1422pctx->delete_vertex_elements_state = v3d_vertex_state_delete;1423pctx->bind_vertex_elements_state = v3d_vertex_state_bind;14241425pctx->create_sampler_state = v3d_create_sampler_state;1426pctx->delete_sampler_state = v3d_sampler_state_delete;1427pctx->bind_sampler_states = v3d_sampler_states_bind;14281429pctx->create_sampler_view = v3d_create_sampler_view;1430pctx->sampler_view_destroy = v3d_sampler_view_destroy;1431pctx->set_sampler_views = v3d_set_sampler_views;14321433pctx->set_shader_buffers = v3d_set_shader_buffers;1434pctx->set_shader_images = v3d_set_shader_images;14351436pctx->create_stream_output_target = v3d_create_stream_output_target;1437pctx->stream_output_target_destroy = v3d_stream_output_target_destroy;1438pctx->set_stream_output_targets = v3d_set_stream_output_targets;1439}144014411442