sp_screen.c revision af69d88d
1/************************************************************************** 2 * 3 * Copyright 2008 VMware, Inc. 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 VMWARE 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_misc.h" 34#include "os/os_time.h" 35#include "pipe/p_defines.h" 36#include "pipe/p_screen.h" 37#include "draw/draw_context.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 48DEBUG_GET_ONCE_BOOL_OPTION(use_llvm, "SOFTPIPE_USE_LLVM", FALSE) 49 50static const char * 51softpipe_get_vendor(struct pipe_screen *screen) 52{ 53 return "VMware, Inc."; 54} 55 56 57static const char * 58softpipe_get_name(struct pipe_screen *screen) 59{ 60 return "softpipe"; 61} 62 63 64static int 65softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) 66{ 67 switch (param) { 68 case PIPE_CAP_NPOT_TEXTURES: 69 case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 70 return 1; 71 case PIPE_CAP_TWO_SIDED_STENCIL: 72 return 1; 73 case PIPE_CAP_SM3: 74 return 1; 75 case PIPE_CAP_ANISOTROPIC_FILTER: 76 return 1; 77 case PIPE_CAP_POINT_SPRITE: 78 return 1; 79 case PIPE_CAP_MAX_RENDER_TARGETS: 80 return PIPE_MAX_COLOR_BUFS; 81 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 82 return 1; 83 case PIPE_CAP_OCCLUSION_QUERY: 84 return 1; 85 case PIPE_CAP_QUERY_TIME_ELAPSED: 86 return 1; 87 case PIPE_CAP_QUERY_PIPELINE_STATISTICS: 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_TEXTURE_BORDER_COLOR_QUIRK: 96 return 0; 97 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 98 return SP_MAX_TEXTURE_2D_LEVELS; 99 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 100 return SP_MAX_TEXTURE_3D_LEVELS; 101 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 102 return SP_MAX_TEXTURE_CUBE_LEVELS; 103 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 104 return 1; 105 case PIPE_CAP_INDEP_BLEND_ENABLE: 106 return 1; 107 case PIPE_CAP_INDEP_BLEND_FUNC: 108 return 1; 109 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 110 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 111 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 112 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 113 return 1; 114 case PIPE_CAP_DEPTH_CLIP_DISABLE: 115 return 1; 116 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 117 return PIPE_MAX_SO_BUFFERS; 118 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 119 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 120 return 16*4; 121 case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: 122 case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: 123 return 1024; 124 case PIPE_CAP_MAX_VERTEX_STREAMS: 125 return 1; 126 case PIPE_CAP_PRIMITIVE_RESTART: 127 return 1; 128 case PIPE_CAP_SHADER_STENCIL_EXPORT: 129 return 1; 130 case PIPE_CAP_TGSI_INSTANCEID: 131 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 132 return 1; 133 case PIPE_CAP_SEAMLESS_CUBE_MAP: 134 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 135 return 1; 136 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 137 return 256; /* for GL3 */ 138 case PIPE_CAP_MIN_TEXEL_OFFSET: 139 return -8; 140 case PIPE_CAP_MAX_TEXEL_OFFSET: 141 return 7; 142 case PIPE_CAP_CONDITIONAL_RENDER: 143 return 1; 144 case PIPE_CAP_TEXTURE_BARRIER: 145 return 0; 146 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: 147 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: /* draw module */ 148 case PIPE_CAP_VERTEX_COLOR_CLAMPED: /* draw module */ 149 return 1; 150 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 151 return 0; 152 case PIPE_CAP_GLSL_FEATURE_LEVEL: 153 return 330; 154 case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 155 return 0; 156 case PIPE_CAP_COMPUTE: 157 return 0; 158 case PIPE_CAP_USER_VERTEX_BUFFERS: 159 case PIPE_CAP_USER_INDEX_BUFFERS: 160 case PIPE_CAP_USER_CONSTANT_BUFFERS: 161 case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 162 case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT: 163 return 1; 164 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 165 return 16; 166 case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: 167 case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: 168 case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: 169 case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: 170 case PIPE_CAP_START_INSTANCE: 171 case PIPE_CAP_TEXTURE_MULTISAMPLE: 172 return 0; 173 case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: 174 return 64; 175 case PIPE_CAP_QUERY_TIMESTAMP: 176 case PIPE_CAP_CUBE_MAP_ARRAY: 177 return 1; 178 case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: 179 return 1; 180 case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE: 181 return 65536; 182 case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: 183 return 0; 184 case PIPE_CAP_TGSI_TEXCOORD: 185 case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: 186 return 0; 187 case PIPE_CAP_MAX_VIEWPORTS: 188 return 1; 189 case PIPE_CAP_ENDIANNESS: 190 return PIPE_ENDIAN_NATIVE; 191 case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: 192 case PIPE_CAP_TEXTURE_GATHER_SM5: 193 case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: 194 case PIPE_CAP_TEXTURE_QUERY_LOD: 195 case PIPE_CAP_SAMPLE_SHADING: 196 case PIPE_CAP_TEXTURE_GATHER_OFFSETS: 197 case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION: 198 case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE: 199 return 0; 200 case PIPE_CAP_FAKE_SW_MSAA: 201 return 1; 202 case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: 203 case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: 204 return 0; 205 case PIPE_CAP_DRAW_INDIRECT: 206 return 1; 207 208 case PIPE_CAP_VENDOR_ID: 209 return 0xFFFFFFFF; 210 case PIPE_CAP_DEVICE_ID: 211 return 0xFFFFFFFF; 212 case PIPE_CAP_ACCELERATED: 213 return 0; 214 case PIPE_CAP_VIDEO_MEMORY: { 215 /* XXX: Do we want to return the full amount fo system memory ? */ 216 uint64_t system_memory; 217 218 if (!os_get_total_physical_memory(&system_memory)) 219 return 0; 220 221 return (int)(system_memory >> 20); 222 } 223 case PIPE_CAP_UMA: 224 return 0; 225 case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: 226 return 1; 227 } 228 /* should only get here on unhandled cases */ 229 debug_printf("Unexpected PIPE_CAP %d query\n", param); 230 return 0; 231} 232 233static int 234softpipe_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param) 235{ 236 struct softpipe_screen *sp_screen = softpipe_screen(screen); 237 switch(shader) 238 { 239 case PIPE_SHADER_FRAGMENT: 240 return tgsi_exec_get_shader_param(param); 241 case PIPE_SHADER_VERTEX: 242 case PIPE_SHADER_GEOMETRY: 243 switch (param) { 244 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 245 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 246 if (sp_screen->use_llvm) 247 /* Softpipe doesn't yet know how to tell draw/llvm about textures */ 248 return 0; 249 else 250 return PIPE_MAX_SAMPLERS; 251 default: 252 if (sp_screen->use_llvm) 253 return draw_get_shader_param(shader, param); 254 else 255 return draw_get_shader_param_no_llvm(shader, param); 256 } 257 default: 258 return 0; 259 } 260} 261 262static float 263softpipe_get_paramf(struct pipe_screen *screen, enum pipe_capf param) 264{ 265 switch (param) { 266 case PIPE_CAPF_MAX_LINE_WIDTH: 267 /* fall-through */ 268 case PIPE_CAPF_MAX_LINE_WIDTH_AA: 269 return 255.0; /* arbitrary */ 270 case PIPE_CAPF_MAX_POINT_WIDTH: 271 /* fall-through */ 272 case PIPE_CAPF_MAX_POINT_WIDTH_AA: 273 return 255.0; /* arbitrary */ 274 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 275 return 16.0; 276 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 277 return 16.0; /* arbitrary */ 278 case PIPE_CAPF_GUARD_BAND_LEFT: 279 case PIPE_CAPF_GUARD_BAND_TOP: 280 case PIPE_CAPF_GUARD_BAND_RIGHT: 281 case PIPE_CAPF_GUARD_BAND_BOTTOM: 282 return 0.0; 283 } 284 /* should only get here on unhandled cases */ 285 debug_printf("Unexpected PIPE_CAPF %d query\n", param); 286 return 0.0; 287} 288 289/** 290 * Query format support for creating a texture, drawing surface, etc. 291 * \param format the format to test 292 * \param type one of PIPE_TEXTURE, PIPE_SURFACE 293 */ 294static boolean 295softpipe_is_format_supported( struct pipe_screen *screen, 296 enum pipe_format format, 297 enum pipe_texture_target target, 298 unsigned sample_count, 299 unsigned bind) 300{ 301 struct sw_winsys *winsys = softpipe_screen(screen)->winsys; 302 const struct util_format_description *format_desc; 303 304 assert(target == PIPE_BUFFER || 305 target == PIPE_TEXTURE_1D || 306 target == PIPE_TEXTURE_1D_ARRAY || 307 target == PIPE_TEXTURE_2D || 308 target == PIPE_TEXTURE_2D_ARRAY || 309 target == PIPE_TEXTURE_RECT || 310 target == PIPE_TEXTURE_3D || 311 target == PIPE_TEXTURE_CUBE || 312 target == PIPE_TEXTURE_CUBE_ARRAY); 313 314 format_desc = util_format_description(format); 315 if (!format_desc) 316 return FALSE; 317 318 if (sample_count > 1) 319 return FALSE; 320 321 if (bind & (PIPE_BIND_DISPLAY_TARGET | 322 PIPE_BIND_SCANOUT | 323 PIPE_BIND_SHARED)) { 324 if(!winsys->is_displaytarget_format_supported(winsys, bind, format)) 325 return FALSE; 326 } 327 328 if (bind & PIPE_BIND_RENDER_TARGET) { 329 if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) 330 return FALSE; 331 332 /* 333 * Although possible, it is unnatural to render into compressed or YUV 334 * surfaces. So disable these here to avoid going into weird paths 335 * inside the state trackers. 336 */ 337 if (format_desc->block.width != 1 || 338 format_desc->block.height != 1) 339 return FALSE; 340 } 341 342 if (bind & PIPE_BIND_DEPTH_STENCIL) { 343 if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) 344 return FALSE; 345 } 346 347 if (format_desc->layout == UTIL_FORMAT_LAYOUT_BPTC) { 348 /* Software decoding is not hooked up. */ 349 return FALSE; 350 } 351 352 /* 353 * All other operations (sampling, transfer, etc). 354 */ 355 356 if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { 357 return util_format_s3tc_enabled; 358 } 359 360 /* 361 * Everything else should be supported by u_format. 362 */ 363 return TRUE; 364} 365 366 367static void 368softpipe_destroy_screen( struct pipe_screen *screen ) 369{ 370 struct softpipe_screen *sp_screen = softpipe_screen(screen); 371 struct sw_winsys *winsys = sp_screen->winsys; 372 373 if(winsys->destroy) 374 winsys->destroy(winsys); 375 376 FREE(screen); 377} 378 379 380/* This is often overriden by the co-state tracker. 381 */ 382static void 383softpipe_flush_frontbuffer(struct pipe_screen *_screen, 384 struct pipe_resource *resource, 385 unsigned level, unsigned layer, 386 void *context_private, 387 struct pipe_box *sub_box) 388{ 389 struct softpipe_screen *screen = softpipe_screen(_screen); 390 struct sw_winsys *winsys = screen->winsys; 391 struct softpipe_resource *texture = softpipe_resource(resource); 392 393 assert(texture->dt); 394 if (texture->dt) 395 winsys->displaytarget_display(winsys, texture->dt, context_private, sub_box); 396} 397 398static uint64_t 399softpipe_get_timestamp(struct pipe_screen *_screen) 400{ 401 return os_time_get_nano(); 402} 403 404/** 405 * Create a new pipe_screen object 406 * Note: we're not presently subclassing pipe_screen (no softpipe_screen). 407 */ 408struct pipe_screen * 409softpipe_create_screen(struct sw_winsys *winsys) 410{ 411 struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen); 412 413 if (!screen) 414 return NULL; 415 416 screen->winsys = winsys; 417 418 screen->base.destroy = softpipe_destroy_screen; 419 420 screen->base.get_name = softpipe_get_name; 421 screen->base.get_vendor = softpipe_get_vendor; 422 screen->base.get_param = softpipe_get_param; 423 screen->base.get_shader_param = softpipe_get_shader_param; 424 screen->base.get_paramf = softpipe_get_paramf; 425 screen->base.get_timestamp = softpipe_get_timestamp; 426 screen->base.is_format_supported = softpipe_is_format_supported; 427 screen->base.context_create = softpipe_create_context; 428 screen->base.flush_frontbuffer = softpipe_flush_frontbuffer; 429 430 screen->use_llvm = debug_get_option_use_llvm(); 431 432 util_format_s3tc_init(); 433 434 softpipe_init_screen_texture_funcs(&screen->base); 435 softpipe_init_screen_fence_funcs(&screen->base); 436 437 return &screen->base; 438} 439