14a49301eSmrg/**********************************************************
24a49301eSmrg * Copyright 2008-2009 VMware, Inc.  All rights reserved.
34a49301eSmrg *
44a49301eSmrg * Permission is hereby granted, free of charge, to any person
54a49301eSmrg * obtaining a copy of this software and associated documentation
64a49301eSmrg * files (the "Software"), to deal in the Software without
74a49301eSmrg * restriction, including without limitation the rights to use, copy,
84a49301eSmrg * modify, merge, publish, distribute, sublicense, and/or sell copies
94a49301eSmrg * of the Software, and to permit persons to whom the Software is
104a49301eSmrg * furnished to do so, subject to the following conditions:
114a49301eSmrg *
124a49301eSmrg * The above copyright notice and this permission notice shall be
134a49301eSmrg * included in all copies or substantial portions of the Software.
144a49301eSmrg *
154a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
164a49301eSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
174a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
184a49301eSmrg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
194a49301eSmrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
204a49301eSmrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
214a49301eSmrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
224a49301eSmrg * SOFTWARE.
234a49301eSmrg *
244a49301eSmrg **********************************************************/
254a49301eSmrg
2601e04c3fSmrg#include "git_sha1.h" /* For MESA_GIT_SHA1 */
277ec681f3Smrg#include "util/format/u_format.h"
284a49301eSmrg#include "util/u_memory.h"
29cdc920a0Smrg#include "util/u_inlines.h"
3001e04c3fSmrg#include "util/u_screen.h"
314a49301eSmrg#include "util/u_string.h"
324a49301eSmrg#include "util/u_math.h"
334a49301eSmrg
3401e04c3fSmrg#include "os/os_process.h"
3501e04c3fSmrg
364a49301eSmrg#include "svga_winsys.h"
373464ebd5Sriastradh#include "svga_public.h"
384a49301eSmrg#include "svga_context.h"
39af69d88dSmrg#include "svga_format.h"
404a49301eSmrg#include "svga_screen.h"
4101e04c3fSmrg#include "svga_tgsi.h"
423464ebd5Sriastradh#include "svga_resource_texture.h"
433464ebd5Sriastradh#include "svga_resource.h"
444a49301eSmrg#include "svga_debug.h"
454a49301eSmrg
464a49301eSmrg#include "svga3d_shaderdefs.h"
4701e04c3fSmrg#include "VGPU10ShaderTokens.h"
484a49301eSmrg
4901e04c3fSmrg/* NOTE: this constant may get moved into a svga3d*.h header file */
5001e04c3fSmrg#define SVGA3D_DX_MAX_RESOURCE_SIZE (128 * 1024 * 1024)
514a49301eSmrg
527ec681f3Smrg#ifndef MESA_GIT_SHA1
537ec681f3Smrg#define MESA_GIT_SHA1 "(unknown git revision)"
547ec681f3Smrg#endif
557ec681f3Smrg
564a49301eSmrg#ifdef DEBUG
574a49301eSmrgint SVGA_DEBUG = 0;
584a49301eSmrg
594a49301eSmrgstatic const struct debug_named_value svga_debug_flags[] = {
6001e04c3fSmrg   { "dma",         DEBUG_DMA, NULL },
6101e04c3fSmrg   { "tgsi",        DEBUG_TGSI, NULL },
6201e04c3fSmrg   { "pipe",        DEBUG_PIPE, NULL },
6301e04c3fSmrg   { "state",       DEBUG_STATE, NULL },
6401e04c3fSmrg   { "screen",      DEBUG_SCREEN, NULL },
6501e04c3fSmrg   { "tex",         DEBUG_TEX, NULL },
6601e04c3fSmrg   { "swtnl",       DEBUG_SWTNL, NULL },
6701e04c3fSmrg   { "const",       DEBUG_CONSTS, NULL },
6801e04c3fSmrg   { "viewport",    DEBUG_VIEWPORT, NULL },
6901e04c3fSmrg   { "views",       DEBUG_VIEWS, NULL },
7001e04c3fSmrg   { "perf",        DEBUG_PERF, NULL },
7101e04c3fSmrg   { "flush",       DEBUG_FLUSH, NULL },
7201e04c3fSmrg   { "sync",        DEBUG_SYNC, NULL },
7301e04c3fSmrg   { "cache",       DEBUG_CACHE, NULL },
7401e04c3fSmrg   { "streamout",   DEBUG_STREAMOUT, NULL },
7501e04c3fSmrg   { "query",       DEBUG_QUERY, NULL },
7601e04c3fSmrg   { "samplers",    DEBUG_SAMPLERS, NULL },
773464ebd5Sriastradh   DEBUG_NAMED_VALUE_END
784a49301eSmrg};
794a49301eSmrg#endif
804a49301eSmrg
814a49301eSmrgstatic const char *
824a49301eSmrgsvga_get_vendor( struct pipe_screen *pscreen )
834a49301eSmrg{
844a49301eSmrg   return "VMware, Inc.";
854a49301eSmrg}
864a49301eSmrg
874a49301eSmrg
884a49301eSmrgstatic const char *
894a49301eSmrgsvga_get_name( struct pipe_screen *pscreen )
904a49301eSmrg{
91af69d88dSmrg   const char *build = "", *llvm = "", *mutex = "";
92af69d88dSmrg   static char name[100];
934a49301eSmrg#ifdef DEBUG
944a49301eSmrg   /* Only return internal details in the DEBUG version:
954a49301eSmrg    */
96af69d88dSmrg   build = "build: DEBUG;";
97af69d88dSmrg   mutex = "mutex: " PIPE_ATOMIC ";";
984a49301eSmrg#else
99af69d88dSmrg   build = "build: RELEASE;";
1004a49301eSmrg#endif
1017ec681f3Smrg#ifdef DRAW_LLVM_AVAILABLE
10201e04c3fSmrg   llvm = "LLVM;";
10301e04c3fSmrg#endif
104af69d88dSmrg
1057ec681f3Smrg   snprintf(name, sizeof(name), "SVGA3D; %s %s %s", build, mutex, llvm);
106af69d88dSmrg   return name;
1074a49301eSmrg}
1084a49301eSmrg
1094a49301eSmrg
11001e04c3fSmrg/** Helper for querying float-valued device cap */
11101e04c3fSmrgstatic float
11201e04c3fSmrgget_float_cap(struct svga_winsys_screen *sws, SVGA3dDevCapIndex cap,
11301e04c3fSmrg              float defaultVal)
11401e04c3fSmrg{
11501e04c3fSmrg   SVGA3dDevCapResult result;
11601e04c3fSmrg   if (sws->get_cap(sws, cap, &result))
11701e04c3fSmrg      return result.f;
11801e04c3fSmrg   else
11901e04c3fSmrg      return defaultVal;
12001e04c3fSmrg}
12101e04c3fSmrg
12201e04c3fSmrg
12301e04c3fSmrg/** Helper for querying uint-valued device cap */
12401e04c3fSmrgstatic unsigned
12501e04c3fSmrgget_uint_cap(struct svga_winsys_screen *sws, SVGA3dDevCapIndex cap,
12601e04c3fSmrg             unsigned defaultVal)
12701e04c3fSmrg{
12801e04c3fSmrg   SVGA3dDevCapResult result;
12901e04c3fSmrg   if (sws->get_cap(sws, cap, &result))
13001e04c3fSmrg      return result.u;
13101e04c3fSmrg   else
13201e04c3fSmrg      return defaultVal;
13301e04c3fSmrg}
13401e04c3fSmrg
13501e04c3fSmrg
13601e04c3fSmrg/** Helper for querying boolean-valued device cap */
13701e04c3fSmrgstatic boolean
13801e04c3fSmrgget_bool_cap(struct svga_winsys_screen *sws, SVGA3dDevCapIndex cap,
13901e04c3fSmrg             boolean defaultVal)
14001e04c3fSmrg{
14101e04c3fSmrg   SVGA3dDevCapResult result;
14201e04c3fSmrg   if (sws->get_cap(sws, cap, &result))
14301e04c3fSmrg      return result.b;
14401e04c3fSmrg   else
14501e04c3fSmrg      return defaultVal;
14601e04c3fSmrg}
1474a49301eSmrg
1484a49301eSmrg
1494a49301eSmrgstatic float
150af69d88dSmrgsvga_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
1514a49301eSmrg{
1524a49301eSmrg   struct svga_screen *svgascreen = svga_screen(screen);
1534a49301eSmrg   struct svga_winsys_screen *sws = svgascreen->sws;
1544a49301eSmrg
1554a49301eSmrg   switch (param) {
156af69d88dSmrg   case PIPE_CAPF_MAX_LINE_WIDTH:
157af69d88dSmrg      return svgascreen->maxLineWidth;
158af69d88dSmrg   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
159af69d88dSmrg      return svgascreen->maxLineWidthAA;
1604a49301eSmrg
161af69d88dSmrg   case PIPE_CAPF_MAX_POINT_WIDTH:
1627ec681f3Smrg      FALLTHROUGH;
163af69d88dSmrg   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
164af69d88dSmrg      return svgascreen->maxPointSize;
1654a49301eSmrg
166af69d88dSmrg   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
16701e04c3fSmrg      return (float) get_uint_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, 4);
168af69d88dSmrg
169af69d88dSmrg   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
170af69d88dSmrg      return 15.0;
17101e04c3fSmrg
17201e04c3fSmrg   case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
1737ec681f3Smrg      FALLTHROUGH;
17401e04c3fSmrg   case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
1757ec681f3Smrg      FALLTHROUGH;
17601e04c3fSmrg   case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
17701e04c3fSmrg      return 0.0f;
17801e04c3fSmrg
179af69d88dSmrg   }
1804a49301eSmrg
181af69d88dSmrg   debug_printf("Unexpected PIPE_CAPF_ query %u\n", param);
182af69d88dSmrg   return 0;
183af69d88dSmrg}
1844a49301eSmrg
185af69d88dSmrg
186af69d88dSmrgstatic int
187af69d88dSmrgsvga_get_param(struct pipe_screen *screen, enum pipe_cap param)
188af69d88dSmrg{
189af69d88dSmrg   struct svga_screen *svgascreen = svga_screen(screen);
190af69d88dSmrg   struct svga_winsys_screen *sws = svgascreen->sws;
191af69d88dSmrg   SVGA3dDevCapResult result;
192af69d88dSmrg
193af69d88dSmrg   switch (param) {
1944a49301eSmrg   case PIPE_CAP_NPOT_TEXTURES:
195af69d88dSmrg   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
19601e04c3fSmrg   case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
1974a49301eSmrg      return 1;
198af69d88dSmrg   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
19901e04c3fSmrg      /*
20001e04c3fSmrg       * "In virtually every OpenGL implementation and hardware,
20101e04c3fSmrg       * GL_MAX_DUAL_SOURCE_DRAW_BUFFERS is 1"
20201e04c3fSmrg       * http://www.opengl.org/wiki/Blending
20301e04c3fSmrg       */
20401e04c3fSmrg      return sws->have_vgpu10 ? 1 : 0;
2054a49301eSmrg   case PIPE_CAP_ANISOTROPIC_FILTER:
2064a49301eSmrg      return 1;
2074a49301eSmrg   case PIPE_CAP_POINT_SPRITE:
2084a49301eSmrg      return 1;
2094a49301eSmrg   case PIPE_CAP_MAX_RENDER_TARGETS:
210af69d88dSmrg      return svgascreen->max_color_buffers;
2114a49301eSmrg   case PIPE_CAP_OCCLUSION_QUERY:
2124a49301eSmrg      return 1;
21301e04c3fSmrg   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
21401e04c3fSmrg      return sws->have_vgpu10;
215af69d88dSmrg   case PIPE_CAP_TEXTURE_SWIZZLE:
216af69d88dSmrg      return 1;
217af69d88dSmrg   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
21801e04c3fSmrg      return 256;
2194a49301eSmrg
2207ec681f3Smrg   case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
2214a49301eSmrg      {
2227ec681f3Smrg         unsigned size = 1 << (SVGA_MAX_TEXTURE_LEVELS - 1);
2234a49301eSmrg         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result))
2247ec681f3Smrg            size = MIN2(result.u, size);
2254a49301eSmrg         else
2267ec681f3Smrg            size = 2048;
2274a49301eSmrg         if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result))
2287ec681f3Smrg            size = MIN2(result.u, size);
2294a49301eSmrg         else
2307ec681f3Smrg            size = 2048;
2317ec681f3Smrg         return size;
2324a49301eSmrg      }
2334a49301eSmrg
2344a49301eSmrg   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
2354a49301eSmrg      if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result))
2364a49301eSmrg         return 8;  /* max 128x128x128 */
2374a49301eSmrg      return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS);
2384a49301eSmrg
2394a49301eSmrg   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
2404a49301eSmrg      /*
2414a49301eSmrg       * No mechanism to query the host, and at least limited to 2048x2048 on
2424a49301eSmrg       * certain hardware.
2434a49301eSmrg       */
2447ec681f3Smrg      return MIN2(util_last_bit(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_SIZE)),
245af69d88dSmrg                  12 /* 2048x2048 */);
2464a49301eSmrg
24701e04c3fSmrg   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
2487ec681f3Smrg      return sws->have_sm5 ? SVGA3D_SM5_MAX_SURFACE_ARRAYSIZE :
2497ec681f3Smrg             (sws->have_vgpu10 ? SVGA3D_SM4_MAX_SURFACE_ARRAYSIZE : 0);
25001e04c3fSmrg
2514a49301eSmrg   case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
2524a49301eSmrg      return 1;
2534a49301eSmrg
254cdc920a0Smrg   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
255cdc920a0Smrg      return 1;
256af69d88dSmrg   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
25701e04c3fSmrg      return sws->have_vgpu10;
258af69d88dSmrg   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
25901e04c3fSmrg      return !sws->have_vgpu10;
260af69d88dSmrg
261af69d88dSmrg   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
262af69d88dSmrg      return 1; /* The color outputs of vertex shaders are not clamped */
263af69d88dSmrg   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
2647ec681f3Smrg      return sws->have_vgpu10;
265af69d88dSmrg
2663464ebd5Sriastradh   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
267af69d88dSmrg      return 1; /* expected for GL_ARB_framebuffer_object */
268af69d88dSmrg
269af69d88dSmrg   case PIPE_CAP_GLSL_FEATURE_LEVEL:
2707ec681f3Smrg      if (sws->have_sm5) {
2717ec681f3Smrg         return 410;
2727ec681f3Smrg      } else if (sws->have_vgpu10) {
2737ec681f3Smrg         return 330;
2747ec681f3Smrg      } else {
2757ec681f3Smrg         return 120;
2767ec681f3Smrg      }
27701e04c3fSmrg
27801e04c3fSmrg   case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
2797ec681f3Smrg      return sws->have_sm5 ? 410 : (sws->have_vgpu10 ? 330 : 120);
280af69d88dSmrg
281af69d88dSmrg   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
2823464ebd5Sriastradh      return 0;
2833464ebd5Sriastradh
2847ec681f3Smrg   case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
2857ec681f3Smrg   case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
2867ec681f3Smrg   case PIPE_CAP_VERTEX_SHADER_SATURATE:
287af69d88dSmrg      return 1;
288af69d88dSmrg
289af69d88dSmrg   case PIPE_CAP_DEPTH_CLIP_DISABLE:
290af69d88dSmrg   case PIPE_CAP_INDEP_BLEND_ENABLE:
29101e04c3fSmrg   case PIPE_CAP_CONDITIONAL_RENDER:
29201e04c3fSmrg   case PIPE_CAP_QUERY_TIMESTAMP:
293af69d88dSmrg   case PIPE_CAP_TGSI_INSTANCEID:
294af69d88dSmrg   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
29501e04c3fSmrg   case PIPE_CAP_SEAMLESS_CUBE_MAP:
29601e04c3fSmrg   case PIPE_CAP_FAKE_SW_MSAA:
29701e04c3fSmrg      return sws->have_vgpu10;
29801e04c3fSmrg
29901e04c3fSmrg   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
30001e04c3fSmrg      return sws->have_vgpu10 ? SVGA3D_DX_MAX_SOTARGETS : 0;
30101e04c3fSmrg   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
30201e04c3fSmrg      return sws->have_vgpu10 ? 4 : 0;
30301e04c3fSmrg   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
3047ec681f3Smrg      return sws->have_sm5 ? SVGA3D_MAX_STREAMOUT_DECLS :
3057ec681f3Smrg             (sws->have_vgpu10 ? SVGA3D_MAX_DX10_STREAMOUT_DECLS : 0);
30601e04c3fSmrg   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
3077ec681f3Smrg      return sws->have_sm5;
30801e04c3fSmrg   case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
3097ec681f3Smrg      return sws->have_sm5;
31001e04c3fSmrg   case PIPE_CAP_TEXTURE_MULTISAMPLE:
31101e04c3fSmrg      return svgascreen->ms_samples ? 1 : 0;
31201e04c3fSmrg
31301e04c3fSmrg   case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
31401e04c3fSmrg      /* convert bytes to texels for the case of the largest texel
31501e04c3fSmrg       * size: float[4].
31601e04c3fSmrg       */
31701e04c3fSmrg      return SVGA3D_DX_MAX_RESOURCE_SIZE / (4 * sizeof(float));
31801e04c3fSmrg
319af69d88dSmrg   case PIPE_CAP_MIN_TEXEL_OFFSET:
32001e04c3fSmrg      return sws->have_vgpu10 ? VGPU10_MIN_TEXEL_FETCH_OFFSET : 0;
321af69d88dSmrg   case PIPE_CAP_MAX_TEXEL_OFFSET:
32201e04c3fSmrg      return sws->have_vgpu10 ? VGPU10_MAX_TEXEL_FETCH_OFFSET : 0;
32301e04c3fSmrg
324af69d88dSmrg   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
325af69d88dSmrg   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
32601e04c3fSmrg      return 0;
32701e04c3fSmrg
328af69d88dSmrg   case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
32901e04c3fSmrg      return sws->have_vgpu10 ? 256 : 0;
330af69d88dSmrg   case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
33101e04c3fSmrg      return sws->have_vgpu10 ? 1024 : 0;
33201e04c3fSmrg
33301e04c3fSmrg   case PIPE_CAP_PRIMITIVE_RESTART:
3347ec681f3Smrg   case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
33501e04c3fSmrg      return 1; /* may be a sw fallback, depending on restart index */
33601e04c3fSmrg
33701e04c3fSmrg   case PIPE_CAP_GENERATE_MIPMAP:
33801e04c3fSmrg      return sws->have_generate_mipmap_cmd;
33901e04c3fSmrg
34001e04c3fSmrg   case PIPE_CAP_NATIVE_FENCE_FD:
34101e04c3fSmrg      return sws->have_fence_fd;
34201e04c3fSmrg
34301e04c3fSmrg   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
34401e04c3fSmrg      return 1;
34501e04c3fSmrg
34601e04c3fSmrg   case PIPE_CAP_CUBE_MAP_ARRAY:
34701e04c3fSmrg   case PIPE_CAP_INDEP_BLEND_FUNC:
34801e04c3fSmrg   case PIPE_CAP_SAMPLE_SHADING:
34901e04c3fSmrg   case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
35001e04c3fSmrg   case PIPE_CAP_TEXTURE_QUERY_LOD:
35101e04c3fSmrg      return sws->have_sm4_1;
35201e04c3fSmrg
35301e04c3fSmrg   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
3547ec681f3Smrg      /* SM4_1 supports only single-channel textures where as SM5 supports
3557ec681f3Smrg       * all four channel textures */
3567ec681f3Smrg      return sws->have_sm5 ? 4 :
3577ec681f3Smrg             (sws->have_sm4_1 ? 1 : 0);
3587ec681f3Smrg   case PIPE_CAP_DRAW_INDIRECT:
3597ec681f3Smrg      return sws->have_sm5;
360af69d88dSmrg   case PIPE_CAP_MAX_VERTEX_STREAMS:
3617ec681f3Smrg      return sws->have_sm5 ? 4 : 0;
362af69d88dSmrg   case PIPE_CAP_COMPUTE:
3637ec681f3Smrg      return 0;
3647ec681f3Smrg   case PIPE_CAP_MAX_VARYINGS:
3657ec681f3Smrg      return sws->have_vgpu10 ? VGPU10_MAX_FS_INPUTS : 10;
366af69d88dSmrg   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
3677ec681f3Smrg      return sws->have_coherent;
3687ec681f3Smrg
3697ec681f3Smrg   case PIPE_CAP_SHAREABLE_SHADERS:
3707ec681f3Smrg      return 0;
3717ec681f3Smrg
37201e04c3fSmrg   case PIPE_CAP_PCI_GROUP:
37301e04c3fSmrg   case PIPE_CAP_PCI_BUS:
37401e04c3fSmrg   case PIPE_CAP_PCI_DEVICE:
37501e04c3fSmrg   case PIPE_CAP_PCI_FUNCTION:
376af69d88dSmrg      return 0;
377af69d88dSmrg   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
378af69d88dSmrg      return 64;
37901e04c3fSmrg   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
38001e04c3fSmrg   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
381af69d88dSmrg   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
38201e04c3fSmrg      return 1;  /* need 4-byte alignment for all offsets and strides */
38301e04c3fSmrg   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
38401e04c3fSmrg      return 2048;
385af69d88dSmrg   case PIPE_CAP_MAX_VIEWPORTS:
3867ec681f3Smrg      assert((!sws->have_vgpu10 && svgascreen->max_viewports == 1) ||
3877ec681f3Smrg             (sws->have_vgpu10 &&
3887ec681f3Smrg              svgascreen->max_viewports == SVGA3D_DX_MAX_VIEWPORTS));
3897ec681f3Smrg      return svgascreen->max_viewports;
390af69d88dSmrg   case PIPE_CAP_ENDIANNESS:
391af69d88dSmrg      return PIPE_ENDIAN_LITTLE;
392af69d88dSmrg
393af69d88dSmrg   case PIPE_CAP_VENDOR_ID:
394af69d88dSmrg      return 0x15ad; /* VMware Inc. */
395af69d88dSmrg   case PIPE_CAP_DEVICE_ID:
396af69d88dSmrg      return 0x0405; /* assume SVGA II */
397af69d88dSmrg   case PIPE_CAP_ACCELERATED:
398af69d88dSmrg      return 0; /* XXX: */
399af69d88dSmrg   case PIPE_CAP_VIDEO_MEMORY:
400af69d88dSmrg      /* XXX: Query the host ? */
401af69d88dSmrg      return 1;
40201e04c3fSmrg   case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
40301e04c3fSmrg      return sws->have_vgpu10;
40401e04c3fSmrg   case PIPE_CAP_CLEAR_TEXTURE:
40501e04c3fSmrg      return sws->have_vgpu10;
4067ec681f3Smrg   case PIPE_CAP_DOUBLES:
4077ec681f3Smrg      return sws->have_sm5;
408af69d88dSmrg   case PIPE_CAP_UMA:
40901e04c3fSmrg   case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
41001e04c3fSmrg   case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
4114a49301eSmrg      return 0;
4129f464c52Smaya   case PIPE_CAP_TGSI_DIV:
4139f464c52Smaya      return 1;
41401e04c3fSmrg   case PIPE_CAP_MAX_GS_INVOCATIONS:
41501e04c3fSmrg      return 32;
41601e04c3fSmrg   case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:
41701e04c3fSmrg      return 1 << 27;
4187ec681f3Smrg   /* Verify this once protocol is finalized. Setting it to minimum value. */
4197ec681f3Smrg   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
4207ec681f3Smrg      return sws->have_sm5 ? 30 : 0;
42101e04c3fSmrg   default:
42201e04c3fSmrg      return u_pipe_screen_get_param_defaults(screen, param);
4234a49301eSmrg   }
4244a49301eSmrg}
4254a49301eSmrg
42601e04c3fSmrg
42701e04c3fSmrgstatic int
42801e04c3fSmrgvgpu9_get_shader_param(struct pipe_screen *screen,
42901e04c3fSmrg                       enum pipe_shader_type shader,
43001e04c3fSmrg                       enum pipe_shader_cap param)
4313464ebd5Sriastradh{
4323464ebd5Sriastradh   struct svga_screen *svgascreen = svga_screen(screen);
4333464ebd5Sriastradh   struct svga_winsys_screen *sws = svgascreen->sws;
43401e04c3fSmrg   unsigned val;
43501e04c3fSmrg
43601e04c3fSmrg   assert(!sws->have_vgpu10);
4373464ebd5Sriastradh
4383464ebd5Sriastradh   switch (shader)
4393464ebd5Sriastradh   {
4403464ebd5Sriastradh   case PIPE_SHADER_FRAGMENT:
4413464ebd5Sriastradh      switch (param)
4423464ebd5Sriastradh      {
4433464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
4443464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
44501e04c3fSmrg         return get_uint_cap(sws,
44601e04c3fSmrg                             SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS,
44701e04c3fSmrg                             512);
4483464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
4493464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
450af69d88dSmrg         return 512;
4513464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
4523464ebd5Sriastradh         return SVGA3D_MAX_NESTING_LEVEL;
4533464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_INPUTS:
4543464ebd5Sriastradh         return 10;
45501e04c3fSmrg      case PIPE_SHADER_CAP_MAX_OUTPUTS:
45601e04c3fSmrg         return svgascreen->max_color_buffers;
457af69d88dSmrg      case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
458af69d88dSmrg         return 224 * sizeof(float[4]);
4593464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
4603464ebd5Sriastradh         return 1;
4613464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_TEMPS:
46201e04c3fSmrg         val = get_uint_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, 32);
46301e04c3fSmrg         return MIN2(val, SVGA3D_TEMPREG_MAX);
4643464ebd5Sriastradh      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
46501e04c3fSmrg         /*
46601e04c3fSmrg          * Although PS 3.0 has some addressing abilities it can only represent
46701e04c3fSmrg          * loops that can be statically determined and unrolled. Given we can
4687ec681f3Smrg          * only handle a subset of the cases that the gallium frontend already
4697ec681f3Smrg          * does it is better to defer loop unrolling to the gallium frontend.
47001e04c3fSmrg          */
4713464ebd5Sriastradh         return 0;
472af69d88dSmrg      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
473af69d88dSmrg         return 0;
474af69d88dSmrg      case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
475af69d88dSmrg         return 0;
4763464ebd5Sriastradh      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
4773464ebd5Sriastradh      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
4783464ebd5Sriastradh      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
4793464ebd5Sriastradh         return 0;
4803464ebd5Sriastradh      case PIPE_SHADER_CAP_SUBROUTINES:
4813464ebd5Sriastradh         return 0;
48201e04c3fSmrg      case PIPE_SHADER_CAP_INT64_ATOMICS:
483af69d88dSmrg      case PIPE_SHADER_CAP_INTEGERS:
484af69d88dSmrg         return 0;
48501e04c3fSmrg      case PIPE_SHADER_CAP_FP16:
4867ec681f3Smrg      case PIPE_SHADER_CAP_FP16_DERIVATIVES:
4877ec681f3Smrg      case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
4887ec681f3Smrg      case PIPE_SHADER_CAP_INT16:
4897ec681f3Smrg      case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
49001e04c3fSmrg         return 0;
491af69d88dSmrg      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
492af69d88dSmrg      case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
493af69d88dSmrg         return 16;
494af69d88dSmrg      case PIPE_SHADER_CAP_PREFERRED_IR:
495af69d88dSmrg         return PIPE_SHADER_IR_TGSI;
49601e04c3fSmrg      case PIPE_SHADER_CAP_SUPPORTED_IRS:
4977ec681f3Smrg         return 1 << PIPE_SHADER_IR_TGSI;
49801e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
49901e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
50001e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
50101e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
50201e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
50301e04c3fSmrg      case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
50401e04c3fSmrg      case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
50501e04c3fSmrg      case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
50601e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
50701e04c3fSmrg      case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
50801e04c3fSmrg      case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
509af69d88dSmrg         return 0;
51001e04c3fSmrg      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
51101e04c3fSmrg         return 32;
5123464ebd5Sriastradh      }
513af69d88dSmrg      /* If we get here, we failed to handle a cap above */
514af69d88dSmrg      debug_printf("Unexpected fragment shader query %u\n", param);
515af69d88dSmrg      return 0;
5163464ebd5Sriastradh   case PIPE_SHADER_VERTEX:
5173464ebd5Sriastradh      switch (param)
5183464ebd5Sriastradh      {
5193464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
5203464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
52101e04c3fSmrg         return get_uint_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS,
52201e04c3fSmrg                             512);
5233464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
5243464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
5253464ebd5Sriastradh         /* XXX: until we have vertex texture support */
5263464ebd5Sriastradh         return 0;
5273464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
5283464ebd5Sriastradh         return SVGA3D_MAX_NESTING_LEVEL;
5293464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_INPUTS:
5303464ebd5Sriastradh         return 16;
53101e04c3fSmrg      case PIPE_SHADER_CAP_MAX_OUTPUTS:
53201e04c3fSmrg         return 10;
533af69d88dSmrg      case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
534af69d88dSmrg         return 256 * sizeof(float[4]);
5353464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
5363464ebd5Sriastradh         return 1;
5373464ebd5Sriastradh      case PIPE_SHADER_CAP_MAX_TEMPS:
53801e04c3fSmrg         val = get_uint_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, 32);
53901e04c3fSmrg         return MIN2(val, SVGA3D_TEMPREG_MAX);
540af69d88dSmrg      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
541af69d88dSmrg         return 0;
542af69d88dSmrg      case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
543af69d88dSmrg         return 0;
5443464ebd5Sriastradh      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
5453464ebd5Sriastradh      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
546af69d88dSmrg         return 1;
5473464ebd5Sriastradh      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
5483464ebd5Sriastradh         return 0;
5493464ebd5Sriastradh      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
5503464ebd5Sriastradh         return 1;
5513464ebd5Sriastradh      case PIPE_SHADER_CAP_SUBROUTINES:
5523464ebd5Sriastradh         return 0;
55301e04c3fSmrg      case PIPE_SHADER_CAP_INT64_ATOMICS:
554af69d88dSmrg      case PIPE_SHADER_CAP_INTEGERS:
555af69d88dSmrg         return 0;
55601e04c3fSmrg      case PIPE_SHADER_CAP_FP16:
5577ec681f3Smrg      case PIPE_SHADER_CAP_FP16_DERIVATIVES:
5587ec681f3Smrg      case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
5597ec681f3Smrg      case PIPE_SHADER_CAP_INT16:
5607ec681f3Smrg      case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
56101e04c3fSmrg         return 0;
562af69d88dSmrg      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
563af69d88dSmrg      case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
564af69d88dSmrg         return 0;
565af69d88dSmrg      case PIPE_SHADER_CAP_PREFERRED_IR:
566af69d88dSmrg         return PIPE_SHADER_IR_TGSI;
56701e04c3fSmrg      case PIPE_SHADER_CAP_SUPPORTED_IRS:
5687ec681f3Smrg         return 1 << PIPE_SHADER_IR_TGSI;
56901e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
57001e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
57101e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
57201e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
57301e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
57401e04c3fSmrg      case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
57501e04c3fSmrg      case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
57601e04c3fSmrg      case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
57701e04c3fSmrg      case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
57801e04c3fSmrg      case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
57901e04c3fSmrg      case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
58001e04c3fSmrg         return 0;
58101e04c3fSmrg      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
58201e04c3fSmrg         return 32;
5833464ebd5Sriastradh      }
584af69d88dSmrg      /* If we get here, we failed to handle a cap above */
585af69d88dSmrg      debug_printf("Unexpected vertex shader query %u\n", param);
586af69d88dSmrg      return 0;
587af69d88dSmrg   case PIPE_SHADER_GEOMETRY:
588af69d88dSmrg   case PIPE_SHADER_COMPUTE:
58901e04c3fSmrg   case PIPE_SHADER_TESS_CTRL:
59001e04c3fSmrg   case PIPE_SHADER_TESS_EVAL:
59101e04c3fSmrg      /* no support for geometry, tess or compute shaders at this time */
592af69d88dSmrg      return 0;
5933464ebd5Sriastradh   default:
594af69d88dSmrg      debug_printf("Unexpected shader type (%u) query\n", shader);
595af69d88dSmrg      return 0;
5963464ebd5Sriastradh   }
5973464ebd5Sriastradh   return 0;
5983464ebd5Sriastradh}
5994a49301eSmrg
6004a49301eSmrg
60101e04c3fSmrgstatic int
60201e04c3fSmrgvgpu10_get_shader_param(struct pipe_screen *screen,
60301e04c3fSmrg                        enum pipe_shader_type shader,
60401e04c3fSmrg                        enum pipe_shader_cap param)
6054a49301eSmrg{
60601e04c3fSmrg   struct svga_screen *svgascreen = svga_screen(screen);
60701e04c3fSmrg   struct svga_winsys_screen *sws = svgascreen->sws;
6084a49301eSmrg
60901e04c3fSmrg   assert(sws->have_vgpu10);
61001e04c3fSmrg   (void) sws;  /* silence unused var warnings in non-debug builds */
611af69d88dSmrg
6127ec681f3Smrg   if ((!sws->have_sm5) &&
6137ec681f3Smrg       (shader == PIPE_SHADER_TESS_CTRL || shader == PIPE_SHADER_TESS_EVAL))
6147ec681f3Smrg      return 0;
6157ec681f3Smrg
6167ec681f3Smrg   if (shader == PIPE_SHADER_COMPUTE)
61701e04c3fSmrg      return 0;
618af69d88dSmrg
61901e04c3fSmrg   /* NOTE: we do not query the device for any caps/limits at this time */
6204a49301eSmrg
62101e04c3fSmrg   /* Generally the same limits for vertex, geometry and fragment shaders */
62201e04c3fSmrg   switch (param) {
62301e04c3fSmrg   case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
62401e04c3fSmrg   case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
62501e04c3fSmrg   case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
62601e04c3fSmrg   case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
62701e04c3fSmrg      return 64 * 1024;
62801e04c3fSmrg   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
62901e04c3fSmrg      return 64;
63001e04c3fSmrg   case PIPE_SHADER_CAP_MAX_INPUTS:
63101e04c3fSmrg      if (shader == PIPE_SHADER_FRAGMENT)
63201e04c3fSmrg         return VGPU10_MAX_FS_INPUTS;
63301e04c3fSmrg      else if (shader == PIPE_SHADER_GEOMETRY)
63401e04c3fSmrg         return VGPU10_MAX_GS_INPUTS;
6357ec681f3Smrg      else if (shader == PIPE_SHADER_TESS_CTRL)
6367ec681f3Smrg         return VGPU11_MAX_HS_INPUT_CONTROL_POINTS;
6377ec681f3Smrg      else if (shader == PIPE_SHADER_TESS_EVAL)
6387ec681f3Smrg         return VGPU11_MAX_DS_INPUT_CONTROL_POINTS;
63901e04c3fSmrg      else
64001e04c3fSmrg         return VGPU10_MAX_VS_INPUTS;
64101e04c3fSmrg   case PIPE_SHADER_CAP_MAX_OUTPUTS:
64201e04c3fSmrg      if (shader == PIPE_SHADER_FRAGMENT)
64301e04c3fSmrg         return VGPU10_MAX_FS_OUTPUTS;
64401e04c3fSmrg      else if (shader == PIPE_SHADER_GEOMETRY)
64501e04c3fSmrg         return VGPU10_MAX_GS_OUTPUTS;
6467ec681f3Smrg      else if (shader == PIPE_SHADER_TESS_CTRL)
6477ec681f3Smrg         return VGPU11_MAX_HS_OUTPUTS;
6487ec681f3Smrg      else if (shader == PIPE_SHADER_TESS_EVAL)
6497ec681f3Smrg         return VGPU11_MAX_DS_OUTPUTS;
65001e04c3fSmrg      else
65101e04c3fSmrg         return VGPU10_MAX_VS_OUTPUTS;
65201e04c3fSmrg   case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
65301e04c3fSmrg      return VGPU10_MAX_CONSTANT_BUFFER_ELEMENT_COUNT * sizeof(float[4]);
65401e04c3fSmrg   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
65501e04c3fSmrg      return svgascreen->max_const_buffers;
65601e04c3fSmrg   case PIPE_SHADER_CAP_MAX_TEMPS:
65701e04c3fSmrg      return VGPU10_MAX_TEMPS;
65801e04c3fSmrg   case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
65901e04c3fSmrg   case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
66001e04c3fSmrg   case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
66101e04c3fSmrg   case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
66201e04c3fSmrg      return TRUE; /* XXX verify */
66301e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
66401e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
66501e04c3fSmrg   case PIPE_SHADER_CAP_SUBROUTINES:
66601e04c3fSmrg   case PIPE_SHADER_CAP_INTEGERS:
66701e04c3fSmrg      return TRUE;
66801e04c3fSmrg   case PIPE_SHADER_CAP_FP16:
6697ec681f3Smrg   case PIPE_SHADER_CAP_FP16_DERIVATIVES:
6707ec681f3Smrg   case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
6717ec681f3Smrg   case PIPE_SHADER_CAP_INT16:
6727ec681f3Smrg   case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
67301e04c3fSmrg      return FALSE;
67401e04c3fSmrg   case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
67501e04c3fSmrg   case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
67601e04c3fSmrg      return SVGA3D_DX_MAX_SAMPLERS;
67701e04c3fSmrg   case PIPE_SHADER_CAP_PREFERRED_IR:
67801e04c3fSmrg      return PIPE_SHADER_IR_TGSI;
67901e04c3fSmrg   case PIPE_SHADER_CAP_SUPPORTED_IRS:
6807ec681f3Smrg      return 1 << PIPE_SHADER_IR_TGSI;
68101e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
68201e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
68301e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
68401e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
68501e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
68601e04c3fSmrg   case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
68701e04c3fSmrg   case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
68801e04c3fSmrg   case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
68901e04c3fSmrg   case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
69001e04c3fSmrg   case PIPE_SHADER_CAP_INT64_ATOMICS:
69101e04c3fSmrg   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
69201e04c3fSmrg   case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
69301e04c3fSmrg      return 0;
69401e04c3fSmrg   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
69501e04c3fSmrg      return 32;
69601e04c3fSmrg   default:
69701e04c3fSmrg      debug_printf("Unexpected vgpu10 shader query %u\n", param);
69801e04c3fSmrg      return 0;
6994a49301eSmrg   }
70001e04c3fSmrg   return 0;
70101e04c3fSmrg}
702af69d88dSmrg
7034a49301eSmrg
70401e04c3fSmrgstatic int
70501e04c3fSmrgsvga_get_shader_param(struct pipe_screen *screen, enum pipe_shader_type shader,
70601e04c3fSmrg                      enum pipe_shader_cap param)
70701e04c3fSmrg{
70801e04c3fSmrg   struct svga_screen *svgascreen = svga_screen(screen);
70901e04c3fSmrg   struct svga_winsys_screen *sws = svgascreen->sws;
71001e04c3fSmrg   if (sws->have_vgpu10) {
71101e04c3fSmrg      return vgpu10_get_shader_param(screen, shader, param);
712af69d88dSmrg   }
71301e04c3fSmrg   else {
71401e04c3fSmrg      return vgpu9_get_shader_param(screen, shader, param);
715af69d88dSmrg   }
7164a49301eSmrg}
7174a49301eSmrg
7184a49301eSmrg
7194a49301eSmrgstatic void
7204a49301eSmrgsvga_fence_reference(struct pipe_screen *screen,
7214a49301eSmrg                     struct pipe_fence_handle **ptr,
7224a49301eSmrg                     struct pipe_fence_handle *fence)
7234a49301eSmrg{
7244a49301eSmrg   struct svga_winsys_screen *sws = svga_screen(screen)->sws;
7254a49301eSmrg   sws->fence_reference(sws, ptr, fence);
7264a49301eSmrg}
7274a49301eSmrg
7284a49301eSmrg
7297ec681f3Smrgstatic bool
73001e04c3fSmrgsvga_fence_finish(struct pipe_screen *screen,
73101e04c3fSmrg                  struct pipe_context *ctx,
73201e04c3fSmrg                  struct pipe_fence_handle *fence,
73301e04c3fSmrg                  uint64_t timeout)
7344a49301eSmrg{
7354a49301eSmrg   struct svga_winsys_screen *sws = svga_screen(screen)->sws;
7367ec681f3Smrg   bool retVal;
73701e04c3fSmrg
73801e04c3fSmrg   SVGA_STATS_TIME_PUSH(sws, SVGA_STATS_TIME_FENCEFINISH);
73901e04c3fSmrg
74001e04c3fSmrg   if (!timeout) {
74101e04c3fSmrg      retVal = sws->fence_signalled(sws, fence, 0) == 0;
74201e04c3fSmrg   }
74301e04c3fSmrg   else {
74401e04c3fSmrg      SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n",
74501e04c3fSmrg               __FUNCTION__, fence);
74601e04c3fSmrg
74701e04c3fSmrg      retVal = sws->fence_finish(sws, fence, timeout, 0) == 0;
74801e04c3fSmrg   }
74901e04c3fSmrg
75001e04c3fSmrg   SVGA_STATS_TIME_POP(sws);
75101e04c3fSmrg
75201e04c3fSmrg   return retVal;
7534a49301eSmrg}
7544a49301eSmrg
7554a49301eSmrg
75601e04c3fSmrgstatic int
75701e04c3fSmrgsvga_fence_get_fd(struct pipe_screen *screen,
75801e04c3fSmrg                  struct pipe_fence_handle *fence)
7594a49301eSmrg{
7604a49301eSmrg   struct svga_winsys_screen *sws = svga_screen(screen)->sws;
7614a49301eSmrg
76201e04c3fSmrg   return sws->fence_get_fd(sws, fence, TRUE);
7634a49301eSmrg}
7644a49301eSmrg
7654a49301eSmrg
766af69d88dSmrgstatic int
767af69d88dSmrgsvga_get_driver_query_info(struct pipe_screen *screen,
768af69d88dSmrg                           unsigned index,
769af69d88dSmrg                           struct pipe_driver_query_info *info)
770af69d88dSmrg{
77101e04c3fSmrg#define QUERY(NAME, ENUM, UNITS) \
77201e04c3fSmrg   {NAME, ENUM, {0}, UNITS, PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE, 0, 0x0}
77301e04c3fSmrg
774af69d88dSmrg   static const struct pipe_driver_query_info queries[] = {
77501e04c3fSmrg      /* per-frame counters */
77601e04c3fSmrg      QUERY("num-draw-calls", SVGA_QUERY_NUM_DRAW_CALLS,
77701e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
77801e04c3fSmrg      QUERY("num-fallbacks", SVGA_QUERY_NUM_FALLBACKS,
77901e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
78001e04c3fSmrg      QUERY("num-flushes", SVGA_QUERY_NUM_FLUSHES,
78101e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
78201e04c3fSmrg      QUERY("num-validations", SVGA_QUERY_NUM_VALIDATIONS,
78301e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
78401e04c3fSmrg      QUERY("map-buffer-time", SVGA_QUERY_MAP_BUFFER_TIME,
78501e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_MICROSECONDS),
78601e04c3fSmrg      QUERY("num-buffers-mapped", SVGA_QUERY_NUM_BUFFERS_MAPPED,
78701e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
78801e04c3fSmrg      QUERY("num-textures-mapped", SVGA_QUERY_NUM_TEXTURES_MAPPED,
78901e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
79001e04c3fSmrg      QUERY("num-bytes-uploaded", SVGA_QUERY_NUM_BYTES_UPLOADED,
79101e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_BYTES),
7927ec681f3Smrg      QUERY("num-command-buffers", SVGA_QUERY_NUM_COMMAND_BUFFERS,
7937ec681f3Smrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
79401e04c3fSmrg      QUERY("command-buffer-size", SVGA_QUERY_COMMAND_BUFFER_SIZE,
79501e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_BYTES),
79601e04c3fSmrg      QUERY("flush-time", SVGA_QUERY_FLUSH_TIME,
79701e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_MICROSECONDS),
79801e04c3fSmrg      QUERY("surface-write-flushes", SVGA_QUERY_SURFACE_WRITE_FLUSHES,
79901e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
80001e04c3fSmrg      QUERY("num-readbacks", SVGA_QUERY_NUM_READBACKS,
80101e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
80201e04c3fSmrg      QUERY("num-resource-updates", SVGA_QUERY_NUM_RESOURCE_UPDATES,
80301e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
80401e04c3fSmrg      QUERY("num-buffer-uploads", SVGA_QUERY_NUM_BUFFER_UPLOADS,
80501e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
80601e04c3fSmrg      QUERY("num-const-buf-updates", SVGA_QUERY_NUM_CONST_BUF_UPDATES,
80701e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
80801e04c3fSmrg      QUERY("num-const-updates", SVGA_QUERY_NUM_CONST_UPDATES,
80901e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
8107ec681f3Smrg      QUERY("num-shader-relocations", SVGA_QUERY_NUM_SHADER_RELOCATIONS,
8117ec681f3Smrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
8127ec681f3Smrg      QUERY("num-surface-relocations", SVGA_QUERY_NUM_SURFACE_RELOCATIONS,
8137ec681f3Smrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
81401e04c3fSmrg
81501e04c3fSmrg      /* running total counters */
81601e04c3fSmrg      QUERY("memory-used", SVGA_QUERY_MEMORY_USED,
81701e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_BYTES),
81801e04c3fSmrg      QUERY("num-shaders", SVGA_QUERY_NUM_SHADERS,
81901e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
82001e04c3fSmrg      QUERY("num-resources", SVGA_QUERY_NUM_RESOURCES,
82101e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
82201e04c3fSmrg      QUERY("num-state-objects", SVGA_QUERY_NUM_STATE_OBJECTS,
82301e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
82401e04c3fSmrg      QUERY("num-surface-views", SVGA_QUERY_NUM_SURFACE_VIEWS,
82501e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
82601e04c3fSmrg      QUERY("num-generate-mipmap", SVGA_QUERY_NUM_GENERATE_MIPMAP,
82701e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
82801e04c3fSmrg      QUERY("num-failed-allocations", SVGA_QUERY_NUM_FAILED_ALLOCATIONS,
82901e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
83001e04c3fSmrg      QUERY("num-commands-per-draw", SVGA_QUERY_NUM_COMMANDS_PER_DRAW,
83101e04c3fSmrg            PIPE_DRIVER_QUERY_TYPE_FLOAT),
8327ec681f3Smrg      QUERY("shader-mem-used", SVGA_QUERY_SHADER_MEM_USED,
8337ec681f3Smrg            PIPE_DRIVER_QUERY_TYPE_UINT64),
834af69d88dSmrg   };
83501e04c3fSmrg#undef QUERY
836af69d88dSmrg
837af69d88dSmrg   if (!info)
83801e04c3fSmrg      return ARRAY_SIZE(queries);
839af69d88dSmrg
84001e04c3fSmrg   if (index >= ARRAY_SIZE(queries))
841af69d88dSmrg      return 0;
842af69d88dSmrg
843af69d88dSmrg   *info = queries[index];
844af69d88dSmrg   return 1;
845af69d88dSmrg}
846af69d88dSmrg
847af69d88dSmrg
84801e04c3fSmrgstatic void
84901e04c3fSmrginit_logging(struct pipe_screen *screen)
85001e04c3fSmrg{
8519f464c52Smaya   struct svga_screen *svgascreen = svga_screen(screen);
85201e04c3fSmrg   static const char *log_prefix = "Mesa: ";
85301e04c3fSmrg   char host_log[1000];
85401e04c3fSmrg
85501e04c3fSmrg   /* Log Version to Host */
8567ec681f3Smrg   snprintf(host_log, sizeof(host_log) - strlen(log_prefix),
8577ec681f3Smrg            "%s%s\n", log_prefix, svga_get_name(screen));
8589f464c52Smaya   svgascreen->sws->host_log(svgascreen->sws, host_log);
85901e04c3fSmrg
8607ec681f3Smrg   snprintf(host_log, sizeof(host_log) - strlen(log_prefix),
8617ec681f3Smrg            "%s" PACKAGE_VERSION MESA_GIT_SHA1, log_prefix);
8629f464c52Smaya   svgascreen->sws->host_log(svgascreen->sws, host_log);
86301e04c3fSmrg
86401e04c3fSmrg   /* If the SVGA_EXTRA_LOGGING env var is set, log the process's command
86501e04c3fSmrg    * line (program name and arguments).
86601e04c3fSmrg    */
86701e04c3fSmrg   if (debug_get_bool_option("SVGA_EXTRA_LOGGING", FALSE)) {
86801e04c3fSmrg      char cmdline[1000];
86901e04c3fSmrg      if (os_get_command_line(cmdline, sizeof(cmdline))) {
8707ec681f3Smrg         snprintf(host_log, sizeof(host_log) - strlen(log_prefix),
8717ec681f3Smrg                  "%s%s\n", log_prefix, cmdline);
8729f464c52Smaya         svgascreen->sws->host_log(svgascreen->sws, host_log);
87301e04c3fSmrg      }
87401e04c3fSmrg   }
87501e04c3fSmrg}
87601e04c3fSmrg
87701e04c3fSmrg
8789f464c52Smaya/**
8799f464c52Smaya * no-op logging function to use when SVGA_NO_LOGGING is set.
8809f464c52Smaya */
8819f464c52Smayastatic void
8829f464c52Smayanop_host_log(struct svga_winsys_screen *sws, const char *message)
8839f464c52Smaya{
8849f464c52Smaya   /* nothing */
8859f464c52Smaya}
8869f464c52Smaya
8879f464c52Smaya
8884a49301eSmrgstatic void
8894a49301eSmrgsvga_destroy_screen( struct pipe_screen *screen )
8904a49301eSmrg{
8914a49301eSmrg   struct svga_screen *svgascreen = svga_screen(screen);
89201e04c3fSmrg
8934a49301eSmrg   svga_screen_cache_cleanup(svgascreen);
8944a49301eSmrg
89501e04c3fSmrg   mtx_destroy(&svgascreen->swc_mutex);
89601e04c3fSmrg   mtx_destroy(&svgascreen->tex_mutex);
8974a49301eSmrg
8984a49301eSmrg   svgascreen->sws->destroy(svgascreen->sws);
89901e04c3fSmrg
9004a49301eSmrg   FREE(svgascreen);
9014a49301eSmrg}
9024a49301eSmrg
9034a49301eSmrg
9044a49301eSmrg/**
9054a49301eSmrg * Create a new svga_screen object
9064a49301eSmrg */
9074a49301eSmrgstruct pipe_screen *
9084a49301eSmrgsvga_screen_create(struct svga_winsys_screen *sws)
9094a49301eSmrg{
9104a49301eSmrg   struct svga_screen *svgascreen;
9114a49301eSmrg   struct pipe_screen *screen;
9124a49301eSmrg
9134a49301eSmrg#ifdef DEBUG
9144a49301eSmrg   SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 );
9154a49301eSmrg#endif
9164a49301eSmrg
9174a49301eSmrg   svgascreen = CALLOC_STRUCT(svga_screen);
9184a49301eSmrg   if (!svgascreen)
9194a49301eSmrg      goto error1;
9204a49301eSmrg
9214a49301eSmrg   svgascreen->debug.force_level_surface_view =
9224a49301eSmrg      debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE);
9234a49301eSmrg   svgascreen->debug.force_surface_view =
9244a49301eSmrg      debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE);
9254a49301eSmrg   svgascreen->debug.force_sampler_view =
9264a49301eSmrg      debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE);
9274a49301eSmrg   svgascreen->debug.no_surface_view =
9284a49301eSmrg      debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE);
9294a49301eSmrg   svgascreen->debug.no_sampler_view =
9304a49301eSmrg      debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE);
93101e04c3fSmrg   svgascreen->debug.no_cache_index_buffers =
93201e04c3fSmrg      debug_get_bool_option("SVGA_NO_CACHE_INDEX_BUFFERS", FALSE);
9334a49301eSmrg
9344a49301eSmrg   screen = &svgascreen->screen;
9354a49301eSmrg
9364a49301eSmrg   screen->destroy = svga_destroy_screen;
9374a49301eSmrg   screen->get_name = svga_get_name;
9384a49301eSmrg   screen->get_vendor = svga_get_vendor;
93901e04c3fSmrg   screen->get_device_vendor = svga_get_vendor; // TODO actual device vendor
9404a49301eSmrg   screen->get_param = svga_get_param;
9413464ebd5Sriastradh   screen->get_shader_param = svga_get_shader_param;
9424a49301eSmrg   screen->get_paramf = svga_get_paramf;
94301e04c3fSmrg   screen->get_timestamp = NULL;
9444a49301eSmrg   screen->is_format_supported = svga_is_format_supported;
945cdc920a0Smrg   screen->context_create = svga_context_create;
9464a49301eSmrg   screen->fence_reference = svga_fence_reference;
9474a49301eSmrg   screen->fence_finish = svga_fence_finish;
94801e04c3fSmrg   screen->fence_get_fd = svga_fence_get_fd;
94901e04c3fSmrg
950af69d88dSmrg   screen->get_driver_query_info = svga_get_driver_query_info;
9514a49301eSmrg   svgascreen->sws = sws;
9524a49301eSmrg
9533464ebd5Sriastradh   svga_init_screen_resource_functions(svgascreen);
9543464ebd5Sriastradh
9553464ebd5Sriastradh   if (sws->get_hw_version) {
9563464ebd5Sriastradh      svgascreen->hw_version = sws->get_hw_version(sws);
9573464ebd5Sriastradh   } else {
9583464ebd5Sriastradh      svgascreen->hw_version = SVGA3D_HWVERSION_WS65_B1;
9593464ebd5Sriastradh   }
9604a49301eSmrg
96101e04c3fSmrg   if (svgascreen->hw_version < SVGA3D_HWVERSION_WS8_B1) {
96201e04c3fSmrg      /* too old for 3D acceleration */
96301e04c3fSmrg      debug_printf("Hardware version 0x%x is too old for accerated 3D\n",
96401e04c3fSmrg                   svgascreen->hw_version);
96501e04c3fSmrg      goto error2;
96601e04c3fSmrg   }
9674a49301eSmrg
9687ec681f3Smrg   debug_printf("%s enabled\n",
9697ec681f3Smrg                sws->have_sm5 ? "SM5" :
9707ec681f3Smrg                sws->have_sm4_1 ? "SM4_1" :
9717ec681f3Smrg                sws->have_vgpu10 ? "VGPU10" : "VGPU9");
9724a49301eSmrg
97301e04c3fSmrg   debug_printf("Mesa: %s %s (%s)\n", svga_get_name(screen),
97401e04c3fSmrg                PACKAGE_VERSION, MESA_GIT_SHA1);
975af69d88dSmrg
976af69d88dSmrg   /*
977af69d88dSmrg    * The D16, D24X8, and D24S8 formats always do an implicit shadow compare
978af69d88dSmrg    * when sampled from, where as the DF16, DF24, and D24S8_INT do not.  So
979af69d88dSmrg    * we prefer the later when available.
980af69d88dSmrg    *
981af69d88dSmrg    * This mimics hardware vendors extensions for D3D depth sampling. See also
982af69d88dSmrg    * http://aras-p.info/texts/D3D9GPUHacks.html
983af69d88dSmrg    */
984af69d88dSmrg
985af69d88dSmrg   {
986af69d88dSmrg      boolean has_df16, has_df24, has_d24s8_int;
987af69d88dSmrg      SVGA3dSurfaceFormatCaps caps;
988af69d88dSmrg      SVGA3dSurfaceFormatCaps mask;
989af69d88dSmrg      mask.value = 0;
990af69d88dSmrg      mask.zStencil = 1;
991af69d88dSmrg      mask.texture = 1;
992af69d88dSmrg
993af69d88dSmrg      svgascreen->depth.z16 = SVGA3D_Z_D16;
994af69d88dSmrg      svgascreen->depth.x8z24 = SVGA3D_Z_D24X8;
995af69d88dSmrg      svgascreen->depth.s8z24 = SVGA3D_Z_D24S8;
996af69d88dSmrg
997af69d88dSmrg      svga_get_format_cap(svgascreen, SVGA3D_Z_DF16, &caps);
998af69d88dSmrg      has_df16 = (caps.value & mask.value) == mask.value;
999af69d88dSmrg
1000af69d88dSmrg      svga_get_format_cap(svgascreen, SVGA3D_Z_DF24, &caps);
1001af69d88dSmrg      has_df24 = (caps.value & mask.value) == mask.value;
1002af69d88dSmrg
1003af69d88dSmrg      svga_get_format_cap(svgascreen, SVGA3D_Z_D24S8_INT, &caps);
1004af69d88dSmrg      has_d24s8_int = (caps.value & mask.value) == mask.value;
1005af69d88dSmrg
1006af69d88dSmrg      /* XXX: We might want some other logic here.
1007af69d88dSmrg       * Like if we only have d24s8_int we should
1008af69d88dSmrg       * emulate the other formats with that.
1009af69d88dSmrg       */
1010af69d88dSmrg      if (has_df16) {
1011af69d88dSmrg         svgascreen->depth.z16 = SVGA3D_Z_DF16;
1012af69d88dSmrg      }
1013af69d88dSmrg      if (has_df24) {
1014af69d88dSmrg         svgascreen->depth.x8z24 = SVGA3D_Z_DF24;
1015af69d88dSmrg      }
1016af69d88dSmrg      if (has_d24s8_int) {
1017af69d88dSmrg         svgascreen->depth.s8z24 = SVGA3D_Z_D24S8_INT;
1018af69d88dSmrg      }
1019af69d88dSmrg   }
1020af69d88dSmrg
1021af69d88dSmrg   /* Query device caps
1022af69d88dSmrg    */
102301e04c3fSmrg   if (sws->have_vgpu10) {
102401e04c3fSmrg      svgascreen->haveProvokingVertex
102501e04c3fSmrg         = get_bool_cap(sws, SVGA3D_DEVCAP_DX_PROVOKING_VERTEX, FALSE);
102601e04c3fSmrg      svgascreen->haveLineSmooth = TRUE;
102701e04c3fSmrg      svgascreen->maxPointSize = 80.0F;
102801e04c3fSmrg      svgascreen->max_color_buffers = SVGA3D_DX_MAX_RENDER_TARGETS;
102901e04c3fSmrg
103001e04c3fSmrg      /* Multisample samples per pixel */
103101e04c3fSmrg      if (sws->have_sm4_1 && debug_get_bool_option("SVGA_MSAA", TRUE)) {
103201e04c3fSmrg         if (get_bool_cap(sws, SVGA3D_DEVCAP_MULTISAMPLE_2X, FALSE))
103301e04c3fSmrg            svgascreen->ms_samples |= 1 << 1;
103401e04c3fSmrg         if (get_bool_cap(sws, SVGA3D_DEVCAP_MULTISAMPLE_4X, FALSE))
103501e04c3fSmrg            svgascreen->ms_samples |= 1 << 3;
103601e04c3fSmrg      }
1037af69d88dSmrg
10387ec681f3Smrg      if (sws->have_sm5 && debug_get_bool_option("SVGA_MSAA", TRUE)) {
10397ec681f3Smrg         if (get_bool_cap(sws, SVGA3D_DEVCAP_MULTISAMPLE_8X, FALSE))
10407ec681f3Smrg            svgascreen->ms_samples |= 1 << 7;
10417ec681f3Smrg      }
10427ec681f3Smrg
104301e04c3fSmrg      /* Maximum number of constant buffers */
104401e04c3fSmrg      svgascreen->max_const_buffers =
104501e04c3fSmrg         get_uint_cap(sws, SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS, 1);
10467ec681f3Smrg      svgascreen->max_const_buffers = MIN2(svgascreen->max_const_buffers,
10477ec681f3Smrg                                           SVGA_MAX_CONST_BUFS);
10487ec681f3Smrg
10497ec681f3Smrg      svgascreen->haveBlendLogicops =
10507ec681f3Smrg         get_bool_cap(sws, SVGA3D_DEVCAP_LOGIC_BLENDOPS, FALSE);
1051af69d88dSmrg
105201e04c3fSmrg      screen->is_format_supported = svga_is_dx_format_supported;
10537ec681f3Smrg
10547ec681f3Smrg      svgascreen->max_viewports = SVGA3D_DX_MAX_VIEWPORTS;
105501e04c3fSmrg   }
105601e04c3fSmrg   else {
105701e04c3fSmrg      /* VGPU9 */
105801e04c3fSmrg      unsigned vs_ver = get_uint_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION,
105901e04c3fSmrg                                     SVGA3DVSVERSION_NONE);
106001e04c3fSmrg      unsigned fs_ver = get_uint_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION,
106101e04c3fSmrg                                     SVGA3DPSVERSION_NONE);
106201e04c3fSmrg
106301e04c3fSmrg      /* we require Shader model 3.0 or later */
106401e04c3fSmrg      if (fs_ver < SVGA3DPSVERSION_30 || vs_ver < SVGA3DVSVERSION_30) {
106501e04c3fSmrg         goto error2;
106601e04c3fSmrg      }
1067af69d88dSmrg
106801e04c3fSmrg      svgascreen->haveProvokingVertex = FALSE;
1069af69d88dSmrg
107001e04c3fSmrg      svgascreen->haveLineSmooth =
107101e04c3fSmrg         get_bool_cap(sws, SVGA3D_DEVCAP_LINE_AA, FALSE);
1072af69d88dSmrg
107301e04c3fSmrg      svgascreen->maxPointSize =
107401e04c3fSmrg         get_float_cap(sws, SVGA3D_DEVCAP_MAX_POINT_SIZE, 1.0f);
107501e04c3fSmrg      /* Keep this to a reasonable size to avoid failures in conform/pntaa.c */
107601e04c3fSmrg      svgascreen->maxPointSize = MIN2(svgascreen->maxPointSize, 80.0f);
107701e04c3fSmrg
107801e04c3fSmrg      /* The SVGA3D device always supports 4 targets at this time, regardless
107901e04c3fSmrg       * of what querying SVGA3D_DEVCAP_MAX_RENDER_TARGETS might return.
108001e04c3fSmrg       */
108101e04c3fSmrg      svgascreen->max_color_buffers = 4;
108201e04c3fSmrg
108301e04c3fSmrg      /* Only support one constant buffer
1084af69d88dSmrg       */
108501e04c3fSmrg      svgascreen->max_const_buffers = 1;
108601e04c3fSmrg
108701e04c3fSmrg      /* No multisampling */
108801e04c3fSmrg      svgascreen->ms_samples = 0;
10897ec681f3Smrg
10907ec681f3Smrg      /* Only one viewport */
10917ec681f3Smrg      svgascreen->max_viewports = 1;
1092af69d88dSmrg   }
1093af69d88dSmrg
109401e04c3fSmrg   /* common VGPU9 / VGPU10 caps */
109501e04c3fSmrg   svgascreen->haveLineStipple =
109601e04c3fSmrg      get_bool_cap(sws, SVGA3D_DEVCAP_LINE_STIPPLE, FALSE);
109701e04c3fSmrg
109801e04c3fSmrg   svgascreen->maxLineWidth =
109901e04c3fSmrg      MAX2(1.0, get_float_cap(sws, SVGA3D_DEVCAP_MAX_LINE_WIDTH, 1.0f));
110001e04c3fSmrg
110101e04c3fSmrg   svgascreen->maxLineWidthAA =
110201e04c3fSmrg      MAX2(1.0, get_float_cap(sws, SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH, 1.0f));
11034a49301eSmrg
110401e04c3fSmrg   if (0) {
110501e04c3fSmrg      debug_printf("svga: haveProvokingVertex %u\n",
110601e04c3fSmrg                   svgascreen->haveProvokingVertex);
110701e04c3fSmrg      debug_printf("svga: haveLineStip %u  "
110801e04c3fSmrg                   "haveLineSmooth %u  maxLineWidth %.2f  maxLineWidthAA %.2f\n",
110901e04c3fSmrg                   svgascreen->haveLineStipple, svgascreen->haveLineSmooth,
111001e04c3fSmrg                   svgascreen->maxLineWidth, svgascreen->maxLineWidthAA);
111101e04c3fSmrg      debug_printf("svga: maxPointSize %g\n", svgascreen->maxPointSize);
111201e04c3fSmrg      debug_printf("svga: msaa samples mask: 0x%x\n", svgascreen->ms_samples);
111301e04c3fSmrg   }
111401e04c3fSmrg
111501e04c3fSmrg   (void) mtx_init(&svgascreen->tex_mutex, mtx_plain);
111601e04c3fSmrg   (void) mtx_init(&svgascreen->swc_mutex, mtx_recursive);
11174a49301eSmrg
11184a49301eSmrg   svga_screen_cache_init(svgascreen);
11194a49301eSmrg
11209f464c52Smaya   if (debug_get_bool_option("SVGA_NO_LOGGING", FALSE) == TRUE) {
11219f464c52Smaya      svgascreen->sws->host_log = nop_host_log;
11229f464c52Smaya   } else {
11239f464c52Smaya      init_logging(screen);
11249f464c52Smaya   }
112501e04c3fSmrg
11264a49301eSmrg   return screen;
11274a49301eSmrgerror2:
11284a49301eSmrg   FREE(svgascreen);
11294a49301eSmrgerror1:
11304a49301eSmrg   return NULL;
11314a49301eSmrg}
11324a49301eSmrg
113301e04c3fSmrg
11344a49301eSmrgstruct svga_winsys_screen *
11354a49301eSmrgsvga_winsys_screen(struct pipe_screen *screen)
11364a49301eSmrg{
11374a49301eSmrg   return svga_screen(screen)->sws;
11384a49301eSmrg}
11394a49301eSmrg
114001e04c3fSmrg
11414a49301eSmrg#ifdef DEBUG
11424a49301eSmrgstruct svga_screen *
11434a49301eSmrgsvga_screen(struct pipe_screen *screen)
11444a49301eSmrg{
11454a49301eSmrg   assert(screen);
11464a49301eSmrg   assert(screen->destroy == svga_destroy_screen);
11474a49301eSmrg   return (struct svga_screen *)screen;
11484a49301eSmrg}
11494a49301eSmrg#endif
1150