Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5563 | serge | 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 "util/u_inlines.h" |
||
28 | #include "util/u_string.h" |
||
29 | #include "util/u_math.h" |
||
30 | |||
31 | #include "svga_winsys.h" |
||
32 | #include "svga_public.h" |
||
33 | #include "svga_context.h" |
||
34 | #include "svga_format.h" |
||
35 | #include "svga_screen.h" |
||
36 | #include "svga_resource_texture.h" |
||
37 | #include "svga_resource.h" |
||
38 | #include "svga_debug.h" |
||
39 | |||
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, NULL }, |
||
48 | { "tgsi", DEBUG_TGSI, NULL }, |
||
49 | { "pipe", DEBUG_PIPE, NULL }, |
||
50 | { "state", DEBUG_STATE, NULL }, |
||
51 | { "screen", DEBUG_SCREEN, NULL }, |
||
52 | { "tex", DEBUG_TEX, NULL }, |
||
53 | { "swtnl", DEBUG_SWTNL, NULL }, |
||
54 | { "const", DEBUG_CONSTS, NULL }, |
||
55 | { "viewport", DEBUG_VIEWPORT, NULL }, |
||
56 | { "views", DEBUG_VIEWS, NULL }, |
||
57 | { "perf", DEBUG_PERF, NULL }, |
||
58 | { "flush", DEBUG_FLUSH, NULL }, |
||
59 | { "sync", DEBUG_SYNC, NULL }, |
||
60 | { "cache", DEBUG_CACHE, NULL }, |
||
61 | DEBUG_NAMED_VALUE_END |
||
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 | const char *build = "", *llvm = "", *mutex = ""; |
||
76 | static char name[100]; |
||
77 | #ifdef DEBUG |
||
78 | /* Only return internal details in the DEBUG version: |
||
79 | */ |
||
80 | build = "build: DEBUG;"; |
||
81 | mutex = "mutex: " PIPE_ATOMIC ";"; |
||
82 | #ifdef HAVE_LLVM |
||
83 | llvm = "LLVM;"; |
||
84 | #endif |
||
85 | #else |
||
86 | build = "build: RELEASE;"; |
||
87 | #endif |
||
88 | |||
89 | util_snprintf(name, sizeof(name), "SVGA3D; %s %s %s", build, mutex, llvm); |
||
90 | return name; |
||
91 | } |
||
92 | |||
93 | |||
94 | |||
95 | |||
96 | static float |
||
97 | svga_get_paramf(struct pipe_screen *screen, enum pipe_capf param) |
||
98 | { |
||
99 | struct svga_screen *svgascreen = svga_screen(screen); |
||
100 | struct svga_winsys_screen *sws = svgascreen->sws; |
||
101 | SVGA3dDevCapResult result; |
||
102 | |||
103 | switch (param) { |
||
104 | case PIPE_CAPF_MAX_LINE_WIDTH: |
||
105 | /* fall-through */ |
||
106 | case PIPE_CAPF_MAX_LINE_WIDTH_AA: |
||
107 | return 7.0; |
||
108 | |||
109 | case PIPE_CAPF_MAX_POINT_WIDTH: |
||
110 | /* fall-through */ |
||
111 | case PIPE_CAPF_MAX_POINT_WIDTH_AA: |
||
112 | return svgascreen->maxPointSize; |
||
113 | |||
114 | case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: |
||
115 | if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, &result)) |
||
116 | return 4.0f; |
||
117 | return (float) result.u; |
||
118 | |||
119 | case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: |
||
120 | return 15.0; |
||
121 | case PIPE_CAPF_GUARD_BAND_LEFT: |
||
122 | case PIPE_CAPF_GUARD_BAND_TOP: |
||
123 | case PIPE_CAPF_GUARD_BAND_RIGHT: |
||
124 | case PIPE_CAPF_GUARD_BAND_BOTTOM: |
||
125 | return 0.0; |
||
126 | } |
||
127 | |||
128 | debug_printf("Unexpected PIPE_CAPF_ query %u\n", param); |
||
129 | return 0; |
||
130 | } |
||
131 | |||
132 | |||
133 | static int |
||
134 | svga_get_param(struct pipe_screen *screen, enum pipe_cap param) |
||
135 | { |
||
136 | struct svga_screen *svgascreen = svga_screen(screen); |
||
137 | struct svga_winsys_screen *sws = svgascreen->sws; |
||
138 | SVGA3dDevCapResult result; |
||
139 | |||
140 | switch (param) { |
||
141 | case PIPE_CAP_MAX_COMBINED_SAMPLERS: |
||
142 | return 16; |
||
143 | case PIPE_CAP_NPOT_TEXTURES: |
||
144 | return 1; |
||
145 | case PIPE_CAP_TWO_SIDED_STENCIL: |
||
146 | return 1; |
||
147 | case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: |
||
148 | return 0; |
||
149 | case PIPE_CAP_ANISOTROPIC_FILTER: |
||
150 | return 1; |
||
151 | case PIPE_CAP_POINT_SPRITE: |
||
152 | return 1; |
||
153 | case PIPE_CAP_TGSI_TEXCOORD: |
||
154 | return 0; |
||
155 | case PIPE_CAP_MAX_RENDER_TARGETS: |
||
156 | if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result)) |
||
157 | return 1; |
||
158 | if(!result.u) |
||
159 | return 1; |
||
160 | return MIN2(result.u, PIPE_MAX_COLOR_BUFS); |
||
161 | case PIPE_CAP_OCCLUSION_QUERY: |
||
162 | return 1; |
||
163 | case PIPE_CAP_QUERY_TIME_ELAPSED: |
||
164 | return 0; |
||
165 | case PIPE_CAP_TEXTURE_SHADOW_MAP: |
||
166 | return 1; |
||
167 | case PIPE_CAP_TEXTURE_SWIZZLE: |
||
168 | return 1; |
||
169 | case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: |
||
170 | return 0; |
||
171 | case PIPE_CAP_USER_VERTEX_BUFFERS: |
||
172 | case PIPE_CAP_USER_INDEX_BUFFERS: |
||
173 | return 0; |
||
174 | case PIPE_CAP_USER_CONSTANT_BUFFERS: |
||
175 | return 1; |
||
176 | case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: |
||
177 | return 16; |
||
178 | |||
179 | case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: |
||
180 | { |
||
181 | unsigned levels = SVGA_MAX_TEXTURE_LEVELS; |
||
182 | if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result)) |
||
183 | levels = MIN2(util_logbase2(result.u) + 1, levels); |
||
184 | else |
||
185 | levels = 12 /* 2048x2048 */; |
||
186 | if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result)) |
||
187 | levels = MIN2(util_logbase2(result.u) + 1, levels); |
||
188 | else |
||
189 | levels = 12 /* 2048x2048 */; |
||
190 | return levels; |
||
191 | } |
||
192 | |||
193 | case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: |
||
194 | if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result)) |
||
195 | return 8; /* max 128x128x128 */ |
||
196 | return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS); |
||
197 | |||
198 | case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: |
||
199 | /* |
||
200 | * No mechanism to query the host, and at least limited to 2048x2048 on |
||
201 | * certain hardware. |
||
202 | */ |
||
203 | return MIN2(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS), |
||
204 | 12 /* 2048x2048 */); |
||
205 | |||
206 | case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */ |
||
207 | return 1; |
||
208 | |||
209 | case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: |
||
210 | case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: |
||
211 | return 1; |
||
212 | case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: |
||
213 | case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: |
||
214 | return 0; |
||
215 | |||
216 | case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: |
||
217 | return 1; /* The color outputs of vertex shaders are not clamped */ |
||
218 | case PIPE_CAP_VERTEX_COLOR_CLAMPED: |
||
219 | return 0; /* The driver can't clamp vertex colors */ |
||
220 | case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: |
||
221 | return 0; /* The driver can't clamp fragment colors */ |
||
222 | |||
223 | case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: |
||
224 | return 1; /* expected for GL_ARB_framebuffer_object */ |
||
225 | |||
226 | case PIPE_CAP_GLSL_FEATURE_LEVEL: |
||
227 | return 120; |
||
228 | |||
229 | case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: |
||
230 | return 1; |
||
231 | |||
232 | /* Unsupported features */ |
||
233 | case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: |
||
234 | case PIPE_CAP_TEXTURE_MIRROR_CLAMP: |
||
235 | case PIPE_CAP_SM3: |
||
236 | case PIPE_CAP_SHADER_STENCIL_EXPORT: |
||
237 | case PIPE_CAP_DEPTH_CLIP_DISABLE: |
||
238 | case PIPE_CAP_SEAMLESS_CUBE_MAP: |
||
239 | case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: |
||
240 | case PIPE_CAP_INDEP_BLEND_ENABLE: |
||
241 | case PIPE_CAP_INDEP_BLEND_FUNC: |
||
242 | case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: |
||
243 | case PIPE_CAP_PRIMITIVE_RESTART: |
||
244 | case PIPE_CAP_TGSI_INSTANCEID: |
||
245 | case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: |
||
246 | case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: |
||
247 | case PIPE_CAP_SCALED_RESOLVE: |
||
248 | case PIPE_CAP_MIN_TEXEL_OFFSET: |
||
249 | case PIPE_CAP_MAX_TEXEL_OFFSET: |
||
250 | case PIPE_CAP_CONDITIONAL_RENDER: |
||
251 | case PIPE_CAP_TEXTURE_BARRIER: |
||
252 | case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: |
||
253 | case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: |
||
254 | case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: |
||
255 | case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: |
||
256 | case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: |
||
257 | case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: |
||
258 | case PIPE_CAP_COMPUTE: |
||
259 | case PIPE_CAP_START_INSTANCE: |
||
260 | case PIPE_CAP_QUERY_TIMESTAMP: |
||
261 | case PIPE_CAP_TEXTURE_MULTISAMPLE: |
||
262 | case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: |
||
263 | case PIPE_CAP_CUBE_MAP_ARRAY: |
||
264 | case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: |
||
265 | case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: |
||
266 | case PIPE_CAP_QUERY_PIPELINE_STATISTICS: |
||
267 | case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE: |
||
268 | return 0; |
||
269 | case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: |
||
270 | return 1; |
||
271 | case PIPE_CAP_MAX_VIEWPORTS: |
||
272 | return 1; |
||
273 | case PIPE_CAP_ENDIANNESS: |
||
274 | return PIPE_ENDIAN_LITTLE; |
||
275 | } |
||
276 | |||
277 | debug_printf("Unexpected PIPE_CAP_ query %u\n", param); |
||
278 | return 0; |
||
279 | } |
||
280 | |||
281 | static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap param) |
||
282 | { |
||
283 | struct svga_screen *svgascreen = svga_screen(screen); |
||
284 | struct svga_winsys_screen *sws = svgascreen->sws; |
||
285 | SVGA3dDevCapResult result; |
||
286 | |||
287 | switch (shader) |
||
288 | { |
||
289 | case PIPE_SHADER_FRAGMENT: |
||
290 | switch (param) |
||
291 | { |
||
292 | case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: |
||
293 | case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: |
||
294 | case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: |
||
295 | case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: |
||
296 | return 512; |
||
297 | case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: |
||
298 | return SVGA3D_MAX_NESTING_LEVEL; |
||
299 | case PIPE_SHADER_CAP_MAX_INPUTS: |
||
300 | return 10; |
||
301 | case PIPE_SHADER_CAP_MAX_CONSTS: |
||
302 | return 224; |
||
303 | case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: |
||
304 | return 1; |
||
305 | case PIPE_SHADER_CAP_MAX_TEMPS: |
||
306 | if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS, &result)) |
||
307 | return 32; |
||
308 | return MIN2(result.u, SVGA3D_TEMPREG_MAX); |
||
309 | case PIPE_SHADER_CAP_MAX_ADDRS: |
||
310 | case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: |
||
311 | /* |
||
312 | * Although PS 3.0 has some addressing abilities it can only represent |
||
313 | * loops that can be statically determined and unrolled. Given we can |
||
314 | * only handle a subset of the cases that the state tracker already |
||
315 | * does it is better to defer loop unrolling to the state tracker. |
||
316 | */ |
||
317 | return 0; |
||
318 | case PIPE_SHADER_CAP_MAX_PREDS: |
||
319 | return 1; |
||
320 | case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: |
||
321 | return 1; |
||
322 | case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: |
||
323 | return 0; |
||
324 | case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: |
||
325 | case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: |
||
326 | case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: |
||
327 | return 0; |
||
328 | case PIPE_SHADER_CAP_SUBROUTINES: |
||
329 | return 0; |
||
330 | case PIPE_SHADER_CAP_INTEGERS: |
||
331 | return 0; |
||
332 | case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: |
||
333 | return 16; |
||
334 | default: |
||
335 | debug_printf("Unexpected vertex shader query %u\n", param); |
||
336 | return 0; |
||
337 | } |
||
338 | break; |
||
339 | case PIPE_SHADER_VERTEX: |
||
340 | switch (param) |
||
341 | { |
||
342 | case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: |
||
343 | case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: |
||
344 | if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS, &result)) |
||
345 | return 512; |
||
346 | return result.u; |
||
347 | case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: |
||
348 | case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: |
||
349 | /* XXX: until we have vertex texture support */ |
||
350 | return 0; |
||
351 | case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: |
||
352 | return SVGA3D_MAX_NESTING_LEVEL; |
||
353 | case PIPE_SHADER_CAP_MAX_INPUTS: |
||
354 | return 16; |
||
355 | case PIPE_SHADER_CAP_MAX_CONSTS: |
||
356 | return 256; |
||
357 | case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: |
||
358 | return 1; |
||
359 | case PIPE_SHADER_CAP_MAX_TEMPS: |
||
360 | if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS, &result)) |
||
361 | return 32; |
||
362 | return MIN2(result.u, SVGA3D_TEMPREG_MAX); |
||
363 | case PIPE_SHADER_CAP_MAX_ADDRS: |
||
364 | return 1; |
||
365 | case PIPE_SHADER_CAP_MAX_PREDS: |
||
366 | return 1; |
||
367 | case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: |
||
368 | return 1; |
||
369 | case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: |
||
370 | return 0; |
||
371 | case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: |
||
372 | case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: |
||
373 | return 1; |
||
374 | case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: |
||
375 | return 0; |
||
376 | case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: |
||
377 | return 1; |
||
378 | case PIPE_SHADER_CAP_SUBROUTINES: |
||
379 | return 0; |
||
380 | case PIPE_SHADER_CAP_INTEGERS: |
||
381 | return 0; |
||
382 | case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: |
||
383 | return 0; |
||
384 | default: |
||
385 | debug_printf("Unexpected vertex shader query %u\n", param); |
||
386 | return 0; |
||
387 | } |
||
388 | break; |
||
389 | case PIPE_SHADER_GEOMETRY: |
||
390 | /* no support for geometry shaders at this time */ |
||
391 | return 0; |
||
392 | default: |
||
393 | debug_printf("Unexpected shader type (%u) query\n", shader); |
||
394 | return 0; |
||
395 | } |
||
396 | return 0; |
||
397 | } |
||
398 | |||
399 | |||
400 | static boolean |
||
401 | svga_is_format_supported( struct pipe_screen *screen, |
||
402 | enum pipe_format format, |
||
403 | enum pipe_texture_target target, |
||
404 | unsigned sample_count, |
||
405 | unsigned tex_usage) |
||
406 | { |
||
407 | struct svga_screen *ss = svga_screen(screen); |
||
408 | SVGA3dSurfaceFormat svga_format; |
||
409 | SVGA3dSurfaceFormatCaps caps; |
||
410 | SVGA3dSurfaceFormatCaps mask; |
||
411 | |||
412 | assert(tex_usage); |
||
413 | |||
414 | if (sample_count > 1) { |
||
415 | return FALSE; |
||
416 | } |
||
417 | |||
418 | svga_format = svga_translate_format(ss, format, tex_usage); |
||
419 | if (svga_format == SVGA3D_FORMAT_INVALID) { |
||
420 | return FALSE; |
||
421 | } |
||
422 | |||
423 | /* |
||
424 | * Override host capabilities, so that we end up with the same |
||
425 | * visuals for all virtual hardware implementations. |
||
426 | */ |
||
427 | |||
428 | if (tex_usage & PIPE_BIND_DISPLAY_TARGET) { |
||
429 | switch (svga_format) { |
||
430 | case SVGA3D_A8R8G8B8: |
||
431 | case SVGA3D_X8R8G8B8: |
||
432 | case SVGA3D_R5G6B5: |
||
433 | break; |
||
434 | |||
435 | /* Often unsupported/problematic. This means we end up with the same |
||
436 | * visuals for all virtual hardware implementations. |
||
437 | */ |
||
438 | case SVGA3D_A4R4G4B4: |
||
439 | case SVGA3D_A1R5G5B5: |
||
440 | return FALSE; |
||
441 | |||
442 | default: |
||
443 | return FALSE; |
||
444 | } |
||
445 | } |
||
446 | |||
447 | /* |
||
448 | * Query the host capabilities. |
||
449 | */ |
||
450 | |||
451 | svga_get_format_cap(ss, svga_format, &caps); |
||
452 | |||
453 | mask.value = 0; |
||
454 | if (tex_usage & PIPE_BIND_RENDER_TARGET) { |
||
455 | mask.offscreenRenderTarget = 1; |
||
456 | } |
||
457 | if (tex_usage & PIPE_BIND_DEPTH_STENCIL) { |
||
458 | mask.zStencil = 1; |
||
459 | } |
||
460 | if (tex_usage & PIPE_BIND_SAMPLER_VIEW) { |
||
461 | mask.texture = 1; |
||
462 | } |
||
463 | |||
464 | return (caps.value & mask.value) == mask.value; |
||
465 | } |
||
466 | |||
467 | |||
468 | static void |
||
469 | svga_fence_reference(struct pipe_screen *screen, |
||
470 | struct pipe_fence_handle **ptr, |
||
471 | struct pipe_fence_handle *fence) |
||
472 | { |
||
473 | struct svga_winsys_screen *sws = svga_screen(screen)->sws; |
||
474 | sws->fence_reference(sws, ptr, fence); |
||
475 | } |
||
476 | |||
477 | |||
478 | static boolean |
||
479 | svga_fence_signalled(struct pipe_screen *screen, |
||
480 | struct pipe_fence_handle *fence) |
||
481 | { |
||
482 | struct svga_winsys_screen *sws = svga_screen(screen)->sws; |
||
483 | return sws->fence_signalled(sws, fence, 0) == 0; |
||
484 | } |
||
485 | |||
486 | |||
487 | static boolean |
||
488 | svga_fence_finish(struct pipe_screen *screen, |
||
489 | struct pipe_fence_handle *fence, |
||
490 | uint64_t timeout) |
||
491 | { |
||
492 | struct svga_winsys_screen *sws = svga_screen(screen)->sws; |
||
493 | |||
494 | SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", |
||
495 | __FUNCTION__, fence); |
||
496 | |||
497 | return sws->fence_finish(sws, fence, 0) == 0; |
||
498 | } |
||
499 | |||
500 | |||
501 | static int |
||
502 | svga_get_driver_query_info(struct pipe_screen *screen, |
||
503 | unsigned index, |
||
504 | struct pipe_driver_query_info *info) |
||
505 | { |
||
506 | static const struct pipe_driver_query_info queries[] = { |
||
507 | {"draw-calls", SVGA_QUERY_DRAW_CALLS, 0, FALSE}, |
||
508 | {"fallbacks", SVGA_QUERY_FALLBACKS, 0, FALSE}, |
||
509 | {"memory-used", SVGA_QUERY_MEMORY_USED, 0, TRUE} |
||
510 | }; |
||
511 | |||
512 | if (!info) |
||
513 | return Elements(queries); |
||
514 | |||
515 | if (index >= Elements(queries)) |
||
516 | return 0; |
||
517 | |||
518 | *info = queries[index]; |
||
519 | return 1; |
||
520 | } |
||
521 | |||
522 | |||
523 | static void |
||
524 | svga_destroy_screen( struct pipe_screen *screen ) |
||
525 | { |
||
526 | struct svga_screen *svgascreen = svga_screen(screen); |
||
527 | |||
528 | svga_screen_cache_cleanup(svgascreen); |
||
529 | |||
530 | pipe_mutex_destroy(svgascreen->swc_mutex); |
||
531 | pipe_mutex_destroy(svgascreen->tex_mutex); |
||
532 | |||
533 | svgascreen->sws->destroy(svgascreen->sws); |
||
534 | |||
535 | FREE(svgascreen); |
||
536 | } |
||
537 | |||
538 | |||
539 | /** |
||
540 | * Create a new svga_screen object |
||
541 | */ |
||
542 | struct pipe_screen * |
||
543 | svga_screen_create(struct svga_winsys_screen *sws) |
||
544 | { |
||
545 | struct svga_screen *svgascreen; |
||
546 | struct pipe_screen *screen; |
||
547 | SVGA3dDevCapResult result; |
||
548 | boolean use_vs30, use_ps30; |
||
549 | |||
550 | #ifdef DEBUG |
||
551 | SVGA_DEBUG = debug_get_flags_option("SVGA_DEBUG", svga_debug_flags, 0 ); |
||
552 | #endif |
||
553 | |||
554 | svgascreen = CALLOC_STRUCT(svga_screen); |
||
555 | if (!svgascreen) |
||
556 | goto error1; |
||
557 | |||
558 | svgascreen->debug.force_level_surface_view = |
||
559 | debug_get_bool_option("SVGA_FORCE_LEVEL_SURFACE_VIEW", FALSE); |
||
560 | svgascreen->debug.force_surface_view = |
||
561 | debug_get_bool_option("SVGA_FORCE_SURFACE_VIEW", FALSE); |
||
562 | svgascreen->debug.force_sampler_view = |
||
563 | debug_get_bool_option("SVGA_FORCE_SAMPLER_VIEW", FALSE); |
||
564 | svgascreen->debug.no_surface_view = |
||
565 | debug_get_bool_option("SVGA_NO_SURFACE_VIEW", FALSE); |
||
566 | svgascreen->debug.no_sampler_view = |
||
567 | debug_get_bool_option("SVGA_NO_SAMPLER_VIEW", FALSE); |
||
568 | |||
569 | screen = &svgascreen->screen; |
||
570 | |||
571 | screen->destroy = svga_destroy_screen; |
||
572 | screen->get_name = svga_get_name; |
||
573 | screen->get_vendor = svga_get_vendor; |
||
574 | screen->get_param = svga_get_param; |
||
575 | screen->get_shader_param = svga_get_shader_param; |
||
576 | screen->get_paramf = svga_get_paramf; |
||
577 | screen->is_format_supported = svga_is_format_supported; |
||
578 | screen->context_create = svga_context_create; |
||
579 | screen->fence_reference = svga_fence_reference; |
||
580 | screen->fence_signalled = svga_fence_signalled; |
||
581 | screen->fence_finish = svga_fence_finish; |
||
582 | screen->get_driver_query_info = svga_get_driver_query_info; |
||
583 | svgascreen->sws = sws; |
||
584 | |||
585 | svga_init_screen_resource_functions(svgascreen); |
||
586 | |||
587 | if (sws->get_hw_version) { |
||
588 | svgascreen->hw_version = sws->get_hw_version(sws); |
||
589 | } else { |
||
590 | svgascreen->hw_version = SVGA3D_HWVERSION_WS65_B1; |
||
591 | } |
||
592 | |||
593 | use_ps30 = |
||
594 | sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) && |
||
595 | result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE; |
||
596 | |||
597 | use_vs30 = |
||
598 | sws->get_cap(sws, SVGA3D_DEVCAP_VERTEX_SHADER_VERSION, &result) && |
||
599 | result.u >= SVGA3DVSVERSION_30 ? TRUE : FALSE; |
||
600 | |||
601 | /* we require Shader model 3.0 or later */ |
||
602 | if (!use_ps30 || !use_vs30) |
||
603 | goto error2; |
||
604 | |||
605 | /* |
||
606 | * The D16, D24X8, and D24S8 formats always do an implicit shadow compare |
||
607 | * when sampled from, where as the DF16, DF24, and D24S8_INT do not. So |
||
608 | * we prefer the later when available. |
||
609 | * |
||
610 | * This mimics hardware vendors extensions for D3D depth sampling. See also |
||
611 | * http://aras-p.info/texts/D3D9GPUHacks.html |
||
612 | */ |
||
613 | |||
614 | { |
||
615 | boolean has_df16, has_df24, has_d24s8_int; |
||
616 | SVGA3dSurfaceFormatCaps caps; |
||
617 | SVGA3dSurfaceFormatCaps mask; |
||
618 | mask.value = 0; |
||
619 | mask.zStencil = 1; |
||
620 | mask.texture = 1; |
||
621 | |||
622 | svgascreen->depth.z16 = SVGA3D_Z_D16; |
||
623 | svgascreen->depth.x8z24 = SVGA3D_Z_D24X8; |
||
624 | svgascreen->depth.s8z24 = SVGA3D_Z_D24S8; |
||
625 | |||
626 | svga_get_format_cap(svgascreen, SVGA3D_Z_DF16, &caps); |
||
627 | has_df16 = (caps.value & mask.value) == mask.value; |
||
628 | |||
629 | svga_get_format_cap(svgascreen, SVGA3D_Z_DF24, &caps); |
||
630 | has_df24 = (caps.value & mask.value) == mask.value; |
||
631 | |||
632 | svga_get_format_cap(svgascreen, SVGA3D_Z_D24S8_INT, &caps); |
||
633 | has_d24s8_int = (caps.value & mask.value) == mask.value; |
||
634 | |||
635 | /* XXX: We might want some other logic here. |
||
636 | * Like if we only have d24s8_int we should |
||
637 | * emulate the other formats with that. |
||
638 | */ |
||
639 | if (has_df16) { |
||
640 | svgascreen->depth.z16 = SVGA3D_Z_DF16; |
||
641 | } |
||
642 | if (has_df24) { |
||
643 | svgascreen->depth.x8z24 = SVGA3D_Z_DF24; |
||
644 | } |
||
645 | if (has_d24s8_int) { |
||
646 | svgascreen->depth.s8z24 = SVGA3D_Z_D24S8_INT; |
||
647 | } |
||
648 | } |
||
649 | |||
650 | if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_POINT_SIZE, &result)) { |
||
651 | svgascreen->maxPointSize = 1.0F; |
||
652 | } else { |
||
653 | /* Keep this to a reasonable size to avoid failures in |
||
654 | * conform/pntaa.c: |
||
655 | */ |
||
656 | svgascreen->maxPointSize = MIN2(result.f, 80.0f); |
||
657 | } |
||
658 | |||
659 | pipe_mutex_init(svgascreen->tex_mutex); |
||
660 | pipe_mutex_init(svgascreen->swc_mutex); |
||
661 | |||
662 | svga_screen_cache_init(svgascreen); |
||
663 | |||
664 | return screen; |
||
665 | error2: |
||
666 | FREE(svgascreen); |
||
667 | error1: |
||
668 | return NULL; |
||
669 | } |
||
670 | |||
671 | struct svga_winsys_screen * |
||
672 | svga_winsys_screen(struct pipe_screen *screen) |
||
673 | { |
||
674 | return svga_screen(screen)->sws; |
||
675 | } |
||
676 | |||
677 | #ifdef DEBUG |
||
678 | struct svga_screen * |
||
679 | svga_screen(struct pipe_screen *screen) |
||
680 | { |
||
681 | assert(screen); |
||
682 | assert(screen->destroy == svga_destroy_screen); |
||
683 | return (struct svga_screen *)screen; |
||
684 | } |
||
685 | #endif |