svga_screen.c 21.6 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 38
#include "svga_resource_texture.h"
#include "svga_resource.h"
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
39 40 41 42 43 44 45 46 47
#include "svga_debug.h"

#include "svga3d_shaderdefs.h"


#ifdef DEBUG
int SVGA_DEBUG = 0;

static const struct debug_named_value svga_debug_flags[] = {
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
   { "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 },
   DEBUG_NAMED_VALUE_END
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
63 64 65 66 67 68 69 70 71 72 73 74 75
};
#endif

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


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

   util_snprintf(name, sizeof(name), "SVGA3D; %s %s %s", build, mutex, llvm);
   return name;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
92 93 94 95 96 97
}




static float
98
svga_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
99 100 101 102 103 104
{
   struct svga_screen *svgascreen = svga_screen(screen);
   struct svga_winsys_screen *sws = svgascreen->sws;
   SVGA3dDevCapResult result;

   switch (param) {
105
   case PIPE_CAPF_MAX_LINE_WIDTH:
106
      return svgascreen->maxLineWidth;
107
   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
108
      return svgascreen->maxLineWidthAA;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
109

110
   case PIPE_CAPF_MAX_POINT_WIDTH:
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
111
      /* fall-through */
112
   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
113
      return svgascreen->maxPointSize;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
114

115
   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
116
      if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, &result))
117 118
         return 4.0f;
      return (float) result.u;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
119

120
   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
121
      return 15.0;
122 123 124 125 126
   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;
127
   }
128 129 130

   debug_printf("Unexpected PIPE_CAPF_ query %u\n", param);
   return 0;
131 132 133 134 135 136 137 138 139 140 141
}


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
142
   case PIPE_CAP_NPOT_TEXTURES:
143
   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
144 145 146
      return 1;
   case PIPE_CAP_TWO_SIDED_STENCIL:
      return 1;
147 148
   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
      return 0;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
149 150 151 152
   case PIPE_CAP_ANISOTROPIC_FILTER:
      return 1;
   case PIPE_CAP_POINT_SPRITE:
      return 1;
153 154
   case PIPE_CAP_TGSI_TEXCOORD:
      return 0;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
155
   case PIPE_CAP_MAX_RENDER_TARGETS:
156
      return svgascreen->max_color_buffers;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
157 158
   case PIPE_CAP_OCCLUSION_QUERY:
      return 1;
159
   case PIPE_CAP_QUERY_TIME_ELAPSED:
160
      return 0;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
161 162
   case PIPE_CAP_TEXTURE_SHADOW_MAP:
      return 1;
Brian Paul's avatar
Brian Paul committed
163 164
   case PIPE_CAP_TEXTURE_SWIZZLE:
      return 1;
165 166
   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
      return 0;
167
   case PIPE_CAP_USER_VERTEX_BUFFERS:
168
   case PIPE_CAP_USER_INDEX_BUFFERS:
169
      return 0;
170
   case PIPE_CAP_USER_CONSTANT_BUFFERS:
171
      return 1;
172 173
   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
      return 16;
174

Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
175
   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
176 177 178 179 180 181 182 183 184 185 186 187 188
      {
         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
189
   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
190 191 192 193
      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
194
   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
195 196 197 198
      /*
       * No mechanism to query the host, and at least limited to 2048x2048 on
       * certain hardware.
       */
199 200
      return MIN2(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
                  12 /* 2048x2048 */);
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
201 202 203 204

   case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
      return 1;

205 206
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
      return 1;
Brian Paul's avatar
Brian Paul committed
207 208
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
      return 0;
209 210
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
      return 0;
Brian Paul's avatar
Brian Paul committed
211 212
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
      return 1;
213

214 215 216 217 218 219 220
   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 */

221
   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
222 223
      return 1; /* expected for GL_ARB_framebuffer_object */

224 225 226
   case PIPE_CAP_GLSL_FEATURE_LEVEL:
      return 120;

227
   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
228
      return 0;
229

230 231 232
   case PIPE_CAP_SM3:
      return 1;

233
   /* Unsupported features */
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
   case PIPE_CAP_SHADER_STENCIL_EXPORT:
   case PIPE_CAP_DEPTH_CLIP_DISABLE:
   case PIPE_CAP_SEAMLESS_CUBE_MAP:
   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
   case PIPE_CAP_INDEP_BLEND_ENABLE:
   case PIPE_CAP_INDEP_BLEND_FUNC:
   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
   case PIPE_CAP_PRIMITIVE_RESTART:
   case PIPE_CAP_TGSI_INSTANCEID:
   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
   case PIPE_CAP_MIN_TEXEL_OFFSET:
   case PIPE_CAP_MAX_TEXEL_OFFSET:
   case PIPE_CAP_CONDITIONAL_RENDER:
   case PIPE_CAP_TEXTURE_BARRIER:
   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
255 256
   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
257
   case PIPE_CAP_COMPUTE:
258
   case PIPE_CAP_START_INSTANCE:
259
   case PIPE_CAP_QUERY_TIMESTAMP:
260
   case PIPE_CAP_TEXTURE_MULTISAMPLE:
261
   case PIPE_CAP_CUBE_MAP_ARRAY:
262
   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
263
   case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
264
   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
265
   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
266
   case PIPE_CAP_TGSI_VS_LAYER:
267
      return 0;
268 269
   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
      return 64;
270 271
   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
      return 1;
272 273
   case PIPE_CAP_MAX_VIEWPORTS:
      return 1;
274 275
   case PIPE_CAP_ENDIANNESS:
      return PIPE_ENDIAN_LITTLE;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
276
   }
277 278 279

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

282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
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;
   SVGA3dDevCapResult result;

   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:
297
         return 512;
298 299 300 301 302
      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
         return SVGA3D_MAX_NESTING_LEVEL;
      case PIPE_SHADER_CAP_MAX_INPUTS:
         return 10;
      case PIPE_SHADER_CAP_MAX_CONSTS:
303
         return 224;
304 305 306 307
      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
         return 1;
      case PIPE_SHADER_CAP_MAX_TEMPS:
         if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, &result))
308
            return 32;
309
         return MIN2(result.u, SVGA3D_TEMPREG_MAX);
310
      case PIPE_SHADER_CAP_MAX_ADDRS:
311 312 313 314 315 316 317 318
      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;
319
      case PIPE_SHADER_CAP_MAX_PREDS:
320
         return 1;
321
      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
322
         return 0;
323 324
      case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
         return 0;
325 326 327 328
      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
         return 0;
329 330
      case PIPE_SHADER_CAP_SUBROUTINES:
         return 0;
331 332
      case PIPE_SHADER_CAP_INTEGERS:
         return 0;
333
      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
334
      case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
335
         return 16;
336
      default:
337
         debug_printf("Unexpected fragment shader query %u\n", param);
338
         return 0;
339 340 341 342 343 344 345 346
      }
      break;
   case PIPE_SHADER_VERTEX:
      switch (param)
      {
      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
         if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS, &result))
347
            return 512;
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
         return result.u;
      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;
      case PIPE_SHADER_CAP_MAX_CONSTS:
         return 256;
      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
         return 1;
      case PIPE_SHADER_CAP_MAX_TEMPS:
         if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, &result))
363
            return 32;
364
         return MIN2(result.u, SVGA3D_TEMPREG_MAX);
365
      case PIPE_SHADER_CAP_MAX_ADDRS:
366
         return 1;
367
      case PIPE_SHADER_CAP_MAX_PREDS:
368
         return 1;
369
      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
370
         return 0;
371 372
      case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
         return 0;
373 374
      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
375
         return 1;
376 377 378 379
      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
         return 0;
      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
         return 1;
380 381
      case PIPE_SHADER_CAP_SUBROUTINES:
         return 0;
382 383
      case PIPE_SHADER_CAP_INTEGERS:
         return 0;
384
      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
385
      case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
386
         return 0;
387
      default:
388 389
         debug_printf("Unexpected vertex shader query %u\n", param);
         return 0;
390 391
      }
      break;
392
   case PIPE_SHADER_GEOMETRY:
393 394
   case PIPE_SHADER_COMPUTE:
      /* no support for geometry or compute shaders at this time */
395
      return 0;
396
   default:
397
      debug_printf("Unexpected shader type (%u) query\n", shader);
398
      return 0;
399 400 401
   }
   return 0;
}
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
402 403


404 405 406 407
/**
 * Implemnt pipe_screen::is_format_supported().
 * \param bindings  bitmask of PIPE_BIND_x flags
 */
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
408 409
static boolean
svga_is_format_supported( struct pipe_screen *screen,
410
                          enum pipe_format format,
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
411
                          enum pipe_texture_target target,
412
                          unsigned sample_count,
413
                          unsigned bindings)
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
414
{
415
   struct svga_screen *ss = svga_screen(screen);
416 417 418
   SVGA3dSurfaceFormat svga_format;
   SVGA3dSurfaceFormatCaps caps;
   SVGA3dSurfaceFormatCaps mask;
419

420
   assert(bindings);
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
421

422
   if (sample_count > 1) {
423
      return FALSE;
424
   }
425

426
   svga_format = svga_translate_format(ss, format, bindings);
427 428 429 430 431 432 433 434 435
   if (svga_format == SVGA3D_FORMAT_INVALID) {
      return FALSE;
   }

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

436
   if (bindings & PIPE_BIND_DISPLAY_TARGET) {
437 438 439 440 441
      switch (svga_format) {
      case SVGA3D_A8R8G8B8:
      case SVGA3D_X8R8G8B8:
      case SVGA3D_R5G6B5:
         break;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
442 443 444 445

      /* Often unsupported/problematic. This means we end up with the same
       * visuals for all virtual hardware implementations.
       */
446 447
      case SVGA3D_A4R4G4B4:
      case SVGA3D_A1R5G5B5:
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
448 449 450
         return FALSE;
         
      default:
451
         return FALSE;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
452 453 454
      }
   }
   
455 456 457 458 459 460 461
   /*
    * Query the host capabilities.
    */

   svga_get_format_cap(ss, svga_format, &caps);

   mask.value = 0;
462
   if (bindings & PIPE_BIND_RENDER_TARGET) {
463 464
      mask.offscreenRenderTarget = 1;
   }
465
   if (bindings & PIPE_BIND_DEPTH_STENCIL) {
466 467
      mask.zStencil = 1;
   }
468
   if (bindings & PIPE_BIND_SAMPLER_VIEW) {
469
      mask.texture = 1;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
470 471
   }

472 473 474 475 476 477 478
   if (target == PIPE_TEXTURE_CUBE) {
      mask.cubeTexture = 1;
   }
   if (target == PIPE_TEXTURE_3D) {
      mask.volumeTexture = 1;
   }

479
   return (caps.value & mask.value) == mask.value;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
480 481 482 483 484 485 486 487 488 489 490 491 492
}


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);
}


493
static boolean
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
494
svga_fence_signalled(struct pipe_screen *screen,
495
                     struct pipe_fence_handle *fence)
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
496 497
{
   struct svga_winsys_screen *sws = svga_screen(screen)->sws;
498
   return sws->fence_signalled(sws, fence, 0) == 0;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
499 500 501
}


502
static boolean
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
503 504
svga_fence_finish(struct pipe_screen *screen,
                  struct pipe_fence_handle *fence,
505
                  uint64_t timeout)
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
506 507
{
   struct svga_winsys_screen *sws = svga_screen(screen)->sws;
Keith Whitwell's avatar
Keith Whitwell committed
508 509 510 511

   SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n",
            __FUNCTION__, fence);

512
   return sws->fence_finish(sws, fence, 0) == 0;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
513 514 515
}


516 517 518 519 520 521 522
static int
svga_get_driver_query_info(struct pipe_screen *screen,
                           unsigned index,
                           struct pipe_driver_query_info *info)
{
   static const struct pipe_driver_query_info queries[] = {
      {"draw-calls", SVGA_QUERY_DRAW_CALLS, 0, FALSE},
523 524
      {"fallbacks", SVGA_QUERY_FALLBACKS, 0, FALSE},
      {"memory-used", SVGA_QUERY_MEMORY_USED, 0, TRUE}
525 526 527 528 529 530 531 532 533 534 535 536 537
   };

   if (!info)
      return Elements(queries);

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

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


Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
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;
   SVGA3dDevCapResult result;
563
   boolean use_vs30, use_ps30;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
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

#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;
   screen->get_param = svga_get_param;
590
   screen->get_shader_param = svga_get_shader_param;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
591 592
   screen->get_paramf = svga_get_paramf;
   screen->is_format_supported = svga_is_format_supported;
593
   screen->context_create = svga_context_create;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
594 595 596
   screen->fence_reference = svga_fence_reference;
   screen->fence_signalled = svga_fence_signalled;
   screen->fence_finish = svga_fence_finish;
597
   screen->get_driver_query_info = svga_get_driver_query_info;
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
598 599
   svgascreen->sws = sws;

600
   svga_init_screen_resource_functions(svgascreen);
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
601

602 603 604 605 606 607
   if (sws->get_hw_version) {
      svgascreen->hw_version = sws->get_hw_version(sws);
   } else {
      svgascreen->hw_version = SVGA3D_HWVERSION_WS65_B1;
   }

608
   use_ps30 =
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
609 610 611
      sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) &&
      result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE;

612
   use_vs30 =
Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
613 614 615
      sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) &&
      result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE;

616 617 618 619
   /* we require Shader model 3.0 or later */
   if (!use_ps30 || !use_vs30)
      goto error2;

620 621 622 623 624 625 626 627 628
   /*
    * 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
    */

629
   {
630 631
      boolean has_df16, has_df24, has_d24s8_int;
      SVGA3dSurfaceFormatCaps caps;
632 633 634 635 636
      SVGA3dSurfaceFormatCaps mask;
      mask.value = 0;
      mask.zStencil = 1;
      mask.texture = 1;

637 638 639 640 641 642 643 644 645 646 647 648
      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;
649

650 651 652 653 654 655 656 657 658 659 660 661 662 663
      /* 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;
      }
   }
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
   /* Query device caps
    */
   if (!sws->get_cap(sws, SVGA3D_DEVCAP_LINE_STIPPLE, &result))
      svgascreen->haveLineStipple = FALSE;
   else
      svgascreen->haveLineStipple = result.u;

   if (!sws->get_cap(sws, SVGA3D_DEVCAP_LINE_AA, &result))
      svgascreen->haveLineSmooth = FALSE;
   else
      svgascreen->haveLineSmooth = result.u;

   if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_LINE_WIDTH, &result))
      svgascreen->maxLineWidth = 1.0F;
   else
      svgascreen->maxLineWidth = result.f;

   if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH, &result))
      svgascreen->maxLineWidthAA = 1.0F;
   else
      svgascreen->maxLineWidthAA = result.f;

   if (0)
      debug_printf("svga: haveLineStip %u  "
                   "haveLineSmooth %u  maxLineWidth %f\n",
                   svgascreen->haveLineStipple, svgascreen->haveLineSmooth,
                   svgascreen->maxLineWidth);

693 694 695 696 697 698 699 700 701
   if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_POINT_SIZE, &result)) {
      svgascreen->maxPointSize = 1.0F;
   } else {
      /* Keep this to a reasonable size to avoid failures in
       * conform/pntaa.c:
       */
      svgascreen->maxPointSize = MIN2(result.f, 80.0f);
   }

702 703 704 705 706
   /* 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;

Jakob Bornecrantz's avatar
Jakob Bornecrantz committed
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
   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