i915_screen.c revision b8e80941
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 "draw/draw_context.h"
30#include "util/os_misc.h"
31#include "util/u_format.h"
32#include "util/u_format_s3tc.h"
33#include "util/u_inlines.h"
34#include "util/u_memory.h"
35#include "util/u_screen.h"
36#include "util/u_string.h"
37
38#include "i915_reg.h"
39#include "i915_debug.h"
40#include "i915_context.h"
41#include "i915_screen.h"
42#include "i915_resource.h"
43#include "i915_winsys.h"
44#include "i915_public.h"
45
46
47/*
48 * Probe functions
49 */
50
51
52static const char *
53i915_get_vendor(struct pipe_screen *screen)
54{
55   return "Mesa Project";
56}
57
58static const char *
59i915_get_device_vendor(struct pipe_screen *screen)
60{
61   return "Intel";
62}
63
64static const char *
65i915_get_name(struct pipe_screen *screen)
66{
67   static char buffer[128];
68   const char *chipset;
69
70   switch (i915_screen(screen)->iws->pci_id) {
71   case PCI_CHIP_I915_G:
72      chipset = "915G";
73      break;
74   case PCI_CHIP_I915_GM:
75      chipset = "915GM";
76      break;
77   case PCI_CHIP_I945_G:
78      chipset = "945G";
79      break;
80   case PCI_CHIP_I945_GM:
81      chipset = "945GM";
82      break;
83   case PCI_CHIP_I945_GME:
84      chipset = "945GME";
85      break;
86   case PCI_CHIP_G33_G:
87      chipset = "G33";
88      break;
89   case PCI_CHIP_Q35_G:
90      chipset = "Q35";
91      break;
92   case PCI_CHIP_Q33_G:
93      chipset = "Q33";
94      break;
95   case PCI_CHIP_PINEVIEW_G:
96      chipset = "Pineview G";
97      break;
98   case PCI_CHIP_PINEVIEW_M:
99      chipset = "Pineview M";
100      break;
101   default:
102      chipset = "unknown";
103      break;
104   }
105
106   util_snprintf(buffer, sizeof(buffer), "i915 (chipset: %s)", chipset);
107   return buffer;
108}
109
110static int
111i915_get_shader_param(struct pipe_screen *screen,
112                      enum pipe_shader_type shader,
113                      enum pipe_shader_cap cap)
114{
115   switch(shader) {
116   case PIPE_SHADER_VERTEX:
117      switch (cap) {
118      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
119      case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
120         if (debug_get_bool_option("DRAW_USE_LLVM", TRUE))
121            return PIPE_MAX_SAMPLERS;
122         else
123            return 0;
124       default:
125         return draw_get_shader_param(shader, cap);
126      }
127   case PIPE_SHADER_FRAGMENT:
128      /* XXX: some of these are just shader model 2.0 values, fix this! */
129      switch(cap) {
130      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
131         return I915_MAX_ALU_INSN + I915_MAX_TEX_INSN;
132      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
133         return I915_MAX_ALU_INSN;
134      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
135         return I915_MAX_TEX_INSN;
136      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
137         return 8;
138      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
139         return 0;
140      case PIPE_SHADER_CAP_MAX_INPUTS:
141         return 10;
142      case PIPE_SHADER_CAP_MAX_OUTPUTS:
143         return 1;
144      case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
145         return 32 * sizeof(float[4]);
146      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
147         return 1;
148      case PIPE_SHADER_CAP_MAX_TEMPS:
149         return 12; /* XXX: 12 -> 32 ? */
150      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
151      case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
152         return 0;
153      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
154      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
155      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
156      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
157         return 1;
158      case PIPE_SHADER_CAP_SUBROUTINES:
159         return 0;
160      case PIPE_SHADER_CAP_INTEGERS:
161      case PIPE_SHADER_CAP_INT64_ATOMICS:
162      case PIPE_SHADER_CAP_FP16:
163         return 0;
164      case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
165      case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
166         return I915_TEX_UNITS;
167      case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
168      case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
169      case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
170      case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
171      case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
172      case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
173      case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
174      case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
175      case PIPE_SHADER_CAP_PREFERRED_IR:
176      case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
177         return 0;
178      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
179         return 32;
180      default:
181         debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap);
182         return 0;
183      }
184      break;
185   default:
186      return 0;
187   }
188
189}
190
191static int
192i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
193{
194   struct i915_screen *is = i915_screen(screen);
195
196   switch (cap) {
197   /* Supported features (boolean caps). */
198   case PIPE_CAP_ANISOTROPIC_FILTER:
199   case PIPE_CAP_NPOT_TEXTURES:
200   case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
201   case PIPE_CAP_POINT_SPRITE:
202   case PIPE_CAP_PRIMITIVE_RESTART: /* draw module */
203   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
204   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
205   case PIPE_CAP_TGSI_INSTANCEID:
206   case PIPE_CAP_VERTEX_COLOR_CLAMPED:
207   case PIPE_CAP_USER_VERTEX_BUFFERS:
208   case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
209      return 1;
210
211   /* Unsupported features (boolean caps). */
212   case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
213   case PIPE_CAP_DEPTH_CLIP_DISABLE:
214   case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
215   case PIPE_CAP_INDEP_BLEND_ENABLE:
216   case PIPE_CAP_INDEP_BLEND_FUNC:
217   case PIPE_CAP_SHADER_STENCIL_EXPORT:
218   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
219   case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:
220   case PIPE_CAP_TEXTURE_SWIZZLE:
221   case PIPE_CAP_QUERY_TIME_ELAPSED:
222   case PIPE_CAP_SM3:
223   case PIPE_CAP_SEAMLESS_CUBE_MAP:
224   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
225   case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
226   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
227   case PIPE_CAP_CONDITIONAL_RENDER:
228   case PIPE_CAP_TEXTURE_BARRIER:
229   case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
230   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
231   case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
232   case PIPE_CAP_START_INSTANCE:
233   case PIPE_CAP_QUERY_TIMESTAMP:
234   case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
235   case PIPE_CAP_TEXTURE_MULTISAMPLE:
236   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
237   case PIPE_CAP_CUBE_MAP_ARRAY:
238   case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
239   case PIPE_CAP_TGSI_TEXCOORD:
240   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
241   case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
242   case PIPE_CAP_TEXTURE_GATHER_SM5:
243   case PIPE_CAP_FAKE_SW_MSAA:
244   case PIPE_CAP_TEXTURE_QUERY_LOD:
245   case PIPE_CAP_SAMPLE_SHADING:
246   case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
247   case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
248   case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
249   case PIPE_CAP_CLIP_HALFZ:
250   case PIPE_CAP_VERTEXID_NOBASE:
251   case PIPE_CAP_POLYGON_OFFSET_CLAMP:
252   case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
253   case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
254   case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
255   case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
256   case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
257   case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
258   case PIPE_CAP_DEPTH_BOUNDS_TEST:
259   case PIPE_CAP_TGSI_TXQS:
260   case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
261   case PIPE_CAP_SHAREABLE_SHADERS:
262   case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
263   case PIPE_CAP_CLEAR_TEXTURE:
264   case PIPE_CAP_DRAW_PARAMETERS:
265   case PIPE_CAP_TGSI_PACK_HALF_FLOAT:
266   case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
267   case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
268   case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
269   case PIPE_CAP_INVALIDATE_BUFFER:
270   case PIPE_CAP_GENERATE_MIPMAP:
271   case PIPE_CAP_STRING_MARKER:
272   case PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY:
273   case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
274   case PIPE_CAP_QUERY_MEMORY_INFO:
275   case PIPE_CAP_PCI_GROUP:
276   case PIPE_CAP_PCI_BUS:
277   case PIPE_CAP_PCI_DEVICE:
278   case PIPE_CAP_PCI_FUNCTION:
279   case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
280   case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
281   case PIPE_CAP_CULL_DISTANCE:
282   case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES:
283   case PIPE_CAP_TGSI_VOTE:
284   case PIPE_CAP_MAX_WINDOW_RECTANGLES:
285   case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED:
286   case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
287   case PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE:
288   case PIPE_CAP_POST_DEPTH_COVERAGE:
289   case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_TRIANGLES:
290   case PIPE_CAP_CONSERVATIVE_RASTER_POST_SNAP_POINTS_LINES:
291   case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_TRIANGLES:
292   case PIPE_CAP_CONSERVATIVE_RASTER_PRE_SNAP_POINTS_LINES:
293   case PIPE_CAP_CONSERVATIVE_RASTER_POST_DEPTH_COVERAGE:
294   case PIPE_CAP_MAX_CONSERVATIVE_RASTER_SUBPIXEL_PRECISION_BIAS:
295   case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET:
296      return 0;
297
298   case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
299   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
300   case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
301   case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
302   case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
303   case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
304   case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
305   case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
306   case PIPE_CAP_DRAW_INDIRECT:
307   case PIPE_CAP_MULTI_DRAW_INDIRECT:
308   case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS:
309   case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
310   case PIPE_CAP_SAMPLER_VIEW_TARGET:
311   case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
312   case PIPE_CAP_TGSI_CAN_READ_OUTPUTS:
313   case PIPE_CAP_NATIVE_FENCE_FD:
314   case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
315   case PIPE_CAP_TGSI_FS_FBFETCH:
316   case PIPE_CAP_TGSI_MUL_ZERO_WINS:
317   case PIPE_CAP_DOUBLES:
318   case PIPE_CAP_INT64:
319   case PIPE_CAP_INT64_DIVMOD:
320   case PIPE_CAP_TGSI_TEX_TXF_LZ:
321   case PIPE_CAP_TGSI_CLOCK:
322   case PIPE_CAP_SPARSE_BUFFER_PAGE_SIZE:
323   case PIPE_CAP_TGSI_BALLOT:
324   case PIPE_CAP_TGSI_TES_LAYER_VIEWPORT:
325   case PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX:
326   case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
327   case PIPE_CAP_BINDLESS_TEXTURE:
328   case PIPE_CAP_NIR_SAMPLERS_AS_DEREF:
329   case PIPE_CAP_QUERY_SO_OVERFLOW:
330   case PIPE_CAP_MEMOBJ:
331   case PIPE_CAP_LOAD_CONSTBUF:
332   case PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS:
333   case PIPE_CAP_TILE_RASTER_ORDER:
334   case PIPE_CAP_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
335   case PIPE_CAP_FRAMEBUFFER_MSAA_CONSTRAINTS:
336   case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET:
337   case PIPE_CAP_CONTEXT_PRIORITY_MASK:
338   case PIPE_CAP_FENCE_SIGNAL:
339   case PIPE_CAP_CONSTBUF0_FLAGS:
340   case PIPE_CAP_PACKED_UNIFORMS:
341   case PIPE_CAP_PROGRAMMABLE_SAMPLE_LOCATIONS:
342      return 0;
343
344   case PIPE_CAP_MAX_GS_INVOCATIONS:
345      return 32;
346
347   case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:
348      return 1 << 27;
349
350   case PIPE_CAP_MAX_VIEWPORTS:
351      return 1;
352
353   case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
354      return 64;
355
356   case PIPE_CAP_GLSL_FEATURE_LEVEL:
357   case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
358      return 120;
359
360   case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
361      return 16;
362
363   /* Features we can lie about (boolean caps). */
364   case PIPE_CAP_OCCLUSION_QUERY:
365      return is->debug.lie ? 1 : 0;
366
367   /* Texturing. */
368   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
369      return I915_MAX_TEXTURE_2D_LEVELS;
370   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
371      return I915_MAX_TEXTURE_3D_LEVELS;
372   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
373      return I915_MAX_TEXTURE_2D_LEVELS;
374   case PIPE_CAP_MIN_TEXEL_OFFSET:
375   case PIPE_CAP_MAX_TEXEL_OFFSET:
376   case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
377   case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
378   case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
379   case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
380   case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
381      return 0;
382
383   /* Render targets. */
384   case PIPE_CAP_MAX_RENDER_TARGETS:
385      return 1;
386
387   /* Geometry shader output, unsupported. */
388   case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
389   case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
390   case PIPE_CAP_MAX_VERTEX_STREAMS:
391      return 0;
392
393   case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
394      return 2048;
395
396   /* Fragment coordinate conventions. */
397   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
398   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
399      return 1;
400   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
401   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
402      return 0;
403   case PIPE_CAP_ENDIANNESS:
404      return PIPE_ENDIAN_LITTLE;
405   case PIPE_CAP_MAX_VARYINGS:
406      return 10;
407
408   case PIPE_CAP_VENDOR_ID:
409      return 0x8086;
410   case PIPE_CAP_DEVICE_ID:
411      return is->iws->pci_id;
412   case PIPE_CAP_ACCELERATED:
413      return 1;
414   case PIPE_CAP_VIDEO_MEMORY: {
415      /* Once a batch uses more than 75% of the maximum mappable size, we
416       * assume that there's some fragmentation, and we start doing extra
417       * flushing, etc.  That's the big cliff apps will care about.
418       */
419      const int gpu_mappable_megabytes = is->iws->aperture_size(is->iws) * 3 / 4;
420      uint64_t system_memory;
421
422      if (!os_get_total_physical_memory(&system_memory))
423         return 0;
424
425      return MIN2(gpu_mappable_megabytes, (int)(system_memory >> 20));
426   }
427   case PIPE_CAP_UMA:
428      return 1;
429
430   case PIPE_CAP_COMPUTE:
431   case PIPE_CAP_QUERY_BUFFER_OBJECT:
432      return 0;
433
434   default:
435      return u_pipe_screen_get_param_defaults(screen, cap);
436   }
437}
438
439static float
440i915_get_paramf(struct pipe_screen *screen, enum pipe_capf cap)
441{
442   switch(cap) {
443   case PIPE_CAPF_MAX_LINE_WIDTH:
444      /* fall-through */
445   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
446      return 7.5;
447
448   case PIPE_CAPF_MAX_POINT_WIDTH:
449      /* fall-through */
450   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
451      return 255.0;
452
453   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
454      return 4.0;
455
456   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
457      return 16.0;
458
459   case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
460      /* fall-through */
461   case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
462      /* fall-through */
463   case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
464      return 0.0f;
465
466   default:
467      debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap);
468      return 0;
469   }
470}
471
472boolean
473i915_is_format_supported(struct pipe_screen *screen,
474                         enum pipe_format format,
475                         enum pipe_texture_target target,
476                         unsigned sample_count,
477                         unsigned storage_sample_count,
478                         unsigned tex_usage)
479{
480   static const enum pipe_format tex_supported[] = {
481      PIPE_FORMAT_B8G8R8A8_UNORM,
482      PIPE_FORMAT_B8G8R8A8_SRGB,
483      PIPE_FORMAT_B8G8R8X8_UNORM,
484      PIPE_FORMAT_R8G8B8A8_UNORM,
485      PIPE_FORMAT_R8G8B8X8_UNORM,
486      PIPE_FORMAT_B4G4R4A4_UNORM,
487      PIPE_FORMAT_B5G6R5_UNORM,
488      PIPE_FORMAT_B5G5R5A1_UNORM,
489      PIPE_FORMAT_B10G10R10A2_UNORM,
490      PIPE_FORMAT_L8_UNORM,
491      PIPE_FORMAT_A8_UNORM,
492      PIPE_FORMAT_I8_UNORM,
493      PIPE_FORMAT_L8A8_UNORM,
494      PIPE_FORMAT_UYVY,
495      PIPE_FORMAT_YUYV,
496      /* XXX why not?
497      PIPE_FORMAT_Z16_UNORM, */
498      PIPE_FORMAT_DXT1_RGB,
499      PIPE_FORMAT_DXT1_RGBA,
500      PIPE_FORMAT_DXT3_RGBA,
501      PIPE_FORMAT_DXT5_RGBA,
502      PIPE_FORMAT_Z24X8_UNORM,
503      PIPE_FORMAT_Z24_UNORM_S8_UINT,
504      PIPE_FORMAT_NONE  /* list terminator */
505   };
506   static const enum pipe_format render_supported[] = {
507      PIPE_FORMAT_B8G8R8A8_UNORM,
508      PIPE_FORMAT_B8G8R8X8_UNORM,
509      PIPE_FORMAT_R8G8B8A8_UNORM,
510      PIPE_FORMAT_R8G8B8X8_UNORM,
511      PIPE_FORMAT_B5G6R5_UNORM,
512      PIPE_FORMAT_B5G5R5A1_UNORM,
513      PIPE_FORMAT_B4G4R4A4_UNORM,
514      PIPE_FORMAT_B10G10R10A2_UNORM,
515      PIPE_FORMAT_L8_UNORM,
516      PIPE_FORMAT_A8_UNORM,
517      PIPE_FORMAT_I8_UNORM,
518      PIPE_FORMAT_NONE  /* list terminator */
519   };
520   static const enum pipe_format depth_supported[] = {
521      /* XXX why not?
522      PIPE_FORMAT_Z16_UNORM, */
523      PIPE_FORMAT_Z24X8_UNORM,
524      PIPE_FORMAT_Z24_UNORM_S8_UINT,
525      PIPE_FORMAT_NONE  /* list terminator */
526   };
527   const enum pipe_format *list;
528   uint i;
529
530   if (sample_count > 1)
531      return FALSE;
532
533   if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
534      return false;
535
536   if(tex_usage & PIPE_BIND_DEPTH_STENCIL)
537      list = depth_supported;
538   else if (tex_usage & PIPE_BIND_RENDER_TARGET)
539      list = render_supported;
540   else if (tex_usage & PIPE_BIND_SAMPLER_VIEW)
541      list = tex_supported;
542   else
543      return TRUE; /* PIPE_BIND_{VERTEX,INDEX}_BUFFER */
544
545   for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) {
546      if (list[i] == format)
547         return TRUE;
548   }
549
550   return FALSE;
551}
552
553
554/*
555 * Fence functions
556 */
557
558
559static void
560i915_fence_reference(struct pipe_screen *screen,
561                     struct pipe_fence_handle **ptr,
562                     struct pipe_fence_handle *fence)
563{
564   struct i915_screen *is = i915_screen(screen);
565
566   is->iws->fence_reference(is->iws, ptr, fence);
567}
568
569static boolean
570i915_fence_finish(struct pipe_screen *screen,
571                  struct pipe_context *ctx,
572                  struct pipe_fence_handle *fence,
573                  uint64_t timeout)
574{
575   struct i915_screen *is = i915_screen(screen);
576
577   if (!timeout)
578      return is->iws->fence_signalled(is->iws, fence) == 1;
579
580   return is->iws->fence_finish(is->iws, fence) == 1;
581}
582
583
584/*
585 * Generic functions
586 */
587
588
589static void
590i915_flush_frontbuffer(struct pipe_screen *screen,
591                       struct pipe_resource *resource,
592                       unsigned level, unsigned layer,
593                       void *winsys_drawable_handle,
594                       struct pipe_box *sub_box)
595{
596   /* XXX: Dummy right now. */
597   (void)screen;
598   (void)resource;
599   (void)level;
600   (void)layer;
601   (void)winsys_drawable_handle;
602   (void)sub_box;
603}
604
605static void
606i915_destroy_screen(struct pipe_screen *screen)
607{
608   struct i915_screen *is = i915_screen(screen);
609
610   if (is->iws)
611      is->iws->destroy(is->iws);
612
613   FREE(is);
614}
615
616/**
617 * Create a new i915_screen object
618 */
619struct pipe_screen *
620i915_screen_create(struct i915_winsys *iws)
621{
622   struct i915_screen *is = CALLOC_STRUCT(i915_screen);
623
624   if (!is)
625      return NULL;
626
627   switch (iws->pci_id) {
628   case PCI_CHIP_I915_G:
629   case PCI_CHIP_I915_GM:
630      is->is_i945 = FALSE;
631      break;
632
633   case PCI_CHIP_I945_G:
634   case PCI_CHIP_I945_GM:
635   case PCI_CHIP_I945_GME:
636   case PCI_CHIP_G33_G:
637   case PCI_CHIP_Q33_G:
638   case PCI_CHIP_Q35_G:
639   case PCI_CHIP_PINEVIEW_G:
640   case PCI_CHIP_PINEVIEW_M:
641      is->is_i945 = TRUE;
642      break;
643
644   default:
645      debug_printf("%s: unknown pci id 0x%x, cannot create screen\n",
646                   __FUNCTION__, iws->pci_id);
647      FREE(is);
648      return NULL;
649   }
650
651   is->iws = iws;
652
653   is->base.destroy = i915_destroy_screen;
654   is->base.flush_frontbuffer = i915_flush_frontbuffer;
655
656   is->base.get_name = i915_get_name;
657   is->base.get_vendor = i915_get_vendor;
658   is->base.get_device_vendor = i915_get_device_vendor;
659   is->base.get_param = i915_get_param;
660   is->base.get_shader_param = i915_get_shader_param;
661   is->base.get_paramf = i915_get_paramf;
662   is->base.is_format_supported = i915_is_format_supported;
663
664   is->base.context_create = i915_create_context;
665
666   is->base.fence_reference = i915_fence_reference;
667   is->base.fence_finish = i915_fence_finish;
668
669   i915_init_screen_resource_functions(is);
670
671   i915_debug_init(is);
672
673   return &is->base;
674}
675