svga_screen.c 32.8 KB
Newer Older
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/**********************************************************
 * Copyright 2008-2009 VMware, Inc.  All rights reserved.
 *
 * 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 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.
 *
 **********************************************************/

26
#include "util/u_format.h"
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
27
#include "util/u_memory.h"
28
#include "util/u_inlines.h"
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
29 30 31 32
#include "util/u_string.h"
#include "util/u_math.h"

#include "svga_winsys.h"
33
#include "svga_public.h"
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
34
#include "svga_context.h"
35
#include "svga_format.h"
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
36
#include "svga_screen.h"
37
#include "svga_tgsi.h"
38 39
#include "svga_resource_texture.h"
#include "svga_resource.h"
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
40 41 42
#include "svga_debug.h"

#include "svga3d_shaderdefs.h"
43
#include "VGPU10ShaderTokens.h"
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
44

45 46
/* NOTE: this constant may get moved into a svga3d*.h header file */
#define SVGA3D_DX_MAX_RESOURCE_SIZE (128 * 1024 * 1024)
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
47 48 49 50 51

#ifdef DEBUG
int SVGA_DEBUG = 0;

static const struct debug_named_value svga_debug_flags[] = {
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
   { "dma",         DEBUG_DMA, NULL },
   { "tgsi",        DEBUG_TGSI, NULL },
   { "pipe",        DEBUG_PIPE, NULL },
   { "state",       DEBUG_STATE, NULL },
   { "screen",      DEBUG_SCREEN, NULL },
   { "tex",         DEBUG_TEX, NULL },
   { "swtnl",       DEBUG_SWTNL, NULL },
   { "const",       DEBUG_CONSTS, NULL },
   { "viewport",    DEBUG_VIEWPORT, NULL },
   { "views",       DEBUG_VIEWS, NULL },
   { "perf",        DEBUG_PERF, NULL },
   { "flush",       DEBUG_FLUSH, NULL },
   { "sync",        DEBUG_SYNC, NULL },
   { "cache",       DEBUG_CACHE, NULL },
   { "streamout",   DEBUG_STREAMOUT, NULL },
   { "query",       DEBUG_QUERY, NULL },
68
   DEBUG_NAMED_VALUE_END
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
69 70 71 72 73 74 75 76 77 78 79 80 81
};
#endif

static const char *
svga_get_vendor( struct pipe_screen *pscreen )
{
   return "VMware, Inc.";
}


static const char *
svga_get_name( struct pipe_screen *pscreen )
{
82 83
   const char *build = "", *llvm = "", *mutex = "";
   static char name[100];
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
84 85 86
#ifdef DEBUG
   /* Only return internal details in the DEBUG version:
    */
87 88
   build = "build: DEBUG;";
   mutex = "mutex: " PIPE_ATOMIC ";";
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
89
#else
90
   build = "build: RELEASE;";
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
91
#endif
92 93 94
#ifdef HAVE_LLVM
   llvm = "LLVM;";
#endif
95 96 97

   util_snprintf(name, sizeof(name), "SVGA3D; %s %s %s", build, mutex, llvm);
   return name;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
98 99 100
}


101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
/** Helper for querying float-valued device cap */
static float
get_float_cap(struct svga_winsys_screen *sws, unsigned cap, float defaultVal)
{
   SVGA3dDevCapResult result;
   if (sws->get_cap(sws, cap, &result))
      return result.f;
   else
      return defaultVal;
}


/** Helper for querying uint-valued device cap */
static unsigned
get_uint_cap(struct svga_winsys_screen *sws, unsigned cap, unsigned defaultVal)
{
   SVGA3dDevCapResult result;
   if (sws->get_cap(sws, cap, &result))
      return result.u;
   else
      return defaultVal;
}


/** Helper for querying boolean-valued device cap */
static boolean
get_bool_cap(struct svga_winsys_screen *sws, unsigned cap, boolean defaultVal)
{
   SVGA3dDevCapResult result;
   if (sws->get_cap(sws, cap, &result))
      return result.b;
   else
      return defaultVal;
}
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
135 136 137


static float
138
svga_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
139 140 141 142 143
{
   struct svga_screen *svgascreen = svga_screen(screen);
   struct svga_winsys_screen *sws = svgascreen->sws;

   switch (param) {
144
   case PIPE_CAPF_MAX_LINE_WIDTH:
145
      return svgascreen->maxLineWidth;
146
   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
147
      return svgascreen->maxLineWidthAA;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
148

149
   case PIPE_CAPF_MAX_POINT_WIDTH:
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
150
      /* fall-through */
151
   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
152
      return svgascreen->maxPointSize;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
153

154
   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
155
      return (float) get_uint_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, 4);
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
156

157
   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
158
      return 15.0;
159

160 161 162 163 164
   case PIPE_CAPF_GUARD_BAND_LEFT:
   case PIPE_CAPF_GUARD_BAND_TOP:
   case PIPE_CAPF_GUARD_BAND_RIGHT:
   case PIPE_CAPF_GUARD_BAND_BOTTOM:
      return 0.0;
165
   }
166 167 168

   debug_printf("Unexpected PIPE_CAPF_ query %u\n", param);
   return 0;
169 170 171 172 173 174 175 176 177 178 179
}


static int
svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
{
   struct svga_screen *svgascreen = svga_screen(screen);
   struct svga_winsys_screen *sws = svgascreen->sws;
   SVGA3dDevCapResult result;

   switch (param) {
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
180
   case PIPE_CAP_NPOT_TEXTURES:
181
   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
182 183 184
      return 1;
   case PIPE_CAP_TWO_SIDED_STENCIL:
      return 1;
185
   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
186 187 188 189 190 191
      /*
       * "In virtually every OpenGL implementation and hardware,
       * GL_MAX_DUAL_SOURCE_DRAW_BUFFERS is 1"
       * http://www.opengl.org/wiki/Blending
       */
      return sws->have_vgpu10 ? 1 : 0;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
192 193 194 195
   case PIPE_CAP_ANISOTROPIC_FILTER:
      return 1;
   case PIPE_CAP_POINT_SPRITE:
      return 1;
196 197
   case PIPE_CAP_TGSI_TEXCOORD:
      return 0;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
198
   case PIPE_CAP_MAX_RENDER_TARGETS:
199
      return svgascreen->max_color_buffers;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
200 201
   case PIPE_CAP_OCCLUSION_QUERY:
      return 1;
202
   case PIPE_CAP_QUERY_TIME_ELAPSED:
203
      return 0;
204 205
   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
      return sws->have_vgpu10;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
206 207
   case PIPE_CAP_TEXTURE_SHADOW_MAP:
      return 1;
Brian Paul's avatar
Brian Paul committed
208 209
   case PIPE_CAP_TEXTURE_SWIZZLE:
      return 1;
210 211
   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
      return 0;
212
   case PIPE_CAP_USER_VERTEX_BUFFERS:
213
   case PIPE_CAP_USER_INDEX_BUFFERS:
214
      return 0;
215
   case PIPE_CAP_USER_CONSTANT_BUFFERS:
216
      return 1;
217
   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
218
      return 256;
219

Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
220
   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
221 222 223 224 225 226 227 228 229 230 231 232 233
      {
         unsigned levels = SVGA_MAX_TEXTURE_LEVELS;
         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result))
            levels = MIN2(util_logbase2(result.u) + 1, levels);
         else
            levels = 12 /* 2048x2048 */;
         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result))
            levels = MIN2(util_logbase2(result.u) + 1, levels);
         else
            levels = 12 /* 2048x2048 */;
         return levels;
      }

Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
234
   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
235 236 237 238
      if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result))
         return 8;  /* max 128x128x128 */
      return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS);

Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
239
   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
240 241 242 243
      /*
       * No mechanism to query the host, and at least limited to 2048x2048 on
       * certain hardware.
       */
244 245
      return MIN2(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
                  12 /* 2048x2048 */);
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
246

247 248 249
   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
      return sws->have_vgpu10 ? SVGA3D_MAX_SURFACE_ARRAYSIZE : 0;

Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
250 251 252
   case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
      return 1;

253 254
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
      return 1;
Brian Paul's avatar
Brian Paul committed
255
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
256
      return sws->have_vgpu10;
257 258
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
      return 0;
Brian Paul's avatar
Brian Paul committed
259
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
260
      return !sws->have_vgpu10;
261

262 263 264 265 266 267 268
   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
      return 1; /* The color outputs of vertex shaders are not clamped */
   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
      return 0; /* The driver can't clamp vertex colors */
   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
      return 0; /* The driver can't clamp fragment colors */

269
   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
270 271
      return 1; /* expected for GL_ARB_framebuffer_object */

272
   case PIPE_CAP_GLSL_FEATURE_LEVEL:
273
      return sws->have_vgpu10 ? 330 : 120;
274

275
   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
276
      return 0;
277

278 279 280
   case PIPE_CAP_SM3:
      return 1;

281 282
   case PIPE_CAP_DEPTH_CLIP_DISABLE:
   case PIPE_CAP_INDEP_BLEND_ENABLE:
283 284
   case PIPE_CAP_CONDITIONAL_RENDER:
   case PIPE_CAP_QUERY_TIMESTAMP:
285 286
   case PIPE_CAP_TGSI_INSTANCEID:
   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
   case PIPE_CAP_SEAMLESS_CUBE_MAP:
   case PIPE_CAP_FAKE_SW_MSAA:
      return sws->have_vgpu10;

   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
      return sws->have_vgpu10 ? SVGA3D_DX_MAX_SOTARGETS : 0;
   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
      return sws->have_vgpu10 ? 4 : 0;
   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
      return sws->have_vgpu10 ? SVGA3D_MAX_STREAMOUT_DECLS : 0;
   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
      return 0;
   case PIPE_CAP_TEXTURE_MULTISAMPLE:
      return svgascreen->ms_samples ? 1 : 0;

   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
      return SVGA3D_DX_MAX_RESOURCE_SIZE;

305
   case PIPE_CAP_MIN_TEXEL_OFFSET:
306
      return sws->have_vgpu10 ? VGPU10_MIN_TEXEL_FETCH_OFFSET : 0;
307
   case PIPE_CAP_MAX_TEXEL_OFFSET:
308 309
      return sws->have_vgpu10 ? VGPU10_MAX_TEXEL_FETCH_OFFSET : 0;

310 311
   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
312 313
      return 0;

314
   case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
315
      return sws->have_vgpu10 ? 256 : 0;
316
   case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
317 318 319 320 321 322 323 324 325 326 327 328
      return sws->have_vgpu10 ? 1024 : 0;

   case PIPE_CAP_PRIMITIVE_RESTART:
      return 1; /* may be a sw fallback, depending on restart index */

   /* Unsupported features */
   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
   case PIPE_CAP_SHADER_STENCIL_EXPORT:
   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
   case PIPE_CAP_INDEP_BLEND_FUNC:
   case PIPE_CAP_TEXTURE_BARRIER:
329
   case PIPE_CAP_MAX_VERTEX_STREAMS:
330
   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
331
   case PIPE_CAP_COMPUTE:
332
   case PIPE_CAP_START_INSTANCE:
333
   case PIPE_CAP_CUBE_MAP_ARRAY:
334
   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
335
   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
336
   case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
337 338
   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
   case PIPE_CAP_TEXTURE_GATHER_SM5:
339
   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
340
   case PIPE_CAP_TEXTURE_QUERY_LOD:
341
   case PIPE_CAP_SAMPLE_SHADING:
342
   case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
343
   case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
344
   case PIPE_CAP_DRAW_INDIRECT:
345 346
   case PIPE_CAP_MULTI_DRAW_INDIRECT:
   case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
347
   case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
348
   case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
349
   case PIPE_CAP_SAMPLER_VIEW_TARGET:
350
   case PIPE_CAP_CLIP_HALFZ:
351
   case PIPE_CAP_VERTEXID_NOBASE:
352
   case PIPE_CAP_POLYGON_OFFSET_CLAMP:
353
   case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
354
   case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
355
      return 0;
356 357
   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
      return 64;
358 359
   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
360
   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
361
      return 1;  /* need 4-byte alignment for all offsets and strides */
362 363
   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
      return 2048;
364 365
   case PIPE_CAP_MAX_VIEWPORTS:
      return 1;
366 367
   case PIPE_CAP_ENDIANNESS:
      return PIPE_ENDIAN_LITTLE;
368 369 370 371 372 373 374 375 376 377 378

   case PIPE_CAP_VENDOR_ID:
      return 0x15ad; /* VMware Inc. */
   case PIPE_CAP_DEVICE_ID:
      return 0x0405; /* assume SVGA II */
   case PIPE_CAP_ACCELERATED:
      return 0; /* XXX: */
   case PIPE_CAP_VIDEO_MEMORY:
      /* XXX: Query the host ? */
      return 1;
   case PIPE_CAP_UMA:
379
   case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
380
   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
381
   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
382 383
   case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
   case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
384
   case PIPE_CAP_DEPTH_BOUNDS_TEST:
385
   case PIPE_CAP_TGSI_TXQS:
386
   case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
387
   case PIPE_CAP_SHAREABLE_SHADERS:
388
   case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
389
   case PIPE_CAP_CLEAR_TEXTURE:
390
   case PIPE_CAP_DRAW_PARAMETERS:
391 392
   case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
   case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
393
      return 0;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
394
   }
395 396 397

   debug_printf("Unexpected PIPE_CAP_ query %u\n", param);
   return 0;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
398 399
}

400 401 402 403

static int
vgpu9_get_shader_param(struct pipe_screen *screen, unsigned shader,
                       enum pipe_shader_cap param)
404 405 406
{
   struct svga_screen *svgascreen = svga_screen(screen);
   struct svga_winsys_screen *sws = svgascreen->sws;
407 408 409
   unsigned val;

   assert(!sws->have_vgpu10);
410 411 412 413 414 415 416 417 418 419

   switch (shader)
   {
   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:
420
         return 512;
421 422 423 424
      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
         return SVGA3D_MAX_NESTING_LEVEL;
      case PIPE_SHADER_CAP_MAX_INPUTS:
         return 10;
425 426
      case PIPE_SHADER_CAP_MAX_OUTPUTS:
         return svgascreen->max_color_buffers;
427 428
      case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
         return 224 * sizeof(float[4]);
429 430 431
      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
         return 1;
      case PIPE_SHADER_CAP_MAX_TEMPS:
432 433
         val = get_uint_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, 32);
         return MIN2(val, SVGA3D_TEMPREG_MAX);
434 435 436 437 438 439 440 441
      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
	 /* 
	  * Although PS 3.0 has some addressing abilities it can only represent
	  * loops that can be statically determined and unrolled. Given we can
	  * only handle a subset of the cases that the state tracker already
	  * does it is better to defer loop unrolling to the state tracker.
	  */
         return 0;
442
      case PIPE_SHADER_CAP_MAX_PREDS:
443
         return 1;
444
      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
445
         return 0;
446 447
      case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
         return 0;
448 449 450 451
      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
         return 0;
452 453
      case PIPE_SHADER_CAP_SUBROUTINES:
         return 0;
454 455
      case PIPE_SHADER_CAP_INTEGERS:
         return 0;
456
      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
457
      case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
458
         return 16;
459 460
      case PIPE_SHADER_CAP_PREFERRED_IR:
         return PIPE_SHADER_IR_TGSI;
461
      case PIPE_SHADER_CAP_DOUBLES:
462
      case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
Ilia Mirkin's avatar
Ilia Mirkin committed
463
      case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
464
      case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
465
      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
466
         return 0;
467 468
      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
         return 32;
469
      }
470 471 472
      /* If we get here, we failed to handle a cap above */
      debug_printf("Unexpected fragment shader query %u\n", param);
      return 0;
473 474 475 476 477
   case PIPE_SHADER_VERTEX:
      switch (param)
      {
      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
478 479
         return get_uint_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS,
                             512);
480 481 482 483 484 485 486 487
      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
         /* XXX: until we have vertex texture support */
         return 0;
      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
         return SVGA3D_MAX_NESTING_LEVEL;
      case PIPE_SHADER_CAP_MAX_INPUTS:
         return 16;
488 489
      case PIPE_SHADER_CAP_MAX_OUTPUTS:
         return 10;
490 491
      case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
         return 256 * sizeof(float[4]);
492 493 494
      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
         return 1;
      case PIPE_SHADER_CAP_MAX_TEMPS:
495 496
         val = get_uint_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, 32);
         return MIN2(val, SVGA3D_TEMPREG_MAX);
497
      case PIPE_SHADER_CAP_MAX_PREDS:
498
         return 1;
499
      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
500
         return 0;
501 502
      case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
         return 0;
503 504
      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
505
         return 1;
506 507 508 509
      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
         return 0;
      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
         return 1;
510 511
      case PIPE_SHADER_CAP_SUBROUTINES:
         return 0;
512 513
      case PIPE_SHADER_CAP_INTEGERS:
         return 0;
514
      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
515
      case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
516
         return 0;
517 518
      case PIPE_SHADER_CAP_PREFERRED_IR:
         return PIPE_SHADER_IR_TGSI;
519
      case PIPE_SHADER_CAP_DOUBLES:
520 521
      case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
      case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
522
      case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
523
      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
524
         return 0;
525 526
      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
         return 32;
527
      }
528 529 530
      /* If we get here, we failed to handle a cap above */
      debug_printf("Unexpected vertex shader query %u\n", param);
      return 0;
531
   case PIPE_SHADER_GEOMETRY:
532
   case PIPE_SHADER_COMPUTE:
533 534 535
   case PIPE_SHADER_TESS_CTRL:
   case PIPE_SHADER_TESS_EVAL:
      /* no support for geometry, tess or compute shaders at this time */
536
      return 0;
537
   default:
538
      debug_printf("Unexpected shader type (%u) query\n", shader);
539
      return 0;
540 541 542
   }
   return 0;
}
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
543 544


545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
static int
vgpu10_get_shader_param(struct pipe_screen *screen, unsigned shader,
                        enum pipe_shader_cap param)
{
   struct svga_screen *svgascreen = svga_screen(screen);
   struct svga_winsys_screen *sws = svgascreen->sws;

   assert(sws->have_vgpu10);
   (void) sws;  /* silence unused var warnings in non-debug builds */

   /* Only VS, GS, FS supported */
   if (shader != PIPE_SHADER_VERTEX &&
       shader != PIPE_SHADER_GEOMETRY &&
       shader != PIPE_SHADER_FRAGMENT) {
      return 0;
   }

   /* NOTE: we do not query the device for any caps/limits at this time */

   /* Generally the same limits for vertex, geometry and fragment shaders */
   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 64 * 1024;
   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
      return 64;
   case PIPE_SHADER_CAP_MAX_INPUTS:
      if (shader == PIPE_SHADER_FRAGMENT)
         return VGPU10_MAX_FS_INPUTS;
      else if (shader == PIPE_SHADER_GEOMETRY)
         return VGPU10_MAX_GS_INPUTS;
      else
         return VGPU10_MAX_VS_INPUTS;
   case PIPE_SHADER_CAP_MAX_OUTPUTS:
      if (shader == PIPE_SHADER_FRAGMENT)
         return VGPU10_MAX_FS_OUTPUTS;
      else if (shader == PIPE_SHADER_GEOMETRY)
         return VGPU10_MAX_GS_OUTPUTS;
      else
         return VGPU10_MAX_VS_OUTPUTS;
   case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
      return VGPU10_MAX_CONSTANT_BUFFER_ELEMENT_COUNT * sizeof(float[4]);
   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
      return svgascreen->max_const_buffers;
   case PIPE_SHADER_CAP_MAX_TEMPS:
      return VGPU10_MAX_TEMPS;
   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:
      return TRUE; /* XXX verify */
   case PIPE_SHADER_CAP_MAX_PREDS:
      return 0;
   case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
   case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
   case PIPE_SHADER_CAP_SUBROUTINES:
   case PIPE_SHADER_CAP_INTEGERS:
      return TRUE;
   case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
   case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
      return SVGA3D_DX_MAX_SAMPLERS;
   case PIPE_SHADER_CAP_PREFERRED_IR:
      return PIPE_SHADER_IR_TGSI;
   case PIPE_SHADER_CAP_DOUBLES:
   case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
   case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
   case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
   case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
      return 0;
616 617
   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
      return 32;
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
   default:
      debug_printf("Unexpected vgpu10 shader query %u\n", param);
      return 0;
   }
   return 0;
}


static int
svga_get_shader_param(struct pipe_screen *screen, unsigned shader,
                      enum pipe_shader_cap param)
{
   struct svga_screen *svgascreen = svga_screen(screen);
   struct svga_winsys_screen *sws = svgascreen->sws;
   if (sws->have_vgpu10) {
      return vgpu10_get_shader_param(screen, shader, param);
   }
   else {
      return vgpu9_get_shader_param(screen, shader, param);
   }
}


641
/**
642
 * Implement pipe_screen::is_format_supported().
643 644
 * \param bindings  bitmask of PIPE_BIND_x flags
 */
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
645 646
static boolean
svga_is_format_supported( struct pipe_screen *screen,
647
                          enum pipe_format format,
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
648
                          enum pipe_texture_target target,
649
                          unsigned sample_count,
650
                          unsigned bindings)
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
651
{
652
   struct svga_screen *ss = svga_screen(screen);
653 654 655
   SVGA3dSurfaceFormat svga_format;
   SVGA3dSurfaceFormatCaps caps;
   SVGA3dSurfaceFormatCaps mask;
656

657
   assert(bindings);
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
658

659
   if (sample_count > 1) {
660 661 662 663 664 665
      /* In ms_samples, if bit N is set it means that we support
       * multisample with N+1 samples per pixel.
       */
      if ((ss->ms_samples & (1 << (sample_count - 1))) == 0) {
         return FALSE;
      }
666
   }
667

668
   svga_format = svga_translate_format(ss, format, bindings);
669 670 671 672
   if (svga_format == SVGA3D_FORMAT_INVALID) {
      return FALSE;
   }

673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688
   /* we don't support sRGB rendering into display targets */
   if (util_format_is_srgb(format) && (bindings & PIPE_BIND_DISPLAY_TARGET)) {
      return FALSE;
   }

   /*
    * For VGPU10 vertex formats, skip querying host capabilities
    */

   if (ss->sws->have_vgpu10 && (bindings & PIPE_BIND_VERTEX_BUFFER)) {
      SVGA3dSurfaceFormat svga_format;
      unsigned flags;
      svga_translate_vertex_format_vgpu10(format, &svga_format, &flags);
      return svga_format != SVGA3D_FORMAT_INVALID;
   }

689 690 691 692 693
   /*
    * Override host capabilities, so that we end up with the same
    * visuals for all virtual hardware implementations.
    */

694
   if (bindings & PIPE_BIND_DISPLAY_TARGET) {
695 696 697 698 699
      switch (svga_format) {
      case SVGA3D_A8R8G8B8:
      case SVGA3D_X8R8G8B8:
      case SVGA3D_R5G6B5:
         break;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
700

701 702 703 704 705 706
      /* VGPU10 formats */
      case SVGA3D_B8G8R8A8_UNORM:
      case SVGA3D_B8G8R8X8_UNORM:
      case SVGA3D_B5G6R5_UNORM:
         break;

Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
707 708 709
      /* Often unsupported/problematic. This means we end up with the same
       * visuals for all virtual hardware implementations.
       */
710 711
      case SVGA3D_A4R4G4B4:
      case SVGA3D_A1R5G5B5:
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
712 713 714
         return FALSE;
         
      default:
715
         return FALSE;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
716 717 718
      }
   }
   
719 720 721 722 723 724
   /*
    * Query the host capabilities.
    */

   svga_get_format_cap(ss, svga_format, &caps);

725 726 727 728 729 730 731 732 733 734
   if (bindings & PIPE_BIND_RENDER_TARGET) {
      /* Check that the color surface is blendable, unless it's an
       * integer format.
       */
      if (!svga_format_is_integer(svga_format) &&
          (caps.value & SVGA3DFORMAT_OP_NOALPHABLEND)) {
         return FALSE;
      }
   }

735
   mask.value = 0;
736
   if (bindings & PIPE_BIND_RENDER_TARGET) {
737
      mask.value |= SVGA3DFORMAT_OP_OFFSCREEN_RENDERTARGET;
738
   }
739
   if (bindings & PIPE_BIND_DEPTH_STENCIL) {
740
      mask.value |= SVGA3DFORMAT_OP_ZSTENCIL;
741
   }
742
   if (bindings & PIPE_BIND_SAMPLER_VIEW) {
743
      mask.value |= SVGA3DFORMAT_OP_TEXTURE;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
744 745
   }

746
   if (target == PIPE_TEXTURE_CUBE) {
747
      mask.value |= SVGA3DFORMAT_OP_CUBETEXTURE;
748
   }
749 750
   else if (target == PIPE_TEXTURE_3D) {
      mask.value |= SVGA3DFORMAT_OP_VOLUMETEXTURE;
751 752
   }

753
   return (caps.value & mask.value) == mask.value;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
754 755 756 757 758 759 760 761 762 763 764 765 766
}


static void
svga_fence_reference(struct pipe_screen *screen,
                     struct pipe_fence_handle **ptr,
                     struct pipe_fence_handle *fence)
{
   struct svga_winsys_screen *sws = svga_screen(screen)->sws;
   sws->fence_reference(sws, ptr, fence);
}


767
static boolean
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
768 769
svga_fence_finish(struct pipe_screen *screen,
                  struct pipe_fence_handle *fence,
770
                  uint64_t timeout)
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
771 772
{
   struct svga_winsys_screen *sws = svga_screen(screen)->sws;
Keith Whitwell's avatar
Keith Whitwell committed
773

774 775 776
   if (!timeout)
      return sws->fence_signalled(sws, fence, 0) == 0;

Keith Whitwell's avatar
Keith Whitwell committed
777 778 779
   SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n",
            __FUNCTION__, fence);

780
   return sws->fence_finish(sws, fence, 0) == 0;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
781 782 783
}


784 785 786 787 788
static int
svga_get_driver_query_info(struct pipe_screen *screen,
                           unsigned index,
                           struct pipe_driver_query_info *info)
{
789 790 791
#define QUERY(NAME, ENUM, UNITS) \
   {NAME, ENUM, {0}, UNITS, PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE, 0, 0x0}

792
   static const struct pipe_driver_query_info queries[] = {
793
      /* per-frame counters */
794 795 796 797 798 799 800 801 802 803 804 805 806 807
      QUERY("num-draw-calls", SVGA_QUERY_NUM_DRAW_CALLS,
            PIPE_DRIVER_QUERY_TYPE_UINT64),
      QUERY("num-fallbacks", SVGA_QUERY_NUM_FALLBACKS,
            PIPE_DRIVER_QUERY_TYPE_UINT64),
      QUERY("num-flushes", SVGA_QUERY_NUM_FLUSHES,
            PIPE_DRIVER_QUERY_TYPE_UINT64),
      QUERY("num-validations", SVGA_QUERY_NUM_VALIDATIONS,
            PIPE_DRIVER_QUERY_TYPE_UINT64),
      QUERY("map-buffer-time", SVGA_QUERY_MAP_BUFFER_TIME,
            PIPE_DRIVER_QUERY_TYPE_MICROSECONDS),
      QUERY("num-resources-mapped", SVGA_QUERY_NUM_RESOURCES_MAPPED,
            PIPE_DRIVER_QUERY_TYPE_UINT64),
      QUERY("num-bytes-uploaded", SVGA_QUERY_NUM_BYTES_UPLOADED,
            PIPE_DRIVER_QUERY_TYPE_BYTES),
808 809

      /* running total counters */
810 811 812 813 814 815 816 817 818 819
      QUERY("memory-used", SVGA_QUERY_MEMORY_USED,
            PIPE_DRIVER_QUERY_TYPE_BYTES),
      QUERY("num-shaders", SVGA_QUERY_NUM_SHADERS,
            PIPE_DRIVER_QUERY_TYPE_UINT64),
      QUERY("num-resources", SVGA_QUERY_NUM_RESOURCES,
            PIPE_DRIVER_QUERY_TYPE_UINT64),
      QUERY("num-state-objects", SVGA_QUERY_NUM_STATE_OBJECTS,
            PIPE_DRIVER_QUERY_TYPE_UINT64),
      QUERY("num-surface-views", SVGA_QUERY_NUM_SURFACE_VIEWS,
            PIPE_DRIVER_QUERY_TYPE_UINT64),
820
   };
821
#undef QUERY
822 823 824 825 826 827 828 829 830 831 832 833

   if (!info)
      return Elements(queries);

   if (index >= Elements(queries))
      return 0;

   *info = queries[index];
   return 1;
}


Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882
static void
svga_destroy_screen( struct pipe_screen *screen )
{
   struct svga_screen *svgascreen = svga_screen(screen);
   
   svga_screen_cache_cleanup(svgascreen);

   pipe_mutex_destroy(svgascreen->swc_mutex);
   pipe_mutex_destroy(svgascreen->tex_mutex);

   svgascreen->sws->destroy(svgascreen->sws);
   
   FREE(svgascreen);
}


/**
 * Create a new svga_screen object
 */
struct pipe_screen *
svga_screen_create(struct svga_winsys_screen *sws)
{
   struct svga_screen *svgascreen;
   struct pipe_screen *screen;

#ifdef DEBUG
   SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 );
#endif

   svgascreen = CALLOC_STRUCT(svga_screen);
   if (!svgascreen)
      goto error1;

   svgascreen->debug.force_level_surface_view =
      debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE);
   svgascreen->debug.force_surface_view =
      debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE);
   svgascreen->debug.force_sampler_view =
      debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE);
   svgascreen->debug.no_surface_view =
      debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE);
   svgascreen->debug.no_sampler_view =
      debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE);

   screen = &svgascreen->screen;

   screen->destroy = svga_destroy_screen;
   screen->get_name = svga_get_name;
   screen->get_vendor = svga_get_vendor;
883
   screen->get_device_vendor = svga_get_vendor; // TODO actual device vendor
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
884
   screen->get_param = svga_get_param;
885
   screen->get_shader_param = svga_get_shader_param;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
886
   screen->get_paramf = svga_get_paramf;
887
   screen->get_timestamp = NULL;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
888
   screen->is_format_supported = svga_is_format_supported;
889
   screen->context_create = svga_context_create;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
890 891
   screen->fence_reference = svga_fence_reference;
   screen->fence_finish = svga_fence_finish;
892
   screen->get_driver_query_info = svga_get_driver_query_info;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
893 894
   svgascreen->sws = sws;

895
   svga_init_screen_resource_functions(svgascreen);
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
896

897 898 899 900 901 902
   if (sws->get_hw_version) {
      svgascreen->hw_version = sws->get_hw_version(sws);
   } else {
      svgascreen->hw_version = SVGA3D_HWVERSION_WS65_B1;
   }

903 904 905 906 907 908 909 910 911
   /*
    * The D16, D24X8, and D24S8 formats always do an implicit shadow compare
    * when sampled from, where as the DF16, DF24, and D24S8_INT do not.  So
    * we prefer the later when available.
    *
    * This mimics hardware vendors extensions for D3D depth sampling. See also
    * http://aras-p.info/texts/D3D9GPUHacks.html
    */

912
   {
913 914
      boolean has_df16, has_df24, has_d24s8_int;
      SVGA3dSurfaceFormatCaps caps;
915 916 917 918 919
      SVGA3dSurfaceFormatCaps mask;
      mask.value = 0;
      mask.zStencil = 1;
      mask.texture = 1;

920 921 922 923 924 925 926 927 928 929 930 931
      svgascreen->depth.z16 = SVGA3D_Z_D16;
      svgascreen->depth.x8z24 = SVGA3D_Z_D24X8;
      svgascreen->depth.s8z24 = SVGA3D_Z_D24S8;

      svga_get_format_cap(svgascreen, SVGA3D_Z_DF16, &caps);
      has_df16 = (caps.value & mask.value) == mask.value;

      svga_get_format_cap(svgascreen, SVGA3D_Z_DF24, &caps);
      has_df24 = (caps.value & mask.value) == mask.value;

      svga_get_format_cap(svgascreen, SVGA3D_Z_D24S8_INT, &caps);
      has_d24s8_int = (caps.value & mask.value) == mask.value;
932

933 934 935 936 937 938 939 940 941 942 943 944 945 946
      /* XXX: We might want some other logic here.
       * Like if we only have d24s8_int we should
       * emulate the other formats with that.
       */
      if (has_df16) {
         svgascreen->depth.z16 = SVGA3D_Z_DF16;
      }
      if (has_df24) {
         svgascreen->depth.x8z24 = SVGA3D_Z_DF24;
      }
      if (has_d24s8_int) {
         svgascreen->depth.s8z24 = SVGA3D_Z_D24S8_INT;
      }
   }
947

948 949
   /* Query device caps
    */
950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976
   if (sws->have_vgpu10) {
      svgascreen->haveProvokingVertex
         = get_bool_cap(sws, SVGA3D_DEVCAP_DX_PROVOKING_VERTEX, FALSE);
      svgascreen->haveLineSmooth = TRUE;
      svgascreen->maxPointSize = 80.0F;
      svgascreen->max_color_buffers = SVGA3D_DX_MAX_RENDER_TARGETS;

      /* Multisample samples per pixel */
      svgascreen->ms_samples =
         get_uint_cap(sws, SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES, 0);

      /* Maximum number of constant buffers */
      svgascreen->max_const_buffers =
         get_uint_cap(sws, SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS, 1);
      assert(svgascreen->max_const_buffers <= SVGA_MAX_CONST_BUFS);
   }
   else {
      /* VGPU9 */
      unsigned vs_ver = get_uint_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION,
                                     SVGA3DVSVERSION_NONE);
      unsigned fs_ver = get_uint_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION,
                                     SVGA3DPSVERSION_NONE);

      /* we require Shader model 3.0 or later */
      if (fs_ver < SVGA3DPSVERSION_30 || vs_ver < SVGA3DVSVERSION_30) {
         goto error2;
      }
977

978
      svgascreen->haveProvokingVertex = FALSE;
979

980 981
      svgascreen->haveLineSmooth =
         get_bool_cap(sws, SVGA3D_DEVCAP_LINE_AA, FALSE);
982

983 984 985 986 987 988 989 990 991 992 993 994 995
      svgascreen->maxPointSize =
         get_float_cap(sws, SVGA3D_DEVCAP_MAX_POINT_SIZE, 1.0f);
      /* Keep this to a reasonable size to avoid failures in conform/pntaa.c */
      svgascreen->maxPointSize = MIN2(svgascreen->maxPointSize, 80.0f);

      /* The SVGA3D device always supports 4 targets at this time, regardless
       * of what querying SVGA3D_DEVCAP_MAX_RENDER_TARGETS might return.
       */
      svgascreen->max_color_buffers = 4;

      /* Only support one constant buffer
       */
      svgascreen->max_const_buffers = 1;
996

997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
      /* No multisampling */
      svgascreen->ms_samples = 0;
   }

   /* common VGPU9 / VGPU10 caps */
   svgascreen->haveLineStipple =
      get_bool_cap(sws, SVGA3D_DEVCAP_LINE_STIPPLE, FALSE);

   svgascreen->maxLineWidth =
      get_float_cap(sws, SVGA3D_DEVCAP_MAX_LINE_WIDTH, 1.0f);

   svgascreen->maxLineWidthAA =
      get_float_cap(sws, SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH, 1.0f);

   if (0) {
      debug_printf("svga: haveProvokingVertex %u\n",
                   svgascreen->haveProvokingVertex);
1014 1015 1016 1017
      debug_printf("svga: haveLineStip %u  "
                   "haveLineSmooth %u  maxLineWidth %f\n",
                   svgascreen->haveLineStipple, svgascreen->haveLineSmooth,
                   svgascreen->maxLineWidth);
1018
      debug_printf("svga: maxPointSize %g\n", svgascreen->maxPointSize);
1019 1020
   }

Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
   pipe_mutex_init(svgascreen->tex_mutex);
   pipe_mutex_init(svgascreen->swc_mutex);

   svga_screen_cache_init(svgascreen);

   return screen;
error2:
   FREE(svgascreen);
error1:
   return NULL;
}

struct svga_winsys_screen *
svga_winsys_screen(struct pipe_screen *screen)
{
   return svga_screen(screen)->sws;
}

#ifdef DEBUG
struct svga_screen *
svga_screen(struct pipe_screen *screen)
{
   assert(screen);
   assert(screen->destroy == svga_destroy_screen);
   return (struct svga_screen *)screen;
}
#endif