sp_screen.c 10 KB
Newer Older
1
/**************************************************************************
2
 *
3 4
 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
 * All Rights Reserved.
5
 *
6 7 8 9 10 11 12
 * 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, sub license, 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:
13
 *
14 15 16
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
17
 *
18 19 20 21 22 23 24
 * 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 NON-INFRINGEMENT.
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
25
 *
26 27 28
 **************************************************************************/


29
#include "util/u_memory.h"
30
#include "util/u_format.h"
31
#include "util/u_format_s3tc.h"
32
#include "util/u_video.h"
33 34
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
35
#include "draw/draw_context.h"
36
#include "vl/vl_decoder.h"
37
#include "vl/vl_video_buffer.h"
38

39
#include "state_tracker/sw_winsys.h"
40
#include "tgsi/tgsi_exec.h"
41

42
#include "sp_texture.h"
43
#include "sp_screen.h"
44
#include "sp_context.h"
45
#include "sp_fence.h"
46
#include "sp_public.h"
47 48 49 50 51


static const char *
softpipe_get_vendor(struct pipe_screen *screen)
{
Jose Fonseca's avatar
Jose Fonseca committed
52
   return "VMware, Inc.";
53 54 55 56 57 58 59 60 61 62 63
}


static const char *
softpipe_get_name(struct pipe_screen *screen)
{
   return "softpipe";
}


static int
64
softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
65 66 67
{
   switch (param) {
   case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
68
      return PIPE_MAX_SAMPLERS;
69
   case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
70 71 72 73
#ifdef HAVE_LLVM
      /* Softpipe doesn't yet know how to tell draw/llvm about textures */
      return 0;
#else
74
      return PIPE_MAX_VERTEX_SAMPLERS;
75
#endif
76 77
   case PIPE_CAP_MAX_COMBINED_SAMPLERS:
      return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
78 79 80 81 82 83
   case PIPE_CAP_NPOT_TEXTURES:
      return 1;
   case PIPE_CAP_TWO_SIDED_STENCIL:
      return 1;
   case PIPE_CAP_GLSL:
      return 1;
84 85
   case PIPE_CAP_SM3:
      return 1;
86
   case PIPE_CAP_ANISOTROPIC_FILTER:
87
      return 1;
88 89 90
   case PIPE_CAP_POINT_SPRITE:
      return 1;
   case PIPE_CAP_MAX_RENDER_TARGETS:
91
      return PIPE_MAX_COLOR_BUFS;
92 93
   case PIPE_CAP_OCCLUSION_QUERY:
      return 1;
94 95
   case PIPE_CAP_TIMER_QUERY:
      return 1;
96 97 98 99
   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
      return 1;
   case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
      return 1;
100 101
   case PIPE_CAP_TEXTURE_SHADOW_MAP:
      return 1;
102 103
   case PIPE_CAP_TEXTURE_SWIZZLE:
      return 1;
104
   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
105
      return SP_MAX_TEXTURE_2D_LEVELS;
106
   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
107
      return SP_MAX_TEXTURE_3D_LEVELS;
108
   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
109
      return SP_MAX_TEXTURE_2D_LEVELS;
110 111
   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
      return 1;
112 113 114 115
   case PIPE_CAP_INDEP_BLEND_ENABLE:
      return 1;
   case PIPE_CAP_INDEP_BLEND_FUNC:
      return 1;
116 117 118
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
119 120
   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
      return 1;
121 122
   case PIPE_CAP_STREAM_OUTPUT:
      return 1;
123 124
   case PIPE_CAP_PRIMITIVE_RESTART:
      return 1;
125 126
   case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
      return 0;
127 128
   case PIPE_CAP_SHADER_STENCIL_EXPORT:
      return 1;
129 130
   case PIPE_CAP_TGSI_INSTANCEID:
   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
131
      return 1;
132 133
   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
      return 64; /* matches core Mesa defaults */
134 135 136 137
   case PIPE_CAP_MIN_TEXEL_OFFSET:
      return -8;
   case PIPE_CAP_MAX_TEXEL_OFFSET:
      return 7;
138 139 140 141 142
   default:
      return 0;
   }
}

143 144 145 146 147 148 149 150 151 152 153 154 155 156
static int
softpipe_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param)
{
   switch(shader)
   {
   case PIPE_SHADER_FRAGMENT:
      return tgsi_exec_get_shader_param(param);
   case PIPE_SHADER_VERTEX:
   case PIPE_SHADER_GEOMETRY:
      return draw_get_shader_param(shader, param);
   default:
      return 0;
   }
}
157 158

static float
159
softpipe_get_paramf(struct pipe_screen *screen, enum pipe_cap param)
160 161 162 163 164 165 166 167 168 169 170
{
   switch (param) {
   case PIPE_CAP_MAX_LINE_WIDTH:
      /* fall-through */
   case PIPE_CAP_MAX_LINE_WIDTH_AA:
      return 255.0; /* arbitrary */
   case PIPE_CAP_MAX_POINT_WIDTH:
      /* fall-through */
   case PIPE_CAP_MAX_POINT_WIDTH_AA:
      return 255.0; /* arbitrary */
   case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
171
      return 16.0;
172 173 174 175 176 177 178
   case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
      return 16.0; /* arbitrary */
   default:
      return 0;
   }
}

179 180 181 182 183 184
static int
softpipe_get_video_param(struct pipe_screen *screen,
                         enum pipe_video_profile profile,
                         enum pipe_video_cap param)
{
   switch (param) {
185 186
   case PIPE_VIDEO_CAP_SUPPORTED:
       return vl_profile_supported(screen, profile);
187 188
   case PIPE_VIDEO_CAP_NPOT_TEXTURES:
      return 0;
189 190 191
   case PIPE_VIDEO_CAP_MAX_WIDTH:
   case PIPE_VIDEO_CAP_MAX_HEIGHT:
      return vl_video_buffer_max_size(screen);
192 193
   case PIPE_VIDEO_CAP_NUM_BUFFERS_DESIRED:
      return vl_num_buffers_desired(screen, profile);
194 195 196 197
   default:
      return 0;
   }
}
198

199 200 201 202 203 204 205
/**
 * Query format support for creating a texture, drawing surface, etc.
 * \param format  the format to test
 * \param type  one of PIPE_TEXTURE, PIPE_SURFACE
 */
static boolean
softpipe_is_format_supported( struct pipe_screen *screen,
206
                              enum pipe_format format,
207
                              enum pipe_texture_target target,
208
                              unsigned sample_count,
209
                              unsigned bind)
210
{
211
   struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
212
   const struct util_format_description *format_desc;
213

214 215
   assert(target == PIPE_BUFFER ||
          target == PIPE_TEXTURE_1D ||
216
          target == PIPE_TEXTURE_1D_ARRAY ||
217
          target == PIPE_TEXTURE_2D ||
218
          target == PIPE_TEXTURE_2D_ARRAY ||
219
          target == PIPE_TEXTURE_RECT ||
220 221 222
          target == PIPE_TEXTURE_3D ||
          target == PIPE_TEXTURE_CUBE);

223 224 225 226
   format_desc = util_format_description(format);
   if (!format_desc)
      return FALSE;

227 228 229
   if (sample_count > 1)
      return FALSE;

230 231 232 233
   if (bind & (PIPE_BIND_DISPLAY_TARGET |
               PIPE_BIND_SCANOUT |
               PIPE_BIND_SHARED)) {
      if(!winsys->is_displaytarget_format_supported(winsys, bind, format))
234
         return FALSE;
235
   }
236

237 238 239
   if (bind & PIPE_BIND_RENDER_TARGET) {
      if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
         return FALSE;
240

241 242 243 244 245 246 247 248
      /*
       * Although possible, it is unnatural to render into compressed or YUV
       * surfaces. So disable these here to avoid going into weird paths
       * inside the state trackers.
       */
      if (format_desc->block.width != 1 ||
          format_desc->block.height != 1)
         return FALSE;
249 250
   }

251 252
   if (bind & PIPE_BIND_DEPTH_STENCIL) {
      if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
253
         return FALSE;
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274

      /*
       * TODO: Unfortunately we cannot render into anything more than 32 bits
       * because we encode depth and stencil clear values into a 32bit word.
       */
      if (format_desc->block.bits > 32)
         return FALSE;

      /*
       * TODO: eliminate this restriction
       */
      if (format == PIPE_FORMAT_Z32_FLOAT)
         return FALSE;
   }

   /*
    * All other operations (sampling, transfer, etc).
    */

   if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
      return util_format_s3tc_enabled;
275 276
   }

277 278
   /*
    * Everything else should be supported by u_format.
279
    */
280
   return TRUE;
281 282 283
}


284 285 286
static void
softpipe_destroy_screen( struct pipe_screen *screen )
{
287 288
   struct softpipe_screen *sp_screen = softpipe_screen(screen);
   struct sw_winsys *winsys = sp_screen->winsys;
289 290 291 292

   if(winsys->destroy)
      winsys->destroy(winsys);

293 294 295 296
   FREE(screen);
}


297 298 299 300
/* This is often overriden by the co-state tracker.
 */
static void
softpipe_flush_frontbuffer(struct pipe_screen *_screen,
301 302
                           struct pipe_resource *resource,
                           unsigned level, unsigned layer,
303 304 305 306
                           void *context_private)
{
   struct softpipe_screen *screen = softpipe_screen(_screen);
   struct sw_winsys *winsys = screen->winsys;
307
   struct softpipe_resource *texture = softpipe_resource(resource);
308 309 310 311 312

   assert(texture->dt);
   if (texture->dt)
      winsys->displaytarget_display(winsys, texture->dt, context_private);
}
313

314 315 316 317 318
/**
 * Create a new pipe_screen object
 * Note: we're not presently subclassing pipe_screen (no softpipe_screen).
 */
struct pipe_screen *
319
softpipe_create_screen(struct sw_winsys *winsys)
320
{
321
   struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen);
322 323 324 325

   if (!screen)
      return NULL;

326
   screen->winsys = winsys;
327

328
   screen->base.winsys = NULL;
329
   screen->base.destroy = softpipe_destroy_screen;
330

331 332 333
   screen->base.get_name = softpipe_get_name;
   screen->base.get_vendor = softpipe_get_vendor;
   screen->base.get_param = softpipe_get_param;
334
   screen->base.get_shader_param = softpipe_get_shader_param;
335
   screen->base.get_paramf = softpipe_get_paramf;
336
   screen->base.get_video_param = softpipe_get_video_param;
337
   screen->base.is_format_supported = softpipe_is_format_supported;
338
   screen->base.is_video_format_supported = vl_video_buffer_is_format_supported;
339
   screen->base.context_create = softpipe_create_context;
340
   screen->base.flush_frontbuffer = softpipe_flush_frontbuffer;
341

342 343
   util_format_s3tc_init();

344
   softpipe_init_screen_texture_funcs(&screen->base);
345
   softpipe_init_screen_fence_funcs(&screen->base);
346

347
   return &screen->base;
348
}