Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nv30/nv30_screen.c
4574 views
/*1* Copyright 2012 Red Hat Inc.2*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*21* Authors: Ben Skeggs22*23*/2425#include <xf86drm.h>26#include <nouveau_drm.h>27#include "util/format/u_format.h"28#include "util/format/u_format_s3tc.h"29#include "util/u_screen.h"3031#include "nv_object.xml.h"32#include "nv_m2mf.xml.h"33#include "nv30/nv30-40_3d.xml.h"34#include "nv30/nv01_2d.xml.h"3536#include "nouveau_fence.h"37#include "nv30/nv30_screen.h"38#include "nv30/nv30_context.h"39#include "nv30/nv30_resource.h"40#include "nv30/nv30_format.h"4142#define RANKINE_0397_CHIPSET 0x0000000343#define RANKINE_0497_CHIPSET 0x000001e044#define RANKINE_0697_CHIPSET 0x0000001045#define CURIE_4097_CHIPSET 0x00000baf46#define CURIE_4497_CHIPSET 0x0000545047#define CURIE_4497_CHIPSET6X 0x000000884849static int50nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)51{52struct nv30_screen *screen = nv30_screen(pscreen);53struct nouveau_object *eng3d = screen->eng3d;54struct nouveau_device *dev = nouveau_screen(pscreen)->device;5556switch (param) {57/* non-boolean capabilities */58case PIPE_CAP_MAX_RENDER_TARGETS:59return (eng3d->oclass >= NV40_3D_CLASS) ? 4 : 1;60case PIPE_CAP_MAX_TEXTURE_2D_SIZE:61return 4096;62case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:63return 10;64case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:65return 13;66case PIPE_CAP_GLSL_FEATURE_LEVEL:67case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:68return 120;69case PIPE_CAP_ENDIANNESS:70return PIPE_ENDIAN_LITTLE;71case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:72return 16;73case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:74return NOUVEAU_MIN_BUFFER_MAP_ALIGN;75case PIPE_CAP_MAX_VIEWPORTS:76return 1;77case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:78return 2048;79case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET:80return 8 * 1024 * 1024;81case PIPE_CAP_MAX_VARYINGS:82return 8;8384/* supported capabilities */85case PIPE_CAP_ANISOTROPIC_FILTER:86case PIPE_CAP_POINT_SPRITE:87case PIPE_CAP_OCCLUSION_QUERY:88case PIPE_CAP_QUERY_TIME_ELAPSED:89case PIPE_CAP_QUERY_TIMESTAMP:90case PIPE_CAP_TEXTURE_SWIZZLE:91case PIPE_CAP_DEPTH_CLIP_DISABLE:92case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:93case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:94case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:95case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:96case PIPE_CAP_TGSI_TEXCOORD:97case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:98case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:99case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:100case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:101case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:102case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:103return 1;104/* nv35 capabilities */105case PIPE_CAP_DEPTH_BOUNDS_TEST:106return eng3d->oclass == NV35_3D_CLASS || eng3d->oclass >= NV40_3D_CLASS;107case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART:108case PIPE_CAP_SUPPORTED_PRIM_MODES:109return BITFIELD_MASK(PIPE_PRIM_MAX);110/* nv4x capabilities */111case PIPE_CAP_BLEND_EQUATION_SEPARATE:112case PIPE_CAP_NPOT_TEXTURES:113case PIPE_CAP_CONDITIONAL_RENDER:114case PIPE_CAP_TEXTURE_MIRROR_CLAMP:115case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:116case PIPE_CAP_PRIMITIVE_RESTART:117case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:118return (eng3d->oclass >= NV40_3D_CLASS) ? 1 : 0;119/* unsupported */120case PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART:121case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:122case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:123case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:124case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:125case PIPE_CAP_VERTEX_SHADER_SATURATE:126case PIPE_CAP_INDEP_BLEND_ENABLE:127case PIPE_CAP_INDEP_BLEND_FUNC:128case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:129case PIPE_CAP_SHADER_STENCIL_EXPORT:130case PIPE_CAP_TGSI_INSTANCEID:131case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: /* XXX: yes? */132case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:133case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:134case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:135case PIPE_CAP_MIN_TEXEL_OFFSET:136case PIPE_CAP_MAX_TEXEL_OFFSET:137case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:138case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:139case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:140case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:141case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:142case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:143case PIPE_CAP_MAX_VERTEX_STREAMS:144case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:145case PIPE_CAP_TEXTURE_BARRIER:146case PIPE_CAP_SEAMLESS_CUBE_MAP:147case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:148case PIPE_CAP_CUBE_MAP_ARRAY:149case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:150case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:151case PIPE_CAP_VERTEX_COLOR_CLAMPED:152case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:153case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:154case PIPE_CAP_START_INSTANCE:155case PIPE_CAP_TEXTURE_MULTISAMPLE:156case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:157case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:158case PIPE_CAP_QUERY_PIPELINE_STATISTICS:159case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:160case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:161case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:162case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:163case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:164case PIPE_CAP_TEXTURE_GATHER_SM5:165case PIPE_CAP_FAKE_SW_MSAA:166case PIPE_CAP_TEXTURE_QUERY_LOD:167case PIPE_CAP_SAMPLE_SHADING:168case PIPE_CAP_TEXTURE_GATHER_OFFSETS:169case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:170case PIPE_CAP_USER_VERTEX_BUFFERS:171case PIPE_CAP_COMPUTE:172case PIPE_CAP_DRAW_INDIRECT:173case PIPE_CAP_MULTI_DRAW_INDIRECT:174case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:175case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:176case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:177case PIPE_CAP_SAMPLER_VIEW_TARGET:178case PIPE_CAP_CLIP_HALFZ:179case PIPE_CAP_VERTEXID_NOBASE:180case PIPE_CAP_POLYGON_OFFSET_CLAMP:181case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:182case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:183case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:184case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:185case PIPE_CAP_TEXTURE_FLOAT_LINEAR:186case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:187case PIPE_CAP_TGSI_TXQS:188case PIPE_CAP_FORCE_PERSAMPLE_INTERP:189case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:190case PIPE_CAP_SHAREABLE_SHADERS:191case PIPE_CAP_CLEAR_TEXTURE:192case PIPE_CAP_DRAW_PARAMETERS:193case PIPE_CAP_TGSI_PACK_HALF_FLOAT:194case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:195case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:196case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:197case PIPE_CAP_INVALIDATE_BUFFER:198case PIPE_CAP_GENERATE_MIPMAP:199case PIPE_CAP_STRING_MARKER:200case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:201case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:202case PIPE_CAP_QUERY_BUFFER_OBJECT:203case PIPE_CAP_QUERY_MEMORY_INFO:204case PIPE_CAP_PCI_GROUP:205case PIPE_CAP_PCI_BUS:206case PIPE_CAP_PCI_DEVICE:207case PIPE_CAP_PCI_FUNCTION:208case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:209case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:210case PIPE_CAP_CULL_DISTANCE:211case PIPE_CAP_TGSI_VOTE:212case PIPE_CAP_MAX_WINDOW_RECTANGLES:213case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:214case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:215case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:216case PIPE_CAP_TGSI_ARRAY_COMPONENTS:217case PIPE_CAP_TGSI_CAN_READ_OUTPUTS:218case PIPE_CAP_NATIVE_FENCE_FD:219case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:220case PIPE_CAP_FBFETCH:221case PIPE_CAP_TGSI_MUL_ZERO_WINS:222case PIPE_CAP_DOUBLES:223case PIPE_CAP_INT64:224case PIPE_CAP_INT64_DIVMOD:225case PIPE_CAP_TGSI_TEX_TXF_LZ:226case PIPE_CAP_TGSI_CLOCK:227case PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE:228case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE:229case PIPE_CAP_TGSI_BALLOT:230case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT:231case PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX:232case PIPE_CAP_POST_DEPTH_COVERAGE:233case PIPE_CAP_BINDLESS_TEXTURE:234case PIPE_CAP_NIR_SAMPLERS_AS_DEREF:235case PIPE_CAP_QUERY_SO_OVERFLOW:236case PIPE_CAP_MEMOBJ:237case PIPE_CAP_LOAD_CONSTBUF:238case PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS:239case PIPE_CAP_TILE_RASTER_ORDER:240case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:241case PIPE_CAP_FRAMEBUFFER_MSAA_CONSTRAINTS:242case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET:243case PIPE_CAP_CONTEXT_PRIORITY_MASK:244case PIPE_CAP_FENCE_SIGNAL:245case PIPE_CAP_CONSTBUF0_FLAGS:246case PIPE_CAP_PACKED_UNIFORMS:247case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_TRIANGLES:248case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_POINTS_LINES:249case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_TRIANGLES:250case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES:251case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE:252case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS:253case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:254case PIPE_CAP_IMAGE_LOAD_FORMATTED:255case PIPE_CAP_TGSI_DIV:256case PIPE_CAP_TGSI_ATOMINC_WRAP:257return 0;258259case PIPE_CAP_MAX_GS_INVOCATIONS:260return 32;261case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:262return 1 << 27;263case PIPE_CAP_VENDOR_ID:264return 0x10de;265case PIPE_CAP_DEVICE_ID: {266uint64_t device_id;267if (nouveau_getparam(dev, NOUVEAU_GETPARAM_PCI_DEVICE, &device_id)) {268NOUVEAU_ERR("NOUVEAU_GETPARAM_PCI_DEVICE failed.\n");269return -1;270}271return device_id;272}273case PIPE_CAP_ACCELERATED:274return 1;275case PIPE_CAP_VIDEO_MEMORY:276return dev->vram_size >> 20;277case PIPE_CAP_UMA:278return 0;279default:280return u_pipe_screen_get_param_defaults(pscreen, param);281}282}283284static float285nv30_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)286{287struct nv30_screen *screen = nv30_screen(pscreen);288struct nouveau_object *eng3d = screen->eng3d;289290switch (param) {291case PIPE_CAPF_MAX_LINE_WIDTH:292case PIPE_CAPF_MAX_LINE_WIDTH_AA:293return 10.0;294case PIPE_CAPF_MAX_POINT_WIDTH:295case PIPE_CAPF_MAX_POINT_WIDTH_AA:296return 64.0;297case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:298return (eng3d->oclass >= NV40_3D_CLASS) ? 16.0 : 8.0;299case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:300return 15.0;301case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:302case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:303case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:304return 0.0;305default:306debug_printf("unknown paramf %d\n", param);307return 0;308}309}310311static int312nv30_screen_get_shader_param(struct pipe_screen *pscreen,313enum pipe_shader_type shader,314enum pipe_shader_cap param)315{316struct nv30_screen *screen = nv30_screen(pscreen);317struct nouveau_object *eng3d = screen->eng3d;318319switch (shader) {320case PIPE_SHADER_VERTEX:321switch (param) {322case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:323case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:324return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 256;325case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:326case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:327return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 0;328case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:329return 0;330case PIPE_SHADER_CAP_MAX_INPUTS:331case PIPE_SHADER_CAP_MAX_OUTPUTS:332return 16;333case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:334return ((eng3d->oclass >= NV40_3D_CLASS) ? (468 - 6): (256 - 6)) * sizeof(float[4]);335case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:336return 1;337case PIPE_SHADER_CAP_MAX_TEMPS:338return (eng3d->oclass >= NV40_3D_CLASS) ? 32 : 13;339case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:340return 32;341case PIPE_SHADER_CAP_PREFERRED_IR:342return PIPE_SHADER_IR_TGSI;343case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:344case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:345return 0;346case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:347case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:348case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:349case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:350case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:351case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:352case PIPE_SHADER_CAP_SUBROUTINES:353case PIPE_SHADER_CAP_INTEGERS:354case PIPE_SHADER_CAP_INT64_ATOMICS:355case PIPE_SHADER_CAP_FP16:356case PIPE_SHADER_CAP_FP16_DERIVATIVES:357case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:358case PIPE_SHADER_CAP_INT16:359case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:360case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:361case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:362case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:363case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:364case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:365case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:366case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:367case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:368case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:369case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:370case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:371return 0;372case PIPE_SHADER_CAP_SUPPORTED_IRS:373return 1 << PIPE_SHADER_IR_TGSI;374default:375debug_printf("unknown vertex shader param %d\n", param);376return 0;377}378break;379case PIPE_SHADER_FRAGMENT:380switch (param) {381case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:382case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:383case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:384case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:385return 4096;386case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:387return 0;388case PIPE_SHADER_CAP_MAX_INPUTS:389return 8; /* should be possible to do 10 with nv4x */390case PIPE_SHADER_CAP_MAX_OUTPUTS:391return 4;392case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:393return ((eng3d->oclass >= NV40_3D_CLASS) ? 224 : 32) * sizeof(float[4]);394case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:395return 1;396case PIPE_SHADER_CAP_MAX_TEMPS:397return 32;398case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:399case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:400return 16;401case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:402return 32;403case PIPE_SHADER_CAP_PREFERRED_IR:404return PIPE_SHADER_IR_TGSI;405case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:406case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:407case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:408case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:409case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:410case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:411case PIPE_SHADER_CAP_SUBROUTINES:412case PIPE_SHADER_CAP_INTEGERS:413case PIPE_SHADER_CAP_FP16:414case PIPE_SHADER_CAP_FP16_DERIVATIVES:415case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:416case PIPE_SHADER_CAP_INT16:417case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:418case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:419case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:420case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:421case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:422case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:423case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:424case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:425case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:426case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:427case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:428case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:429return 0;430case PIPE_SHADER_CAP_SUPPORTED_IRS:431return 1 << PIPE_SHADER_IR_TGSI;432default:433debug_printf("unknown fragment shader param %d\n", param);434return 0;435}436break;437default:438return 0;439}440}441442static bool443nv30_screen_is_format_supported(struct pipe_screen *pscreen,444enum pipe_format format,445enum pipe_texture_target target,446unsigned sample_count,447unsigned storage_sample_count,448unsigned bindings)449{450if (sample_count > nv30_screen(pscreen)->max_sample_count)451return false;452453if (!(0x00000017 & (1 << sample_count)))454return false;455456if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))457return false;458459/* No way to render to a swizzled 3d texture. We don't necessarily know if460* it's swizzled or not here, but we have to assume anyways.461*/462if (target == PIPE_TEXTURE_3D && (bindings & PIPE_BIND_RENDER_TARGET))463return false;464465/* shared is always supported */466bindings &= ~PIPE_BIND_SHARED;467468if (bindings & PIPE_BIND_INDEX_BUFFER) {469if (format != PIPE_FORMAT_R8_UINT &&470format != PIPE_FORMAT_R16_UINT &&471format != PIPE_FORMAT_R32_UINT)472return false;473bindings &= ~PIPE_BIND_INDEX_BUFFER;474}475476return (nv30_format_info(pscreen, format)->bindings & bindings) == bindings;477}478479static void480nv30_screen_fence_emit(struct pipe_screen *pscreen, uint32_t *sequence)481{482struct nv30_screen *screen = nv30_screen(pscreen);483struct nouveau_pushbuf *push = screen->base.pushbuf;484485*sequence = ++screen->base.fence.sequence;486487assert(PUSH_AVAIL(push) + push->rsvd_kick >= 3);488PUSH_DATA (push, NV30_3D_FENCE_OFFSET |489(2 /* size */ << 18) | (7 /* subchan */ << 13));490PUSH_DATA (push, 0);491PUSH_DATA (push, *sequence);492}493494static uint32_t495nv30_screen_fence_update(struct pipe_screen *pscreen)496{497struct nv30_screen *screen = nv30_screen(pscreen);498struct nv04_notify *fence = screen->fence->data;499return *(uint32_t *)((char *)screen->notify->map + fence->offset);500}501502static void503nv30_screen_destroy(struct pipe_screen *pscreen)504{505struct nv30_screen *screen = nv30_screen(pscreen);506507if (!nouveau_drm_screen_unref(&screen->base))508return;509510nouveau_fence_cleanup(&screen->base);511512nouveau_bo_ref(NULL, &screen->notify);513514nouveau_heap_destroy(&screen->query_heap);515nouveau_heap_destroy(&screen->vp_exec_heap);516nouveau_heap_destroy(&screen->vp_data_heap);517518nouveau_object_del(&screen->query);519nouveau_object_del(&screen->fence);520nouveau_object_del(&screen->ntfy);521522nouveau_object_del(&screen->sifm);523nouveau_object_del(&screen->swzsurf);524nouveau_object_del(&screen->surf2d);525nouveau_object_del(&screen->m2mf);526nouveau_object_del(&screen->eng3d);527nouveau_object_del(&screen->null);528529nouveau_screen_fini(&screen->base);530FREE(screen);531}532533#define FAIL_SCREEN_INIT(str, err) \534do { \535NOUVEAU_ERR(str, err); \536screen->base.base.context_create = NULL; \537return &screen->base; \538} while(0)539540struct nouveau_screen *541nv30_screen_create(struct nouveau_device *dev)542{543struct nv30_screen *screen;544struct pipe_screen *pscreen;545struct nouveau_pushbuf *push;546struct nv04_fifo *fifo;547unsigned oclass = 0;548int ret, i;549550switch (dev->chipset & 0xf0) {551case 0x30:552if (RANKINE_0397_CHIPSET & (1 << (dev->chipset & 0x0f)))553oclass = NV30_3D_CLASS;554else555if (RANKINE_0697_CHIPSET & (1 << (dev->chipset & 0x0f)))556oclass = NV34_3D_CLASS;557else558if (RANKINE_0497_CHIPSET & (1 << (dev->chipset & 0x0f)))559oclass = NV35_3D_CLASS;560break;561case 0x40:562if (CURIE_4097_CHIPSET & (1 << (dev->chipset & 0x0f)))563oclass = NV40_3D_CLASS;564else565if (CURIE_4497_CHIPSET & (1 << (dev->chipset & 0x0f)))566oclass = NV44_3D_CLASS;567break;568case 0x60:569if (CURIE_4497_CHIPSET6X & (1 << (dev->chipset & 0x0f)))570oclass = NV44_3D_CLASS;571break;572default:573break;574}575576if (!oclass) {577NOUVEAU_ERR("unknown 3d class for 0x%02x\n", dev->chipset);578return NULL;579}580581screen = CALLOC_STRUCT(nv30_screen);582if (!screen)583return NULL;584585pscreen = &screen->base.base;586pscreen->destroy = nv30_screen_destroy;587588/*589* Some modern apps try to use msaa without keeping in mind the590* restrictions on videomem of older cards. Resulting in dmesg saying:591* [ 1197.850642] nouveau E[soffice.bin[3785]] fail ttm_validate592* [ 1197.850648] nouveau E[soffice.bin[3785]] validating bo list593* [ 1197.850654] nouveau E[soffice.bin[3785]] validate: -12594*595* Because we are running out of video memory, after which the program596* using the msaa visual freezes, and eventually the entire system freezes.597*598* To work around this we do not allow msaa visauls by default and allow599* the user to override this via NV30_MAX_MSAA.600*/601screen->max_sample_count = debug_get_num_option("NV30_MAX_MSAA", 0);602if (screen->max_sample_count > 4)603screen->max_sample_count = 4;604605pscreen->get_param = nv30_screen_get_param;606pscreen->get_paramf = nv30_screen_get_paramf;607pscreen->get_shader_param = nv30_screen_get_shader_param;608pscreen->context_create = nv30_context_create;609pscreen->is_format_supported = nv30_screen_is_format_supported;610nv30_resource_screen_init(pscreen);611nouveau_screen_init_vdec(&screen->base);612613screen->base.fence.emit = nv30_screen_fence_emit;614screen->base.fence.update = nv30_screen_fence_update;615616ret = nouveau_screen_init(&screen->base, dev);617if (ret)618FAIL_SCREEN_INIT("nv30_screen_init failed: %d\n", ret);619620screen->base.vidmem_bindings |= PIPE_BIND_VERTEX_BUFFER;621screen->base.sysmem_bindings |= PIPE_BIND_VERTEX_BUFFER;622if (oclass == NV40_3D_CLASS) {623screen->base.vidmem_bindings |= PIPE_BIND_INDEX_BUFFER;624screen->base.sysmem_bindings |= PIPE_BIND_INDEX_BUFFER;625}626627fifo = screen->base.channel->data;628push = screen->base.pushbuf;629push->rsvd_kick = 16;630631ret = nouveau_object_new(screen->base.channel, 0x00000000, NV01_NULL_CLASS,632NULL, 0, &screen->null);633if (ret)634FAIL_SCREEN_INIT("error allocating null object: %d\n", ret);635636/* DMA_FENCE refuses to accept DMA objects with "adjust" filled in,637* this means that the address pointed at by the DMA object must638* be 4KiB aligned, which means this object needs to be the first639* one allocated on the channel.640*/641ret = nouveau_object_new(screen->base.channel, 0xbeef1e00,642NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {643.length = 32 }, sizeof(struct nv04_notify),644&screen->fence);645if (ret)646FAIL_SCREEN_INIT("error allocating fence notifier: %d\n", ret);647648/* DMA_NOTIFY object, we don't actually use this but M2MF fails without */649ret = nouveau_object_new(screen->base.channel, 0xbeef0301,650NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {651.length = 32 }, sizeof(struct nv04_notify),652&screen->ntfy);653if (ret)654FAIL_SCREEN_INIT("error allocating sync notifier: %d\n", ret);655656/* DMA_QUERY, used to implement occlusion queries, we attempt to allocate657* the remainder of the "notifier block" assigned by the kernel for658* use as query objects659*/660ret = nouveau_object_new(screen->base.channel, 0xbeef0351,661NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {662.length = 4096 - 128 }, sizeof(struct nv04_notify),663&screen->query);664if (ret)665FAIL_SCREEN_INIT("error allocating query notifier: %d\n", ret);666667ret = nouveau_heap_init(&screen->query_heap, 0, 4096 - 128);668if (ret)669FAIL_SCREEN_INIT("error creating query heap: %d\n", ret);670671list_inithead(&screen->queries);672673/* Vertex program resources (code/data), currently 6 of the constant674* slots are reserved to implement user clipping planes675*/676if (oclass < NV40_3D_CLASS) {677nouveau_heap_init(&screen->vp_exec_heap, 0, 256);678nouveau_heap_init(&screen->vp_data_heap, 6, 256 - 6);679} else {680nouveau_heap_init(&screen->vp_exec_heap, 0, 512);681nouveau_heap_init(&screen->vp_data_heap, 6, 468 - 6);682}683684ret = nouveau_bo_wrap(screen->base.device, fifo->notify, &screen->notify);685if (ret == 0)686ret = nouveau_bo_map(screen->notify, 0, screen->base.client);687if (ret)688FAIL_SCREEN_INIT("error mapping notifier memory: %d\n", ret);689690ret = nouveau_object_new(screen->base.channel, 0xbeef3097, oclass,691NULL, 0, &screen->eng3d);692if (ret)693FAIL_SCREEN_INIT("error allocating 3d object: %d\n", ret);694695BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);696PUSH_DATA (push, screen->eng3d->handle);697BEGIN_NV04(push, NV30_3D(DMA_NOTIFY), 13);698PUSH_DATA (push, screen->ntfy->handle);699PUSH_DATA (push, fifo->vram); /* TEXTURE0 */700PUSH_DATA (push, fifo->gart); /* TEXTURE1 */701PUSH_DATA (push, fifo->vram); /* COLOR1 */702PUSH_DATA (push, screen->null->handle); /* UNK190 */703PUSH_DATA (push, fifo->vram); /* COLOR0 */704PUSH_DATA (push, fifo->vram); /* ZETA */705PUSH_DATA (push, fifo->vram); /* VTXBUF0 */706PUSH_DATA (push, fifo->gart); /* VTXBUF1 */707PUSH_DATA (push, screen->fence->handle); /* FENCE */708PUSH_DATA (push, screen->query->handle); /* QUERY - intr 0x80 if nullobj */709PUSH_DATA (push, screen->null->handle); /* UNK1AC */710PUSH_DATA (push, screen->null->handle); /* UNK1B0 */711if (screen->eng3d->oclass < NV40_3D_CLASS) {712BEGIN_NV04(push, SUBC_3D(0x03b0), 1);713PUSH_DATA (push, 0x00100000);714BEGIN_NV04(push, SUBC_3D(0x1d80), 1);715PUSH_DATA (push, 3);716717BEGIN_NV04(push, SUBC_3D(0x1e98), 1);718PUSH_DATA (push, 0);719BEGIN_NV04(push, SUBC_3D(0x17e0), 3);720PUSH_DATA (push, fui(0.0));721PUSH_DATA (push, fui(0.0));722PUSH_DATA (push, fui(1.0));723BEGIN_NV04(push, SUBC_3D(0x1f80), 16);724for (i = 0; i < 16; i++)725PUSH_DATA (push, (i == 8) ? 0x0000ffff : 0);726727BEGIN_NV04(push, NV30_3D(RC_ENABLE), 1);728PUSH_DATA (push, 0);729} else {730BEGIN_NV04(push, NV40_3D(DMA_COLOR2), 2);731PUSH_DATA (push, fifo->vram);732PUSH_DATA (push, fifo->vram); /* COLOR3 */733734BEGIN_NV04(push, SUBC_3D(0x1450), 1);735PUSH_DATA (push, 0x00000004);736737BEGIN_NV04(push, SUBC_3D(0x1ea4), 3); /* ZCULL */738PUSH_DATA (push, 0x00000010);739PUSH_DATA (push, 0x01000100);740PUSH_DATA (push, 0xff800006);741742/* vtxprog output routing */743BEGIN_NV04(push, SUBC_3D(0x1fc4), 1);744PUSH_DATA (push, 0x06144321);745BEGIN_NV04(push, SUBC_3D(0x1fc8), 2);746PUSH_DATA (push, 0xedcba987);747PUSH_DATA (push, 0x0000006f);748BEGIN_NV04(push, SUBC_3D(0x1fd0), 1);749PUSH_DATA (push, 0x00171615);750BEGIN_NV04(push, SUBC_3D(0x1fd4), 1);751PUSH_DATA (push, 0x001b1a19);752753BEGIN_NV04(push, SUBC_3D(0x1ef8), 1);754PUSH_DATA (push, 0x0020ffff);755BEGIN_NV04(push, SUBC_3D(0x1d64), 1);756PUSH_DATA (push, 0x01d300d4);757758BEGIN_NV04(push, NV40_3D(MIPMAP_ROUNDING), 1);759PUSH_DATA (push, NV40_3D_MIPMAP_ROUNDING_MODE_DOWN);760}761762ret = nouveau_object_new(screen->base.channel, 0xbeef3901, NV03_M2MF_CLASS,763NULL, 0, &screen->m2mf);764if (ret)765FAIL_SCREEN_INIT("error allocating m2mf object: %d\n", ret);766767BEGIN_NV04(push, NV01_SUBC(M2MF, OBJECT), 1);768PUSH_DATA (push, screen->m2mf->handle);769BEGIN_NV04(push, NV03_M2MF(DMA_NOTIFY), 1);770PUSH_DATA (push, screen->ntfy->handle);771772ret = nouveau_object_new(screen->base.channel, 0xbeef6201,773NV10_SURFACE_2D_CLASS, NULL, 0, &screen->surf2d);774if (ret)775FAIL_SCREEN_INIT("error allocating surf2d object: %d\n", ret);776777BEGIN_NV04(push, NV01_SUBC(SF2D, OBJECT), 1);778PUSH_DATA (push, screen->surf2d->handle);779BEGIN_NV04(push, NV04_SF2D(DMA_NOTIFY), 1);780PUSH_DATA (push, screen->ntfy->handle);781782if (dev->chipset < 0x40)783oclass = NV30_SURFACE_SWZ_CLASS;784else785oclass = NV40_SURFACE_SWZ_CLASS;786787ret = nouveau_object_new(screen->base.channel, 0xbeef5201, oclass,788NULL, 0, &screen->swzsurf);789if (ret)790FAIL_SCREEN_INIT("error allocating swizzled surface object: %d\n", ret);791792BEGIN_NV04(push, NV01_SUBC(SSWZ, OBJECT), 1);793PUSH_DATA (push, screen->swzsurf->handle);794BEGIN_NV04(push, NV04_SSWZ(DMA_NOTIFY), 1);795PUSH_DATA (push, screen->ntfy->handle);796797if (dev->chipset < 0x40)798oclass = NV30_SIFM_CLASS;799else800oclass = NV40_SIFM_CLASS;801802ret = nouveau_object_new(screen->base.channel, 0xbeef7701, oclass,803NULL, 0, &screen->sifm);804if (ret)805FAIL_SCREEN_INIT("error allocating scaled image object: %d\n", ret);806807BEGIN_NV04(push, NV01_SUBC(SIFM, OBJECT), 1);808PUSH_DATA (push, screen->sifm->handle);809BEGIN_NV04(push, NV03_SIFM(DMA_NOTIFY), 1);810PUSH_DATA (push, screen->ntfy->handle);811BEGIN_NV04(push, NV05_SIFM(COLOR_CONVERSION), 1);812PUSH_DATA (push, NV05_SIFM_COLOR_CONVERSION_TRUNCATE);813814nouveau_pushbuf_kick(push, push->channel);815816nouveau_fence_new(&screen->base, &screen->base.fence.current);817return &screen->base;818}819820821