nv30_screen.c 28.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * Copyright 2012 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 18 19 20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
21 22 23 24 25
 *
 * Authors: Ben Skeggs
 *
 */

26 27
#include <xf86drm.h>
#include <nouveau_drm.h>
28
#include "util/u_format.h"
29 30
#include "util/u_format_s3tc.h"

31 32 33 34
#include "nv_object.xml.h"
#include "nv_m2mf.xml.h"
#include "nv30/nv30-40_3d.xml.h"
#include "nv30/nv01_2d.xml.h"
35

36 37 38 39 40
#include "nouveau_fence.h"
#include "nv30/nv30_screen.h"
#include "nv30/nv30_context.h"
#include "nv30/nv30_resource.h"
#include "nv30/nv30_format.h"
41 42 43 44 45 46 47 48 49 50 51 52 53

#define RANKINE_0397_CHIPSET 0x00000003
#define RANKINE_0497_CHIPSET 0x000001e0
#define RANKINE_0697_CHIPSET 0x00000010
#define CURIE_4097_CHIPSET   0x00000baf
#define CURIE_4497_CHIPSET   0x00005450
#define CURIE_4497_CHIPSET6X 0x00000088

static int
nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
{
   struct nv30_screen *screen = nv30_screen(pscreen);
   struct nouveau_object *eng3d = screen->eng3d;
54
   struct nouveau_device *dev = nouveau_screen(pscreen)->device;
55 56 57 58 59 60 61 62 63 64 65 66

   switch (param) {
   /* non-boolean capabilities */
   case PIPE_CAP_MAX_RENDER_TARGETS:
      return (eng3d->oclass >= NV40_3D_CLASS) ? 4 : 1;
   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
      return 13;
   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
      return 10;
   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
      return 13;
   case PIPE_CAP_GLSL_FEATURE_LEVEL:
67
   case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
68
      return 120;
69 70 71 72
   case PIPE_CAP_ENDIANNESS:
      return PIPE_ENDIAN_LITTLE;
   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
      return 16;
73 74
   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
      return NOUVEAU_MIN_BUFFER_MAP_ALIGN;
75 76
   case PIPE_CAP_MAX_VIEWPORTS:
      return 1;
77 78
   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
      return 2048;
79 80 81 82
   /* supported capabilities */
   case PIPE_CAP_ANISOTROPIC_FILTER:
   case PIPE_CAP_POINT_SPRITE:
   case PIPE_CAP_OCCLUSION_QUERY:
83
   case PIPE_CAP_QUERY_TIME_ELAPSED:
84
   case PIPE_CAP_QUERY_TIMESTAMP:
85 86 87 88 89 90
   case PIPE_CAP_TEXTURE_SWIZZLE:
   case PIPE_CAP_DEPTH_CLIP_DISABLE:
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
91
   case PIPE_CAP_TGSI_TEXCOORD:
92
   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
93 94 95 96
   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
97
   case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
98
      return 1;
99 100 101
   /* nv35 capabilities */
   case PIPE_CAP_DEPTH_BOUNDS_TEST:
      return eng3d->oclass == NV35_3D_CLASS || eng3d->oclass >= NV40_3D_CLASS;
102 103 104 105 106 107 108 109
   /* nv4x capabilities */
   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
   case PIPE_CAP_NPOT_TEXTURES:
   case PIPE_CAP_CONDITIONAL_RENDER:
   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
   case PIPE_CAP_PRIMITIVE_RESTART:
      return (eng3d->oclass >= NV40_3D_CLASS) ? 1 : 0;
   /* unsupported */
110
   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
111 112 113 114 115 116 117 118 119
   case PIPE_CAP_SM3:
   case PIPE_CAP_INDEP_BLEND_ENABLE:
   case PIPE_CAP_INDEP_BLEND_FUNC:
   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
   case PIPE_CAP_SHADER_STENCIL_EXPORT:
   case PIPE_CAP_TGSI_INSTANCEID:
   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: /* XXX: yes? */
   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
120
   case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
121 122
   case PIPE_CAP_MIN_TEXEL_OFFSET:
   case PIPE_CAP_MAX_TEXEL_OFFSET:
123 124
   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
125 126
   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
127 128
   case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
   case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
129
   case PIPE_CAP_MAX_VERTEX_STREAMS:
130 131 132 133
   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
   case PIPE_CAP_TEXTURE_BARRIER:
   case PIPE_CAP_SEAMLESS_CUBE_MAP:
   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
134
   case PIPE_CAP_CUBE_MAP_ARRAY:
135
   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
136 137
   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
138 139
   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
140
   case PIPE_CAP_START_INSTANCE:
141
   case PIPE_CAP_TEXTURE_MULTISAMPLE:
142
   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
143
   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
144
   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
145
   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
146
   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
147
   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
148
   case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
149 150
   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
   case PIPE_CAP_TEXTURE_GATHER_SM5:
151
   case PIPE_CAP_FAKE_SW_MSAA:
152
   case PIPE_CAP_TEXTURE_QUERY_LOD:
153
   case PIPE_CAP_SAMPLE_SHADING:
154
   case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
155
   case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
156 157
   case PIPE_CAP_USER_VERTEX_BUFFERS:
   case PIPE_CAP_COMPUTE:
158
   case PIPE_CAP_DRAW_INDIRECT:
159 160
   case PIPE_CAP_MULTI_DRAW_INDIRECT:
   case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
161
   case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
162
   case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
163
   case PIPE_CAP_SAMPLER_VIEW_TARGET:
164
   case PIPE_CAP_CLIP_HALFZ:
165
   case PIPE_CAP_VERTEXID_NOBASE:
166
   case PIPE_CAP_POLYGON_OFFSET_CLAMP:
167
   case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
168
   case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
169
   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
170
   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
171 172
   case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
   case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
173
   case PIPE_CAP_TGSI_TXQS:
174
   case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
175
   case PIPE_CAP_SHAREABLE_SHADERS:
176
   case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
177
   case PIPE_CAP_CLEAR_TEXTURE:
178
   case PIPE_CAP_DRAW_PARAMETERS:
179
   case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
180 181
   case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
   case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
182
   case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
183
   case PIPE_CAP_INVALIDATE_BUFFER:
184
   case PIPE_CAP_GENERATE_MIPMAP:
Rob Clark's avatar
Rob Clark committed
185
   case PIPE_CAP_STRING_MARKER:
186
   case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
187
   case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
188
   case PIPE_CAP_QUERY_BUFFER_OBJECT:
189
   case PIPE_CAP_QUERY_MEMORY_INFO:
190 191 192 193
   case PIPE_CAP_PCI_GROUP:
   case PIPE_CAP_PCI_BUS:
   case PIPE_CAP_PCI_DEVICE:
   case PIPE_CAP_PCI_FUNCTION:
194
   case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
195
   case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
196
   case PIPE_CAP_CULL_DISTANCE:
197
   case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
198
   case PIPE_CAP_TGSI_VOTE:
199
   case PIPE_CAP_MAX_WINDOW_RECTANGLES:
200
   case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
201
   case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
202
   case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
203
   case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
204
   case PIPE_CAP_TGSI_CAN_READ_OUTPUTS:
205
   case PIPE_CAP_NATIVE_FENCE_FD:
206
   case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
207
   case PIPE_CAP_TGSI_FS_FBFETCH:
208
   case PIPE_CAP_TGSI_MUL_ZERO_WINS:
209
   case PIPE_CAP_DOUBLES:
210
   case PIPE_CAP_INT64:
211
   case PIPE_CAP_INT64_DIVMOD:
212
   case PIPE_CAP_TGSI_TEX_TXF_LZ:
213
   case PIPE_CAP_TGSI_CLOCK:
214
   case PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE:
215
   case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE:
216
   case PIPE_CAP_TGSI_BALLOT:
217
   case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT:
218
   case PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX:
219
   case PIPE_CAP_POST_DEPTH_COVERAGE:
220
   case PIPE_CAP_BINDLESS_TEXTURE:
221
   case PIPE_CAP_NIR_SAMPLERS_AS_DEREF:
222
   case PIPE_CAP_QUERY_SO_OVERFLOW:
223
   case PIPE_CAP_MEMOBJ:
224
   case PIPE_CAP_LOAD_CONSTBUF:
225
   case PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS:
226
   case PIPE_CAP_TILE_RASTER_ORDER:
227
   case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
228
   case PIPE_CAP_FRAMEBUFFER_MSAA_CONSTRAINTS:
229
   case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET:
230
   case PIPE_CAP_CONTEXT_PRIORITY_MASK:
231
   case PIPE_CAP_FENCE_SIGNAL:
232
   case PIPE_CAP_CONSTBUF0_FLAGS:
233
   case PIPE_CAP_PACKED_UNIFORMS:
234 235 236 237 238 239
   case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_TRIANGLES:
   case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_POINTS_LINES:
   case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_TRIANGLES:
   case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES:
   case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE:
   case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS:
240
   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
241
      return 0;
242

243 244
   case PIPE_CAP_MAX_GS_INVOCATIONS:
      return 32;
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
   case PIPE_CAP_VENDOR_ID:
      return 0x10de;
   case PIPE_CAP_DEVICE_ID: {
      uint64_t device_id;
      if (nouveau_getparam(dev, NOUVEAU_GETPARAM_PCI_DEVICE, &device_id)) {
         NOUVEAU_ERR("NOUVEAU_GETPARAM_PCI_DEVICE failed.\n");
         return -1;
      }
      return device_id;
   }
   case PIPE_CAP_ACCELERATED:
      return 1;
   case PIPE_CAP_VIDEO_MEMORY:
      return dev->vram_size >> 20;
   case PIPE_CAP_UMA:
      return 0;
261
   }
262 263 264

   debug_printf("unknown param %d\n", param);
   return 0;
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
}

static float
nv30_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
{
   struct nv30_screen *screen = nv30_screen(pscreen);
   struct nouveau_object *eng3d = screen->eng3d;

   switch (param) {
   case PIPE_CAPF_MAX_LINE_WIDTH:
   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
      return 10.0;
   case PIPE_CAPF_MAX_POINT_WIDTH:
   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
      return 64.0;
   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
      return (eng3d->oclass >= NV40_3D_CLASS) ? 16.0 : 8.0;
   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
      return 15.0;
284 285 286 287
   case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
   case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
   case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
      return 0.0;
288 289 290 291 292 293 294
   default:
      debug_printf("unknown paramf %d\n", param);
      return 0;
   }
}

static int
295 296
nv30_screen_get_shader_param(struct pipe_screen *pscreen,
                             enum pipe_shader_type shader,
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
                             enum pipe_shader_cap param)
{
   struct nv30_screen *screen = nv30_screen(pscreen);
   struct nouveau_object *eng3d = screen->eng3d;

   switch (shader) {
   case PIPE_SHADER_VERTEX:
      switch (param) {
      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
         return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 256;
      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
         return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 0;
      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
         return 0;
      case PIPE_SHADER_CAP_MAX_INPUTS:
314
      case PIPE_SHADER_CAP_MAX_OUTPUTS:
315
         return 16;
316 317
      case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
         return ((eng3d->oclass >= NV40_3D_CLASS) ? (468 - 6): (256 - 6)) * sizeof(float[4]);
318 319 320 321
      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
         return 1;
      case PIPE_SHADER_CAP_MAX_TEMPS:
         return (eng3d->oclass >= NV40_3D_CLASS) ? 32 : 13;
322 323 324 325
      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
         return 32;
      case PIPE_SHADER_CAP_PREFERRED_IR:
         return PIPE_SHADER_IR_TGSI;
326
      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
327
      case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
328 329
         return 0;
      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
330
      case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
331 332 333 334 335 336
      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
      case PIPE_SHADER_CAP_SUBROUTINES:
      case PIPE_SHADER_CAP_INTEGERS:
337
      case PIPE_SHADER_CAP_INT64_ATOMICS:
Jan Vesely's avatar
Jan Vesely committed
338
      case PIPE_SHADER_CAP_FP16:
339 340
      case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
      case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
341
      case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
342
      case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
343
      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
344
      case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
345
      case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
346
      case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
347
      case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
348 349
      case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
      case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
350
      case PIPE_SHADER_CAP_SCALAR_ISA:
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
         return 0;
      default:
         debug_printf("unknown vertex shader param %d\n", param);
         return 0;
      }
      break;
   case PIPE_SHADER_FRAGMENT:
      switch (param) {
      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
         return 4096;
      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
         return 0;
      case PIPE_SHADER_CAP_MAX_INPUTS:
Ilia Mirkin's avatar
Ilia Mirkin committed
367
         return 8; /* should be possible to do 10 with nv4x */
368 369
      case PIPE_SHADER_CAP_MAX_OUTPUTS:
         return 4;
370 371
      case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
         return ((eng3d->oclass >= NV40_3D_CLASS) ? 224 : 32) * sizeof(float[4]);
372 373 374 375 376
      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
         return 1;
      case PIPE_SHADER_CAP_MAX_TEMPS:
         return 32;
      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
377
      case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
378
         return 16;
379 380 381 382
      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
         return 32;
      case PIPE_SHADER_CAP_PREFERRED_IR:
         return PIPE_SHADER_IR_TGSI;
383
      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
384
      case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
385 386 387 388 389
      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
      case PIPE_SHADER_CAP_SUBROUTINES:
390
      case PIPE_SHADER_CAP_INTEGERS:
Jan Vesely's avatar
Jan Vesely committed
391
      case PIPE_SHADER_CAP_FP16:
392 393
      case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
      case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
394
      case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
395
      case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
396
      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
397
      case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
398
      case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
399
      case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
400
      case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
401 402
      case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
      case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
403
      case PIPE_SHADER_CAP_SCALAR_ISA:
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
         return 0;
      default:
         debug_printf("unknown fragment shader param %d\n", param);
         return 0;
      }
      break;
   default:
      return 0;
   }
}

static boolean
nv30_screen_is_format_supported(struct pipe_screen *pscreen,
                                enum pipe_format format,
                                enum pipe_texture_target target,
                                unsigned sample_count,
420
                                unsigned storage_sample_count,
421 422
                                unsigned bindings)
{
423
   if (sample_count > nv30_screen(pscreen)->max_sample_count)
424
      return false;
425

426
   if (!(0x00000017 & (1 << sample_count)))
427
      return false;
428

429 430 431
   if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
      return false;

432 433
   /* shared is always supported */
   bindings &= ~PIPE_BIND_SHARED;
434 435 436 437 438 439 440 441 442 443 444 445

   return (nv30_format_info(pscreen, format)->bindings & bindings) == bindings;
}

static void
nv30_screen_fence_emit(struct pipe_screen *pscreen, uint32_t *sequence)
{
   struct nv30_screen *screen = nv30_screen(pscreen);
   struct nouveau_pushbuf *push = screen->base.pushbuf;

   *sequence = ++screen->base.fence.sequence;

446
   assert(PUSH_AVAIL(push) + push->rsvd_kick >= 3);
447 448
   PUSH_DATA (push, NV30_3D_FENCE_OFFSET |
              (2 /* size */ << 18) | (7 /* subchan */ << 13));
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
   PUSH_DATA (push, 0);
   PUSH_DATA (push, *sequence);
}

static uint32_t
nv30_screen_fence_update(struct pipe_screen *pscreen)
{
   struct nv30_screen *screen = nv30_screen(pscreen);
   struct nv04_notify *fence = screen->fence->data;
   return *(uint32_t *)((char *)screen->notify->map + fence->offset);
}

static void
nv30_screen_destroy(struct pipe_screen *pscreen)
{
   struct nv30_screen *screen = nv30_screen(pscreen);

466 467 468
   if (!nouveau_drm_screen_unref(&screen->base))
      return;

469 470 471 472 473 474 475
   if (screen->base.fence.current) {
      struct nouveau_fence *current = NULL;

      /* nouveau_fence_wait will create a new current fence, so wait on the
       * _current_ one, and remove both.
       */
      nouveau_fence_ref(screen->base.fence.current, &current);
476
      nouveau_fence_wait(current, NULL);
477 478
      nouveau_fence_ref(NULL, &current);
      nouveau_fence_ref(NULL, &screen->base.fence.current);
479 480
   }

481 482 483 484 485 486
   nouveau_bo_ref(NULL, &screen->notify);

   nouveau_heap_destroy(&screen->query_heap);
   nouveau_heap_destroy(&screen->vp_exec_heap);
   nouveau_heap_destroy(&screen->vp_data_heap);

487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504
   nouveau_object_del(&screen->query);
   nouveau_object_del(&screen->fence);
   nouveau_object_del(&screen->ntfy);

   nouveau_object_del(&screen->sifm);
   nouveau_object_del(&screen->swzsurf);
   nouveau_object_del(&screen->surf2d);
   nouveau_object_del(&screen->m2mf);
   nouveau_object_del(&screen->eng3d);
   nouveau_object_del(&screen->null);

   nouveau_screen_fini(&screen->base);
   FREE(screen);
}

#define FAIL_SCREEN_INIT(str, err)                    \
   do {                                               \
      NOUVEAU_ERR(str, err);                          \
505 506
      screen->base.base.context_create = NULL;        \
      return &screen->base;                           \
507 508
   } while(0)

509
struct nouveau_screen *
510 511
nv30_screen_create(struct nouveau_device *dev)
{
512
   struct nv30_screen *screen;
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
   struct pipe_screen *pscreen;
   struct nouveau_pushbuf *push;
   struct nv04_fifo *fifo;
   unsigned oclass = 0;
   int ret, i;

   switch (dev->chipset & 0xf0) {
   case 0x30:
      if (RANKINE_0397_CHIPSET & (1 << (dev->chipset & 0x0f)))
         oclass = NV30_3D_CLASS;
      else
      if (RANKINE_0697_CHIPSET & (1 << (dev->chipset & 0x0f)))
         oclass = NV34_3D_CLASS;
      else
      if (RANKINE_0497_CHIPSET & (1 << (dev->chipset & 0x0f)))
         oclass = NV35_3D_CLASS;
      break;
   case 0x40:
      if (CURIE_4097_CHIPSET & (1 << (dev->chipset & 0x0f)))
         oclass = NV40_3D_CLASS;
      else
      if (CURIE_4497_CHIPSET & (1 << (dev->chipset & 0x0f)))
         oclass = NV44_3D_CLASS;
      break;
   case 0x60:
      if (CURIE_4497_CHIPSET6X & (1 << (dev->chipset & 0x0f)))
         oclass = NV44_3D_CLASS;
      break;
   default:
      break;
   }

   if (!oclass) {
      NOUVEAU_ERR("unknown 3d class for 0x%02x\n", dev->chipset);
      return NULL;
   }

550 551 552 553 554 555 556
   screen = CALLOC_STRUCT(nv30_screen);
   if (!screen)
      return NULL;

   pscreen = &screen->base.base;
   pscreen->destroy = nv30_screen_destroy;

557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
   /*
    * Some modern apps try to use msaa without keeping in mind the
    * restrictions on videomem of older cards. Resulting in dmesg saying:
    * [ 1197.850642] nouveau E[soffice.bin[3785]] fail ttm_validate
    * [ 1197.850648] nouveau E[soffice.bin[3785]] validating bo list
    * [ 1197.850654] nouveau E[soffice.bin[3785]] validate: -12
    *
    * Because we are running out of video memory, after which the program
    * using the msaa visual freezes, and eventually the entire system freezes.
    *
    * To work around this we do not allow msaa visauls by default and allow
    * the user to override this via NV30_MAX_MSAA.
    */
   screen->max_sample_count = debug_get_num_option("NV30_MAX_MSAA", 0);
   if (screen->max_sample_count > 4)
      screen->max_sample_count = 4;

574 575 576 577 578 579
   pscreen->get_param = nv30_screen_get_param;
   pscreen->get_paramf = nv30_screen_get_paramf;
   pscreen->get_shader_param = nv30_screen_get_shader_param;
   pscreen->context_create = nv30_context_create;
   pscreen->is_format_supported = nv30_screen_is_format_supported;
   nv30_resource_screen_init(pscreen);
580
   nouveau_screen_init_vdec(&screen->base);
581 582 583 584 585 586 587 588

   screen->base.fence.emit = nv30_screen_fence_emit;
   screen->base.fence.update = nv30_screen_fence_update;

   ret = nouveau_screen_init(&screen->base, dev);
   if (ret)
      FAIL_SCREEN_INIT("nv30_screen_init failed: %d\n", ret);

589 590 591 592 593 594 595
   screen->base.vidmem_bindings |= PIPE_BIND_VERTEX_BUFFER;
   screen->base.sysmem_bindings |= PIPE_BIND_VERTEX_BUFFER;
   if (oclass == NV40_3D_CLASS) {
      screen->base.vidmem_bindings |= PIPE_BIND_INDEX_BUFFER;
      screen->base.sysmem_bindings |= PIPE_BIND_INDEX_BUFFER;
   }

596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
   fifo = screen->base.channel->data;
   push = screen->base.pushbuf;
   push->rsvd_kick = 16;

   ret = nouveau_object_new(screen->base.channel, 0x00000000, NV01_NULL_CLASS,
                            NULL, 0, &screen->null);
   if (ret)
      FAIL_SCREEN_INIT("error allocating null object: %d\n", ret);

   /* DMA_FENCE refuses to accept DMA objects with "adjust" filled in,
    * this means that the address pointed at by the DMA object must
    * be 4KiB aligned, which means this object needs to be the first
    * one allocated on the channel.
    */
   ret = nouveau_object_new(screen->base.channel, 0xbeef1e00,
                            NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {
                            .length = 32 }, sizeof(struct nv04_notify),
                            &screen->fence);
   if (ret)
      FAIL_SCREEN_INIT("error allocating fence notifier: %d\n", ret);

   /* DMA_NOTIFY object, we don't actually use this but M2MF fails without */
   ret = nouveau_object_new(screen->base.channel, 0xbeef0301,
                            NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {
                            .length = 32 }, sizeof(struct nv04_notify),
                            &screen->ntfy);
   if (ret)
      FAIL_SCREEN_INIT("error allocating sync notifier: %d\n", ret);

   /* DMA_QUERY, used to implement occlusion queries, we attempt to allocate
    * the remainder of the "notifier block" assigned by the kernel for
    * use as query objects
    */
   ret = nouveau_object_new(screen->base.channel, 0xbeef0351,
                            NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) {
                            .length = 4096 - 128 }, sizeof(struct nv04_notify),
                            &screen->query);
   if (ret)
      FAIL_SCREEN_INIT("error allocating query notifier: %d\n", ret);

   ret = nouveau_heap_init(&screen->query_heap, 0, 4096 - 128);
   if (ret)
      FAIL_SCREEN_INIT("error creating query heap: %d\n", ret);

   LIST_INITHEAD(&screen->queries);

   /* Vertex program resources (code/data), currently 6 of the constant
    * slots are reserved to implement user clipping planes
    */
   if (oclass < NV40_3D_CLASS) {
      nouveau_heap_init(&screen->vp_exec_heap, 0, 256);
      nouveau_heap_init(&screen->vp_data_heap, 6, 256 - 6);
   } else {
      nouveau_heap_init(&screen->vp_exec_heap, 0, 512);
      nouveau_heap_init(&screen->vp_data_heap, 6, 468 - 6);
   }

   ret = nouveau_bo_wrap(screen->base.device, fifo->notify, &screen->notify);
   if (ret == 0)
655
      ret = nouveau_bo_map(screen->notify, 0, screen->base.client);
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
   if (ret)
      FAIL_SCREEN_INIT("error mapping notifier memory: %d\n", ret);

   ret = nouveau_object_new(screen->base.channel, 0xbeef3097, oclass,
                            NULL, 0, &screen->eng3d);
   if (ret)
      FAIL_SCREEN_INIT("error allocating 3d object: %d\n", ret);

   BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1);
   PUSH_DATA (push, screen->eng3d->handle);
   BEGIN_NV04(push, NV30_3D(DMA_NOTIFY), 13);
   PUSH_DATA (push, screen->ntfy->handle);
   PUSH_DATA (push, fifo->vram);     /* TEXTURE0 */
   PUSH_DATA (push, fifo->gart);     /* TEXTURE1 */
   PUSH_DATA (push, fifo->vram);     /* COLOR1 */
   PUSH_DATA (push, screen->null->handle);  /* UNK190 */
   PUSH_DATA (push, fifo->vram);     /* COLOR0 */
   PUSH_DATA (push, fifo->vram);     /* ZETA */
   PUSH_DATA (push, fifo->vram);     /* VTXBUF0 */
   PUSH_DATA (push, fifo->gart);     /* VTXBUF1 */
   PUSH_DATA (push, screen->fence->handle);  /* FENCE */
   PUSH_DATA (push, screen->query->handle);  /* QUERY - intr 0x80 if nullobj */
   PUSH_DATA (push, screen->null->handle);  /* UNK1AC */
   PUSH_DATA (push, screen->null->handle);  /* UNK1B0 */
   if (screen->eng3d->oclass < NV40_3D_CLASS) {
      BEGIN_NV04(push, SUBC_3D(0x03b0), 1);
      PUSH_DATA (push, 0x00100000);
      BEGIN_NV04(push, SUBC_3D(0x1d80), 1);
      PUSH_DATA (push, 3);

      BEGIN_NV04(push, SUBC_3D(0x1e98), 1);
      PUSH_DATA (push, 0);
      BEGIN_NV04(push, SUBC_3D(0x17e0), 3);
      PUSH_DATA (push, fui(0.0));
      PUSH_DATA (push, fui(0.0));
      PUSH_DATA (push, fui(1.0));
      BEGIN_NV04(push, SUBC_3D(0x1f80), 16);
      for (i = 0; i < 16; i++)
         PUSH_DATA (push, (i == 8) ? 0x0000ffff : 0);

      BEGIN_NV04(push, NV30_3D(RC_ENABLE), 1);
      PUSH_DATA (push, 0);
   } else {
      BEGIN_NV04(push, NV40_3D(DMA_COLOR2), 2);
      PUSH_DATA (push, fifo->vram);
      PUSH_DATA (push, fifo->vram);  /* COLOR3 */

      BEGIN_NV04(push, SUBC_3D(0x1450), 1);
      PUSH_DATA (push, 0x00000004);

      BEGIN_NV04(push, SUBC_3D(0x1ea4), 3); /* ZCULL */
      PUSH_DATA (push, 0x00000010);
      PUSH_DATA (push, 0x01000100);
      PUSH_DATA (push, 0xff800006);

      /* vtxprog output routing */
      BEGIN_NV04(push, SUBC_3D(0x1fc4), 1);
      PUSH_DATA (push, 0x06144321);
      BEGIN_NV04(push, SUBC_3D(0x1fc8), 2);
      PUSH_DATA (push, 0xedcba987);
      PUSH_DATA (push, 0x0000006f);
      BEGIN_NV04(push, SUBC_3D(0x1fd0), 1);
      PUSH_DATA (push, 0x00171615);
      BEGIN_NV04(push, SUBC_3D(0x1fd4), 1);
      PUSH_DATA (push, 0x001b1a19);

      BEGIN_NV04(push, SUBC_3D(0x1ef8), 1);
      PUSH_DATA (push, 0x0020ffff);
      BEGIN_NV04(push, SUBC_3D(0x1d64), 1);
      PUSH_DATA (push, 0x01d300d4);

      BEGIN_NV04(push, NV40_3D(MIPMAP_ROUNDING), 1);
      PUSH_DATA (push, NV40_3D_MIPMAP_ROUNDING_MODE_DOWN);
   }

   ret = nouveau_object_new(screen->base.channel, 0xbeef3901, NV03_M2MF_CLASS,
                            NULL, 0, &screen->m2mf);
   if (ret)
      FAIL_SCREEN_INIT("error allocating m2mf object: %d\n", ret);

   BEGIN_NV04(push, NV01_SUBC(M2MF, OBJECT), 1);
   PUSH_DATA (push, screen->m2mf->handle);
   BEGIN_NV04(push, NV03_M2MF(DMA_NOTIFY), 1);
   PUSH_DATA (push, screen->ntfy->handle);

   ret = nouveau_object_new(screen->base.channel, 0xbeef6201,
                            NV10_SURFACE_2D_CLASS, NULL, 0, &screen->surf2d);
   if (ret)
      FAIL_SCREEN_INIT("error allocating surf2d object: %d\n", ret);

   BEGIN_NV04(push, NV01_SUBC(SF2D, OBJECT), 1);
   PUSH_DATA (push, screen->surf2d->handle);
   BEGIN_NV04(push, NV04_SF2D(DMA_NOTIFY), 1);
   PUSH_DATA (push, screen->ntfy->handle);

   if (dev->chipset < 0x40)
      oclass = NV30_SURFACE_SWZ_CLASS;
   else
      oclass = NV40_SURFACE_SWZ_CLASS;

   ret = nouveau_object_new(screen->base.channel, 0xbeef5201, oclass,
                            NULL, 0, &screen->swzsurf);
   if (ret)
      FAIL_SCREEN_INIT("error allocating swizzled surface object: %d\n", ret);

   BEGIN_NV04(push, NV01_SUBC(SSWZ, OBJECT), 1);
   PUSH_DATA (push, screen->swzsurf->handle);
   BEGIN_NV04(push, NV04_SSWZ(DMA_NOTIFY), 1);
   PUSH_DATA (push, screen->ntfy->handle);

   if (dev->chipset < 0x40)
      oclass = NV30_SIFM_CLASS;
   else
      oclass = NV40_SIFM_CLASS;

   ret = nouveau_object_new(screen->base.channel, 0xbeef7701, oclass,
                            NULL, 0, &screen->sifm);
   if (ret)
      FAIL_SCREEN_INIT("error allocating scaled image object: %d\n", ret);

   BEGIN_NV04(push, NV01_SUBC(SIFM, OBJECT), 1);
   PUSH_DATA (push, screen->sifm->handle);
   BEGIN_NV04(push, NV03_SIFM(DMA_NOTIFY), 1);
   PUSH_DATA (push, screen->ntfy->handle);
   BEGIN_NV04(push, NV05_SIFM(COLOR_CONVERSION), 1);
   PUSH_DATA (push, NV05_SIFM_COLOR_CONVERSION_TRUNCATE);

   nouveau_pushbuf_kick(push, push->channel);

785
   nouveau_fence_new(&screen->base, &screen->base.fence.current);
786
   return &screen->base;
787
}