Merge commit 'origin/tgsi-simplify-ext'
[mesa.git] / src / gallium / drivers / svga / svga_screen.c
1 /**********************************************************
2 * Copyright 2008-2009 VMware, Inc. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 **********************************************************/
25
26 #include "util/u_memory.h"
27 #include "pipe/p_inlines.h"
28 #include "util/u_string.h"
29 #include "util/u_math.h"
30
31 #include "svga_winsys.h"
32 #include "svga_context.h"
33 #include "svga_screen.h"
34 #include "svga_screen_texture.h"
35 #include "svga_screen_buffer.h"
36 #include "svga_cmd.h"
37 #include "svga_debug.h"
38
39 #include "svga_hw_reg.h"
40 #include "svga3d_shaderdefs.h"
41
42
43 #ifdef DEBUG
44 int SVGA_DEBUG = 0;
45
46 static const struct debug_named_value svga_debug_flags[] = {
47 { "dma", DEBUG_DMA },
48 { "tgsi", DEBUG_TGSI },
49 { "pipe", DEBUG_PIPE },
50 { "state", DEBUG_STATE },
51 { "screen", DEBUG_SCREEN },
52 { "tex", DEBUG_TEX },
53 { "swtnl", DEBUG_SWTNL },
54 { "const", DEBUG_CONSTS },
55 { "viewport", DEBUG_VIEWPORT },
56 { "views", DEBUG_VIEWS },
57 { "perf", DEBUG_PERF },
58 { "flush", DEBUG_FLUSH },
59 { "sync", DEBUG_SYNC },
60 { "cache", DEBUG_CACHE },
61 {NULL, 0}
62 };
63 #endif
64
65 static const char *
66 svga_get_vendor( struct pipe_screen *pscreen )
67 {
68 return "VMware, Inc.";
69 }
70
71
72 static const char *
73 svga_get_name( struct pipe_screen *pscreen )
74 {
75 #ifdef DEBUG
76 /* Only return internal details in the DEBUG version:
77 */
78 return "SVGA3D; build: DEBUG; mutex: " PIPE_ATOMIC;
79 #else
80 return "SVGA3D; build: RELEASE; ";
81 #endif
82 }
83
84
85
86
87 static float
88 svga_get_paramf(struct pipe_screen *screen, int param)
89 {
90 struct svga_screen *svgascreen = svga_screen(screen);
91 struct svga_winsys_screen *sws = svgascreen->sws;
92 SVGA3dDevCapResult result;
93
94 switch (param) {
95 case PIPE_CAP_MAX_LINE_WIDTH:
96 /* fall-through */
97 case PIPE_CAP_MAX_LINE_WIDTH_AA:
98 return 7.0;
99
100 case PIPE_CAP_MAX_POINT_WIDTH:
101 /* fall-through */
102 case PIPE_CAP_MAX_POINT_WIDTH_AA:
103 /* Keep this to a reasonable size to avoid failures in
104 * conform/pntaa.c:
105 */
106 return 80.0;
107
108 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
109 return 4.0;
110
111 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
112 return 16.0;
113
114 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
115 return 16;
116 case PIPE_CAP_NPOT_TEXTURES:
117 return 1;
118 case PIPE_CAP_TWO_SIDED_STENCIL:
119 return 1;
120 case PIPE_CAP_GLSL:
121 return svgascreen->use_ps30 && svgascreen->use_vs30;
122 case PIPE_CAP_ANISOTROPIC_FILTER:
123 return 1;
124 case PIPE_CAP_POINT_SPRITE:
125 return 1;
126 case PIPE_CAP_MAX_RENDER_TARGETS:
127 if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result))
128 return 1;
129 if(!result.u)
130 return 1;
131 return MIN2(result.u, PIPE_MAX_COLOR_BUFS);
132 case PIPE_CAP_OCCLUSION_QUERY:
133 return 1;
134 case PIPE_CAP_TEXTURE_SHADOW_MAP:
135 return 1;
136 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
137 return SVGA_MAX_TEXTURE_LEVELS;
138 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
139 return 8; /* max 128x128x128 */
140 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
141 return SVGA_MAX_TEXTURE_LEVELS;
142
143 case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */
144 return 1;
145
146 case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
147 return 1;
148
149 default:
150 return 0;
151 }
152 }
153
154
155 /* This is a fairly pointless interface
156 */
157 static int
158 svga_get_param(struct pipe_screen *screen, int param)
159 {
160 return (int) svga_get_paramf( screen, param );
161 }
162
163
164 static INLINE SVGA3dDevCapIndex
165 svga_translate_format_cap(enum pipe_format format)
166 {
167 switch(format) {
168
169 case PIPE_FORMAT_A8R8G8B8_UNORM:
170 return SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8;
171 case PIPE_FORMAT_X8R8G8B8_UNORM:
172 return SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8;
173
174 case PIPE_FORMAT_R5G6B5_UNORM:
175 return SVGA3D_DEVCAP_SURFACEFMT_R5G6B5;
176 case PIPE_FORMAT_A1R5G5B5_UNORM:
177 return SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5;
178 case PIPE_FORMAT_A4R4G4B4_UNORM:
179 return SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4;
180
181 case PIPE_FORMAT_Z16_UNORM:
182 return SVGA3D_DEVCAP_SURFACEFMT_Z_D16;
183 case PIPE_FORMAT_Z24S8_UNORM:
184 return SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8;
185 case PIPE_FORMAT_Z24X8_UNORM:
186 return SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8;
187
188 case PIPE_FORMAT_A8_UNORM:
189 return SVGA3D_DEVCAP_SURFACEFMT_ALPHA8;
190 case PIPE_FORMAT_L8_UNORM:
191 return SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8;
192
193 case PIPE_FORMAT_DXT1_RGB:
194 case PIPE_FORMAT_DXT1_RGBA:
195 return SVGA3D_DEVCAP_SURFACEFMT_DXT1;
196 case PIPE_FORMAT_DXT3_RGBA:
197 return SVGA3D_DEVCAP_SURFACEFMT_DXT3;
198 case PIPE_FORMAT_DXT5_RGBA:
199 return SVGA3D_DEVCAP_SURFACEFMT_DXT5;
200
201 default:
202 return SVGA3D_DEVCAP_MAX;
203 }
204 }
205
206
207 static boolean
208 svga_is_format_supported( struct pipe_screen *screen,
209 enum pipe_format format,
210 enum pipe_texture_target target,
211 unsigned tex_usage,
212 unsigned geom_flags )
213 {
214 struct svga_winsys_screen *sws = svga_screen(screen)->sws;
215 SVGA3dDevCapIndex index;
216 SVGA3dDevCapResult result;
217
218 assert(tex_usage);
219
220 /* Override host capabilities */
221 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
222 switch(format) {
223
224 /* Often unsupported/problematic. This means we end up with the same
225 * visuals for all virtual hardware implementations.
226 */
227 case PIPE_FORMAT_A4R4G4B4_UNORM:
228 case PIPE_FORMAT_A1R5G5B5_UNORM:
229 return FALSE;
230
231 /* Simulate ability to render into compressed textures */
232 case PIPE_FORMAT_DXT1_RGB:
233 case PIPE_FORMAT_DXT1_RGBA:
234 case PIPE_FORMAT_DXT3_RGBA:
235 case PIPE_FORMAT_DXT5_RGBA:
236 return TRUE;
237
238 default:
239 break;
240 }
241 }
242
243 /* Try to query the host */
244 index = svga_translate_format_cap(format);
245 if( index < SVGA3D_DEVCAP_MAX &&
246 sws->get_cap(sws, index, &result) )
247 {
248 SVGA3dSurfaceFormatCaps mask;
249
250 mask.value = 0;
251 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET)
252 mask.offscreenRenderTarget = 1;
253 if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL)
254 mask.zStencil = 1;
255 if (tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
256 mask.texture = 1;
257
258 if ((result.u & mask.value) == mask.value)
259 return TRUE;
260 else
261 return FALSE;
262 }
263
264 /* Use our translate functions directly rather than relying on a
265 * duplicated list of supported formats which is prone to getting
266 * out of sync:
267 */
268 if(tex_usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
269 return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID;
270 else
271 return svga_translate_format(format) != SVGA3D_FORMAT_INVALID;
272 }
273
274
275 static void
276 svga_fence_reference(struct pipe_screen *screen,
277 struct pipe_fence_handle **ptr,
278 struct pipe_fence_handle *fence)
279 {
280 struct svga_winsys_screen *sws = svga_screen(screen)->sws;
281 sws->fence_reference(sws, ptr, fence);
282 }
283
284
285 static int
286 svga_fence_signalled(struct pipe_screen *screen,
287 struct pipe_fence_handle *fence,
288 unsigned flag)
289 {
290 struct svga_winsys_screen *sws = svga_screen(screen)->sws;
291 return sws->fence_signalled(sws, fence, flag);
292 }
293
294
295 static int
296 svga_fence_finish(struct pipe_screen *screen,
297 struct pipe_fence_handle *fence,
298 unsigned flag)
299 {
300 struct svga_winsys_screen *sws = svga_screen(screen)->sws;
301
302 SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n",
303 __FUNCTION__, fence);
304
305 return sws->fence_finish(sws, fence, flag);
306 }
307
308
309 static void
310 svga_destroy_screen( struct pipe_screen *screen )
311 {
312 struct svga_screen *svgascreen = svga_screen(screen);
313
314 svga_screen_cache_cleanup(svgascreen);
315
316 pipe_mutex_destroy(svgascreen->swc_mutex);
317 pipe_mutex_destroy(svgascreen->tex_mutex);
318
319 svgascreen->swc->destroy(svgascreen->swc);
320
321 svgascreen->sws->destroy(svgascreen->sws);
322
323 FREE(svgascreen);
324 }
325
326
327 /**
328 * Create a new svga_screen object
329 */
330 struct pipe_screen *
331 svga_screen_create(struct svga_winsys_screen *sws)
332 {
333 struct svga_screen *svgascreen;
334 struct pipe_screen *screen;
335 SVGA3dDevCapResult result;
336
337 #ifdef DEBUG
338 SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 );
339 #endif
340
341 svgascreen = CALLOC_STRUCT(svga_screen);
342 if (!svgascreen)
343 goto error1;
344
345 svgascreen->debug.force_level_surface_view =
346 debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE);
347 svgascreen->debug.force_surface_view =
348 debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE);
349 svgascreen->debug.force_sampler_view =
350 debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE);
351 svgascreen->debug.no_surface_view =
352 debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE);
353 svgascreen->debug.no_sampler_view =
354 debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE);
355
356 screen = &svgascreen->screen;
357
358 screen->destroy = svga_destroy_screen;
359 screen->get_name = svga_get_name;
360 screen->get_vendor = svga_get_vendor;
361 screen->get_param = svga_get_param;
362 screen->get_paramf = svga_get_paramf;
363 screen->is_format_supported = svga_is_format_supported;
364 screen->fence_reference = svga_fence_reference;
365 screen->fence_signalled = svga_fence_signalled;
366 screen->fence_finish = svga_fence_finish;
367 svgascreen->sws = sws;
368
369 svga_screen_init_texture_functions(screen);
370 svga_screen_init_buffer_functions(screen);
371
372 svgascreen->use_ps30 =
373 sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) &&
374 result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE;
375
376 svgascreen->use_vs30 =
377 sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) &&
378 result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE;
379
380 #if 1
381 /* Shader model 2.0 is unsupported at the moment. */
382 if(!svgascreen->use_ps30 || !svgascreen->use_vs30)
383 goto error2;
384 #else
385 if(debug_get_bool_option("SVGA_NO_SM30", FALSE))
386 svgascreen->use_vs30 = svgascreen->use_ps30 = FALSE;
387 #endif
388
389 svgascreen->swc = sws->context_create(sws);
390 if(!svgascreen->swc)
391 goto error2;
392
393 pipe_mutex_init(svgascreen->tex_mutex);
394 pipe_mutex_init(svgascreen->swc_mutex);
395
396 LIST_INITHEAD(&svgascreen->cached_buffers);
397
398 svga_screen_cache_init(svgascreen);
399
400 return screen;
401 error2:
402 FREE(svgascreen);
403 error1:
404 return NULL;
405 }
406
407 void svga_screen_flush( struct svga_screen *svgascreen,
408 struct pipe_fence_handle **pfence )
409 {
410 struct pipe_fence_handle *fence = NULL;
411
412 SVGA_DBG(DEBUG_PERF, "%s\n", __FUNCTION__);
413
414 pipe_mutex_lock(svgascreen->swc_mutex);
415 svgascreen->swc->flush(svgascreen->swc, &fence);
416 pipe_mutex_unlock(svgascreen->swc_mutex);
417
418 svga_screen_cache_flush(svgascreen, fence);
419
420 if(pfence)
421 *pfence = fence;
422 else
423 svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
424 }
425
426 struct svga_winsys_screen *
427 svga_winsys_screen(struct pipe_screen *screen)
428 {
429 return svga_screen(screen)->sws;
430 }
431
432 #ifdef DEBUG
433 struct svga_screen *
434 svga_screen(struct pipe_screen *screen)
435 {
436 assert(screen);
437 assert(screen->destroy == svga_destroy_screen);
438 return (struct svga_screen *)screen;
439 }
440 #endif