Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nvc0/nvc0_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"2728#include "tgsi/tgsi_parse.h"29#include "compiler/nir/nir.h"30#include "compiler/nir/nir_serialize.h"3132#include "nvc0/nvc0_stateobj.h"33#include "nvc0/nvc0_context.h"34#include "nvc0/nvc0_query_hw.h"3536#include "nvc0/nvc0_3d.xml.h"3738#include "nouveau_gldefs.h"3940static inline uint32_t41nvc0_colormask(unsigned mask)42{43uint32_t ret = 0;4445if (mask & PIPE_MASK_R)46ret |= 0x0001;47if (mask & PIPE_MASK_G)48ret |= 0x0010;49if (mask & PIPE_MASK_B)50ret |= 0x0100;51if (mask & PIPE_MASK_A)52ret |= 0x1000;5354return ret;55}5657#define NVC0_BLEND_FACTOR_CASE(a, b) \58case PIPE_BLENDFACTOR_##a: return NV50_BLEND_FACTOR_##b5960static inline uint32_t61nvc0_blend_fac(unsigned factor)62{63switch (factor) {64NVC0_BLEND_FACTOR_CASE(ONE, ONE);65NVC0_BLEND_FACTOR_CASE(SRC_COLOR, SRC_COLOR);66NVC0_BLEND_FACTOR_CASE(SRC_ALPHA, SRC_ALPHA);67NVC0_BLEND_FACTOR_CASE(DST_ALPHA, DST_ALPHA);68NVC0_BLEND_FACTOR_CASE(DST_COLOR, DST_COLOR);69NVC0_BLEND_FACTOR_CASE(SRC_ALPHA_SATURATE, SRC_ALPHA_SATURATE);70NVC0_BLEND_FACTOR_CASE(CONST_COLOR, CONSTANT_COLOR);71NVC0_BLEND_FACTOR_CASE(CONST_ALPHA, CONSTANT_ALPHA);72NVC0_BLEND_FACTOR_CASE(SRC1_COLOR, SRC1_COLOR);73NVC0_BLEND_FACTOR_CASE(SRC1_ALPHA, SRC1_ALPHA);74NVC0_BLEND_FACTOR_CASE(ZERO, ZERO);75NVC0_BLEND_FACTOR_CASE(INV_SRC_COLOR, ONE_MINUS_SRC_COLOR);76NVC0_BLEND_FACTOR_CASE(INV_SRC_ALPHA, ONE_MINUS_SRC_ALPHA);77NVC0_BLEND_FACTOR_CASE(INV_DST_ALPHA, ONE_MINUS_DST_ALPHA);78NVC0_BLEND_FACTOR_CASE(INV_DST_COLOR, ONE_MINUS_DST_COLOR);79NVC0_BLEND_FACTOR_CASE(INV_CONST_COLOR, ONE_MINUS_CONSTANT_COLOR);80NVC0_BLEND_FACTOR_CASE(INV_CONST_ALPHA, ONE_MINUS_CONSTANT_ALPHA);81NVC0_BLEND_FACTOR_CASE(INV_SRC1_COLOR, ONE_MINUS_SRC1_COLOR);82NVC0_BLEND_FACTOR_CASE(INV_SRC1_ALPHA, ONE_MINUS_SRC1_ALPHA);83default:84return NV50_BLEND_FACTOR_ZERO;85}86}8788static void *89nvc0_blend_state_create(struct pipe_context *pipe,90const struct pipe_blend_state *cso)91{92struct nvc0_blend_stateobj *so = CALLOC_STRUCT(nvc0_blend_stateobj);93int i;94int r; /* reference */95uint32_t ms;96uint8_t blend_en = 0;97bool indep_masks = false;98bool indep_funcs = false;99100so->pipe = *cso;101102/* check which states actually have differing values */103if (cso->independent_blend_enable) {104for (r = 0; r < 8 && !cso->rt[r].blend_enable; ++r);105blend_en |= 1 << r;106for (i = r + 1; i < 8; ++i) {107if (!cso->rt[i].blend_enable)108continue;109blend_en |= 1 << i;110if (cso->rt[i].rgb_func != cso->rt[r].rgb_func ||111cso->rt[i].rgb_src_factor != cso->rt[r].rgb_src_factor ||112cso->rt[i].rgb_dst_factor != cso->rt[r].rgb_dst_factor ||113cso->rt[i].alpha_func != cso->rt[r].alpha_func ||114cso->rt[i].alpha_src_factor != cso->rt[r].alpha_src_factor ||115cso->rt[i].alpha_dst_factor != cso->rt[r].alpha_dst_factor) {116indep_funcs = true;117break;118}119}120for (; i < 8; ++i)121blend_en |= (cso->rt[i].blend_enable ? 1 : 0) << i;122123for (i = 1; i < 8; ++i) {124if (cso->rt[i].colormask != cso->rt[0].colormask) {125indep_masks = true;126break;127}128}129} else {130r = 0;131if (cso->rt[0].blend_enable)132blend_en = 0xff;133}134135if (cso->logicop_enable) {136SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2);137SB_DATA (so, 1);138SB_DATA (so, nvgl_logicop_func(cso->logicop_func));139140SB_IMMED_3D(so, MACRO_BLEND_ENABLES, 0);141} else {142SB_IMMED_3D(so, LOGIC_OP_ENABLE, 0);143144SB_IMMED_3D(so, BLEND_INDEPENDENT, indep_funcs);145SB_IMMED_3D(so, MACRO_BLEND_ENABLES, blend_en);146if (indep_funcs) {147for (i = 0; i < 8; ++i) {148if (cso->rt[i].blend_enable) {149SB_BEGIN_3D(so, IBLEND_EQUATION_RGB(i), 6);150SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func));151SB_DATA (so, nvc0_blend_fac(cso->rt[i].rgb_src_factor));152SB_DATA (so, nvc0_blend_fac(cso->rt[i].rgb_dst_factor));153SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func));154SB_DATA (so, nvc0_blend_fac(cso->rt[i].alpha_src_factor));155SB_DATA (so, nvc0_blend_fac(cso->rt[i].alpha_dst_factor));156}157}158} else159if (blend_en) {160SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5);161SB_DATA (so, nvgl_blend_eqn(cso->rt[r].rgb_func));162SB_DATA (so, nvc0_blend_fac(cso->rt[r].rgb_src_factor));163SB_DATA (so, nvc0_blend_fac(cso->rt[r].rgb_dst_factor));164SB_DATA (so, nvgl_blend_eqn(cso->rt[r].alpha_func));165SB_DATA (so, nvc0_blend_fac(cso->rt[r].alpha_src_factor));166SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1);167SB_DATA (so, nvc0_blend_fac(cso->rt[r].alpha_dst_factor));168}169170SB_IMMED_3D(so, COLOR_MASK_COMMON, !indep_masks);171if (indep_masks) {172SB_BEGIN_3D(so, COLOR_MASK(0), 8);173for (i = 0; i < 8; ++i)174SB_DATA(so, nvc0_colormask(cso->rt[i].colormask));175} else {176SB_BEGIN_3D(so, COLOR_MASK(0), 1);177SB_DATA (so, nvc0_colormask(cso->rt[0].colormask));178}179}180181ms = 0;182if (cso->alpha_to_coverage)183ms |= NVC0_3D_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE;184if (cso->alpha_to_one)185ms |= NVC0_3D_MULTISAMPLE_CTRL_ALPHA_TO_ONE;186187SB_BEGIN_3D(so, MULTISAMPLE_CTRL, 1);188SB_DATA (so, ms);189190assert(so->size <= ARRAY_SIZE(so->state));191return so;192}193194static void195nvc0_blend_state_bind(struct pipe_context *pipe, void *hwcso)196{197struct nvc0_context *nvc0 = nvc0_context(pipe);198199nvc0->blend = hwcso;200nvc0->dirty_3d |= NVC0_NEW_3D_BLEND;201}202203static void204nvc0_blend_state_delete(struct pipe_context *pipe, void *hwcso)205{206FREE(hwcso);207}208209/* NOTE: ignoring line_last_pixel */210static void *211nvc0_rasterizer_state_create(struct pipe_context *pipe,212const struct pipe_rasterizer_state *cso)213{214struct nvc0_rasterizer_stateobj *so;215uint16_t class_3d = nouveau_screen(pipe->screen)->class_3d;216uint32_t reg;217218so = CALLOC_STRUCT(nvc0_rasterizer_stateobj);219if (!so)220return NULL;221so->pipe = *cso;222223/* Scissor enables are handled in scissor state, we will not want to224* always emit 16 commands, one for each scissor rectangle, here.225*/226227SB_IMMED_3D(so, PROVOKING_VERTEX_LAST, !cso->flatshade_first);228SB_IMMED_3D(so, VERTEX_TWO_SIDE_ENABLE, cso->light_twoside);229230SB_IMMED_3D(so, VERT_COLOR_CLAMP_EN, cso->clamp_vertex_color);231SB_BEGIN_3D(so, FRAG_COLOR_CLAMP_EN, 1);232SB_DATA (so, cso->clamp_fragment_color ? 0x11111111 : 0x00000000);233234SB_IMMED_3D(so, MULTISAMPLE_ENABLE, cso->multisample);235236SB_IMMED_3D(so, LINE_SMOOTH_ENABLE, cso->line_smooth);237if (cso->line_smooth || cso->multisample)238SB_BEGIN_3D(so, LINE_WIDTH_SMOOTH, 1);239else240SB_BEGIN_3D(so, LINE_WIDTH_ALIASED, 1);241SB_DATA (so, fui(cso->line_width));242243SB_IMMED_3D(so, LINE_STIPPLE_ENABLE, cso->line_stipple_enable);244if (cso->line_stipple_enable) {245SB_BEGIN_3D(so, LINE_STIPPLE_PATTERN, 1);246SB_DATA (so, (cso->line_stipple_pattern << 8) |247cso->line_stipple_factor);248249}250251SB_IMMED_3D(so, VP_POINT_SIZE, cso->point_size_per_vertex);252if (!cso->point_size_per_vertex) {253SB_BEGIN_3D(so, POINT_SIZE, 1);254SB_DATA (so, fui(cso->point_size));255}256257reg = (cso->sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT) ?258NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_UPPER_LEFT :259NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_LOWER_LEFT;260261SB_BEGIN_3D(so, POINT_COORD_REPLACE, 1);262SB_DATA (so, ((cso->sprite_coord_enable & 0xff) << 3) | reg);263SB_IMMED_3D(so, POINT_SPRITE_ENABLE, cso->point_quad_rasterization);264SB_IMMED_3D(so, POINT_SMOOTH_ENABLE, cso->point_smooth);265266if (class_3d >= GM200_3D_CLASS) {267SB_IMMED_3D(so, FILL_RECTANGLE,268cso->fill_front == PIPE_POLYGON_MODE_FILL_RECTANGLE ?269NVC0_3D_FILL_RECTANGLE_ENABLE : 0);270}271272SB_BEGIN_3D(so, MACRO_POLYGON_MODE_FRONT, 1);273SB_DATA (so, nvgl_polygon_mode(cso->fill_front));274SB_BEGIN_3D(so, MACRO_POLYGON_MODE_BACK, 1);275SB_DATA (so, nvgl_polygon_mode(cso->fill_back));276SB_IMMED_3D(so, POLYGON_SMOOTH_ENABLE, cso->poly_smooth);277278SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3);279SB_DATA (so, cso->cull_face != PIPE_FACE_NONE);280SB_DATA (so, cso->front_ccw ? NVC0_3D_FRONT_FACE_CCW :281NVC0_3D_FRONT_FACE_CW);282switch (cso->cull_face) {283case PIPE_FACE_FRONT_AND_BACK:284SB_DATA(so, NVC0_3D_CULL_FACE_FRONT_AND_BACK);285break;286case PIPE_FACE_FRONT:287SB_DATA(so, NVC0_3D_CULL_FACE_FRONT);288break;289case PIPE_FACE_BACK:290default:291SB_DATA(so, NVC0_3D_CULL_FACE_BACK);292break;293}294295SB_IMMED_3D(so, POLYGON_STIPPLE_ENABLE, cso->poly_stipple_enable);296SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3);297SB_DATA (so, cso->offset_point);298SB_DATA (so, cso->offset_line);299SB_DATA (so, cso->offset_tri);300301if (cso->offset_point || cso->offset_line || cso->offset_tri) {302SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1);303SB_DATA (so, fui(cso->offset_scale));304if (!cso->offset_units_unscaled) {305SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1);306SB_DATA (so, fui(cso->offset_units * 2.0f));307}308SB_BEGIN_3D(so, POLYGON_OFFSET_CLAMP, 1);309SB_DATA (so, fui(cso->offset_clamp));310}311312if (cso->depth_clip_near)313reg = NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1;314else315reg =316NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1 |317NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR |318NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR |319NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK2;320321SB_BEGIN_3D(so, VIEW_VOLUME_CLIP_CTRL, 1);322SB_DATA (so, reg);323324SB_IMMED_3D(so, DEPTH_CLIP_NEGATIVE_Z, cso->clip_halfz);325326SB_IMMED_3D(so, PIXEL_CENTER_INTEGER, !cso->half_pixel_center);327328if (class_3d >= GM200_3D_CLASS) {329if (cso->conservative_raster_mode != PIPE_CONSERVATIVE_RASTER_OFF) {330bool post_snap = cso->conservative_raster_mode ==331PIPE_CONSERVATIVE_RASTER_POST_SNAP;332uint32_t state = cso->subpixel_precision_x;333state |= cso->subpixel_precision_y << 4;334state |= (uint32_t)(cso->conservative_raster_dilate * 4) << 8;335state |= (post_snap || class_3d < GP100_3D_CLASS) ? 1 << 10 : 0;336SB_IMMED_3D(so, MACRO_CONSERVATIVE_RASTER_STATE, state);337} else {338SB_IMMED_3D(so, CONSERVATIVE_RASTER, 0);339}340}341342assert(so->size <= ARRAY_SIZE(so->state));343return (void *)so;344}345346static void347nvc0_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)348{349struct nvc0_context *nvc0 = nvc0_context(pipe);350351nvc0->rast = hwcso;352nvc0->dirty_3d |= NVC0_NEW_3D_RASTERIZER;353}354355static void356nvc0_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)357{358FREE(hwcso);359}360361static void *362nvc0_zsa_state_create(struct pipe_context *pipe,363const struct pipe_depth_stencil_alpha_state *cso)364{365struct nvc0_zsa_stateobj *so = CALLOC_STRUCT(nvc0_zsa_stateobj);366367so->pipe = *cso;368369SB_IMMED_3D(so, DEPTH_TEST_ENABLE, cso->depth_enabled);370if (cso->depth_enabled) {371SB_IMMED_3D(so, DEPTH_WRITE_ENABLE, cso->depth_writemask);372SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1);373SB_DATA (so, nvgl_comparison_op(cso->depth_func));374}375376SB_IMMED_3D(so, DEPTH_BOUNDS_EN, cso->depth_bounds_test);377if (cso->depth_bounds_test) {378SB_BEGIN_3D(so, DEPTH_BOUNDS(0), 2);379SB_DATA (so, fui(cso->depth_bounds_min));380SB_DATA (so, fui(cso->depth_bounds_max));381}382383if (cso->stencil[0].enabled) {384SB_BEGIN_3D(so, STENCIL_ENABLE, 5);385SB_DATA (so, 1);386SB_DATA (so, nvgl_stencil_op(cso->stencil[0].fail_op));387SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zfail_op));388SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zpass_op));389SB_DATA (so, nvgl_comparison_op(cso->stencil[0].func));390SB_BEGIN_3D(so, STENCIL_FRONT_FUNC_MASK, 2);391SB_DATA (so, cso->stencil[0].valuemask);392SB_DATA (so, cso->stencil[0].writemask);393} else {394SB_IMMED_3D(so, STENCIL_ENABLE, 0);395}396397if (cso->stencil[1].enabled) {398assert(cso->stencil[0].enabled);399SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5);400SB_DATA (so, 1);401SB_DATA (so, nvgl_stencil_op(cso->stencil[1].fail_op));402SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zfail_op));403SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zpass_op));404SB_DATA (so, nvgl_comparison_op(cso->stencil[1].func));405SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2);406SB_DATA (so, cso->stencil[1].writemask);407SB_DATA (so, cso->stencil[1].valuemask);408} else409if (cso->stencil[0].enabled) {410SB_IMMED_3D(so, STENCIL_TWO_SIDE_ENABLE, 0);411}412413SB_IMMED_3D(so, ALPHA_TEST_ENABLE, cso->alpha_enabled);414if (cso->alpha_enabled) {415SB_BEGIN_3D(so, ALPHA_TEST_REF, 2);416SB_DATA (so, fui(cso->alpha_ref_value));417SB_DATA (so, nvgl_comparison_op(cso->alpha_func));418}419420assert(so->size <= ARRAY_SIZE(so->state));421return (void *)so;422}423424static void425nvc0_zsa_state_bind(struct pipe_context *pipe, void *hwcso)426{427struct nvc0_context *nvc0 = nvc0_context(pipe);428429nvc0->zsa = hwcso;430nvc0->dirty_3d |= NVC0_NEW_3D_ZSA;431}432433static void434nvc0_zsa_state_delete(struct pipe_context *pipe, void *hwcso)435{436FREE(hwcso);437}438439/* ====================== SAMPLERS AND TEXTURES ================================440*/441442#define NV50_TSC_WRAP_CASE(n) \443case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n444445static void446nvc0_sampler_state_delete(struct pipe_context *pipe, void *hwcso)447{448unsigned s, i;449450for (s = 0; s < 6; ++s)451for (i = 0; i < nvc0_context(pipe)->num_samplers[s]; ++i)452if (nvc0_context(pipe)->samplers[s][i] == hwcso)453nvc0_context(pipe)->samplers[s][i] = NULL;454455nvc0_screen_tsc_free(nvc0_context(pipe)->screen, nv50_tsc_entry(hwcso));456457FREE(hwcso);458}459460static inline void461nvc0_stage_sampler_states_bind(struct nvc0_context *nvc0,462unsigned s,463unsigned nr, void **hwcsos)464{465unsigned highest_found = 0;466unsigned i;467468for (i = 0; i < nr; ++i) {469struct nv50_tsc_entry *hwcso = hwcsos ? nv50_tsc_entry(hwcsos[i]) : NULL;470struct nv50_tsc_entry *old = nvc0->samplers[s][i];471472if (hwcso)473highest_found = i;474475if (hwcso == old)476continue;477nvc0->samplers_dirty[s] |= 1 << i;478479nvc0->samplers[s][i] = hwcso;480if (old)481nvc0_screen_tsc_unlock(nvc0->screen, old);482}483if (nr >= nvc0->num_samplers[s])484nvc0->num_samplers[s] = highest_found + 1;485}486487static void488nvc0_bind_sampler_states(struct pipe_context *pipe,489enum pipe_shader_type shader,490unsigned start, unsigned nr, void **samplers)491{492const unsigned s = nvc0_shader_stage(shader);493494assert(start == 0);495nvc0_stage_sampler_states_bind(nvc0_context(pipe), s, nr, samplers);496497if (s == 5)498nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_SAMPLERS;499else500nvc0_context(pipe)->dirty_3d |= NVC0_NEW_3D_SAMPLERS;501}502503504/* NOTE: only called when not referenced anywhere, won't be bound */505static void506nvc0_sampler_view_destroy(struct pipe_context *pipe,507struct pipe_sampler_view *view)508{509pipe_resource_reference(&view->texture, NULL);510511nvc0_screen_tic_free(nvc0_context(pipe)->screen, nv50_tic_entry(view));512513FREE(nv50_tic_entry(view));514}515516static inline void517nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s,518unsigned nr,519struct pipe_sampler_view **views)520{521unsigned i;522523for (i = 0; i < nr; ++i) {524struct pipe_sampler_view *view = views ? views[i] : NULL;525struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);526527if (view == nvc0->textures[s][i])528continue;529nvc0->textures_dirty[s] |= 1 << i;530531if (view && view->texture) {532struct pipe_resource *res = view->texture;533if (res->target == PIPE_BUFFER &&534(res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT))535nvc0->textures_coherent[s] |= 1 << i;536else537nvc0->textures_coherent[s] &= ~(1 << i);538} else {539nvc0->textures_coherent[s] &= ~(1 << i);540}541542if (old) {543if (s == 5)544nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_TEX(i));545else546nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(s, i));547nvc0_screen_tic_unlock(nvc0->screen, old);548}549550pipe_sampler_view_reference(&nvc0->textures[s][i], view);551}552553for (i = nr; i < nvc0->num_textures[s]; ++i) {554struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);555if (old) {556if (s == 5)557nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_TEX(i));558else559nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEX(s, i));560nvc0_screen_tic_unlock(nvc0->screen, old);561pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);562}563}564565nvc0->num_textures[s] = nr;566}567568static void569nvc0_set_sampler_views(struct pipe_context *pipe, enum pipe_shader_type shader,570unsigned start, unsigned nr,571unsigned unbind_num_trailing_slots,572struct pipe_sampler_view **views)573{574const unsigned s = nvc0_shader_stage(shader);575576assert(start == 0);577nvc0_stage_set_sampler_views(nvc0_context(pipe), s, nr, views);578579if (s == 5)580nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_TEXTURES;581else582nvc0_context(pipe)->dirty_3d |= NVC0_NEW_3D_TEXTURES;583}584585/* ============================= SHADERS =======================================586*/587588static void *589nvc0_sp_state_create(struct pipe_context *pipe,590const struct pipe_shader_state *cso, unsigned type)591{592struct nvc0_program *prog;593594prog = CALLOC_STRUCT(nvc0_program);595if (!prog)596return NULL;597598prog->type = type;599prog->pipe.type = cso->type;600601switch(cso->type) {602case PIPE_SHADER_IR_TGSI:603prog->pipe.tokens = tgsi_dup_tokens(cso->tokens);604break;605case PIPE_SHADER_IR_NIR:606prog->pipe.ir.nir = cso->ir.nir;607break;608default:609assert(!"unsupported IR!");610free(prog);611return NULL;612}613614if (cso->stream_output.num_outputs)615prog->pipe.stream_output = cso->stream_output;616617prog->translated = nvc0_program_translate(618prog, nvc0_context(pipe)->screen->base.device->chipset,619nvc0_context(pipe)->screen->base.disk_shader_cache,620&nouveau_context(pipe)->debug);621622return (void *)prog;623}624625static void626nvc0_sp_state_delete(struct pipe_context *pipe, void *hwcso)627{628struct nvc0_program *prog = (struct nvc0_program *)hwcso;629630nvc0_program_destroy(nvc0_context(pipe), prog);631632if (prog->pipe.type == PIPE_SHADER_IR_TGSI)633FREE((void *)prog->pipe.tokens);634else if (prog->pipe.type == PIPE_SHADER_IR_NIR)635ralloc_free(prog->pipe.ir.nir);636FREE(prog);637}638639static void *640nvc0_vp_state_create(struct pipe_context *pipe,641const struct pipe_shader_state *cso)642{643return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX);644}645646static void647nvc0_vp_state_bind(struct pipe_context *pipe, void *hwcso)648{649struct nvc0_context *nvc0 = nvc0_context(pipe);650651nvc0->vertprog = hwcso;652nvc0->dirty_3d |= NVC0_NEW_3D_VERTPROG;653}654655static void *656nvc0_fp_state_create(struct pipe_context *pipe,657const struct pipe_shader_state *cso)658{659return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT);660}661662static void663nvc0_fp_state_bind(struct pipe_context *pipe, void *hwcso)664{665struct nvc0_context *nvc0 = nvc0_context(pipe);666667nvc0->fragprog = hwcso;668nvc0->dirty_3d |= NVC0_NEW_3D_FRAGPROG;669}670671static void *672nvc0_gp_state_create(struct pipe_context *pipe,673const struct pipe_shader_state *cso)674{675return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY);676}677678static void679nvc0_gp_state_bind(struct pipe_context *pipe, void *hwcso)680{681struct nvc0_context *nvc0 = nvc0_context(pipe);682683nvc0->gmtyprog = hwcso;684nvc0->dirty_3d |= NVC0_NEW_3D_GMTYPROG;685}686687static void *688nvc0_tcp_state_create(struct pipe_context *pipe,689const struct pipe_shader_state *cso)690{691return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_TESS_CTRL);692}693694static void695nvc0_tcp_state_bind(struct pipe_context *pipe, void *hwcso)696{697struct nvc0_context *nvc0 = nvc0_context(pipe);698699nvc0->tctlprog = hwcso;700nvc0->dirty_3d |= NVC0_NEW_3D_TCTLPROG;701}702703static void *704nvc0_tep_state_create(struct pipe_context *pipe,705const struct pipe_shader_state *cso)706{707return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_TESS_EVAL);708}709710static void711nvc0_tep_state_bind(struct pipe_context *pipe, void *hwcso)712{713struct nvc0_context *nvc0 = nvc0_context(pipe);714715nvc0->tevlprog = hwcso;716nvc0->dirty_3d |= NVC0_NEW_3D_TEVLPROG;717}718719static void *720nvc0_cp_state_create(struct pipe_context *pipe,721const struct pipe_compute_state *cso)722{723struct nvc0_program *prog;724725prog = CALLOC_STRUCT(nvc0_program);726if (!prog)727return NULL;728prog->type = PIPE_SHADER_COMPUTE;729prog->pipe.type = cso->ir_type;730731prog->cp.smem_size = cso->req_local_mem;732prog->cp.lmem_size = cso->req_private_mem;733prog->parm_size = cso->req_input_mem;734735switch(cso->ir_type) {736case PIPE_SHADER_IR_TGSI:737prog->pipe.tokens = tgsi_dup_tokens((const struct tgsi_token *)cso->prog);738break;739case PIPE_SHADER_IR_NIR:740prog->pipe.ir.nir = (nir_shader *)cso->prog;741break;742case PIPE_SHADER_IR_NIR_SERIALIZED: {743struct blob_reader reader;744const struct pipe_binary_program_header *hdr = cso->prog;745746blob_reader_init(&reader, hdr->blob, hdr->num_bytes);747prog->pipe.ir.nir = nir_deserialize(NULL, pipe->screen->get_compiler_options(pipe->screen, PIPE_SHADER_IR_NIR, PIPE_SHADER_COMPUTE), &reader);748prog->pipe.type = PIPE_SHADER_IR_NIR;749break;750}751default:752assert(!"unsupported IR!");753free(prog);754return NULL;755}756757prog->translated = nvc0_program_translate(758prog, nvc0_context(pipe)->screen->base.device->chipset,759nvc0_context(pipe)->screen->base.disk_shader_cache,760&nouveau_context(pipe)->debug);761762return (void *)prog;763}764765static void766nvc0_cp_state_bind(struct pipe_context *pipe, void *hwcso)767{768struct nvc0_context *nvc0 = nvc0_context(pipe);769770nvc0->compprog = hwcso;771nvc0->dirty_cp |= NVC0_NEW_CP_PROGRAM;772}773774static void775nvc0_set_constant_buffer(struct pipe_context *pipe,776enum pipe_shader_type shader, uint index,777bool take_ownership,778const struct pipe_constant_buffer *cb)779{780struct nvc0_context *nvc0 = nvc0_context(pipe);781struct pipe_resource *res = cb ? cb->buffer : NULL;782const unsigned s = nvc0_shader_stage(shader);783const unsigned i = index;784785if (unlikely(shader == PIPE_SHADER_COMPUTE)) {786if (nvc0->constbuf[s][i].user)787nvc0->constbuf[s][i].u.buf = NULL;788else789if (nvc0->constbuf[s][i].u.buf)790nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_CB(i));791792nvc0->dirty_cp |= NVC0_NEW_CP_CONSTBUF;793} else {794if (nvc0->constbuf[s][i].user)795nvc0->constbuf[s][i].u.buf = NULL;796else797if (nvc0->constbuf[s][i].u.buf)798nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_CB(s, i));799800nvc0->dirty_3d |= NVC0_NEW_3D_CONSTBUF;801}802nvc0->constbuf_dirty[s] |= 1 << i;803804if (nvc0->constbuf[s][i].u.buf)805nv04_resource(nvc0->constbuf[s][i].u.buf)->cb_bindings[s] &= ~(1 << i);806807if (take_ownership) {808pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, NULL);809nvc0->constbuf[s][i].u.buf = res;810} else {811pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, res);812}813814nvc0->constbuf[s][i].user = (cb && cb->user_buffer) ? true : false;815if (nvc0->constbuf[s][i].user) {816nvc0->constbuf[s][i].u.data = cb->user_buffer;817nvc0->constbuf[s][i].size = MIN2(cb->buffer_size, 0x10000);818nvc0->constbuf_valid[s] |= 1 << i;819nvc0->constbuf_coherent[s] &= ~(1 << i);820} else821if (cb) {822nvc0->constbuf[s][i].offset = cb->buffer_offset;823nvc0->constbuf[s][i].size = MIN2(align(cb->buffer_size, 0x100), 0x10000);824nvc0->constbuf_valid[s] |= 1 << i;825if (res && res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)826nvc0->constbuf_coherent[s] |= 1 << i;827else828nvc0->constbuf_coherent[s] &= ~(1 << i);829}830else {831nvc0->constbuf_valid[s] &= ~(1 << i);832nvc0->constbuf_coherent[s] &= ~(1 << i);833}834}835836/* =============================================================================837*/838839static void840nvc0_set_blend_color(struct pipe_context *pipe,841const struct pipe_blend_color *bcol)842{843struct nvc0_context *nvc0 = nvc0_context(pipe);844845nvc0->blend_colour = *bcol;846nvc0->dirty_3d |= NVC0_NEW_3D_BLEND_COLOUR;847}848849static void850nvc0_set_stencil_ref(struct pipe_context *pipe,851const struct pipe_stencil_ref sr)852{853struct nvc0_context *nvc0 = nvc0_context(pipe);854855nvc0->stencil_ref = sr;856nvc0->dirty_3d |= NVC0_NEW_3D_STENCIL_REF;857}858859static void860nvc0_set_clip_state(struct pipe_context *pipe,861const struct pipe_clip_state *clip)862{863struct nvc0_context *nvc0 = nvc0_context(pipe);864865memcpy(nvc0->clip.ucp, clip->ucp, sizeof(clip->ucp));866867nvc0->dirty_3d |= NVC0_NEW_3D_CLIP;868}869870static void871nvc0_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)872{873struct nvc0_context *nvc0 = nvc0_context(pipe);874875nvc0->sample_mask = sample_mask;876nvc0->dirty_3d |= NVC0_NEW_3D_SAMPLE_MASK;877}878879static void880nvc0_set_min_samples(struct pipe_context *pipe, unsigned min_samples)881{882struct nvc0_context *nvc0 = nvc0_context(pipe);883884if (nvc0->min_samples != min_samples) {885nvc0->min_samples = min_samples;886nvc0->dirty_3d |= NVC0_NEW_3D_MIN_SAMPLES;887}888}889890static void891nvc0_set_framebuffer_state(struct pipe_context *pipe,892const struct pipe_framebuffer_state *fb)893{894struct nvc0_context *nvc0 = nvc0_context(pipe);895896nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_FB);897898util_copy_framebuffer_state(&nvc0->framebuffer, fb);899900nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER | NVC0_NEW_3D_SAMPLE_LOCATIONS |901NVC0_NEW_3D_TEXTURES;902nvc0->dirty_cp |= NVC0_NEW_CP_TEXTURES;903}904905static void906nvc0_set_sample_locations(struct pipe_context *pipe,907size_t size, const uint8_t *locations)908{909struct nvc0_context *nvc0 = nvc0_context(pipe);910911nvc0->sample_locations_enabled = size && locations;912if (size > sizeof(nvc0->sample_locations))913size = sizeof(nvc0->sample_locations);914memcpy(nvc0->sample_locations, locations, size);915916nvc0->dirty_3d |= NVC0_NEW_3D_SAMPLE_LOCATIONS;917}918919static void920nvc0_set_polygon_stipple(struct pipe_context *pipe,921const struct pipe_poly_stipple *stipple)922{923struct nvc0_context *nvc0 = nvc0_context(pipe);924925nvc0->stipple = *stipple;926nvc0->dirty_3d |= NVC0_NEW_3D_STIPPLE;927}928929static void930nvc0_set_scissor_states(struct pipe_context *pipe,931unsigned start_slot,932unsigned num_scissors,933const struct pipe_scissor_state *scissor)934{935struct nvc0_context *nvc0 = nvc0_context(pipe);936int i;937938assert(start_slot + num_scissors <= NVC0_MAX_VIEWPORTS);939for (i = 0; i < num_scissors; i++) {940if (!memcmp(&nvc0->scissors[start_slot + i], &scissor[i], sizeof(*scissor)))941continue;942nvc0->scissors[start_slot + i] = scissor[i];943nvc0->scissors_dirty |= 1 << (start_slot + i);944nvc0->dirty_3d |= NVC0_NEW_3D_SCISSOR;945}946}947948static void949nvc0_set_viewport_states(struct pipe_context *pipe,950unsigned start_slot,951unsigned num_viewports,952const struct pipe_viewport_state *vpt)953{954struct nvc0_context *nvc0 = nvc0_context(pipe);955int i;956957assert(start_slot + num_viewports <= NVC0_MAX_VIEWPORTS);958for (i = 0; i < num_viewports; i++) {959if (!memcmp(&nvc0->viewports[start_slot + i], &vpt[i], sizeof(*vpt)))960continue;961nvc0->viewports[start_slot + i] = vpt[i];962nvc0->viewports_dirty |= 1 << (start_slot + i);963nvc0->dirty_3d |= NVC0_NEW_3D_VIEWPORT;964}965966}967968static void969nvc0_set_window_rectangles(struct pipe_context *pipe,970bool include,971unsigned num_rectangles,972const struct pipe_scissor_state *rectangles)973{974struct nvc0_context *nvc0 = nvc0_context(pipe);975976nvc0->window_rect.inclusive = include;977nvc0->window_rect.rects = MIN2(num_rectangles, NVC0_MAX_WINDOW_RECTANGLES);978memcpy(nvc0->window_rect.rect, rectangles,979sizeof(struct pipe_scissor_state) * nvc0->window_rect.rects);980981nvc0->dirty_3d |= NVC0_NEW_3D_WINDOW_RECTS;982}983984static void985nvc0_set_tess_state(struct pipe_context *pipe,986const float default_tess_outer[4],987const float default_tess_inner[2])988{989struct nvc0_context *nvc0 = nvc0_context(pipe);990991memcpy(nvc0->default_tess_outer, default_tess_outer, 4 * sizeof(float));992memcpy(nvc0->default_tess_inner, default_tess_inner, 2 * sizeof(float));993nvc0->dirty_3d |= NVC0_NEW_3D_TESSFACTOR;994}995996static void997nvc0_set_vertex_buffers(struct pipe_context *pipe,998unsigned start_slot, unsigned count,999unsigned unbind_num_trailing_slots,1000bool take_ownership,1001const struct pipe_vertex_buffer *vb)1002{1003struct nvc0_context *nvc0 = nvc0_context(pipe);1004unsigned i;10051006nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_VTX);1007nvc0->dirty_3d |= NVC0_NEW_3D_ARRAYS;10081009util_set_vertex_buffers_count(nvc0->vtxbuf, &nvc0->num_vtxbufs, vb,1010start_slot, count,1011unbind_num_trailing_slots,1012take_ownership);10131014unsigned clear_mask = ~u_bit_consecutive(start_slot + count, unbind_num_trailing_slots);1015nvc0->vbo_user &= clear_mask;1016nvc0->constant_vbos &= clear_mask;1017nvc0->vtxbufs_coherent &= clear_mask;10181019if (!vb) {1020clear_mask = ~u_bit_consecutive(start_slot, count);1021nvc0->vbo_user &= clear_mask;1022nvc0->constant_vbos &= clear_mask;1023nvc0->vtxbufs_coherent &= clear_mask;1024return;1025}10261027for (i = 0; i < count; ++i) {1028unsigned dst_index = start_slot + i;10291030if (vb[i].is_user_buffer) {1031nvc0->vbo_user |= 1 << dst_index;1032if (!vb[i].stride && nvc0->screen->eng3d->oclass < GM107_3D_CLASS)1033nvc0->constant_vbos |= 1 << dst_index;1034else1035nvc0->constant_vbos &= ~(1 << dst_index);1036nvc0->vtxbufs_coherent &= ~(1 << dst_index);1037} else {1038nvc0->vbo_user &= ~(1 << dst_index);1039nvc0->constant_vbos &= ~(1 << dst_index);10401041if (vb[i].buffer.resource &&1042vb[i].buffer.resource->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)1043nvc0->vtxbufs_coherent |= (1 << dst_index);1044else1045nvc0->vtxbufs_coherent &= ~(1 << dst_index);1046}1047}1048}10491050static void1051nvc0_vertex_state_bind(struct pipe_context *pipe, void *hwcso)1052{1053struct nvc0_context *nvc0 = nvc0_context(pipe);10541055nvc0->vertex = hwcso;1056nvc0->dirty_3d |= NVC0_NEW_3D_VERTEX;1057}10581059static struct pipe_stream_output_target *1060nvc0_so_target_create(struct pipe_context *pipe,1061struct pipe_resource *res,1062unsigned offset, unsigned size)1063{1064struct nv04_resource *buf = (struct nv04_resource *)res;1065struct nvc0_so_target *targ = MALLOC_STRUCT(nvc0_so_target);1066if (!targ)1067return NULL;10681069targ->pq = pipe->create_query(pipe, NVC0_HW_QUERY_TFB_BUFFER_OFFSET, 0);1070if (!targ->pq) {1071FREE(targ);1072return NULL;1073}1074targ->clean = true;10751076targ->pipe.buffer_size = size;1077targ->pipe.buffer_offset = offset;1078targ->pipe.context = pipe;1079targ->pipe.buffer = NULL;1080pipe_resource_reference(&targ->pipe.buffer, res);1081pipe_reference_init(&targ->pipe.reference, 1);10821083assert(buf->base.target == PIPE_BUFFER);1084util_range_add(&buf->base, &buf->valid_buffer_range, offset, offset + size);10851086return &targ->pipe;1087}10881089static void1090nvc0_so_target_save_offset(struct pipe_context *pipe,1091struct pipe_stream_output_target *ptarg,1092unsigned index, bool *serialize)1093{1094struct nvc0_so_target *targ = nvc0_so_target(ptarg);10951096if (*serialize) {1097*serialize = false;1098PUSH_SPACE(nvc0_context(pipe)->base.pushbuf, 1);1099IMMED_NVC0(nvc0_context(pipe)->base.pushbuf, NVC0_3D(SERIALIZE), 0);11001101NOUVEAU_DRV_STAT(nouveau_screen(pipe->screen), gpu_serialize_count, 1);1102}11031104nvc0_query(targ->pq)->index = index;1105pipe->end_query(pipe, targ->pq);1106}11071108static void1109nvc0_so_target_destroy(struct pipe_context *pipe,1110struct pipe_stream_output_target *ptarg)1111{1112struct nvc0_so_target *targ = nvc0_so_target(ptarg);1113pipe->destroy_query(pipe, targ->pq);1114pipe_resource_reference(&targ->pipe.buffer, NULL);1115FREE(targ);1116}11171118static void1119nvc0_set_transform_feedback_targets(struct pipe_context *pipe,1120unsigned num_targets,1121struct pipe_stream_output_target **targets,1122const unsigned *offsets)1123{1124struct nvc0_context *nvc0 = nvc0_context(pipe);1125unsigned i;1126bool serialize = true;11271128assert(num_targets <= 4);11291130for (i = 0; i < num_targets; ++i) {1131const bool changed = nvc0->tfbbuf[i] != targets[i];1132const bool append = (offsets[i] == ((unsigned)-1));1133if (!changed && append)1134continue;1135nvc0->tfbbuf_dirty |= 1 << i;11361137if (nvc0->tfbbuf[i] && changed)1138nvc0_so_target_save_offset(pipe, nvc0->tfbbuf[i], i, &serialize);11391140if (targets[i] && !append)1141nvc0_so_target(targets[i])->clean = true;11421143pipe_so_target_reference(&nvc0->tfbbuf[i], targets[i]);1144}1145for (; i < nvc0->num_tfbbufs; ++i) {1146if (nvc0->tfbbuf[i]) {1147nvc0->tfbbuf_dirty |= 1 << i;1148nvc0_so_target_save_offset(pipe, nvc0->tfbbuf[i], i, &serialize);1149pipe_so_target_reference(&nvc0->tfbbuf[i], NULL);1150}1151}1152nvc0->num_tfbbufs = num_targets;11531154if (nvc0->tfbbuf_dirty) {1155nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TFB);1156nvc0->dirty_3d |= NVC0_NEW_3D_TFB_TARGETS;1157}1158}11591160static void1161nvc0_bind_surfaces_range(struct nvc0_context *nvc0, const unsigned t,1162unsigned start, unsigned nr,1163struct pipe_surface **psurfaces)1164{1165const unsigned end = start + nr;1166const unsigned mask = ((1 << nr) - 1) << start;1167unsigned i;11681169if (psurfaces) {1170for (i = start; i < end; ++i) {1171const unsigned p = i - start;1172if (psurfaces[p])1173nvc0->surfaces_valid[t] |= (1 << i);1174else1175nvc0->surfaces_valid[t] &= ~(1 << i);1176pipe_surface_reference(&nvc0->surfaces[t][i], psurfaces[p]);1177}1178} else {1179for (i = start; i < end; ++i)1180pipe_surface_reference(&nvc0->surfaces[t][i], NULL);1181nvc0->surfaces_valid[t] &= ~mask;1182}1183nvc0->surfaces_dirty[t] |= mask;11841185if (t == 0)1186nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_SUF);1187else1188nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF);1189}11901191static void1192nvc0_set_compute_resources(struct pipe_context *pipe,1193unsigned start, unsigned nr,1194struct pipe_surface **resources)1195{1196nvc0_bind_surfaces_range(nvc0_context(pipe), 1, start, nr, resources);11971198nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_SURFACES;1199}12001201static bool1202nvc0_bind_images_range(struct nvc0_context *nvc0, const unsigned s,1203unsigned start, unsigned nr,1204const struct pipe_image_view *pimages)1205{1206const unsigned end = start + nr;1207unsigned mask = 0;1208unsigned i;12091210assert(s < 6);12111212if (pimages) {1213for (i = start; i < end; ++i) {1214struct pipe_image_view *img = &nvc0->images[s][i];1215const unsigned p = i - start;12161217if (img->resource == pimages[p].resource &&1218img->format == pimages[p].format &&1219img->access == pimages[p].access) {1220if (img->resource == NULL)1221continue;1222if (img->resource->target == PIPE_BUFFER &&1223img->u.buf.offset == pimages[p].u.buf.offset &&1224img->u.buf.size == pimages[p].u.buf.size)1225continue;1226if (img->resource->target != PIPE_BUFFER &&1227img->u.tex.first_layer == pimages[p].u.tex.first_layer &&1228img->u.tex.last_layer == pimages[p].u.tex.last_layer &&1229img->u.tex.level == pimages[p].u.tex.level)1230continue;1231}12321233mask |= (1 << i);1234if (pimages[p].resource)1235nvc0->images_valid[s] |= (1 << i);1236else1237nvc0->images_valid[s] &= ~(1 << i);12381239img->format = pimages[p].format;1240img->access = pimages[p].access;1241if (pimages[p].resource && pimages[p].resource->target == PIPE_BUFFER)1242img->u.buf = pimages[p].u.buf;1243else1244img->u.tex = pimages[p].u.tex;12451246pipe_resource_reference(1247&img->resource, pimages[p].resource);12481249if (nvc0->screen->base.class_3d >= GM107_3D_CLASS) {1250if (nvc0->images_tic[s][i]) {1251struct nv50_tic_entry *old =1252nv50_tic_entry(nvc0->images_tic[s][i]);1253nvc0_screen_tic_unlock(nvc0->screen, old);1254pipe_sampler_view_reference(&nvc0->images_tic[s][i], NULL);1255}12561257nvc0->images_tic[s][i] =1258gm107_create_texture_view_from_image(&nvc0->base.pipe,1259&pimages[p]);1260}1261}1262if (!mask)1263return false;1264} else {1265mask = ((1 << nr) - 1) << start;1266if (!(nvc0->images_valid[s] & mask))1267return false;1268for (i = start; i < end; ++i) {1269pipe_resource_reference(&nvc0->images[s][i].resource, NULL);1270if (nvc0->screen->base.class_3d >= GM107_3D_CLASS) {1271struct nv50_tic_entry *old = nv50_tic_entry(nvc0->images_tic[s][i]);1272if (old) {1273nvc0_screen_tic_unlock(nvc0->screen, old);1274pipe_sampler_view_reference(&nvc0->images_tic[s][i], NULL);1275}1276}1277}1278nvc0->images_valid[s] &= ~mask;1279}1280nvc0->images_dirty[s] |= mask;12811282if (s == 5)1283nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF);1284else1285nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_SUF);12861287return true;1288}12891290static void1291nvc0_set_shader_images(struct pipe_context *pipe,1292enum pipe_shader_type shader,1293unsigned start, unsigned nr,1294unsigned unbind_num_trailing_slots,1295const struct pipe_image_view *images)1296{1297const unsigned s = nvc0_shader_stage(shader);12981299nvc0_bind_images_range(nvc0_context(pipe), s, start + nr,1300unbind_num_trailing_slots, NULL);13011302if (!nvc0_bind_images_range(nvc0_context(pipe), s, start, nr, images))1303return;13041305if (s == 5)1306nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_SURFACES;1307else1308nvc0_context(pipe)->dirty_3d |= NVC0_NEW_3D_SURFACES;1309}13101311static bool1312nvc0_bind_buffers_range(struct nvc0_context *nvc0, const unsigned t,1313unsigned start, unsigned nr,1314const struct pipe_shader_buffer *pbuffers)1315{1316const unsigned end = start + nr;1317unsigned mask = 0;1318unsigned i;13191320assert(t < 6);13211322if (pbuffers) {1323for (i = start; i < end; ++i) {1324struct pipe_shader_buffer *buf = &nvc0->buffers[t][i];1325const unsigned p = i - start;1326if (buf->buffer == pbuffers[p].buffer &&1327buf->buffer_offset == pbuffers[p].buffer_offset &&1328buf->buffer_size == pbuffers[p].buffer_size)1329continue;13301331mask |= (1 << i);1332if (pbuffers[p].buffer)1333nvc0->buffers_valid[t] |= (1 << i);1334else1335nvc0->buffers_valid[t] &= ~(1 << i);1336buf->buffer_offset = pbuffers[p].buffer_offset;1337buf->buffer_size = pbuffers[p].buffer_size;1338pipe_resource_reference(&buf->buffer, pbuffers[p].buffer);1339}1340if (!mask)1341return false;1342} else {1343mask = ((1 << nr) - 1) << start;1344if (!(nvc0->buffers_valid[t] & mask))1345return false;1346for (i = start; i < end; ++i)1347pipe_resource_reference(&nvc0->buffers[t][i].buffer, NULL);1348nvc0->buffers_valid[t] &= ~mask;1349}1350nvc0->buffers_dirty[t] |= mask;13511352if (t == 5)1353nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_BUF);1354else1355nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_BUF);13561357return true;1358}13591360static void1361nvc0_set_shader_buffers(struct pipe_context *pipe,1362enum pipe_shader_type shader,1363unsigned start, unsigned nr,1364const struct pipe_shader_buffer *buffers,1365unsigned writable_bitmask)1366{1367const unsigned s = nvc0_shader_stage(shader);1368if (!nvc0_bind_buffers_range(nvc0_context(pipe), s, start, nr, buffers))1369return;13701371if (s == 5)1372nvc0_context(pipe)->dirty_cp |= NVC0_NEW_CP_BUFFERS;1373else1374nvc0_context(pipe)->dirty_3d |= NVC0_NEW_3D_BUFFERS;1375}13761377static inline void1378nvc0_set_global_handle(uint32_t *phandle, struct pipe_resource *res)1379{1380struct nv04_resource *buf = nv04_resource(res);1381if (buf) {1382uint64_t address = buf->address + *phandle;1383/* even though it's a pointer to uint32_t that's fine */1384memcpy(phandle, &address, 8);1385} else {1386*phandle = 0;1387}1388}13891390static void1391nvc0_set_global_bindings(struct pipe_context *pipe,1392unsigned start, unsigned nr,1393struct pipe_resource **resources,1394uint32_t **handles)1395{1396struct nvc0_context *nvc0 = nvc0_context(pipe);1397struct pipe_resource **ptr;1398unsigned i;1399const unsigned end = start + nr;14001401if (!nr)1402return;14031404if (nvc0->global_residents.size <= (end * sizeof(struct pipe_resource *))) {1405const unsigned old_size = nvc0->global_residents.size;1406if (util_dynarray_resize(&nvc0->global_residents, struct pipe_resource *, end)) {1407memset((uint8_t *)nvc0->global_residents.data + old_size, 0,1408nvc0->global_residents.size - old_size);1409} else {1410NOUVEAU_ERR("Could not resize global residents array\n");1411return;1412}1413}14141415if (resources) {1416ptr = util_dynarray_element(1417&nvc0->global_residents, struct pipe_resource *, start);1418for (i = 0; i < nr; ++i) {1419pipe_resource_reference(&ptr[i], resources[i]);1420nvc0_set_global_handle(handles[i], resources[i]);1421}1422} else {1423ptr = util_dynarray_element(1424&nvc0->global_residents, struct pipe_resource *, start);1425for (i = 0; i < nr; ++i)1426pipe_resource_reference(&ptr[i], NULL);1427}14281429nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_GLOBAL);14301431nvc0->dirty_cp |= NVC0_NEW_CP_GLOBALS;1432}14331434void1435nvc0_init_state_functions(struct nvc0_context *nvc0)1436{1437struct pipe_context *pipe = &nvc0->base.pipe;14381439pipe->create_blend_state = nvc0_blend_state_create;1440pipe->bind_blend_state = nvc0_blend_state_bind;1441pipe->delete_blend_state = nvc0_blend_state_delete;14421443pipe->create_rasterizer_state = nvc0_rasterizer_state_create;1444pipe->bind_rasterizer_state = nvc0_rasterizer_state_bind;1445pipe->delete_rasterizer_state = nvc0_rasterizer_state_delete;14461447pipe->create_depth_stencil_alpha_state = nvc0_zsa_state_create;1448pipe->bind_depth_stencil_alpha_state = nvc0_zsa_state_bind;1449pipe->delete_depth_stencil_alpha_state = nvc0_zsa_state_delete;14501451pipe->create_sampler_state = nv50_sampler_state_create;1452pipe->delete_sampler_state = nvc0_sampler_state_delete;1453pipe->bind_sampler_states = nvc0_bind_sampler_states;14541455pipe->create_sampler_view = nvc0_create_sampler_view;1456pipe->sampler_view_destroy = nvc0_sampler_view_destroy;1457pipe->set_sampler_views = nvc0_set_sampler_views;14581459pipe->create_vs_state = nvc0_vp_state_create;1460pipe->create_fs_state = nvc0_fp_state_create;1461pipe->create_gs_state = nvc0_gp_state_create;1462pipe->create_tcs_state = nvc0_tcp_state_create;1463pipe->create_tes_state = nvc0_tep_state_create;1464pipe->bind_vs_state = nvc0_vp_state_bind;1465pipe->bind_fs_state = nvc0_fp_state_bind;1466pipe->bind_gs_state = nvc0_gp_state_bind;1467pipe->bind_tcs_state = nvc0_tcp_state_bind;1468pipe->bind_tes_state = nvc0_tep_state_bind;1469pipe->delete_vs_state = nvc0_sp_state_delete;1470pipe->delete_fs_state = nvc0_sp_state_delete;1471pipe->delete_gs_state = nvc0_sp_state_delete;1472pipe->delete_tcs_state = nvc0_sp_state_delete;1473pipe->delete_tes_state = nvc0_sp_state_delete;14741475pipe->create_compute_state = nvc0_cp_state_create;1476pipe->bind_compute_state = nvc0_cp_state_bind;1477pipe->delete_compute_state = nvc0_sp_state_delete;14781479pipe->set_blend_color = nvc0_set_blend_color;1480pipe->set_stencil_ref = nvc0_set_stencil_ref;1481pipe->set_clip_state = nvc0_set_clip_state;1482pipe->set_sample_mask = nvc0_set_sample_mask;1483pipe->set_min_samples = nvc0_set_min_samples;1484pipe->set_constant_buffer = nvc0_set_constant_buffer;1485pipe->set_framebuffer_state = nvc0_set_framebuffer_state;1486pipe->set_sample_locations = nvc0_set_sample_locations;1487pipe->set_polygon_stipple = nvc0_set_polygon_stipple;1488pipe->set_scissor_states = nvc0_set_scissor_states;1489pipe->set_viewport_states = nvc0_set_viewport_states;1490pipe->set_window_rectangles = nvc0_set_window_rectangles;1491pipe->set_tess_state = nvc0_set_tess_state;14921493pipe->create_vertex_elements_state = nvc0_vertex_state_create;1494pipe->delete_vertex_elements_state = nvc0_vertex_state_delete;1495pipe->bind_vertex_elements_state = nvc0_vertex_state_bind;14961497pipe->set_vertex_buffers = nvc0_set_vertex_buffers;14981499pipe->create_stream_output_target = nvc0_so_target_create;1500pipe->stream_output_target_destroy = nvc0_so_target_destroy;1501pipe->set_stream_output_targets = nvc0_set_transform_feedback_targets;15021503pipe->set_global_binding = nvc0_set_global_bindings;1504pipe->set_compute_resources = nvc0_set_compute_resources;1505pipe->set_shader_images = nvc0_set_shader_images;1506pipe->set_shader_buffers = nvc0_set_shader_buffers;15071508nvc0->sample_mask = ~0;1509nvc0->min_samples = 1;1510nvc0->default_tess_outer[0] =1511nvc0->default_tess_outer[1] =1512nvc0->default_tess_outer[2] =1513nvc0->default_tess_outer[3] = 1.0;1514nvc0->default_tess_inner[0] =1515nvc0->default_tess_inner[1] = 1.0;1516}151715181519