svga: whitespace, line wrapping fixes in svga_surface.c
[mesa.git] / src / gallium / drivers / svga / svga_surface.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 "svga_cmd.h"
27
28 #include "pipe/p_state.h"
29 #include "pipe/p_defines.h"
30 #include "util/u_inlines.h"
31 #include "os/os_thread.h"
32 #include "util/u_bitmask.h"
33 #include "util/u_format.h"
34 #include "util/u_math.h"
35 #include "util/u_memory.h"
36
37 #include "svga_format.h"
38 #include "svga_screen.h"
39 #include "svga_context.h"
40 #include "svga_sampler_view.h"
41 #include "svga_resource_texture.h"
42 #include "svga_surface.h"
43 #include "svga_debug.h"
44
45 static void svga_mark_surface_dirty(struct pipe_surface *surf);
46
47 void
48 svga_texture_copy_handle(struct svga_context *svga,
49 struct svga_winsys_surface *src_handle,
50 unsigned src_x, unsigned src_y, unsigned src_z,
51 unsigned src_level, unsigned src_layer,
52 struct svga_winsys_surface *dst_handle,
53 unsigned dst_x, unsigned dst_y, unsigned dst_z,
54 unsigned dst_level, unsigned dst_layer,
55 unsigned width, unsigned height, unsigned depth)
56 {
57 struct svga_surface dst, src;
58 enum pipe_error ret;
59 SVGA3dCopyBox box, *boxes;
60
61 assert(svga);
62
63 src.handle = src_handle;
64 src.real_level = src_level;
65 src.real_layer = src_layer;
66 src.real_zslice = 0;
67
68 dst.handle = dst_handle;
69 dst.real_level = dst_level;
70 dst.real_layer = dst_layer;
71 dst.real_zslice = 0;
72
73 box.x = dst_x;
74 box.y = dst_y;
75 box.z = dst_z;
76 box.w = width;
77 box.h = height;
78 box.d = depth;
79 box.srcx = src_x;
80 box.srcy = src_y;
81 box.srcz = src_z;
82
83 /*
84 SVGA_DBG(DEBUG_VIEWS, "mipcopy src: %p %u (%ux%ux%u), dst: %p %u (%ux%ux%u)\n",
85 src_handle, src_level, src_x, src_y, src_z,
86 dst_handle, dst_level, dst_x, dst_y, dst_z);
87 */
88
89 ret = SVGA3D_BeginSurfaceCopy(svga->swc,
90 &src.base,
91 &dst.base,
92 &boxes, 1);
93 if (ret != PIPE_OK) {
94 svga_context_flush(svga, NULL);
95 ret = SVGA3D_BeginSurfaceCopy(svga->swc,
96 &src.base,
97 &dst.base,
98 &boxes, 1);
99 assert(ret == PIPE_OK);
100 }
101 *boxes = box;
102 SVGA_FIFOCommitAll(svga->swc);
103 }
104
105
106 struct svga_winsys_surface *
107 svga_texture_view_surface(struct svga_context *svga,
108 struct svga_texture *tex,
109 unsigned bind_flags,
110 SVGA3dSurfaceFlags flags,
111 SVGA3dSurfaceFormat format,
112 unsigned start_mip,
113 unsigned num_mip,
114 int layer_pick,
115 unsigned num_layers,
116 int zslice_pick,
117 struct svga_host_surface_cache_key *key) /* OUT */
118 {
119 struct svga_screen *ss = svga_screen(svga->pipe.screen);
120 struct svga_winsys_surface *handle;
121 uint32_t i, j;
122 unsigned z_offset = 0;
123
124 SVGA_DBG(DEBUG_PERF,
125 "svga: Create surface view: layer %d zslice %d mips %d..%d\n",
126 layer_pick, zslice_pick, start_mip, start_mip+num_mip-1);
127
128 key->flags = flags;
129 key->format = format;
130 key->numMipLevels = num_mip;
131 key->size.width = u_minify(tex->b.b.width0, start_mip);
132 key->size.height = u_minify(tex->b.b.height0, start_mip);
133 key->size.depth = zslice_pick < 0 ? u_minify(tex->b.b.depth0, start_mip) : 1;
134 key->cachable = 1;
135 key->arraySize = 1;
136 key->numFaces = 1;
137 key->sampleCount = tex->b.b.nr_samples;
138
139 if (key->sampleCount > 1) {
140 key->flags |= SVGA3D_SURFACE_MASKABLE_ANTIALIAS;
141 }
142
143 if (tex->b.b.target == PIPE_TEXTURE_CUBE && layer_pick < 0) {
144 key->flags |= SVGA3D_SURFACE_CUBEMAP;
145 key->numFaces = 6;
146 } else if (tex->b.b.target == PIPE_TEXTURE_1D_ARRAY ||
147 tex->b.b.target == PIPE_TEXTURE_2D_ARRAY) {
148 key->arraySize = num_layers;
149 }
150
151 if (key->format == SVGA3D_FORMAT_INVALID) {
152 key->cachable = 0;
153 return NULL;
154 }
155
156 SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
157 handle = svga_screen_surface_create(ss, bind_flags, PIPE_USAGE_DEFAULT, key);
158 if (!handle) {
159 key->cachable = 0;
160 return NULL;
161 }
162
163 SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle);
164
165 if (layer_pick < 0)
166 layer_pick = 0;
167
168 if (zslice_pick >= 0)
169 z_offset = zslice_pick;
170
171 for (i = 0; i < key->numMipLevels; i++) {
172 for (j = 0; j < key->numFaces * key->arraySize; j++) {
173 if (svga_is_texture_level_defined(tex, j + layer_pick, i + start_mip)) {
174 unsigned depth = (zslice_pick < 0 ?
175 u_minify(tex->b.b.depth0, i + start_mip) :
176 1);
177
178 svga_texture_copy_handle(svga,
179 tex->handle,
180 0, 0, z_offset,
181 i + start_mip,
182 j + layer_pick,
183 handle, 0, 0, 0, i, j,
184 u_minify(tex->b.b.width0, i + start_mip),
185 u_minify(tex->b.b.height0, i + start_mip),
186 depth);
187 }
188 }
189 }
190
191 return handle;
192 }
193
194
195 /**
196 * A helper function to create a surface view.
197 * The view boolean flag specifies whether svga_texture_view_surface()
198 * will be called to create a cloned surface and resource for the view.
199 */
200 static struct pipe_surface *
201 svga_create_surface_view(struct pipe_context *pipe,
202 struct pipe_resource *pt,
203 const struct pipe_surface *surf_tmpl,
204 boolean view)
205 {
206 struct svga_context *svga = svga_context(pipe);
207 struct svga_texture *tex = svga_texture(pt);
208 struct pipe_screen *screen = pipe->screen;
209 struct svga_screen *ss = svga_screen(screen);
210 struct svga_surface *s;
211 unsigned layer, zslice, bind;
212 unsigned nlayers = 1;
213 SVGA3dSurfaceFlags flags = 0;
214 SVGA3dSurfaceFormat format;
215
216 s = CALLOC_STRUCT(svga_surface);
217 if (!s)
218 return NULL;
219
220 if (pt->target == PIPE_TEXTURE_CUBE) {
221 layer = surf_tmpl->u.tex.first_layer;
222 zslice = 0;
223 }
224 else if (pt->target == PIPE_TEXTURE_1D_ARRAY ||
225 pt->target == PIPE_TEXTURE_2D_ARRAY) {
226 layer = surf_tmpl->u.tex.first_layer;
227 zslice = 0;
228 nlayers = surf_tmpl->u.tex.last_layer - surf_tmpl->u.tex.first_layer + 1;
229 }
230 else {
231 layer = 0;
232 zslice = surf_tmpl->u.tex.first_layer;
233 }
234
235 pipe_reference_init(&s->base.reference, 1);
236 pipe_resource_reference(&s->base.texture, pt);
237 s->base.context = pipe;
238 s->base.format = surf_tmpl->format;
239 s->base.width = u_minify(pt->width0, surf_tmpl->u.tex.level);
240 s->base.height = u_minify(pt->height0, surf_tmpl->u.tex.level);
241 s->base.u.tex.level = surf_tmpl->u.tex.level;
242 s->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
243 s->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
244 s->view_id = SVGA3D_INVALID_ID;
245
246 s->backed = NULL;
247
248 if (util_format_is_depth_or_stencil(surf_tmpl->format)) {
249 flags = SVGA3D_SURFACE_HINT_DEPTHSTENCIL |
250 SVGA3D_SURFACE_BIND_DEPTH_STENCIL;
251 bind = PIPE_BIND_DEPTH_STENCIL;
252 }
253 else {
254 flags = SVGA3D_SURFACE_HINT_RENDERTARGET |
255 SVGA3D_SURFACE_BIND_RENDER_TARGET;
256 bind = PIPE_BIND_RENDER_TARGET;
257 }
258
259 if (tex->imported)
260 format = tex->key.format;
261 else
262 format = svga_translate_format(ss, surf_tmpl->format, bind);
263
264 assert(format != SVGA3D_FORMAT_INVALID);
265
266 if (view) {
267 SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u layer %u z %u, %p\n",
268 pt, surf_tmpl->u.tex.level, layer, zslice, s);
269
270 if (svga_have_vgpu10(svga)) {
271 switch (pt->target) {
272 case PIPE_TEXTURE_1D:
273 flags |= SVGA3D_SURFACE_1D;
274 break;
275 case PIPE_TEXTURE_1D_ARRAY:
276 flags |= SVGA3D_SURFACE_1D | SVGA3D_SURFACE_ARRAY;
277 break;
278 case PIPE_TEXTURE_2D_ARRAY:
279 flags |= SVGA3D_SURFACE_ARRAY;
280 break;
281 case PIPE_TEXTURE_3D:
282 flags |= SVGA3D_SURFACE_VOLUME;
283 break;
284 case PIPE_TEXTURE_CUBE:
285 if (nlayers == 6)
286 flags |= SVGA3D_SURFACE_CUBEMAP;
287 break;
288 default:
289 break;
290 }
291 }
292
293 /* When we clone the surface view resource, use the format used in
294 * the creation of the original resource.
295 */
296 s->handle = svga_texture_view_surface(svga, tex, bind, flags,
297 tex->key.format,
298 surf_tmpl->u.tex.level, 1,
299 layer, nlayers, zslice, &s->key);
300 if (!s->handle) {
301 FREE(s);
302 return NULL;
303 }
304
305 s->key.format = format;
306 s->real_layer = 0;
307 s->real_level = 0;
308 s->real_zslice = 0;
309 } else {
310 SVGA_DBG(DEBUG_VIEWS,
311 "svga: Surface view: no %p, level %u, layer %u, z %u, %p\n",
312 pt, surf_tmpl->u.tex.level, layer, zslice, s);
313
314 memset(&s->key, 0, sizeof s->key);
315 s->key.format = format;
316 s->handle = tex->handle;
317 s->real_layer = layer;
318 s->real_zslice = zslice;
319 s->real_level = surf_tmpl->u.tex.level;
320 }
321
322 svga->hud.num_surface_views++;
323
324 return &s->base;
325 }
326
327
328 static struct pipe_surface *
329 svga_create_surface(struct pipe_context *pipe,
330 struct pipe_resource *pt,
331 const struct pipe_surface *surf_tmpl)
332 {
333 struct svga_context *svga = svga_context(pipe);
334 struct pipe_screen *screen = pipe->screen;
335 boolean view = FALSE;
336
337 if (svga_screen(screen)->debug.force_surface_view)
338 view = TRUE;
339
340 if (surf_tmpl->u.tex.level != 0 &&
341 svga_screen(screen)->debug.force_level_surface_view)
342 view = TRUE;
343
344 if (pt->target == PIPE_TEXTURE_3D)
345 view = TRUE;
346
347 if (svga_have_vgpu10(svga) || svga_screen(screen)->debug.no_surface_view)
348 view = FALSE;
349
350 return svga_create_surface_view(pipe, pt, surf_tmpl, view);
351 }
352
353
354 /**
355 * Clone the surface view and its associated resource.
356 */
357 static struct svga_surface *
358 create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
359 {
360 struct svga_surface *bs = s->backed;
361
362 if (!bs) {
363 struct svga_texture *tex = svga_texture(s->base.texture);
364 struct pipe_surface *backed_view;
365
366 backed_view = svga_create_surface_view(&svga->pipe,
367 &tex->b.b,
368 &s->base,
369 TRUE);
370 if (!backed_view)
371 return NULL;
372
373 bs = svga_surface(backed_view);
374 s->backed = bs;
375 }
376
377 svga_mark_surface_dirty(&bs->base);
378
379 return bs;
380 }
381
382 /**
383 * Create a DX RenderTarget/DepthStencil View for the given surface,
384 * if needed.
385 */
386 struct pipe_surface *
387 svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
388 {
389 enum pipe_error ret = PIPE_OK;
390 unsigned shader;
391
392 assert(svga_have_vgpu10(svga));
393
394 /**
395 * DX spec explicitly specifies that no resource can be bound to a render
396 * target view and a shader resource view simultanously.
397 * So first check if the resource bound to this surface view collides with
398 * a sampler view. If so, then we will clone this surface view and its
399 * associated resource. We will then use the cloned surface view for
400 * render target.
401 */
402 for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
403 if (svga_check_sampler_view_resource_collision(svga, s->handle, shader)) {
404 SVGA_DBG(DEBUG_VIEWS,
405 "same resource used in shaderResource and renderTarget 0x%x\n",
406 s->handle);
407 s = create_backed_surface_view(svga, s);
408 if (!s)
409 return NULL;
410
411 break;
412 }
413 }
414
415 if (s->view_id == SVGA3D_INVALID_ID) {
416 SVGA3dResourceType resType;
417 SVGA3dRenderTargetViewDesc desc;
418
419 desc.tex.mipSlice = s->real_level;
420 desc.tex.firstArraySlice = s->real_layer + s->real_zslice;
421 desc.tex.arraySize =
422 s->base.u.tex.last_layer - s->base.u.tex.first_layer + 1;
423
424 s->view_id = util_bitmask_add(svga->surface_view_id_bm);
425
426 switch (s->base.texture->target) {
427 case PIPE_TEXTURE_1D:
428 case PIPE_TEXTURE_1D_ARRAY:
429 resType = SVGA3D_RESOURCE_TEXTURE1D;
430 break;
431 case PIPE_TEXTURE_RECT:
432 case PIPE_TEXTURE_2D:
433 case PIPE_TEXTURE_2D_ARRAY:
434 case PIPE_TEXTURE_CUBE:
435 /* drawing to cube map is treated as drawing to 2D array */
436 resType = SVGA3D_RESOURCE_TEXTURE2D;
437 break;
438 case PIPE_TEXTURE_3D:
439 resType = SVGA3D_RESOURCE_TEXTURE3D;
440 break;
441 default:
442 assert(!"Unexpected texture target");
443 resType = SVGA3D_RESOURCE_TEXTURE2D;
444 }
445
446 if (util_format_is_depth_or_stencil(s->base.format)) {
447 ret = SVGA3D_vgpu10_DefineDepthStencilView(svga->swc,
448 s->view_id,
449 s->handle,
450 s->key.format,
451 resType,
452 &desc);
453 }
454 else {
455 ret = SVGA3D_vgpu10_DefineRenderTargetView(svga->swc,
456 s->view_id,
457 s->handle,
458 s->key.format,
459 resType,
460 &desc);
461 }
462
463 if (ret != PIPE_OK) {
464 util_bitmask_clear(svga->surface_view_id_bm, s->view_id);
465 s->view_id = SVGA3D_INVALID_ID;
466 return NULL;
467 }
468 }
469 return &s->base;
470 }
471
472
473
474 static void
475 svga_surface_destroy(struct pipe_context *pipe,
476 struct pipe_surface *surf)
477 {
478 struct svga_context *svga = svga_context(pipe);
479 struct svga_surface *s = svga_surface(surf);
480 struct svga_texture *t = svga_texture(surf->texture);
481 struct svga_screen *ss = svga_screen(surf->texture->screen);
482 enum pipe_error ret = PIPE_OK;
483
484 /* Destroy the backed view surface if it exists */
485 if (s->backed) {
486 svga_surface_destroy(pipe, &s->backed->base);
487 s->backed = NULL;
488 }
489
490 if (s->handle != t->handle) {
491 SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
492 svga_screen_surface_destroy(ss, &s->key, &s->handle);
493 }
494
495 if (s->view_id != SVGA3D_INVALID_ID) {
496 unsigned try;
497
498 assert(svga_have_vgpu10(svga));
499 for (try = 0; try < 2; try++) {
500 if (util_format_is_depth_or_stencil(s->base.format)) {
501 ret = SVGA3D_vgpu10_DestroyDepthStencilView(svga->swc, s->view_id);
502 }
503 else {
504 ret = SVGA3D_vgpu10_DestroyRenderTargetView(svga->swc, s->view_id);
505 }
506 if (ret == PIPE_OK)
507 break;
508 svga_context_flush(svga, NULL);
509 }
510 assert(ret == PIPE_OK);
511 util_bitmask_clear(svga->surface_view_id_bm, s->view_id);
512 }
513
514 pipe_resource_reference(&surf->texture, NULL);
515 FREE(surf);
516
517 svga->hud.num_surface_views--;
518 }
519
520
521 static void
522 svga_mark_surface_dirty(struct pipe_surface *surf)
523 {
524 struct svga_surface *s = svga_surface(surf);
525 struct svga_texture *tex = svga_texture(surf->texture);
526
527 if (!s->dirty) {
528 s->dirty = TRUE;
529
530 if (s->handle == tex->handle) {
531 /* hmm so 3d textures always have all their slices marked ? */
532 svga_define_texture_level(tex, surf->u.tex.first_layer,
533 surf->u.tex.level);
534 }
535 else {
536 /* this will happen later in svga_propagate_surface */
537 }
538 }
539
540 /* Increment the view_age and texture age for this surface's mipmap
541 * level so that any sampler views into the texture are re-validated too.
542 */
543 svga_age_texture_view(tex, surf->u.tex.level);
544 }
545
546
547 void
548 svga_mark_surfaces_dirty(struct svga_context *svga)
549 {
550 struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
551 unsigned i;
552
553 for (i = 0; i < svgascreen->max_color_buffers; i++) {
554 if (svga->curr.framebuffer.cbufs[i])
555 svga_mark_surface_dirty(svga->curr.framebuffer.cbufs[i]);
556 }
557 if (svga->curr.framebuffer.zsbuf)
558 svga_mark_surface_dirty(svga->curr.framebuffer.zsbuf);
559 }
560
561
562 /**
563 * Progagate any changes from surfaces to texture.
564 * pipe is optional context to inline the blit command in.
565 */
566 void
567 svga_propagate_surface(struct svga_context *svga, struct pipe_surface *surf)
568 {
569 struct svga_surface *s = svga_surface(surf);
570 struct svga_texture *tex = svga_texture(surf->texture);
571 struct svga_screen *ss = svga_screen(surf->texture->screen);
572 unsigned zslice, layer;
573 unsigned nlayers = 1;
574 unsigned i;
575
576 if (!s->dirty)
577 return;
578
579 if (surf->texture->target == PIPE_TEXTURE_CUBE) {
580 zslice = 0;
581 layer = surf->u.tex.first_layer;
582 }
583 else if (surf->texture->target == PIPE_TEXTURE_1D_ARRAY ||
584 surf->texture->target == PIPE_TEXTURE_2D_ARRAY) {
585 zslice = 0;
586 layer = surf->u.tex.first_layer;
587 nlayers = surf->u.tex.last_layer - surf->u.tex.first_layer + 1;
588 }
589 else {
590 zslice = surf->u.tex.first_layer;
591 layer = 0;
592 }
593
594 s->dirty = FALSE;
595 ss->texture_timestamp++;
596 svga_age_texture_view(tex, surf->u.tex.level);
597
598 if (s->handle != tex->handle) {
599 SVGA_DBG(DEBUG_VIEWS,
600 "svga: Surface propagate: tex %p, level %u, from %p\n",
601 tex, surf->u.tex.level, surf);
602 for (i = 0; i < nlayers; i++) {
603 svga_texture_copy_handle(svga,
604 s->handle, 0, 0, 0, s->real_level,
605 s->real_layer + i,
606 tex->handle, 0, 0, zslice, surf->u.tex.level,
607 layer + i,
608 u_minify(tex->b.b.width0, surf->u.tex.level),
609 u_minify(tex->b.b.height0, surf->u.tex.level),
610 1);
611 svga_define_texture_level(tex, layer + i, surf->u.tex.level);
612 }
613 }
614 }
615
616
617 /**
618 * Check if we should call svga_propagate_surface on the surface.
619 */
620 boolean
621 svga_surface_needs_propagation(const struct pipe_surface *surf)
622 {
623 const struct svga_surface *s = svga_surface_const(surf);
624 struct svga_texture *tex = svga_texture(surf->texture);
625
626 return s->dirty && s->handle != tex->handle;
627 }
628
629
630 static void
631 svga_get_sample_position(struct pipe_context *context,
632 unsigned sample_count, unsigned sample_index,
633 float *pos_out)
634 {
635 /* We can't actually query the device to learn the sample positions.
636 * These were grabbed from nvidia's driver.
637 */
638 static const float pos1[1][2] = {
639 { 0.5, 0.5 }
640 };
641 static const float pos4[4][2] = {
642 { 0.375000, 0.125000 },
643 { 0.875000, 0.375000 },
644 { 0.125000, 0.625000 },
645 { 0.625000, 0.875000 }
646 };
647 static const float pos8[8][2] = {
648 { 0.562500, 0.312500 },
649 { 0.437500, 0.687500 },
650 { 0.812500, 0.562500 },
651 { 0.312500, 0.187500 },
652 { 0.187500, 0.812500 },
653 { 0.062500, 0.437500 },
654 { 0.687500, 0.937500 },
655 { 0.937500, 0.062500 }
656 };
657 static const float pos16[16][2] = {
658 { 0.187500, 0.062500 },
659 { 0.437500, 0.187500 },
660 { 0.062500, 0.312500 },
661 { 0.312500, 0.437500 },
662 { 0.687500, 0.062500 },
663 { 0.937500, 0.187500 },
664 { 0.562500, 0.312500 },
665 { 0.812500, 0.437500 },
666 { 0.187500, 0.562500 },
667 { 0.437500, 0.687500 },
668 { 0.062500, 0.812500 },
669 { 0.312500, 0.937500 },
670 { 0.687500, 0.562500 },
671 { 0.937500, 0.687500 },
672 { 0.562500, 0.812500 },
673 { 0.812500, 0.937500 }
674 };
675 const float (*positions)[2];
676
677 switch (sample_count) {
678 case 4:
679 positions = pos4;
680 break;
681 case 8:
682 positions = pos8;
683 break;
684 case 16:
685 positions = pos16;
686 break;
687 default:
688 positions = pos1;
689 }
690
691 pos_out[0] = positions[sample_index][0];
692 pos_out[1] = positions[sample_index][1];
693 }
694
695
696 void
697 svga_init_surface_functions(struct svga_context *svga)
698 {
699 svga->pipe.create_surface = svga_create_surface;
700 svga->pipe.surface_destroy = svga_surface_destroy;
701 svga->pipe.get_sample_position = svga_get_sample_position;
702 }