1 /************************************************************************** 2 * 3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * 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 #include "os/os_time.h" 34 #include "pipe/p_defines.h" 35 #include "pipe/p_screen.h" 36 #include "draw/draw_context.h" 37 #include "vl/vl_decoder.h" 38 #include "vl/vl_video_buffer.h" 39 40 #include "state_tracker/sw_winsys.h" 41 #include "tgsi/tgsi_exec.h" 42 43 #include "sp_texture.h" 44 #include "sp_screen.h" 45 #include "sp_context.h" 46 #include "sp_fence.h" 47 #include "sp_public.h" 48 49 DEBUG_GET_ONCE_BOOL_OPTION(use_llvm, "SOFTPIPE_USE_LLVM", FALSE) 50 51 static const char * 52 softpipe_get_vendor(struct pipe_screen *screen) 53 { 54 return "VMware, Inc."; 55 } 56 57 58 static const char * 59 softpipe_get_name(struct pipe_screen *screen) 60 { 61 return "softpipe"; 62 } 63 64 65 static int 66 softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) 67 { 68 switch (param) { 69 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 70 return 2 * PIPE_MAX_SAMPLERS; /* VS + FS */ 71 case PIPE_CAP_NPOT_TEXTURES: 72 return 1; 73 case PIPE_CAP_TWO_SIDED_STENCIL: 74 return 1; 75 case PIPE_CAP_SM3: 76 return 1; 77 case PIPE_CAP_ANISOTROPIC_FILTER: 78 return 1; 79 case PIPE_CAP_POINT_SPRITE: 80 return 1; 81 case PIPE_CAP_MAX_RENDER_TARGETS: 82 return PIPE_MAX_COLOR_BUFS; 83 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 84 return 1; 85 case PIPE_CAP_OCCLUSION_QUERY: 86 return 1; 87 case PIPE_CAP_TIMER_QUERY: 88 return 1; 89 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 90 return 1; 91 case PIPE_CAP_TEXTURE_SHADOW_MAP: 92 return 1; 93 case PIPE_CAP_TEXTURE_SWIZZLE: 94 return 1; 95 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 96 return SP_MAX_TEXTURE_2D_LEVELS; 97 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 98 return SP_MAX_TEXTURE_3D_LEVELS; 99 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 100 return SP_MAX_TEXTURE_CUBE_LEVELS; 101 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 102 return 1; 103 case PIPE_CAP_INDEP_BLEND_ENABLE: 104 return 1; 105 case PIPE_CAP_INDEP_BLEND_FUNC: 106 return 1; 107 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 108 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 109 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 110 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 111 return 1; 112 case PIPE_CAP_DEPTH_CLIP_DISABLE: 113 return 0; 114 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 115 return PIPE_MAX_SO_BUFFERS; 116 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 117 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 118 return 16*4; 119 case PIPE_CAP_PRIMITIVE_RESTART: 120 return 1; 121 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: 122 return 0; 123 case PIPE_CAP_SHADER_STENCIL_EXPORT: 124 return 1; 125 case PIPE_CAP_TGSI_INSTANCEID: 126 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 127 return 1; 128 case PIPE_CAP_SEAMLESS_CUBE_MAP: 129 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 130 return 0; 131 case PIPE_CAP_SCALED_RESOLVE: 132 return 0; 133 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 134 return 256; /* for GL3 */ 135 case PIPE_CAP_MIN_TEXEL_OFFSET: 136 return -8; 137 case PIPE_CAP_MAX_TEXEL_OFFSET: 138 return 7; 139 case PIPE_CAP_CONDITIONAL_RENDER: 140 return 1; 141 case PIPE_CAP_TEXTURE_BARRIER: 142 return 0; 143 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: 144 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: /* draw module */ 145 case PIPE_CAP_VERTEX_COLOR_CLAMPED: /* draw module */ 146 return 1; 147 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 148 return 0; 149 case PIPE_CAP_GLSL_FEATURE_LEVEL: 150 return 130; 151 case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 152 return 0; 153 case PIPE_CAP_COMPUTE: 154 return 0; 155 case PIPE_CAP_USER_VERTEX_BUFFERS: 156 case PIPE_CAP_USER_INDEX_BUFFERS: 157 case PIPE_CAP_USER_CONSTANT_BUFFERS: 158 return 1; 159 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 160 return 16; 161 case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 162 case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS: 163 case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: 164 case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: 165 case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: 166 case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: 167 case PIPE_CAP_START_INSTANCE: 168 return 0; 169 case PIPE_CAP_QUERY_TIMESTAMP: 170 return 1; 171 } 172 /* should only get here on unhandled cases */ 173 debug_printf("Unexpected PIPE_CAP %d query\n", param); 174 return 0; 175 } 176 177 static int 178 softpipe_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param) 179 { 180 struct softpipe_screen *sp_screen = softpipe_screen(screen); 181 switch(shader) 182 { 183 case PIPE_SHADER_FRAGMENT: 184 return tgsi_exec_get_shader_param(param); 185 case PIPE_SHADER_VERTEX: 186 case PIPE_SHADER_GEOMETRY: 187 switch (param) { 188 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 189 if (sp_screen->use_llvm) 190 /* Softpipe doesn't yet know how to tell draw/llvm about textures */ 191 return 0; 192 else 193 return PIPE_MAX_SAMPLERS; 194 default: 195 if (sp_screen->use_llvm) 196 return draw_get_shader_param(shader, param); 197 else 198 return draw_get_shader_param_no_llvm(shader, param); 199 } 200 default: 201 return 0; 202 } 203 } 204 205 static float 206 softpipe_get_paramf(struct pipe_screen *screen, enum pipe_capf param) 207 { 208 switch (param) { 209 case PIPE_CAPF_MAX_LINE_WIDTH: 210 /* fall-through */ 211 case PIPE_CAPF_MAX_LINE_WIDTH_AA: 212 return 255.0; /* arbitrary */ 213 case PIPE_CAPF_MAX_POINT_WIDTH: 214 /* fall-through */ 215 case PIPE_CAPF_MAX_POINT_WIDTH_AA: 216 return 255.0; /* arbitrary */ 217 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 218 return 16.0; 219 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 220 return 16.0; /* arbitrary */ 221 case PIPE_CAPF_GUARD_BAND_LEFT: 222 case PIPE_CAPF_GUARD_BAND_TOP: 223 case PIPE_CAPF_GUARD_BAND_RIGHT: 224 case PIPE_CAPF_GUARD_BAND_BOTTOM: 225 return 0.0; 226 } 227 /* should only get here on unhandled cases */ 228 debug_printf("Unexpected PIPE_CAPF %d query\n", param); 229 return 0.0; 230 } 231 232 static int 233 softpipe_get_video_param(struct pipe_screen *screen, 234 enum pipe_video_profile profile, 235 enum pipe_video_cap param) 236 { 237 switch (param) { 238 case PIPE_VIDEO_CAP_SUPPORTED: 239 return vl_profile_supported(screen, profile); 240 case PIPE_VIDEO_CAP_NPOT_TEXTURES: 241 return 0; 242 case PIPE_VIDEO_CAP_MAX_WIDTH: 243 case PIPE_VIDEO_CAP_MAX_HEIGHT: 244 return vl_video_buffer_max_size(screen); 245 case PIPE_VIDEO_CAP_PREFERED_FORMAT: 246 return PIPE_FORMAT_NV12; 247 case PIPE_VIDEO_CAP_PREFERS_INTERLACED: 248 return false; 249 case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED: 250 return false; 251 case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE: 252 return true; 253 default: 254 return 0; 255 } 256 } 257 258 /** 259 * Query format support for creating a texture, drawing surface, etc. 260 * \param format the format to test 261 * \param type one of PIPE_TEXTURE, PIPE_SURFACE 262 */ 263 static boolean 264 softpipe_is_format_supported( struct pipe_screen *screen, 265 enum pipe_format format, 266 enum pipe_texture_target target, 267 unsigned sample_count, 268 unsigned bind) 269 { 270 struct sw_winsys *winsys = softpipe_screen(screen)->winsys; 271 const struct util_format_description *format_desc; 272 273 assert(target == PIPE_BUFFER || 274 target == PIPE_TEXTURE_1D || 275 target == PIPE_TEXTURE_1D_ARRAY || 276 target == PIPE_TEXTURE_2D || 277 target == PIPE_TEXTURE_2D_ARRAY || 278 target == PIPE_TEXTURE_RECT || 279 target == PIPE_TEXTURE_3D || 280 target == PIPE_TEXTURE_CUBE); 281 282 format_desc = util_format_description(format); 283 if (!format_desc) 284 return FALSE; 285 286 if (sample_count > 1) 287 return FALSE; 288 289 if (bind & (PIPE_BIND_DISPLAY_TARGET | 290 PIPE_BIND_SCANOUT | 291 PIPE_BIND_SHARED)) { 292 if(!winsys->is_displaytarget_format_supported(winsys, bind, format)) 293 return FALSE; 294 } 295 296 if (bind & PIPE_BIND_RENDER_TARGET) { 297 if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) 298 return FALSE; 299 300 /* 301 * Although possible, it is unnatural to render into compressed or YUV 302 * surfaces. So disable these here to avoid going into weird paths 303 * inside the state trackers. 304 */ 305 if (format_desc->block.width != 1 || 306 format_desc->block.height != 1) 307 return FALSE; 308 } 309 310 if (bind & PIPE_BIND_DEPTH_STENCIL) { 311 if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) 312 return FALSE; 313 } 314 315 /* 316 * All other operations (sampling, transfer, etc). 317 */ 318 319 if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { 320 return util_format_s3tc_enabled; 321 } 322 323 /* 324 * Everything else should be supported by u_format. 325 */ 326 return TRUE; 327 } 328 329 330 static void 331 softpipe_destroy_screen( struct pipe_screen *screen ) 332 { 333 struct softpipe_screen *sp_screen = softpipe_screen(screen); 334 struct sw_winsys *winsys = sp_screen->winsys; 335 336 if(winsys->destroy) 337 winsys->destroy(winsys); 338 339 FREE(screen); 340 } 341 342 343 /* This is often overriden by the co-state tracker. 344 */ 345 static void 346 softpipe_flush_frontbuffer(struct pipe_screen *_screen, 347 struct pipe_resource *resource, 348 unsigned level, unsigned layer, 349 void *context_private) 350 { 351 struct softpipe_screen *screen = softpipe_screen(_screen); 352 struct sw_winsys *winsys = screen->winsys; 353 struct softpipe_resource *texture = softpipe_resource(resource); 354 355 assert(texture->dt); 356 if (texture->dt) 357 winsys->displaytarget_display(winsys, texture->dt, context_private); 358 } 359 360 static uint64_t 361 softpipe_get_timestamp(struct pipe_screen *_screen) 362 { 363 return os_time_get()*1000; 364 } 365 366 /** 367 * Create a new pipe_screen object 368 * Note: we're not presently subclassing pipe_screen (no softpipe_screen). 369 */ 370 struct pipe_screen * 371 softpipe_create_screen(struct sw_winsys *winsys) 372 { 373 struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen); 374 375 if (!screen) 376 return NULL; 377 378 screen->winsys = winsys; 379 380 screen->base.destroy = softpipe_destroy_screen; 381 382 screen->base.get_name = softpipe_get_name; 383 screen->base.get_vendor = softpipe_get_vendor; 384 screen->base.get_param = softpipe_get_param; 385 screen->base.get_shader_param = softpipe_get_shader_param; 386 screen->base.get_paramf = softpipe_get_paramf; 387 screen->base.get_video_param = softpipe_get_video_param; 388 screen->base.get_timestamp = softpipe_get_timestamp; 389 screen->base.is_format_supported = softpipe_is_format_supported; 390 screen->base.is_video_format_supported = vl_video_buffer_is_format_supported; 391 screen->base.context_create = softpipe_create_context; 392 screen->base.flush_frontbuffer = softpipe_flush_frontbuffer; 393 394 screen->use_llvm = debug_get_option_use_llvm(); 395 396 util_format_s3tc_init(); 397 398 softpipe_init_screen_texture_funcs(&screen->base); 399 softpipe_init_screen_fence_funcs(&screen->base); 400 401 return &screen->base; 402 } 403