Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nv50/nv50_state.c
4574 views
/*1* Copyright 2010 Christoph Bumiller2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice shall be included in11* all copies or substantial portions of the Software.12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR17* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,18* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR19* OTHER DEALINGS IN THE SOFTWARE.20*/2122#include "pipe/p_defines.h"23#include "util/u_framebuffer.h"24#include "util/u_helpers.h"25#include "util/u_inlines.h"26#include "util/u_transfer.h"27#include "util/format_srgb.h"2829#include "tgsi/tgsi_parse.h"30#include "compiler/nir/nir.h"3132#include "nv50/nv50_stateobj.h"33#include "nv50/nv50_context.h"34#include "nv50/nv50_query_hw.h"3536#include "nv50/nv50_3d.xml.h"37#include "nv50/g80_texture.xml.h"3839#include "nouveau_gldefs.h"4041/* Caveats:42* ! pipe_sampler_state.normalized_coords is ignored - rectangle textures will43* use non-normalized coordinates, everything else won't44* (The relevant bit is in the TIC entry and not the TSC entry.)45*46* ! pipe_sampler_state.seamless_cube_map is ignored - seamless filtering is47* always activated on NVA0 +48* (Give me the global bit, otherwise it's not worth the CPU work.)49*50* ! pipe_sampler_state.border_color is not swizzled according to the texture51* swizzle in pipe_sampler_view52* (This will be ugly with indirect independent texture/sampler access,53* we'd have to emulate the logic in the shader. GL doesn't have that,54* D3D doesn't have swizzle, if we knew what we were implementing we'd be55* good.)56*57* ! pipe_rasterizer_state.line_last_pixel is ignored - it is never drawn58*59* ! pipe_rasterizer_state.flatshade_first also applies to QUADS60* (There's a GL query for that, forcing an exception is just ridiculous.)61*62* ! pipe_rasterizer_state.sprite_coord_enable is masked with 0xff on NVC063* (The hardware only has 8 slots meant for TexCoord and we have to assign64* in advance to maintain elegant separate shader objects.)65*/6667static inline uint32_t68nv50_colormask(unsigned mask)69{70uint32_t ret = 0;7172if (mask & PIPE_MASK_R)73ret |= 0x0001;74if (mask & PIPE_MASK_G)75ret |= 0x0010;76if (mask & PIPE_MASK_B)77ret |= 0x0100;78if (mask & PIPE_MASK_A)79ret |= 0x1000;8081return ret;82}8384#define NV50_BLEND_FACTOR_CASE(a, b) \85case PIPE_BLENDFACTOR_##a: return NV50_BLEND_FACTOR_##b8687static inline uint32_t88nv50_blend_fac(unsigned factor)89{90switch (factor) {91NV50_BLEND_FACTOR_CASE(ONE, ONE);92NV50_BLEND_FACTOR_CASE(SRC_COLOR, SRC_COLOR);93NV50_BLEND_FACTOR_CASE(SRC_ALPHA, SRC_ALPHA);94NV50_BLEND_FACTOR_CASE(DST_ALPHA, DST_ALPHA);95NV50_BLEND_FACTOR_CASE(DST_COLOR, DST_COLOR);96NV50_BLEND_FACTOR_CASE(SRC_ALPHA_SATURATE, SRC_ALPHA_SATURATE);97NV50_BLEND_FACTOR_CASE(CONST_COLOR, CONSTANT_COLOR);98NV50_BLEND_FACTOR_CASE(CONST_ALPHA, CONSTANT_ALPHA);99NV50_BLEND_FACTOR_CASE(SRC1_COLOR, SRC1_COLOR);100NV50_BLEND_FACTOR_CASE(SRC1_ALPHA, SRC1_ALPHA);101NV50_BLEND_FACTOR_CASE(ZERO, ZERO);102NV50_BLEND_FACTOR_CASE(INV_SRC_COLOR, ONE_MINUS_SRC_COLOR);103NV50_BLEND_FACTOR_CASE(INV_SRC_ALPHA, ONE_MINUS_SRC_ALPHA);104NV50_BLEND_FACTOR_CASE(INV_DST_ALPHA, ONE_MINUS_DST_ALPHA);105NV50_BLEND_FACTOR_CASE(INV_DST_COLOR, ONE_MINUS_DST_COLOR);106NV50_BLEND_FACTOR_CASE(INV_CONST_COLOR, ONE_MINUS_CONSTANT_COLOR);107NV50_BLEND_FACTOR_CASE(INV_CONST_ALPHA, ONE_MINUS_CONSTANT_ALPHA);108NV50_BLEND_FACTOR_CASE(INV_SRC1_COLOR, ONE_MINUS_SRC1_COLOR);109NV50_BLEND_FACTOR_CASE(INV_SRC1_ALPHA, ONE_MINUS_SRC1_ALPHA);110default:111return NV50_BLEND_FACTOR_ZERO;112}113}114115static void *116nv50_blend_state_create(struct pipe_context *pipe,117const struct pipe_blend_state *cso)118{119struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj);120int i;121bool emit_common_func = cso->rt[0].blend_enable;122uint32_t ms;123124if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {125SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1);126SB_DATA (so, cso->independent_blend_enable);127}128129so->pipe = *cso;130131SB_BEGIN_3D(so, COLOR_MASK_COMMON, 1);132SB_DATA (so, !cso->independent_blend_enable);133134SB_BEGIN_3D(so, BLEND_ENABLE_COMMON, 1);135SB_DATA (so, !cso->independent_blend_enable);136137if (cso->independent_blend_enable) {138SB_BEGIN_3D(so, BLEND_ENABLE(0), 8);139for (i = 0; i < 8; ++i) {140SB_DATA(so, cso->rt[i].blend_enable);141if (cso->rt[i].blend_enable)142emit_common_func = true;143}144145if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {146emit_common_func = false;147148for (i = 0; i < 8; ++i) {149if (!cso->rt[i].blend_enable)150continue;151SB_BEGIN_3D_(so, NVA3_3D_IBLEND_EQUATION_RGB(i), 6);152SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func));153SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_src_factor));154SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_dst_factor));155SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func));156SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_src_factor));157SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_dst_factor));158}159}160} else {161SB_BEGIN_3D(so, BLEND_ENABLE(0), 1);162SB_DATA (so, cso->rt[0].blend_enable);163}164165if (emit_common_func) {166SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5);167SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func));168SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_src_factor));169SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_dst_factor));170SB_DATA (so, nvgl_blend_eqn(cso->rt[0].alpha_func));171SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_src_factor));172SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1);173SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_dst_factor));174}175176if (cso->logicop_enable) {177SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2);178SB_DATA (so, 1);179SB_DATA (so, nvgl_logicop_func(cso->logicop_func));180} else {181SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 1);182SB_DATA (so, 0);183}184185if (cso->independent_blend_enable) {186SB_BEGIN_3D(so, COLOR_MASK(0), 8);187for (i = 0; i < 8; ++i)188SB_DATA(so, nv50_colormask(cso->rt[i].colormask));189} else {190SB_BEGIN_3D(so, COLOR_MASK(0), 1);191SB_DATA (so, nv50_colormask(cso->rt[0].colormask));192}193194ms = 0;195if (cso->alpha_to_coverage)196ms |= NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE;197if (cso->alpha_to_one)198ms |= NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_ONE;199200SB_BEGIN_3D(so, MULTISAMPLE_CTRL, 1);201SB_DATA (so, ms);202203assert(so->size <= ARRAY_SIZE(so->state));204return so;205}206207static void208nv50_blend_state_bind(struct pipe_context *pipe, void *hwcso)209{210struct nv50_context *nv50 = nv50_context(pipe);211212nv50->blend = hwcso;213nv50->dirty_3d |= NV50_NEW_3D_BLEND;214}215216static void217nv50_blend_state_delete(struct pipe_context *pipe, void *hwcso)218{219FREE(hwcso);220}221222/* NOTE: ignoring line_last_pixel */223static void *224nv50_rasterizer_state_create(struct pipe_context *pipe,225const struct pipe_rasterizer_state *cso)226{227struct nv50_rasterizer_stateobj *so;228uint32_t reg;229230so = CALLOC_STRUCT(nv50_rasterizer_stateobj);231if (!so)232return NULL;233so->pipe = *cso;234235#ifndef NV50_SCISSORS_CLIPPING236for (int i = 0; i < NV50_MAX_VIEWPORTS; i++) {237SB_BEGIN_3D(so, SCISSOR_ENABLE(i), 1);238SB_DATA (so, cso->scissor);239}240#endif241242SB_BEGIN_3D(so, SHADE_MODEL, 1);243SB_DATA (so, cso->flatshade ? NV50_3D_SHADE_MODEL_FLAT :244NV50_3D_SHADE_MODEL_SMOOTH);245SB_BEGIN_3D(so, PROVOKING_VERTEX_LAST, 1);246SB_DATA (so, !cso->flatshade_first);247SB_BEGIN_3D(so, VERTEX_TWO_SIDE_ENABLE, 1);248SB_DATA (so, cso->light_twoside);249250SB_BEGIN_3D(so, FRAG_COLOR_CLAMP_EN, 1);251SB_DATA (so, cso->clamp_fragment_color ? 0x11111111 : 0x00000000);252253SB_BEGIN_3D(so, MULTISAMPLE_ENABLE, 1);254SB_DATA (so, cso->multisample);255256SB_BEGIN_3D(so, LINE_WIDTH, 1);257SB_DATA (so, fui(cso->line_width));258SB_BEGIN_3D(so, LINE_SMOOTH_ENABLE, 1);259SB_DATA (so, cso->line_smooth);260261SB_BEGIN_3D(so, LINE_STIPPLE_ENABLE, 1);262if (cso->line_stipple_enable) {263SB_DATA (so, 1);264SB_BEGIN_3D(so, LINE_STIPPLE, 1);265SB_DATA (so, (cso->line_stipple_pattern << 8) |266cso->line_stipple_factor);267} else {268SB_DATA (so, 0);269}270271if (!cso->point_size_per_vertex) {272SB_BEGIN_3D(so, POINT_SIZE, 1);273SB_DATA (so, fui(cso->point_size));274}275SB_BEGIN_3D(so, POINT_SPRITE_ENABLE, 1);276SB_DATA (so, cso->point_quad_rasterization);277SB_BEGIN_3D(so, POINT_SMOOTH_ENABLE, 1);278SB_DATA (so, cso->point_smooth);279280SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 3);281SB_DATA (so, nvgl_polygon_mode(cso->fill_front));282SB_DATA (so, nvgl_polygon_mode(cso->fill_back));283SB_DATA (so, cso->poly_smooth);284285SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3);286SB_DATA (so, cso->cull_face != PIPE_FACE_NONE);287SB_DATA (so, cso->front_ccw ? NV50_3D_FRONT_FACE_CCW :288NV50_3D_FRONT_FACE_CW);289switch (cso->cull_face) {290case PIPE_FACE_FRONT_AND_BACK:291SB_DATA(so, NV50_3D_CULL_FACE_FRONT_AND_BACK);292break;293case PIPE_FACE_FRONT:294SB_DATA(so, NV50_3D_CULL_FACE_FRONT);295break;296case PIPE_FACE_BACK:297default:298SB_DATA(so, NV50_3D_CULL_FACE_BACK);299break;300}301302SB_BEGIN_3D(so, POLYGON_STIPPLE_ENABLE, 1);303SB_DATA (so, cso->poly_stipple_enable);304SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3);305SB_DATA (so, cso->offset_point);306SB_DATA (so, cso->offset_line);307SB_DATA (so, cso->offset_tri);308309if (cso->offset_point || cso->offset_line || cso->offset_tri) {310SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1);311SB_DATA (so, fui(cso->offset_scale));312SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1);313SB_DATA (so, fui(cso->offset_units * 2.0f));314SB_BEGIN_3D(so, POLYGON_OFFSET_CLAMP, 1);315SB_DATA (so, fui(cso->offset_clamp));316}317318if (cso->depth_clip_near) {319reg = 0;320} else {321reg =322NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR |323NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR |324NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1;325}326#ifndef NV50_SCISSORS_CLIPPING327reg |=328NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK7 |329NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1;330#endif331SB_BEGIN_3D(so, VIEW_VOLUME_CLIP_CTRL, 1);332SB_DATA (so, reg);333334SB_BEGIN_3D(so, DEPTH_CLIP_NEGATIVE_Z, 1);335SB_DATA (so, cso->clip_halfz);336337SB_BEGIN_3D(so, PIXEL_CENTER_INTEGER, 1);338SB_DATA (so, !cso->half_pixel_center);339340assert(so->size <= ARRAY_SIZE(so->state));341return (void *)so;342}343344static void345nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)346{347struct nv50_context *nv50 = nv50_context(pipe);348349nv50->rast = hwcso;350nv50->dirty_3d |= NV50_NEW_3D_RASTERIZER;351}352353static void354nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)355{356FREE(hwcso);357}358359static void *360nv50_zsa_state_create(struct pipe_context *pipe,361const struct pipe_depth_stencil_alpha_state *cso)362{363struct nv50_zsa_stateobj *so = CALLOC_STRUCT(nv50_zsa_stateobj);364365so->pipe = *cso;366367SB_BEGIN_3D(so, DEPTH_WRITE_ENABLE, 1);368SB_DATA (so, cso->depth_writemask);369SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1);370if (cso->depth_enabled) {371SB_DATA (so, 1);372SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1);373SB_DATA (so, nvgl_comparison_op(cso->depth_func));374} else {375SB_DATA (so, 0);376}377378SB_BEGIN_3D(so, DEPTH_BOUNDS_EN, 1);379if (cso->depth_bounds_test) {380SB_DATA (so, 1);381SB_BEGIN_3D(so, DEPTH_BOUNDS(0), 2);382SB_DATA (so, fui(cso->depth_bounds_min));383SB_DATA (so, fui(cso->depth_bounds_max));384} else {385SB_DATA (so, 0);386}387388if (cso->stencil[0].enabled) {389SB_BEGIN_3D(so, STENCIL_ENABLE, 5);390SB_DATA (so, 1);391SB_DATA (so, nvgl_stencil_op(cso->stencil[0].fail_op));392SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zfail_op));393SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zpass_op));394SB_DATA (so, nvgl_comparison_op(cso->stencil[0].func));395SB_BEGIN_3D(so, STENCIL_FRONT_MASK, 2);396SB_DATA (so, cso->stencil[0].writemask);397SB_DATA (so, cso->stencil[0].valuemask);398} else {399SB_BEGIN_3D(so, STENCIL_ENABLE, 1);400SB_DATA (so, 0);401}402403if (cso->stencil[1].enabled) {404assert(cso->stencil[0].enabled);405SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5);406SB_DATA (so, 1);407SB_DATA (so, nvgl_stencil_op(cso->stencil[1].fail_op));408SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zfail_op));409SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zpass_op));410SB_DATA (so, nvgl_comparison_op(cso->stencil[1].func));411SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2);412SB_DATA (so, cso->stencil[1].writemask);413SB_DATA (so, cso->stencil[1].valuemask);414} else {415SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 1);416SB_DATA (so, 0);417}418419SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1);420if (cso->alpha_enabled) {421SB_DATA (so, 1);422SB_BEGIN_3D(so, ALPHA_TEST_REF, 2);423SB_DATA (so, fui(cso->alpha_ref_value));424SB_DATA (so, nvgl_comparison_op(cso->alpha_func));425} else {426SB_DATA (so, 0);427}428429SB_BEGIN_3D(so, CB_ADDR, 1);430SB_DATA (so, NV50_CB_AUX_ALPHATEST_OFFSET << (8 - 2) | NV50_CB_AUX);431SB_BEGIN_3D(so, CB_DATA(0), 1);432SB_DATA (so, fui(cso->alpha_ref_value));433434assert(so->size <= ARRAY_SIZE(so->state));435return (void *)so;436}437438static void439nv50_zsa_state_bind(struct pipe_context *pipe, void *hwcso)440{441struct nv50_context *nv50 = nv50_context(pipe);442443nv50->zsa = hwcso;444nv50->dirty_3d |= NV50_NEW_3D_ZSA;445}446447static void448nv50_zsa_state_delete(struct pipe_context *pipe, void *hwcso)449{450FREE(hwcso);451}452453/* ====================== SAMPLERS AND TEXTURES ================================454*/455456static inline unsigned457nv50_tsc_wrap_mode(unsigned wrap)458{459switch (wrap) {460case PIPE_TEX_WRAP_REPEAT:461return G80_TSC_WRAP_WRAP;462case PIPE_TEX_WRAP_MIRROR_REPEAT:463return G80_TSC_WRAP_MIRROR;464case PIPE_TEX_WRAP_CLAMP_TO_EDGE:465return G80_TSC_WRAP_CLAMP_TO_EDGE;466case PIPE_TEX_WRAP_CLAMP_TO_BORDER:467return G80_TSC_WRAP_BORDER;468case PIPE_TEX_WRAP_CLAMP:469return G80_TSC_WRAP_CLAMP_OGL;470case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:471return G80_TSC_WRAP_MIRROR_ONCE_CLAMP_TO_EDGE;472case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:473return G80_TSC_WRAP_MIRROR_ONCE_BORDER;474case PIPE_TEX_WRAP_MIRROR_CLAMP:475return G80_TSC_WRAP_MIRROR_ONCE_CLAMP_OGL;476default:477NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);478return G80_TSC_WRAP_WRAP;479}480}481482void *483nv50_sampler_state_create(struct pipe_context *pipe,484const struct pipe_sampler_state *cso)485{486struct nv50_tsc_entry *so = MALLOC_STRUCT(nv50_tsc_entry);487float f[2];488489so->id = -1;490491so->tsc[0] = (0x00026000 |492(nv50_tsc_wrap_mode(cso->wrap_s) << 0) |493(nv50_tsc_wrap_mode(cso->wrap_t) << 3) |494(nv50_tsc_wrap_mode(cso->wrap_r) << 6));495496switch (cso->mag_img_filter) {497case PIPE_TEX_FILTER_LINEAR:498so->tsc[1] = G80_TSC_1_MAG_FILTER_LINEAR;499break;500case PIPE_TEX_FILTER_NEAREST:501default:502so->tsc[1] = G80_TSC_1_MAG_FILTER_NEAREST;503break;504}505506switch (cso->min_img_filter) {507case PIPE_TEX_FILTER_LINEAR:508so->tsc[1] |= G80_TSC_1_MIN_FILTER_LINEAR;509break;510case PIPE_TEX_FILTER_NEAREST:511default:512so->tsc[1] |= G80_TSC_1_MIN_FILTER_NEAREST;513break;514}515516switch (cso->min_mip_filter) {517case PIPE_TEX_MIPFILTER_LINEAR:518so->tsc[1] |= G80_TSC_1_MIP_FILTER_LINEAR;519break;520case PIPE_TEX_MIPFILTER_NEAREST:521so->tsc[1] |= G80_TSC_1_MIP_FILTER_NEAREST;522break;523case PIPE_TEX_MIPFILTER_NONE:524default:525so->tsc[1] |= G80_TSC_1_MIP_FILTER_NONE;526break;527}528529if (nouveau_screen(pipe->screen)->class_3d >= NVE4_3D_CLASS) {530if (cso->seamless_cube_map)531so->tsc[1] |= GK104_TSC_1_CUBEMAP_INTERFACE_FILTERING;532if (!cso->normalized_coords)533so->tsc[1] |= GK104_TSC_1_FLOAT_COORD_NORMALIZATION_FORCE_UNNORMALIZED_COORDS;534} else {535so->seamless_cube_map = cso->seamless_cube_map;536}537538if (nouveau_screen(pipe->screen)->class_3d >= GM200_3D_CLASS) {539if (cso->reduction_mode == PIPE_TEX_REDUCTION_MIN)540so->tsc[1] |= GM204_TSC_1_REDUCTION_MODE_MIN;541if (cso->reduction_mode == PIPE_TEX_REDUCTION_MAX)542so->tsc[1] |= GM204_TSC_1_REDUCTION_MODE_MAX;543}544545if (cso->max_anisotropy >= 16)546so->tsc[0] |= (7 << 20);547else548if (cso->max_anisotropy >= 12)549so->tsc[0] |= (6 << 20);550else {551so->tsc[0] |= (cso->max_anisotropy >> 1) << 20;552553if (cso->max_anisotropy >= 4)554so->tsc[1] |= 6 << G80_TSC_1_TRILIN_OPT__SHIFT;555else556if (cso->max_anisotropy >= 2)557so->tsc[1] |= 4 << G80_TSC_1_TRILIN_OPT__SHIFT;558}559560if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {561/* NOTE: must be deactivated for non-shadow textures */562so->tsc[0] |= (1 << 9);563so->tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10;564}565566f[0] = CLAMP(cso->lod_bias, -16.0f, 15.0f);567so->tsc[1] |= ((int)(f[0] * 256.0f) & 0x1fff) << 12;568569f[0] = CLAMP(cso->min_lod, 0.0f, 15.0f);570f[1] = CLAMP(cso->max_lod, 0.0f, 15.0f);571so->tsc[2] =572(((int)(f[1] * 256.0f) & 0xfff) << 12) | ((int)(f[0] * 256.0f) & 0xfff);573574so->tsc[2] |=575util_format_linear_float_to_srgb_8unorm(cso->border_color.f[0]) << 24;576so->tsc[3] =577util_format_linear_float_to_srgb_8unorm(cso->border_color.f[1]) << 12;578so->tsc[3] |=579util_format_linear_float_to_srgb_8unorm(cso->border_color.f[2]) << 20;580581so->tsc[4] = fui(cso->border_color.f[0]);582so->tsc[5] = fui(cso->border_color.f[1]);583so->tsc[6] = fui(cso->border_color.f[2]);584so->tsc[7] = fui(cso->border_color.f[3]);585586return (void *)so;587}588589static void590nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso)591{592unsigned s, i;593594for (s = 0; s < NV50_MAX_SHADER_STAGES; ++s) {595assert(nv50_context(pipe)->num_samplers[s] <= PIPE_MAX_SAMPLERS);596for (i = 0; i < nv50_context(pipe)->num_samplers[s]; ++i)597if (nv50_context(pipe)->samplers[s][i] == hwcso)598nv50_context(pipe)->samplers[s][i] = NULL;599}600601nv50_screen_tsc_free(nv50_context(pipe)->screen, nv50_tsc_entry(hwcso));602603FREE(hwcso);604}605606static inline void607nv50_stage_sampler_states_bind(struct nv50_context *nv50, int s,608unsigned nr, void **hwcsos)609{610unsigned highest_found = 0;611unsigned i;612613assert(nr <= PIPE_MAX_SAMPLERS);614for (i = 0; i < nr; ++i) {615struct nv50_tsc_entry *hwcso = hwcsos ? nv50_tsc_entry(hwcsos[i]) : NULL;616struct nv50_tsc_entry *old = nv50->samplers[s][i];617618if (hwcso)619highest_found = i;620621nv50->samplers[s][i] = hwcso;622if (old)623nv50_screen_tsc_unlock(nv50->screen, old);624}625assert(nv50->num_samplers[s] <= PIPE_MAX_SAMPLERS);626if (nr >= nv50->num_samplers[s])627nv50->num_samplers[s] = highest_found + 1;628}629630static void631nv50_bind_sampler_states(struct pipe_context *pipe,632enum pipe_shader_type shader, unsigned start,633unsigned num_samplers, void **samplers)634{635unsigned s = nv50_context_shader_stage(shader);636637assert(start == 0);638nv50_stage_sampler_states_bind(nv50_context(pipe), s, num_samplers,639samplers);640641if (unlikely(s == NV50_SHADER_STAGE_COMPUTE))642nv50_context(pipe)->dirty_cp |= NV50_NEW_CP_SAMPLERS;643else644nv50_context(pipe)->dirty_3d |= NV50_NEW_3D_SAMPLERS;645}646647648649/* NOTE: only called when not referenced anywhere, won't be bound */650static void651nv50_sampler_view_destroy(struct pipe_context *pipe,652struct pipe_sampler_view *view)653{654pipe_resource_reference(&view->texture, NULL);655656nv50_screen_tic_free(nv50_context(pipe)->screen, nv50_tic_entry(view));657658FREE(nv50_tic_entry(view));659}660661static inline void662nv50_stage_set_sampler_views(struct nv50_context *nv50, int s,663unsigned nr,664struct pipe_sampler_view **views)665{666unsigned i;667668assert(nr <= PIPE_MAX_SAMPLERS);669for (i = 0; i < nr; ++i) {670struct pipe_sampler_view *view = views ? views[i] : NULL;671struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);672if (old)673nv50_screen_tic_unlock(nv50->screen, old);674675if (view && view->texture) {676struct pipe_resource *res = view->texture;677if (res->target == PIPE_BUFFER &&678(res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT))679nv50->textures_coherent[s] |= 1 << i;680else681nv50->textures_coherent[s] &= ~(1 << i);682} else {683nv50->textures_coherent[s] &= ~(1 << i);684}685686pipe_sampler_view_reference(&nv50->textures[s][i], view);687}688689assert(nv50->num_textures[s] <= PIPE_MAX_SAMPLERS);690for (i = nr; i < nv50->num_textures[s]; ++i) {691struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]);692if (!old)693continue;694nv50_screen_tic_unlock(nv50->screen, old);695696pipe_sampler_view_reference(&nv50->textures[s][i], NULL);697}698699nv50->num_textures[s] = nr;700}701702static void703nv50_set_sampler_views(struct pipe_context *pipe, enum pipe_shader_type shader,704unsigned start, unsigned nr,705unsigned unbind_num_trailing_slots,706struct pipe_sampler_view **views)707{708struct nv50_context *nv50 = nv50_context(pipe);709unsigned s = nv50_context_shader_stage(shader);710711assert(start == 0);712nv50_stage_set_sampler_views(nv50, s, nr, views);713714if (unlikely(s == NV50_SHADER_STAGE_COMPUTE)) {715nouveau_bufctx_reset(nv50->bufctx_cp, NV50_BIND_CP_TEXTURES);716717nv50->dirty_cp |= NV50_NEW_CP_TEXTURES;718} else {719nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_TEXTURES);720721nv50->dirty_3d |= NV50_NEW_3D_TEXTURES;722}723}724725726727/* ============================= SHADERS =======================================728*/729730static void *731nv50_sp_state_create(struct pipe_context *pipe,732const struct pipe_shader_state *cso,733enum pipe_shader_type type)734{735struct nv50_program *prog;736737prog = CALLOC_STRUCT(nv50_program);738if (!prog)739return NULL;740741prog->type = type;742prog->pipe.type = cso->type;743744switch (cso->type) {745case PIPE_SHADER_IR_TGSI:746prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);747break;748case PIPE_SHADER_IR_NIR:749prog->pipe.ir.nir = cso->ir.nir;750break;751default:752assert(!"unsupported IR!");753free(prog);754return NULL;755}756757if (cso->stream_output.num_outputs)758prog->pipe.stream_output = cso->stream_output;759760prog->translated = nv50_program_translate(761prog, nv50_context(pipe)->screen->base.device->chipset,762&nouveau_context(pipe)->debug);763764return (void *)prog;765}766767static void768nv50_sp_state_delete(struct pipe_context *pipe, void *hwcso)769{770struct nv50_program *prog = (struct nv50_program *)hwcso;771772nv50_program_destroy(nv50_context(pipe), prog);773774if (prog->pipe.type == PIPE_SHADER_IR_TGSI)775FREE((void *)prog->pipe.tokens);776else if (prog->pipe.type == PIPE_SHADER_IR_NIR)777ralloc_free(prog->pipe.ir.nir);778FREE(prog);779}780781static void *782nv50_vp_state_create(struct pipe_context *pipe,783const struct pipe_shader_state *cso)784{785return nv50_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX);786}787788static void789nv50_vp_state_bind(struct pipe_context *pipe, void *hwcso)790{791struct nv50_context *nv50 = nv50_context(pipe);792793nv50->vertprog = hwcso;794nv50->dirty_3d |= NV50_NEW_3D_VERTPROG;795}796797static void *798nv50_fp_state_create(struct pipe_context *pipe,799const struct pipe_shader_state *cso)800{801return nv50_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT);802}803804static void805nv50_fp_state_bind(struct pipe_context *pipe, void *hwcso)806{807struct nv50_context *nv50 = nv50_context(pipe);808809nv50->fragprog = hwcso;810nv50->dirty_3d |= NV50_NEW_3D_FRAGPROG;811}812813static void *814nv50_gp_state_create(struct pipe_context *pipe,815const struct pipe_shader_state *cso)816{817return nv50_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY);818}819820static void821nv50_gp_state_bind(struct pipe_context *pipe, void *hwcso)822{823struct nv50_context *nv50 = nv50_context(pipe);824825nv50->gmtyprog = hwcso;826nv50->dirty_3d |= NV50_NEW_3D_GMTYPROG;827}828829static void *830nv50_cp_state_create(struct pipe_context *pipe,831const struct pipe_compute_state *cso)832{833struct nv50_program *prog;834835prog = CALLOC_STRUCT(nv50_program);836if (!prog)837return NULL;838prog->type = PIPE_SHADER_COMPUTE;839prog->pipe.type = cso->ir_type;840841switch(cso->ir_type) {842case PIPE_SHADER_IR_TGSI:843prog->pipe.tokens = tgsi_dup_tokens((const struct tgsi_token *)cso->prog);844break;845case PIPE_SHADER_IR_NIR:846prog->pipe.ir.nir = (nir_shader *)cso->prog;847break;848default:849assert(!"unsupported IR!");850free(prog);851return NULL;852}853854prog->cp.smem_size = cso->req_local_mem;855prog->cp.lmem_size = cso->req_private_mem;856prog->parm_size = cso->req_input_mem;857858return (void *)prog;859}860861static void862nv50_cp_state_bind(struct pipe_context *pipe, void *hwcso)863{864struct nv50_context *nv50 = nv50_context(pipe);865866nv50->compprog = hwcso;867nv50->dirty_cp |= NV50_NEW_CP_PROGRAM;868}869870static void871nv50_set_constant_buffer(struct pipe_context *pipe,872enum pipe_shader_type shader, uint index,873bool take_ownership,874const struct pipe_constant_buffer *cb)875{876struct nv50_context *nv50 = nv50_context(pipe);877struct pipe_resource *res = cb ? cb->buffer : NULL;878const unsigned s = nv50_context_shader_stage(shader);879const unsigned i = index;880881if (unlikely(shader == PIPE_SHADER_COMPUTE)) {882if (nv50->constbuf[s][i].user)883nv50->constbuf[s][i].u.buf = NULL;884else885if (nv50->constbuf[s][i].u.buf)886nouveau_bufctx_reset(nv50->bufctx_cp, NV50_BIND_CP_CB(i));887888nv50->dirty_cp |= NV50_NEW_CP_CONSTBUF;889} else {890if (nv50->constbuf[s][i].user)891nv50->constbuf[s][i].u.buf = NULL;892else893if (nv50->constbuf[s][i].u.buf)894nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_CB(s, i));895896nv50->dirty_3d |= NV50_NEW_3D_CONSTBUF;897}898nv50->constbuf_dirty[s] |= 1 << i;899900if (nv50->constbuf[s][i].u.buf)901nv04_resource(nv50->constbuf[s][i].u.buf)->cb_bindings[s] &= ~(1 << i);902903if (take_ownership) {904pipe_resource_reference(&nv50->constbuf[s][i].u.buf, NULL);905nv50->constbuf[s][i].u.buf = res;906} else {907pipe_resource_reference(&nv50->constbuf[s][i].u.buf, res);908}909910nv50->constbuf[s][i].user = (cb && cb->user_buffer) ? true : false;911if (nv50->constbuf[s][i].user) {912nv50->constbuf[s][i].u.data = cb->user_buffer;913nv50->constbuf[s][i].size = MIN2(cb->buffer_size, 0x10000);914nv50->constbuf_valid[s] |= 1 << i;915nv50->constbuf_coherent[s] &= ~(1 << i);916} else917if (cb) {918nv50->constbuf[s][i].offset = cb->buffer_offset;919nv50->constbuf[s][i].size = MIN2(align(cb->buffer_size, 0x100), 0x10000);920nv50->constbuf_valid[s] |= 1 << i;921if (res && res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)922nv50->constbuf_coherent[s] |= 1 << i;923else924nv50->constbuf_coherent[s] &= ~(1 << i);925}926else {927nv50->constbuf_valid[s] &= ~(1 << i);928nv50->constbuf_coherent[s] &= ~(1 << i);929}930}931932/* =============================================================================933*/934935static void936nv50_set_blend_color(struct pipe_context *pipe,937const struct pipe_blend_color *bcol)938{939struct nv50_context *nv50 = nv50_context(pipe);940941nv50->blend_colour = *bcol;942nv50->dirty_3d |= NV50_NEW_3D_BLEND_COLOUR;943}944945static void946nv50_set_stencil_ref(struct pipe_context *pipe,947const struct pipe_stencil_ref sr)948{949struct nv50_context *nv50 = nv50_context(pipe);950951nv50->stencil_ref = sr;952nv50->dirty_3d |= NV50_NEW_3D_STENCIL_REF;953}954955static void956nv50_set_clip_state(struct pipe_context *pipe,957const struct pipe_clip_state *clip)958{959struct nv50_context *nv50 = nv50_context(pipe);960961memcpy(nv50->clip.ucp, clip->ucp, sizeof(clip->ucp));962963nv50->dirty_3d |= NV50_NEW_3D_CLIP;964}965966static void967nv50_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)968{969struct nv50_context *nv50 = nv50_context(pipe);970971nv50->sample_mask = sample_mask;972nv50->dirty_3d |= NV50_NEW_3D_SAMPLE_MASK;973}974975static void976nv50_set_min_samples(struct pipe_context *pipe, unsigned min_samples)977{978struct nv50_context *nv50 = nv50_context(pipe);979980if (nv50->min_samples != min_samples) {981nv50->min_samples = min_samples;982nv50->dirty_3d |= NV50_NEW_3D_MIN_SAMPLES;983}984}985986static void987nv50_set_framebuffer_state(struct pipe_context *pipe,988const struct pipe_framebuffer_state *fb)989{990struct nv50_context *nv50 = nv50_context(pipe);991992nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_FB);993994util_copy_framebuffer_state(&nv50->framebuffer, fb);995996nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_TEXTURES;997}998999static void1000nv50_set_polygon_stipple(struct pipe_context *pipe,1001const struct pipe_poly_stipple *stipple)1002{1003struct nv50_context *nv50 = nv50_context(pipe);10041005nv50->stipple = *stipple;1006nv50->dirty_3d |= NV50_NEW_3D_STIPPLE;1007}10081009static void1010nv50_set_scissor_states(struct pipe_context *pipe,1011unsigned start_slot,1012unsigned num_scissors,1013const struct pipe_scissor_state *scissor)1014{1015struct nv50_context *nv50 = nv50_context(pipe);1016int i;10171018assert(start_slot + num_scissors <= NV50_MAX_VIEWPORTS);1019for (i = 0; i < num_scissors; i++) {1020if (!memcmp(&nv50->scissors[start_slot + i], &scissor[i], sizeof(*scissor)))1021continue;1022nv50->scissors[start_slot + i] = scissor[i];1023nv50->scissors_dirty |= 1 << (start_slot + i);1024nv50->dirty_3d |= NV50_NEW_3D_SCISSOR;1025}1026}10271028static void1029nv50_set_viewport_states(struct pipe_context *pipe,1030unsigned start_slot,1031unsigned num_viewports,1032const struct pipe_viewport_state *vpt)1033{1034struct nv50_context *nv50 = nv50_context(pipe);1035int i;10361037assert(start_slot + num_viewports <= NV50_MAX_VIEWPORTS);1038for (i = 0; i < num_viewports; i++) {1039if (!memcmp(&nv50->viewports[start_slot + i], &vpt[i], sizeof(*vpt)))1040continue;1041nv50->viewports[start_slot + i] = vpt[i];1042nv50->viewports_dirty |= 1 << (start_slot + i);1043nv50->dirty_3d |= NV50_NEW_3D_VIEWPORT;1044}1045}10461047static void1048nv50_set_window_rectangles(struct pipe_context *pipe,1049bool include,1050unsigned num_rectangles,1051const struct pipe_scissor_state *rectangles)1052{1053struct nv50_context *nv50 = nv50_context(pipe);10541055nv50->window_rect.inclusive = include;1056nv50->window_rect.rects = MIN2(num_rectangles, NV50_MAX_WINDOW_RECTANGLES);1057memcpy(nv50->window_rect.rect, rectangles,1058sizeof(struct pipe_scissor_state) * nv50->window_rect.rects);10591060nv50->dirty_3d |= NV50_NEW_3D_WINDOW_RECTS;1061}10621063static void1064nv50_set_vertex_buffers(struct pipe_context *pipe,1065unsigned start_slot, unsigned count,1066unsigned unbind_num_trailing_slots,1067bool take_ownership,1068const struct pipe_vertex_buffer *vb)1069{1070struct nv50_context *nv50 = nv50_context(pipe);1071unsigned i;10721073nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_VERTEX);1074nv50->dirty_3d |= NV50_NEW_3D_ARRAYS;10751076util_set_vertex_buffers_count(nv50->vtxbuf, &nv50->num_vtxbufs, vb,1077start_slot, count,1078unbind_num_trailing_slots,1079take_ownership);10801081unsigned clear_mask = ~u_bit_consecutive(start_slot + count, unbind_num_trailing_slots);1082nv50->vbo_user &= clear_mask;1083nv50->vbo_constant &= clear_mask;1084nv50->vtxbufs_coherent &= clear_mask;10851086if (!vb) {1087clear_mask = ~u_bit_consecutive(start_slot, count);1088nv50->vbo_user &= clear_mask;1089nv50->vbo_constant &= clear_mask;1090nv50->vtxbufs_coherent &= clear_mask;1091return;1092}10931094for (i = 0; i < count; ++i) {1095unsigned dst_index = start_slot + i;10961097if (vb[i].is_user_buffer) {1098nv50->vbo_user |= 1 << dst_index;1099if (!vb[i].stride)1100nv50->vbo_constant |= 1 << dst_index;1101else1102nv50->vbo_constant &= ~(1 << dst_index);1103nv50->vtxbufs_coherent &= ~(1 << dst_index);1104} else {1105nv50->vbo_user &= ~(1 << dst_index);1106nv50->vbo_constant &= ~(1 << dst_index);11071108if (vb[i].buffer.resource &&1109vb[i].buffer.resource->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)1110nv50->vtxbufs_coherent |= (1 << dst_index);1111else1112nv50->vtxbufs_coherent &= ~(1 << dst_index);1113}1114}1115}11161117static void1118nv50_vertex_state_bind(struct pipe_context *pipe, void *hwcso)1119{1120struct nv50_context *nv50 = nv50_context(pipe);11211122nv50->vertex = hwcso;1123nv50->dirty_3d |= NV50_NEW_3D_VERTEX;1124}11251126static struct pipe_stream_output_target *1127nv50_so_target_create(struct pipe_context *pipe,1128struct pipe_resource *res,1129unsigned offset, unsigned size)1130{1131struct nv04_resource *buf = (struct nv04_resource *)res;1132struct nv50_so_target *targ = MALLOC_STRUCT(nv50_so_target);1133if (!targ)1134return NULL;11351136if (nouveau_context(pipe)->screen->class_3d >= NVA0_3D_CLASS) {1137targ->pq = pipe->create_query(pipe,1138NVA0_HW_QUERY_STREAM_OUTPUT_BUFFER_OFFSET, 0);1139if (!targ->pq) {1140FREE(targ);1141return NULL;1142}1143} else {1144targ->pq = NULL;1145}1146targ->clean = true;11471148targ->pipe.buffer_size = size;1149targ->pipe.buffer_offset = offset;1150targ->pipe.context = pipe;1151targ->pipe.buffer = NULL;1152pipe_resource_reference(&targ->pipe.buffer, res);1153pipe_reference_init(&targ->pipe.reference, 1);11541155assert(buf->base.target == PIPE_BUFFER);1156util_range_add(&buf->base, &buf->valid_buffer_range, offset, offset + size);11571158return &targ->pipe;1159}11601161static void1162nva0_so_target_save_offset(struct pipe_context *pipe,1163struct pipe_stream_output_target *ptarg,1164unsigned index, bool serialize)1165{1166struct nv50_so_target *targ = nv50_so_target(ptarg);11671168if (serialize) {1169struct nouveau_pushbuf *push = nv50_context(pipe)->base.pushbuf;1170PUSH_SPACE(push, 2);1171BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);1172PUSH_DATA (push, 0);1173}11741175nv50_query(targ->pq)->index = index;1176pipe->end_query(pipe, targ->pq);1177}11781179static void1180nv50_so_target_destroy(struct pipe_context *pipe,1181struct pipe_stream_output_target *ptarg)1182{1183struct nv50_so_target *targ = nv50_so_target(ptarg);1184if (targ->pq)1185pipe->destroy_query(pipe, targ->pq);1186pipe_resource_reference(&targ->pipe.buffer, NULL);1187FREE(targ);1188}11891190static void1191nv50_set_stream_output_targets(struct pipe_context *pipe,1192unsigned num_targets,1193struct pipe_stream_output_target **targets,1194const unsigned *offsets)1195{1196struct nv50_context *nv50 = nv50_context(pipe);1197unsigned i;1198bool serialize = true;1199const bool can_resume = nv50->screen->base.class_3d >= NVA0_3D_CLASS;12001201assert(num_targets <= 4);12021203for (i = 0; i < num_targets; ++i) {1204const bool changed = nv50->so_target[i] != targets[i];1205const bool append = (offsets[i] == (unsigned)-1);1206if (!changed && append)1207continue;1208nv50->so_targets_dirty |= 1 << i;12091210if (can_resume && changed && nv50->so_target[i]) {1211nva0_so_target_save_offset(pipe, nv50->so_target[i], i, serialize);1212serialize = false;1213}12141215if (targets[i] && !append) {1216nv50_so_target(targets[i])->clean = true;1217nv50->so_used[i] = 0;1218}12191220pipe_so_target_reference(&nv50->so_target[i], targets[i]);1221}1222for (; i < nv50->num_so_targets; ++i) {1223if (can_resume && nv50->so_target[i]) {1224nva0_so_target_save_offset(pipe, nv50->so_target[i], i, serialize);1225serialize = false;1226}1227pipe_so_target_reference(&nv50->so_target[i], NULL);1228nv50->so_targets_dirty |= 1 << i;1229}1230nv50->num_so_targets = num_targets;12311232if (nv50->so_targets_dirty) {1233nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_SO);1234nv50->dirty_3d |= NV50_NEW_3D_STRMOUT;1235}1236}12371238static bool1239nv50_bind_images_range(struct nv50_context *nv50,1240unsigned start, unsigned nr,1241const struct pipe_image_view *pimages)1242{1243const unsigned end = start + nr;1244unsigned mask = 0;1245unsigned i;12461247if (pimages) {1248for (i = start; i < end; ++i) {1249struct pipe_image_view *img = &nv50->images[i];1250const unsigned p = i - start;12511252if (img->resource == pimages[p].resource &&1253img->format == pimages[p].format &&1254img->access == pimages[p].access) {1255if (img->resource == NULL)1256continue;1257if (img->resource->target == PIPE_BUFFER &&1258img->u.buf.offset == pimages[p].u.buf.offset &&1259img->u.buf.size == pimages[p].u.buf.size)1260continue;1261if (img->resource->target != PIPE_BUFFER &&1262img->u.tex.first_layer == pimages[p].u.tex.first_layer &&1263img->u.tex.last_layer == pimages[p].u.tex.last_layer &&1264img->u.tex.level == pimages[p].u.tex.level)1265continue;1266}12671268mask |= (1 << i);1269if (pimages[p].resource)1270nv50->images_valid |= (1 << i);1271else1272nv50->images_valid &= ~(1 << i);12731274img->format = pimages[p].format;1275img->access = pimages[p].access;1276if (pimages[p].resource && pimages[p].resource->target == PIPE_BUFFER)1277img->u.buf = pimages[p].u.buf;1278else1279img->u.tex = pimages[p].u.tex;12801281pipe_resource_reference(1282&img->resource, pimages[p].resource);1283}1284if (!mask)1285return false;1286} else {1287mask = ((1 << nr) - 1) << start;1288if (!(nv50->images_valid & mask))1289return false;1290for (i = start; i < end; ++i) {1291pipe_resource_reference(&nv50->images[i].resource, NULL);1292}1293nv50->images_valid &= ~mask;1294}1295nv50->images_dirty |= mask;12961297nouveau_bufctx_reset(nv50->bufctx_cp, NV50_BIND_CP_SUF);12981299return true;1300}13011302static void1303nv50_set_shader_images(struct pipe_context *pipe,1304enum pipe_shader_type shader,1305unsigned start, unsigned nr,1306unsigned unbind_num_trailing_slots,1307const struct pipe_image_view *images)1308{1309const unsigned s = nv50_context_shader_stage(shader);13101311if (s != NV50_SHADER_STAGE_COMPUTE)1312return;13131314nv50_bind_images_range(nv50_context(pipe), start + nr,1315unbind_num_trailing_slots, NULL);13161317if (!nv50_bind_images_range(nv50_context(pipe), start, nr, images))1318return;13191320nv50_context(pipe)->dirty_cp |= NV50_NEW_CP_SURFACES;1321}13221323static void1324nv50_set_compute_resources(struct pipe_context *pipe,1325unsigned start, unsigned nr,1326struct pipe_surface **resources)1327{1328/* TODO: bind surfaces */1329}13301331static bool1332nv50_bind_buffers_range(struct nv50_context *nv50,1333unsigned start, unsigned nr,1334const struct pipe_shader_buffer *pbuffers)1335{1336const unsigned end = start + nr;1337unsigned mask = 0;1338unsigned i;13391340if (pbuffers) {1341for (i = start; i < end; ++i) {1342struct pipe_shader_buffer *buf = &nv50->buffers[i];1343const unsigned p = i - start;1344if (buf->buffer == pbuffers[p].buffer &&1345buf->buffer_offset == pbuffers[p].buffer_offset &&1346buf->buffer_size == pbuffers[p].buffer_size)1347continue;13481349mask |= (1 << i);1350if (pbuffers[p].buffer)1351nv50->buffers_valid |= (1 << i);1352else1353nv50->buffers_valid &= ~(1 << i);1354buf->buffer_offset = pbuffers[p].buffer_offset;1355buf->buffer_size = pbuffers[p].buffer_size;1356pipe_resource_reference(&buf->buffer, pbuffers[p].buffer);1357}1358if (!mask)1359return false;1360} else {1361mask = ((1 << nr) - 1) << start;1362if (!(nv50->buffers_valid & mask))1363return false;1364for (i = start; i < end; ++i)1365pipe_resource_reference(&nv50->buffers[i].buffer, NULL);1366nv50->buffers_valid &= ~mask;1367}1368nv50->buffers_dirty |= mask;13691370nouveau_bufctx_reset(nv50->bufctx_cp, NV50_BIND_CP_BUF);13711372return true;1373}13741375static void1376nv50_set_shader_buffers(struct pipe_context *pipe,1377enum pipe_shader_type shader,1378unsigned start, unsigned nr,1379const struct pipe_shader_buffer *buffers,1380unsigned writable_bitmask)1381{1382const unsigned s = nv50_context_shader_stage(shader);13831384if (s != NV50_SHADER_STAGE_COMPUTE)1385return;13861387if (!nv50_bind_buffers_range(nv50_context(pipe), start, nr, buffers))1388return;13891390nv50_context(pipe)->dirty_cp |= NV50_NEW_CP_BUFFERS;1391}13921393static inline void1394nv50_set_global_handle(uint32_t *phandle, struct pipe_resource *res)1395{1396struct nv04_resource *buf = nv04_resource(res);1397if (buf) {1398uint64_t limit = (buf->address + buf->base.width0) - 1;1399if (limit < (1ULL << 32)) {1400*phandle = (uint32_t)buf->address;1401} else {1402NOUVEAU_ERR("Cannot map into TGSI_RESOURCE_GLOBAL: "1403"resource not contained within 32-bit address space !\n");1404*phandle = 0;1405}1406} else {1407*phandle = 0;1408}1409}14101411static void1412nv50_set_global_bindings(struct pipe_context *pipe,1413unsigned start, unsigned nr,1414struct pipe_resource **resources,1415uint32_t **handles)1416{1417struct nv50_context *nv50 = nv50_context(pipe);1418struct pipe_resource **ptr;1419unsigned i;1420const unsigned end = start + nr;14211422if (nv50->global_residents.size <= (end * sizeof(struct pipe_resource *))) {1423const unsigned old_size = nv50->global_residents.size;1424if (util_dynarray_resize(&nv50->global_residents, struct pipe_resource *, end)) {1425memset((uint8_t *)nv50->global_residents.data + old_size, 0,1426nv50->global_residents.size - old_size);1427} else {1428NOUVEAU_ERR("Could not resize global residents array\n");1429return;1430}1431}14321433if (resources) {1434ptr = util_dynarray_element(1435&nv50->global_residents, struct pipe_resource *, start);1436for (i = 0; i < nr; ++i) {1437pipe_resource_reference(&ptr[i], resources[i]);1438nv50_set_global_handle(handles[i], resources[i]);1439}1440} else {1441ptr = util_dynarray_element(1442&nv50->global_residents, struct pipe_resource *, start);1443for (i = 0; i < nr; ++i)1444pipe_resource_reference(&ptr[i], NULL);1445}14461447nouveau_bufctx_reset(nv50->bufctx_cp, NV50_BIND_CP_GLOBAL);14481449nv50->dirty_cp |= NV50_NEW_CP_GLOBALS;1450}14511452void1453nv50_init_state_functions(struct nv50_context *nv50)1454{1455struct pipe_context *pipe = &nv50->base.pipe;14561457pipe->create_blend_state = nv50_blend_state_create;1458pipe->bind_blend_state = nv50_blend_state_bind;1459pipe->delete_blend_state = nv50_blend_state_delete;14601461pipe->create_rasterizer_state = nv50_rasterizer_state_create;1462pipe->bind_rasterizer_state = nv50_rasterizer_state_bind;1463pipe->delete_rasterizer_state = nv50_rasterizer_state_delete;14641465pipe->create_depth_stencil_alpha_state = nv50_zsa_state_create;1466pipe->bind_depth_stencil_alpha_state = nv50_zsa_state_bind;1467pipe->delete_depth_stencil_alpha_state = nv50_zsa_state_delete;14681469pipe->create_sampler_state = nv50_sampler_state_create;1470pipe->delete_sampler_state = nv50_sampler_state_delete;1471pipe->bind_sampler_states = nv50_bind_sampler_states;14721473pipe->create_sampler_view = nv50_create_sampler_view;1474pipe->sampler_view_destroy = nv50_sampler_view_destroy;1475pipe->set_sampler_views = nv50_set_sampler_views;14761477pipe->create_vs_state = nv50_vp_state_create;1478pipe->create_fs_state = nv50_fp_state_create;1479pipe->create_gs_state = nv50_gp_state_create;1480pipe->create_compute_state = nv50_cp_state_create;1481pipe->bind_vs_state = nv50_vp_state_bind;1482pipe->bind_fs_state = nv50_fp_state_bind;1483pipe->bind_gs_state = nv50_gp_state_bind;1484pipe->bind_compute_state = nv50_cp_state_bind;1485pipe->delete_vs_state = nv50_sp_state_delete;1486pipe->delete_fs_state = nv50_sp_state_delete;1487pipe->delete_gs_state = nv50_sp_state_delete;1488pipe->delete_compute_state = nv50_sp_state_delete;14891490pipe->set_blend_color = nv50_set_blend_color;1491pipe->set_stencil_ref = nv50_set_stencil_ref;1492pipe->set_clip_state = nv50_set_clip_state;1493pipe->set_sample_mask = nv50_set_sample_mask;1494pipe->set_min_samples = nv50_set_min_samples;1495pipe->set_constant_buffer = nv50_set_constant_buffer;1496pipe->set_framebuffer_state = nv50_set_framebuffer_state;1497pipe->set_polygon_stipple = nv50_set_polygon_stipple;1498pipe->set_scissor_states = nv50_set_scissor_states;1499pipe->set_viewport_states = nv50_set_viewport_states;1500pipe->set_window_rectangles = nv50_set_window_rectangles;15011502pipe->create_vertex_elements_state = nv50_vertex_state_create;1503pipe->delete_vertex_elements_state = nv50_vertex_state_delete;1504pipe->bind_vertex_elements_state = nv50_vertex_state_bind;15051506pipe->set_vertex_buffers = nv50_set_vertex_buffers;15071508pipe->create_stream_output_target = nv50_so_target_create;1509pipe->stream_output_target_destroy = nv50_so_target_destroy;1510pipe->set_stream_output_targets = nv50_set_stream_output_targets;15111512pipe->set_global_binding = nv50_set_global_bindings;1513pipe->set_compute_resources = nv50_set_compute_resources;1514pipe->set_shader_images = nv50_set_shader_images;1515pipe->set_shader_buffers = nv50_set_shader_buffers;15161517nv50->sample_mask = ~0;1518nv50->min_samples = 1;1519}152015211522