14a49301eSmrg/********************************************************** 24a49301eSmrg * Copyright 2008-2009 VMware, Inc. All rights reserved. 34a49301eSmrg * 44a49301eSmrg * Permission is hereby granted, free of charge, to any person 54a49301eSmrg * obtaining a copy of this software and associated documentation 64a49301eSmrg * files (the "Software"), to deal in the Software without 74a49301eSmrg * restriction, including without limitation the rights to use, copy, 84a49301eSmrg * modify, merge, publish, distribute, sublicense, and/or sell copies 94a49301eSmrg * of the Software, and to permit persons to whom the Software is 104a49301eSmrg * furnished to do so, subject to the following conditions: 114a49301eSmrg * 124a49301eSmrg * The above copyright notice and this permission notice shall be 134a49301eSmrg * included in all copies or substantial portions of the Software. 144a49301eSmrg * 154a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 164a49301eSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 174a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 184a49301eSmrg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 194a49301eSmrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 204a49301eSmrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 214a49301eSmrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 224a49301eSmrg * SOFTWARE. 234a49301eSmrg * 244a49301eSmrg **********************************************************/ 254a49301eSmrg 2601e04c3fSmrg#include "util/u_bitmask.h" 274a49301eSmrg#include "util/u_debug.h" 284a49301eSmrg#include "pipe/p_defines.h" 294a49301eSmrg#include "util/u_memory.h" 304a49301eSmrg#include "draw/draw_context.h" 314a49301eSmrg 324a49301eSmrg#include "svga_context.h" 334a49301eSmrg#include "svga_screen.h" 344a49301eSmrg#include "svga_state.h" 354a49301eSmrg#include "svga_draw.h" 364a49301eSmrg#include "svga_cmd.h" 374a49301eSmrg#include "svga_hw_reg.h" 384a49301eSmrg 394a49301eSmrg/* This is just enough to decide whether we need to use the draw 404a49301eSmrg * module (swtnl) or not. 414a49301eSmrg */ 424a49301eSmrgstatic const struct svga_tracked_state *need_swtnl_state[] = 434a49301eSmrg{ 444a49301eSmrg &svga_update_need_swvfetch, 454a49301eSmrg &svga_update_need_pipeline, 464a49301eSmrg &svga_update_need_swtnl, 474a49301eSmrg NULL 484a49301eSmrg}; 494a49301eSmrg 504a49301eSmrg 514a49301eSmrg/* Atoms to update hardware state prior to emitting a clear or draw 524a49301eSmrg * packet. 534a49301eSmrg */ 544a49301eSmrgstatic const struct svga_tracked_state *hw_clear_state[] = 554a49301eSmrg{ 564a49301eSmrg &svga_hw_scissor, 574a49301eSmrg &svga_hw_viewport, 584a49301eSmrg &svga_hw_framebuffer, 594a49301eSmrg NULL 604a49301eSmrg}; 614a49301eSmrg 624a49301eSmrg 637ec681f3Smrg/** 647ec681f3Smrg * Atoms to update hardware state prior to emitting a draw packet 657ec681f3Smrg * for VGPU9 device. 664a49301eSmrg */ 677ec681f3Smrgstatic const struct svga_tracked_state *hw_draw_state_vgpu9[] = 687ec681f3Smrg{ 697ec681f3Smrg &svga_hw_fs, 707ec681f3Smrg &svga_hw_vs, 717ec681f3Smrg &svga_hw_rss, 727ec681f3Smrg &svga_hw_tss, 737ec681f3Smrg &svga_hw_tss_binding, 747ec681f3Smrg &svga_hw_clip_planes, 757ec681f3Smrg &svga_hw_vdecl, 767ec681f3Smrg &svga_hw_fs_constants, 777ec681f3Smrg &svga_hw_vs_constants, 787ec681f3Smrg NULL 797ec681f3Smrg}; 807ec681f3Smrg 817ec681f3Smrg 827ec681f3Smrg/** 837ec681f3Smrg * Atoms to update hardware state prior to emitting a draw packet 847ec681f3Smrg * for VGPU10 device. 857ec681f3Smrg * Geometry Shader is new to VGPU10. 867ec681f3Smrg * TSS and TSS bindings are replaced by sampler and sampler bindings. 877ec681f3Smrg */ 887ec681f3Smrgstatic const struct svga_tracked_state *hw_draw_state_vgpu10[] = 894a49301eSmrg{ 9001e04c3fSmrg &svga_need_tgsi_transform, 914a49301eSmrg &svga_hw_fs, 9201e04c3fSmrg &svga_hw_gs, 934a49301eSmrg &svga_hw_vs, 944a49301eSmrg &svga_hw_rss, 957ec681f3Smrg &svga_hw_sampler, 967ec681f3Smrg &svga_hw_sampler_bindings, 974a49301eSmrg &svga_hw_clip_planes, 984a49301eSmrg &svga_hw_vdecl, 99af69d88dSmrg &svga_hw_fs_constants, 1007ec681f3Smrg &svga_hw_fs_constbufs, 10101e04c3fSmrg &svga_hw_gs_constants, 1027ec681f3Smrg &svga_hw_gs_constbufs, 103af69d88dSmrg &svga_hw_vs_constants, 1047ec681f3Smrg &svga_hw_vs_constbufs, 1057ec681f3Smrg NULL 1067ec681f3Smrg}; 1077ec681f3Smrg 1087ec681f3Smrg 1097ec681f3Smrg/** 1107ec681f3Smrg * Atoms to update hardware state prior to emitting a draw packet 1117ec681f3Smrg * for SM5 device. 1127ec681f3Smrg * TCS and TES Shaders are new to SM5 device. 1137ec681f3Smrg */ 1147ec681f3Smrgstatic const struct svga_tracked_state *hw_draw_state_sm5[] = 1157ec681f3Smrg{ 1167ec681f3Smrg &svga_need_tgsi_transform, 1177ec681f3Smrg &svga_hw_fs, 1187ec681f3Smrg &svga_hw_gs, 1197ec681f3Smrg &svga_hw_tes, 1207ec681f3Smrg &svga_hw_tcs, 1217ec681f3Smrg &svga_hw_vs, 1227ec681f3Smrg &svga_hw_rss, 1237ec681f3Smrg &svga_hw_sampler, 1247ec681f3Smrg &svga_hw_sampler_bindings, 1257ec681f3Smrg &svga_hw_clip_planes, 1267ec681f3Smrg &svga_hw_vdecl, 1277ec681f3Smrg &svga_hw_fs_constants, 1287ec681f3Smrg &svga_hw_fs_constbufs, 1297ec681f3Smrg &svga_hw_gs_constants, 1307ec681f3Smrg &svga_hw_gs_constbufs, 1317ec681f3Smrg &svga_hw_tes_constants, 1327ec681f3Smrg &svga_hw_tes_constbufs, 1337ec681f3Smrg &svga_hw_tcs_constants, 1347ec681f3Smrg &svga_hw_tcs_constbufs, 1357ec681f3Smrg &svga_hw_vs_constants, 1367ec681f3Smrg &svga_hw_vs_constbufs, 1374a49301eSmrg NULL 1384a49301eSmrg}; 1394a49301eSmrg 1404a49301eSmrg 1414a49301eSmrgstatic const struct svga_tracked_state *swtnl_draw_state[] = 1424a49301eSmrg{ 1434a49301eSmrg &svga_update_swtnl_draw, 1444a49301eSmrg &svga_update_swtnl_vdecl, 1454a49301eSmrg NULL 1464a49301eSmrg}; 1474a49301eSmrg 1487ec681f3Smrg 1494a49301eSmrg/* Flattens the graph of state dependencies. Could swap the positions 1504a49301eSmrg * of hw_clear_state and need_swtnl_state without breaking anything. 1514a49301eSmrg */ 15201e04c3fSmrgstatic const struct svga_tracked_state **state_levels[] = 1534a49301eSmrg{ 1544a49301eSmrg need_swtnl_state, 1554a49301eSmrg hw_clear_state, 1567ec681f3Smrg NULL, /* hw_draw_state, to be set to the right version */ 1574a49301eSmrg swtnl_draw_state 1584a49301eSmrg}; 1594a49301eSmrg 1604a49301eSmrg 1617ec681f3Smrgstatic uint64_t 1627ec681f3Smrgcheck_state(uint64_t a, uint64_t b) 1634a49301eSmrg{ 1644a49301eSmrg return (a & b); 1654a49301eSmrg} 1664a49301eSmrg 16701e04c3fSmrgstatic void 1687ec681f3Smrgaccumulate_state(uint64_t *a, uint64_t b) 1694a49301eSmrg{ 1704a49301eSmrg *a |= b; 1714a49301eSmrg} 1724a49301eSmrg 1734a49301eSmrg 17401e04c3fSmrgstatic void 1757ec681f3Smrgxor_states(uint64_t *result, uint64_t a, uint64_t b) 1764a49301eSmrg{ 1774a49301eSmrg *result = a ^ b; 1784a49301eSmrg} 1794a49301eSmrg 1804a49301eSmrg 181af69d88dSmrgstatic enum pipe_error 182af69d88dSmrgupdate_state(struct svga_context *svga, 183af69d88dSmrg const struct svga_tracked_state *atoms[], 1847ec681f3Smrg uint64_t *state) 1854a49301eSmrg{ 18601e04c3fSmrg#ifdef DEBUG 1874a49301eSmrg boolean debug = TRUE; 18801e04c3fSmrg#else 18901e04c3fSmrg boolean debug = FALSE; 19001e04c3fSmrg#endif 191af69d88dSmrg enum pipe_error ret = PIPE_OK; 1924a49301eSmrg unsigned i; 1934a49301eSmrg 1944a49301eSmrg ret = svga_hwtnl_flush( svga->hwtnl ); 195af69d88dSmrg if (ret != PIPE_OK) 1964a49301eSmrg return ret; 1974a49301eSmrg 1984a49301eSmrg if (debug) { 1994a49301eSmrg /* Debug version which enforces various sanity checks on the 2004a49301eSmrg * state flags which are generated and checked to help ensure 2014a49301eSmrg * state atoms are ordered correctly in the list. 2024a49301eSmrg */ 2037ec681f3Smrg uint64_t examined, prev; 2044a49301eSmrg 2054a49301eSmrg examined = 0; 2064a49301eSmrg prev = *state; 2074a49301eSmrg 20801e04c3fSmrg for (i = 0; atoms[i] != NULL; i++) { 2097ec681f3Smrg uint64_t generated; 2104a49301eSmrg 21101e04c3fSmrg assert(atoms[i]->dirty); 21201e04c3fSmrg assert(atoms[i]->update); 2134a49301eSmrg 21401e04c3fSmrg if (check_state(*state, atoms[i]->dirty)) { 21501e04c3fSmrg if (0) 2164a49301eSmrg debug_printf("update: %s\n", atoms[i]->name); 21701e04c3fSmrg ret = atoms[i]->update( svga, *state ); 218af69d88dSmrg if (ret != PIPE_OK) 2194a49301eSmrg return ret; 22001e04c3fSmrg } 22101e04c3fSmrg 22201e04c3fSmrg /* generated = (prev ^ state) 22301e04c3fSmrg * if (examined & generated) 22401e04c3fSmrg * fail; 22501e04c3fSmrg */ 22601e04c3fSmrg xor_states(&generated, prev, *state); 22701e04c3fSmrg if (check_state(examined, generated)) { 22801e04c3fSmrg debug_printf("state atom %s generated state already examined\n", 2294a49301eSmrg atoms[i]->name); 23001e04c3fSmrg assert(0); 23101e04c3fSmrg } 23201e04c3fSmrg 23301e04c3fSmrg prev = *state; 23401e04c3fSmrg accumulate_state(&examined, atoms[i]->dirty); 2354a49301eSmrg } 2364a49301eSmrg } 2374a49301eSmrg else { 23801e04c3fSmrg for (i = 0; atoms[i] != NULL; i++) { 23901e04c3fSmrg if (check_state(*state, atoms[i]->dirty)) { 24001e04c3fSmrg ret = atoms[i]->update( svga, *state ); 241af69d88dSmrg if (ret != PIPE_OK) 2424a49301eSmrg return ret; 2434a49301eSmrg } 2444a49301eSmrg } 2454a49301eSmrg } 2464a49301eSmrg 247af69d88dSmrg return PIPE_OK; 2484a49301eSmrg} 2494a49301eSmrg 2504a49301eSmrg 251af69d88dSmrgenum pipe_error 252af69d88dSmrgsvga_update_state(struct svga_context *svga, unsigned max_level) 2534a49301eSmrg{ 2544a49301eSmrg struct svga_screen *screen = svga_screen(svga->pipe.screen); 255af69d88dSmrg enum pipe_error ret = PIPE_OK; 256af69d88dSmrg unsigned i; 2574a49301eSmrg 25801e04c3fSmrg SVGA_STATS_TIME_PUSH(screen->sws, SVGA_STATS_TIME_UPDATESTATE); 25901e04c3fSmrg 2604a49301eSmrg /* Check for updates to bound textures. This can't be done in an 2614a49301eSmrg * atom as there is no flag which could provoke this test, and we 2624a49301eSmrg * cannot create one. 2634a49301eSmrg */ 2644a49301eSmrg if (svga->state.texture_timestamp != screen->texture_timestamp) { 2654a49301eSmrg svga->state.texture_timestamp = screen->texture_timestamp; 2664a49301eSmrg svga->dirty |= SVGA_NEW_TEXTURE; 2674a49301eSmrg } 2684a49301eSmrg 2694a49301eSmrg for (i = 0; i <= max_level; i++) { 2704a49301eSmrg svga->dirty |= svga->state.dirty[i]; 2714a49301eSmrg 2724a49301eSmrg if (svga->dirty) { 27301e04c3fSmrg ret = update_state( svga, 27401e04c3fSmrg state_levels[i], 2754a49301eSmrg &svga->dirty ); 276af69d88dSmrg if (ret != PIPE_OK) 27701e04c3fSmrg goto done; 2784a49301eSmrg 2794a49301eSmrg svga->state.dirty[i] = 0; 2804a49301eSmrg } 2814a49301eSmrg } 28201e04c3fSmrg 28301e04c3fSmrg for (; i < SVGA_STATE_MAX; i++) 2844a49301eSmrg svga->state.dirty[i] |= svga->dirty; 2854a49301eSmrg 2864a49301eSmrg svga->dirty = 0; 2874a49301eSmrg 28801e04c3fSmrg svga->hud.num_validations++; 2894a49301eSmrg 29001e04c3fSmrgdone: 29101e04c3fSmrg SVGA_STATS_TIME_POP(screen->sws); 29201e04c3fSmrg return ret; 29301e04c3fSmrg} 2944a49301eSmrg 2954a49301eSmrg 29601e04c3fSmrg/** 29701e04c3fSmrg * Update state. If the first attempt fails, flush the command buffer 29801e04c3fSmrg * and retry. 29901e04c3fSmrg * \return true if success, false if second attempt fails. 30001e04c3fSmrg */ 30101e04c3fSmrgbool 30201e04c3fSmrgsvga_update_state_retry(struct svga_context *svga, unsigned max_level) 3034a49301eSmrg{ 304af69d88dSmrg enum pipe_error ret; 3054a49301eSmrg 3067ec681f3Smrg SVGA_RETRY_OOM(svga, ret, svga_update_state( svga, max_level )); 3074a49301eSmrg 30801e04c3fSmrg return ret == PIPE_OK; 3094a49301eSmrg} 3104a49301eSmrg 3114a49301eSmrg 3124a49301eSmrg 3134a49301eSmrg#define EMIT_RS(_rs, _count, _name, _value) \ 3144a49301eSmrgdo { \ 3154a49301eSmrg _rs[_count].state = _name; \ 3164a49301eSmrg _rs[_count].uintValue = _value; \ 3174a49301eSmrg _count++; \ 3184a49301eSmrg} while (0) 3194a49301eSmrg 3204a49301eSmrg 3214a49301eSmrg/* Setup any hardware state which will be constant through the life of 3224a49301eSmrg * a context. 3234a49301eSmrg */ 32401e04c3fSmrgenum pipe_error 32501e04c3fSmrgsvga_emit_initial_state(struct svga_context *svga) 3264a49301eSmrg{ 32701e04c3fSmrg if (svga_have_vgpu10(svga)) { 32801e04c3fSmrg SVGA3dRasterizerStateId id = util_bitmask_add(svga->rast_object_id_bm); 32901e04c3fSmrg enum pipe_error ret; 33001e04c3fSmrg 33101e04c3fSmrg /* XXX preliminary code */ 33201e04c3fSmrg ret = SVGA3D_vgpu10_DefineRasterizerState(svga->swc, 33301e04c3fSmrg id, 33401e04c3fSmrg SVGA3D_FILLMODE_FILL, 33501e04c3fSmrg SVGA3D_CULL_NONE, 33601e04c3fSmrg 1, /* frontCounterClockwise */ 33701e04c3fSmrg 0, /* depthBias */ 33801e04c3fSmrg 0.0f, /* depthBiasClamp */ 33901e04c3fSmrg 0.0f, /* slopeScaledDepthBiasClamp */ 34001e04c3fSmrg 0, /* depthClampEnable */ 34101e04c3fSmrg 0, /* scissorEnable */ 34201e04c3fSmrg 0, /* multisampleEnable */ 34301e04c3fSmrg 0, /* aalineEnable */ 34401e04c3fSmrg 1.0f, /* lineWidth */ 34501e04c3fSmrg 0, /* lineStippleEnable */ 34601e04c3fSmrg 0, /* lineStippleFactor */ 34701e04c3fSmrg 0, /* lineStipplePattern */ 34801e04c3fSmrg 0); /* provokingVertexLast */ 34901e04c3fSmrg 35001e04c3fSmrg 35101e04c3fSmrg assert(ret == PIPE_OK); 35201e04c3fSmrg 35301e04c3fSmrg ret = SVGA3D_vgpu10_SetRasterizerState(svga->swc, id); 3544a49301eSmrg return ret; 35501e04c3fSmrg } 35601e04c3fSmrg else { 35701e04c3fSmrg SVGA3dRenderState *rs; 35801e04c3fSmrg unsigned count = 0; 35901e04c3fSmrg const unsigned COUNT = 2; 36001e04c3fSmrg enum pipe_error ret; 3614a49301eSmrg 36201e04c3fSmrg ret = SVGA3D_BeginSetRenderState( svga->swc, &rs, COUNT ); 36301e04c3fSmrg if (ret != PIPE_OK) 36401e04c3fSmrg return ret; 3654a49301eSmrg 36601e04c3fSmrg /* Always use D3D style coordinate space as this is the only one 36701e04c3fSmrg * which is implemented on all backends. 36801e04c3fSmrg */ 36901e04c3fSmrg EMIT_RS(rs, count, SVGA3D_RS_COORDINATETYPE, 37001e04c3fSmrg SVGA3D_COORDINATE_LEFTHANDED ); 37101e04c3fSmrg EMIT_RS(rs, count, SVGA3D_RS_FRONTWINDING, SVGA3D_FRONTWINDING_CW ); 37201e04c3fSmrg 37301e04c3fSmrg assert( COUNT == count ); 37401e04c3fSmrg SVGA_FIFOCommitAll( svga->swc ); 37501e04c3fSmrg 37601e04c3fSmrg return PIPE_OK; 37701e04c3fSmrg } 3784a49301eSmrg} 3797ec681f3Smrg 3807ec681f3Smrg 3817ec681f3Smrgvoid 3827ec681f3Smrgsvga_init_tracked_state(struct svga_context *svga) 3837ec681f3Smrg{ 3847ec681f3Smrg /* Set the hw_draw_state atom list to the one for the particular gpu version. 3857ec681f3Smrg */ 3867ec681f3Smrg state_levels[2] = svga_have_sm5(svga) ? hw_draw_state_sm5 : 3877ec681f3Smrg (svga_have_vgpu10(svga) ? hw_draw_state_vgpu10 : 3887ec681f3Smrg hw_draw_state_vgpu9); 3897ec681f3Smrg} 390