i915_screen.c revision 3464ebd5
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 "draw/draw_context.h"
30#include "util/u_format.h"
31#include "util/u_format_s3tc.h"
32#include "util/u_inlines.h"
33#include "util/u_memory.h"
34#include "util/u_string.h"
35
36#include "i915_reg.h"
37#include "i915_debug.h"
38#include "i915_context.h"
39#include "i915_screen.h"
40#include "i915_resource.h"
41#include "i915_winsys.h"
42#include "i915_public.h"
43
44
45/*
46 * Probe functions
47 */
48
49
50static const char *
51i915_get_vendor(struct pipe_screen *screen)
52{
53   return "VMware, Inc.";
54}
55
56static const char *
57i915_get_name(struct pipe_screen *screen)
58{
59   static char buffer[128];
60   const char *chipset;
61
62   switch (i915_screen(screen)->iws->pci_id) {
63   case PCI_CHIP_I915_G:
64      chipset = "915G";
65      break;
66   case PCI_CHIP_I915_GM:
67      chipset = "915GM";
68      break;
69   case PCI_CHIP_I945_G:
70      chipset = "945G";
71      break;
72   case PCI_CHIP_I945_GM:
73      chipset = "945GM";
74      break;
75   case PCI_CHIP_I945_GME:
76      chipset = "945GME";
77      break;
78   case PCI_CHIP_G33_G:
79      chipset = "G33";
80      break;
81   case PCI_CHIP_Q35_G:
82      chipset = "Q35";
83      break;
84   case PCI_CHIP_Q33_G:
85      chipset = "Q33";
86      break;
87   case PCI_CHIP_PINEVIEW_G:
88      chipset = "Pineview G";
89      break;
90   case PCI_CHIP_PINEVIEW_M:
91      chipset = "Pineview M";
92      break;
93   default:
94      chipset = "unknown";
95      break;
96   }
97
98   util_snprintf(buffer, sizeof(buffer), "i915 (chipset: %s)", chipset);
99   return buffer;
100}
101
102static int
103i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
104{
105   struct i915_screen *is = i915_screen(screen);
106
107   switch (cap) {
108   /* Supported features (boolean caps). */
109   case PIPE_CAP_ANISOTROPIC_FILTER:
110   case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
111   case PIPE_CAP_NPOT_TEXTURES:
112   case PIPE_CAP_POINT_SPRITE:
113   case PIPE_CAP_PRIMITIVE_RESTART: /* draw module */
114   case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
115   case PIPE_CAP_TEXTURE_SHADOW_MAP:
116   case PIPE_CAP_TWO_SIDED_STENCIL:
117      return 1;
118
119   /* Features that should be supported (boolean caps). */
120   /* XXX: Just test the code */
121   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
122      /* Also lie about these when asked to (needed for GLSL / GL 2.0) */
123      return is->debug.lie ? 1 : 0;
124
125   /* Unsupported features (boolean caps). */
126   case PIPE_CAP_ARRAY_TEXTURES:
127   case PIPE_CAP_DEPTH_CLAMP:
128   case PIPE_CAP_INDEP_BLEND_ENABLE:
129   case PIPE_CAP_INDEP_BLEND_FUNC:
130   case PIPE_CAP_TGSI_INSTANCEID:
131   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
132   case PIPE_CAP_SHADER_STENCIL_EXPORT:
133   case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
134   case PIPE_CAP_TEXTURE_SWIZZLE:
135   case PIPE_CAP_TIMER_QUERY:
136   case PIPE_CAP_SM3:
137   case PIPE_CAP_SEAMLESS_CUBE_MAP:
138   case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
139   case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL:
140   case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
141      return 0;
142
143   /* Features we can lie about (boolean caps). */
144   case PIPE_CAP_GLSL:
145   case PIPE_CAP_OCCLUSION_QUERY:
146      return is->debug.lie ? 1 : 0;
147
148   /* Texturing. */
149   case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
150   case PIPE_CAP_MAX_COMBINED_SAMPLERS:
151      return 8;
152   case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
153      return 0;
154   case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
155      return I915_MAX_TEXTURE_2D_LEVELS;
156   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
157      return I915_MAX_TEXTURE_3D_LEVELS;
158   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
159      return I915_MAX_TEXTURE_2D_LEVELS;
160
161   /* Render targets. */
162   case PIPE_CAP_MAX_RENDER_TARGETS:
163      return 1;
164
165   /* Fragment coordinate conventions. */
166   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
167   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
168      return 1;
169   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
170   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
171      return 0;
172
173   default:
174      debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap);
175      return 0;
176   }
177}
178
179static int
180i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap cap)
181{
182   switch(shader) {
183   case PIPE_SHADER_VERTEX:
184      return draw_get_shader_param(shader, cap);
185   case PIPE_SHADER_FRAGMENT:
186      break;
187   default:
188      return 0;
189   }
190
191   /* XXX: these are just shader model 2.0 values, fix this! */
192   switch(cap) {
193      case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
194         return 96;
195      case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
196         return 64;
197      case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
198         return 32;
199      case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
200         return 8;
201      case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
202         return 0;
203      case PIPE_SHADER_CAP_MAX_INPUTS:
204         return 10;
205      case PIPE_SHADER_CAP_MAX_CONSTS:
206         return 32;
207      case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
208         return 1;
209      case PIPE_SHADER_CAP_MAX_TEMPS:
210         return 12; /* XXX: 12 -> 32 ? */
211      case PIPE_SHADER_CAP_MAX_ADDRS:
212         return 0;
213      case PIPE_SHADER_CAP_MAX_PREDS:
214         return 0;
215      case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
216         return 0;
217      case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
218      case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
219      case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
220      case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
221         return 1;
222      case PIPE_SHADER_CAP_SUBROUTINES:
223         return 0;
224      default:
225         debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap);
226         return 0;
227   }
228}
229
230static float
231i915_get_paramf(struct pipe_screen *screen, enum pipe_cap cap)
232{
233   switch(cap) {
234   case PIPE_CAP_MAX_LINE_WIDTH:
235      /* fall-through */
236   case PIPE_CAP_MAX_LINE_WIDTH_AA:
237      return 7.5;
238
239   case PIPE_CAP_MAX_POINT_WIDTH:
240      /* fall-through */
241   case PIPE_CAP_MAX_POINT_WIDTH_AA:
242      return 255.0;
243
244   case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
245      return 4.0;
246
247   case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
248      return 16.0;
249
250   default:
251      debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap);
252      return 0;
253   }
254}
255
256boolean
257i915_is_format_supported(struct pipe_screen *screen,
258                         enum pipe_format format,
259                         enum pipe_texture_target target,
260                         unsigned sample_count,
261                         unsigned tex_usage)
262{
263   static const enum pipe_format tex_supported[] = {
264      PIPE_FORMAT_B8G8R8A8_UNORM,
265      PIPE_FORMAT_B8G8R8X8_UNORM,
266      PIPE_FORMAT_R8G8B8A8_UNORM,
267      PIPE_FORMAT_R8G8B8X8_UNORM,
268      PIPE_FORMAT_B5G6R5_UNORM,
269      PIPE_FORMAT_L8_UNORM,
270      PIPE_FORMAT_A8_UNORM,
271      PIPE_FORMAT_I8_UNORM,
272      PIPE_FORMAT_L8A8_UNORM,
273      PIPE_FORMAT_UYVY,
274      PIPE_FORMAT_YUYV,
275      /* XXX why not?
276      PIPE_FORMAT_Z16_UNORM, */
277      PIPE_FORMAT_DXT1_RGB,
278      PIPE_FORMAT_DXT1_RGBA,
279      PIPE_FORMAT_DXT3_RGBA,
280      PIPE_FORMAT_DXT5_RGBA,
281      PIPE_FORMAT_Z24X8_UNORM,
282      PIPE_FORMAT_Z24_UNORM_S8_USCALED,
283      PIPE_FORMAT_NONE  /* list terminator */
284   };
285   static const enum pipe_format render_supported[] = {
286      PIPE_FORMAT_B8G8R8A8_UNORM,
287      PIPE_FORMAT_R8G8B8A8_UNORM,
288      PIPE_FORMAT_B5G6R5_UNORM,
289      PIPE_FORMAT_L8_UNORM,
290      PIPE_FORMAT_A8_UNORM,
291      PIPE_FORMAT_I8_UNORM,
292      PIPE_FORMAT_NONE  /* list terminator */
293   };
294   static const enum pipe_format depth_supported[] = {
295      /* XXX why not?
296      PIPE_FORMAT_Z16_UNORM, */
297      PIPE_FORMAT_Z24X8_UNORM,
298      PIPE_FORMAT_Z24_UNORM_S8_USCALED,
299      PIPE_FORMAT_NONE  /* list terminator */
300   };
301   const enum pipe_format *list;
302   uint i;
303
304   if (!util_format_is_supported(format, tex_usage))
305      return FALSE;
306
307   if (sample_count > 1)
308      return FALSE;
309
310   if(tex_usage & PIPE_BIND_DEPTH_STENCIL)
311      list = depth_supported;
312   else if (tex_usage & PIPE_BIND_RENDER_TARGET)
313      list = render_supported;
314   else
315      list = tex_supported;
316
317   for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) {
318      if (list[i] == format)
319         return TRUE;
320   }
321
322   return FALSE;
323}
324
325
326/*
327 * Fence functions
328 */
329
330
331static void
332i915_fence_reference(struct pipe_screen *screen,
333                     struct pipe_fence_handle **ptr,
334                     struct pipe_fence_handle *fence)
335{
336   struct i915_screen *is = i915_screen(screen);
337
338   is->iws->fence_reference(is->iws, ptr, fence);
339}
340
341static boolean
342i915_fence_signalled(struct pipe_screen *screen,
343                     struct pipe_fence_handle *fence)
344{
345   struct i915_screen *is = i915_screen(screen);
346
347   return is->iws->fence_signalled(is->iws, fence) == 0;
348}
349
350static boolean
351i915_fence_finish(struct pipe_screen *screen,
352                  struct pipe_fence_handle *fence,
353                  uint64_t timeout)
354{
355   struct i915_screen *is = i915_screen(screen);
356
357   return is->iws->fence_finish(is->iws, fence) == 0;
358}
359
360
361/*
362 * Generic functions
363 */
364
365
366static void
367i915_flush_frontbuffer(struct pipe_screen *screen,
368                       struct pipe_resource *resource,
369                       unsigned level, unsigned layer,
370                       void *winsys_drawable_handle)
371{
372   /* XXX: Dummy right now. */
373   (void)screen;
374   (void)resource;
375   (void)level;
376   (void)layer;
377   (void)winsys_drawable_handle;
378}
379
380static void
381i915_destroy_screen(struct pipe_screen *screen)
382{
383   struct i915_screen *is = i915_screen(screen);
384
385   if (is->iws)
386      is->iws->destroy(is->iws);
387
388   FREE(is);
389}
390
391/**
392 * Create a new i915_screen object
393 */
394struct pipe_screen *
395i915_screen_create(struct i915_winsys *iws)
396{
397   struct i915_screen *is = CALLOC_STRUCT(i915_screen);
398
399   if (!is)
400      return NULL;
401
402   switch (iws->pci_id) {
403   case PCI_CHIP_I915_G:
404   case PCI_CHIP_I915_GM:
405      is->is_i945 = FALSE;
406      break;
407
408   case PCI_CHIP_I945_G:
409   case PCI_CHIP_I945_GM:
410   case PCI_CHIP_I945_GME:
411   case PCI_CHIP_G33_G:
412   case PCI_CHIP_Q33_G:
413   case PCI_CHIP_Q35_G:
414   case PCI_CHIP_PINEVIEW_G:
415   case PCI_CHIP_PINEVIEW_M:
416      is->is_i945 = TRUE;
417      break;
418
419   default:
420      debug_printf("%s: unknown pci id 0x%x, cannot create screen\n",
421                   __FUNCTION__, iws->pci_id);
422      FREE(is);
423      return NULL;
424   }
425
426   is->iws = iws;
427
428   is->base.winsys = NULL;
429
430   is->base.destroy = i915_destroy_screen;
431   is->base.flush_frontbuffer = i915_flush_frontbuffer;
432
433   is->base.get_name = i915_get_name;
434   is->base.get_vendor = i915_get_vendor;
435   is->base.get_param = i915_get_param;
436   is->base.get_shader_param = i915_get_shader_param;
437   is->base.get_paramf = i915_get_paramf;
438   is->base.is_format_supported = i915_is_format_supported;
439
440   is->base.context_create = i915_create_context;
441
442   is->base.fence_reference = i915_fence_reference;
443   is->base.fence_signalled = i915_fence_signalled;
444   is->base.fence_finish = i915_fence_finish;
445
446   i915_init_screen_resource_functions(is);
447
448   i915_debug_init(is);
449
450   util_format_s3tc_init();
451
452   return &is->base;
453}
454