u_blitter: add a msaa parameter to util_blitter_clear
[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_region(struct svga_context *svga,
49 struct svga_winsys_surface *src_handle,
50 unsigned srcSubResource,
51 unsigned src_x, unsigned src_y, unsigned src_z,
52 struct svga_winsys_surface *dst_handle,
53 unsigned dstSubResource,
54 unsigned dst_x, unsigned dst_y, unsigned dst_z,
55 unsigned width, unsigned height, unsigned depth)
56 {
57 enum pipe_error ret;
58 SVGA3dCopyBox box;
59
60 assert(svga_have_vgpu10(svga));
61
62 box.x = dst_x;
63 box.y = dst_y;
64 box.z = dst_z;
65 box.w = width;
66 box.h = height;
67 box.d = depth;
68 box.srcx = src_x;
69 box.srcy = src_y;
70 box.srcz = src_z;
71
72 ret = SVGA3D_vgpu10_PredCopyRegion(svga->swc,
73 dst_handle, dstSubResource,
74 src_handle, srcSubResource, &box);
75 if (ret != PIPE_OK) {
76 svga_context_flush(svga, NULL);
77 ret = SVGA3D_vgpu10_PredCopyRegion(svga->swc,
78 dst_handle, dstSubResource,
79 src_handle, srcSubResource, &box);
80 assert(ret == PIPE_OK);
81 }
82 }
83
84
85 void
86 svga_texture_copy_handle(struct svga_context *svga,
87 struct svga_winsys_surface *src_handle,
88 unsigned src_x, unsigned src_y, unsigned src_z,
89 unsigned src_level, unsigned src_layer,
90 struct svga_winsys_surface *dst_handle,
91 unsigned dst_x, unsigned dst_y, unsigned dst_z,
92 unsigned dst_level, unsigned dst_layer,
93 unsigned width, unsigned height, unsigned depth)
94 {
95 struct svga_surface dst, src;
96 enum pipe_error ret;
97 SVGA3dCopyBox box, *boxes;
98
99 assert(svga);
100
101 src.handle = src_handle;
102 src.real_level = src_level;
103 src.real_layer = src_layer;
104 src.real_zslice = 0;
105
106 dst.handle = dst_handle;
107 dst.real_level = dst_level;
108 dst.real_layer = dst_layer;
109 dst.real_zslice = 0;
110
111 box.x = dst_x;
112 box.y = dst_y;
113 box.z = dst_z;
114 box.w = width;
115 box.h = height;
116 box.d = depth;
117 box.srcx = src_x;
118 box.srcy = src_y;
119 box.srcz = src_z;
120
121 /*
122 SVGA_DBG(DEBUG_VIEWS, "mipcopy src: %p %u (%ux%ux%u), dst: %p %u (%ux%ux%u)\n",
123 src_handle, src_level, src_x, src_y, src_z,
124 dst_handle, dst_level, dst_x, dst_y, dst_z);
125 */
126
127 ret = SVGA3D_BeginSurfaceCopy(svga->swc,
128 &src.base,
129 &dst.base,
130 &boxes, 1);
131 if (ret != PIPE_OK) {
132 svga_context_flush(svga, NULL);
133 ret = SVGA3D_BeginSurfaceCopy(svga->swc,
134 &src.base,
135 &dst.base,
136 &boxes, 1);
137 assert(ret == PIPE_OK);
138 }
139 *boxes = box;
140 SVGA_FIFOCommitAll(svga->swc);
141 }
142
143
144 /* A helper function to sync up the two surface handles.
145 */
146 static void
147 svga_texture_copy_handle_resource(struct svga_context *svga,
148 struct svga_texture *src_tex,
149 struct svga_winsys_surface *dst,
150 unsigned int numMipLevels,
151 unsigned int numLayers,
152 int zslice_pick,
153 unsigned int mipoffset,
154 unsigned int layeroffset)
155 {
156 unsigned int i, j;
157 unsigned int zoffset = 0;
158
159 /* A negative zslice_pick implies zoffset at 0, and depth to copy is
160 * from the depth of the texture at the particular mipmap level.
161 */
162 if (zslice_pick >= 0)
163 zoffset = zslice_pick;
164
165 for (i = 0; i < numMipLevels; i++) {
166 unsigned int miplevel = i + mipoffset;
167
168 for (j = 0; j < numLayers; j++) {
169 if (svga_is_texture_level_defined(src_tex, j+layeroffset, miplevel)) {
170 unsigned depth = (zslice_pick < 0 ?
171 u_minify(src_tex->b.b.depth0, miplevel) : 1);
172
173 if (src_tex->b.b.nr_samples > 1) {
174 unsigned subResource = j * numMipLevels + i;
175 svga_texture_copy_region(svga, src_tex->handle,
176 subResource, 0, 0, zoffset,
177 dst, subResource, 0, 0, 0,
178 src_tex->b.b.width0, src_tex->b.b.height0, depth);
179 }
180 else {
181 svga_texture_copy_handle(svga,
182 src_tex->handle,
183 0, 0, zoffset,
184 miplevel,
185 j + layeroffset,
186 dst, 0, 0, 0, i, j,
187 u_minify(src_tex->b.b.width0, miplevel),
188 u_minify(src_tex->b.b.height0, miplevel),
189 depth);
190 }
191 }
192 }
193 }
194 }
195
196
197 struct svga_winsys_surface *
198 svga_texture_view_surface(struct svga_context *svga,
199 struct svga_texture *tex,
200 unsigned bind_flags,
201 SVGA3dSurfaceAllFlags flags,
202 SVGA3dSurfaceFormat format,
203 unsigned start_mip,
204 unsigned num_mip,
205 int layer_pick,
206 unsigned num_layers,
207 int zslice_pick,
208 boolean cacheable,
209 struct svga_host_surface_cache_key *key) /* OUT */
210 {
211 struct svga_screen *ss = svga_screen(svga->pipe.screen);
212 struct svga_winsys_surface *handle = NULL;
213 boolean validated;
214 boolean needCopyResource;
215
216 SVGA_DBG(DEBUG_PERF,
217 "svga: Create surface view: layer %d zslice %d mips %d..%d\n",
218 layer_pick, zslice_pick, start_mip, start_mip+num_mip-1);
219
220 SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_EMULATESURFACEVIEW);
221
222 key->flags = flags;
223 key->format = format;
224 key->numMipLevels = num_mip;
225 key->size.width = u_minify(tex->b.b.width0, start_mip);
226 key->size.height = u_minify(tex->b.b.height0, start_mip);
227 key->size.depth = zslice_pick < 0 ? u_minify(tex->b.b.depth0, start_mip) : 1;
228 key->cachable = 1;
229 key->arraySize = 1;
230 key->numFaces = 1;
231
232 /* single sample surface can be treated as non-multisamples surface */
233 key->sampleCount = tex->b.b.nr_samples > 1 ? tex->b.b.nr_samples : 0;
234
235 if (key->sampleCount > 1) {
236 assert(ss->sws->have_sm4_1);
237 key->flags |= SVGA3D_SURFACE_MULTISAMPLE;
238 }
239
240 if (tex->b.b.target == PIPE_TEXTURE_CUBE && layer_pick < 0) {
241 key->flags |= SVGA3D_SURFACE_CUBEMAP;
242 key->numFaces = 6;
243 } else if (tex->b.b.target == PIPE_TEXTURE_1D_ARRAY ||
244 tex->b.b.target == PIPE_TEXTURE_2D_ARRAY) {
245 key->arraySize = num_layers;
246 }
247
248 if (key->format == SVGA3D_FORMAT_INVALID) {
249 key->cachable = 0;
250 goto done;
251 }
252
253 if (cacheable && tex->backed_handle &&
254 memcmp(key, &tex->backed_key, sizeof *key) == 0) {
255 handle = tex->backed_handle;
256 needCopyResource = tex->backed_age < tex->age;
257 } else {
258 SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
259 handle = svga_screen_surface_create(ss, bind_flags, PIPE_USAGE_DEFAULT,
260 &validated, key);
261 needCopyResource = TRUE;
262
263 if (cacheable && !tex->backed_handle) {
264 tex->backed_handle = handle;
265 memcpy(&tex->backed_key, key, sizeof *key);
266 }
267 }
268
269 if (!handle) {
270 key->cachable = 0;
271 goto done;
272 }
273
274 SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle);
275
276 if (layer_pick < 0)
277 layer_pick = 0;
278
279 if (needCopyResource) {
280 svga_texture_copy_handle_resource(svga, tex, handle,
281 key->numMipLevels,
282 key->numFaces * key->arraySize,
283 zslice_pick, start_mip, layer_pick);
284 tex->backed_age = tex->age;
285 }
286
287 done:
288 SVGA_STATS_TIME_POP(ss->sws);
289
290 return handle;
291 }
292
293
294 /**
295 * A helper function to create a surface view.
296 * The view boolean flag specifies whether svga_texture_view_surface()
297 * will be called to create a cloned surface and resource for the view.
298 */
299 static struct pipe_surface *
300 svga_create_surface_view(struct pipe_context *pipe,
301 struct pipe_resource *pt,
302 const struct pipe_surface *surf_tmpl,
303 boolean view)
304 {
305 struct svga_context *svga = svga_context(pipe);
306 struct svga_texture *tex = svga_texture(pt);
307 struct pipe_screen *screen = pipe->screen;
308 struct svga_screen *ss = svga_screen(screen);
309 struct svga_surface *s;
310 unsigned layer, zslice, bind;
311 unsigned nlayers = 1;
312 SVGA3dSurfaceAllFlags flags = 0;
313 SVGA3dSurfaceFormat format;
314 struct pipe_surface *retVal = NULL;
315
316 s = CALLOC_STRUCT(svga_surface);
317 if (!s)
318 return NULL;
319
320 SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_CREATESURFACEVIEW);
321
322 if (pt->target == PIPE_TEXTURE_CUBE) {
323 layer = surf_tmpl->u.tex.first_layer;
324 zslice = 0;
325 }
326 else if (pt->target == PIPE_TEXTURE_1D_ARRAY ||
327 pt->target == PIPE_TEXTURE_2D_ARRAY ||
328 pt->target == PIPE_TEXTURE_CUBE_ARRAY) {
329 layer = surf_tmpl->u.tex.first_layer;
330 zslice = 0;
331 nlayers = surf_tmpl->u.tex.last_layer - surf_tmpl->u.tex.first_layer + 1;
332 }
333 else {
334 layer = 0;
335 zslice = surf_tmpl->u.tex.first_layer;
336 }
337
338 pipe_reference_init(&s->base.reference, 1);
339 pipe_resource_reference(&s->base.texture, pt);
340 s->base.context = pipe;
341 s->base.format = surf_tmpl->format;
342 s->base.width = u_minify(pt->width0, surf_tmpl->u.tex.level);
343 s->base.height = u_minify(pt->height0, surf_tmpl->u.tex.level);
344 s->base.u.tex.level = surf_tmpl->u.tex.level;
345 s->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
346 s->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
347 s->view_id = SVGA3D_INVALID_ID;
348
349 s->backed = NULL;
350
351 if (util_format_is_depth_or_stencil(surf_tmpl->format)) {
352 flags = SVGA3D_SURFACE_HINT_DEPTHSTENCIL |
353 SVGA3D_SURFACE_BIND_DEPTH_STENCIL;
354 bind = PIPE_BIND_DEPTH_STENCIL;
355 }
356 else {
357 flags = SVGA3D_SURFACE_HINT_RENDERTARGET |
358 SVGA3D_SURFACE_BIND_RENDER_TARGET;
359 bind = PIPE_BIND_RENDER_TARGET;
360 }
361
362 if (tex->imported) {
363 /* imported resource (a window) */
364 format = tex->key.format;
365 if (util_format_is_srgb(surf_tmpl->format)) {
366 /* sRGB rendering to window */
367 format = svga_linear_to_srgb(format);
368 }
369 }
370 else {
371 format = svga_translate_format(ss, surf_tmpl->format, bind);
372 }
373
374 assert(format != SVGA3D_FORMAT_INVALID);
375
376 if (view) {
377 SVGA_DBG(DEBUG_VIEWS,
378 "New backed surface view: resource %p, level %u layer %u z %u, %p\n",
379 pt, surf_tmpl->u.tex.level, layer, zslice, s);
380
381 if (svga_have_vgpu10(svga)) {
382 switch (pt->target) {
383 case PIPE_TEXTURE_1D:
384 flags |= SVGA3D_SURFACE_1D;
385 break;
386 case PIPE_TEXTURE_1D_ARRAY:
387 flags |= SVGA3D_SURFACE_1D | SVGA3D_SURFACE_ARRAY;
388 break;
389 case PIPE_TEXTURE_2D_ARRAY:
390 flags |= SVGA3D_SURFACE_ARRAY;
391 break;
392 case PIPE_TEXTURE_3D:
393 flags |= SVGA3D_SURFACE_VOLUME;
394 break;
395 case PIPE_TEXTURE_CUBE:
396 if (nlayers == 6)
397 flags |= SVGA3D_SURFACE_CUBEMAP;
398 break;
399 case PIPE_TEXTURE_CUBE_ARRAY:
400 if (nlayers % 6 == 0)
401 flags |= SVGA3D_SURFACE_CUBEMAP | SVGA3D_SURFACE_ARRAY;
402 break;
403 default:
404 break;
405 }
406 }
407
408 /* When we clone the surface view resource, use the format used in
409 * the creation of the original resource.
410 */
411 s->handle = svga_texture_view_surface(svga, tex, bind, flags,
412 tex->key.format,
413 surf_tmpl->u.tex.level, 1,
414 layer, nlayers, zslice,
415 TRUE, &s->key);
416 if (!s->handle) {
417 FREE(s);
418 goto done;
419 }
420
421 s->key.format = format;
422 s->real_layer = 0;
423 s->real_level = 0;
424 s->real_zslice = 0;
425 } else {
426 SVGA_DBG(DEBUG_VIEWS,
427 "New surface view: resource %p, level %u, layer %u, z %u, %p\n",
428 pt, surf_tmpl->u.tex.level, layer, zslice, s);
429
430 memset(&s->key, 0, sizeof s->key);
431 s->key.format = format;
432 s->handle = tex->handle;
433 s->real_layer = layer;
434 s->real_zslice = zslice;
435 s->real_level = surf_tmpl->u.tex.level;
436 }
437
438 svga->hud.num_surface_views++;
439 retVal = &s->base;
440
441 done:
442 SVGA_STATS_TIME_POP(ss->sws);
443 return retVal;
444 }
445
446
447 static struct pipe_surface *
448 svga_create_surface(struct pipe_context *pipe,
449 struct pipe_resource *pt,
450 const struct pipe_surface *surf_tmpl)
451 {
452 struct svga_context *svga = svga_context(pipe);
453 struct pipe_screen *screen = pipe->screen;
454 struct pipe_surface *surf = NULL;
455 boolean view = FALSE;
456
457 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATESURFACE);
458
459 if (svga_screen(screen)->debug.force_surface_view)
460 view = TRUE;
461
462 if (surf_tmpl->u.tex.level != 0 &&
463 svga_screen(screen)->debug.force_level_surface_view)
464 view = TRUE;
465
466 if (pt->target == PIPE_TEXTURE_3D)
467 view = TRUE;
468
469 if (svga_have_vgpu10(svga) || svga_screen(screen)->debug.no_surface_view)
470 view = FALSE;
471
472 surf = svga_create_surface_view(pipe, pt, surf_tmpl, view);
473
474 SVGA_STATS_TIME_POP(svga_sws(svga));
475
476 return surf;
477 }
478
479
480 /**
481 * Clone the surface view and its associated resource.
482 */
483 static struct svga_surface *
484 create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
485 {
486 struct svga_texture *tex = svga_texture(s->base.texture);
487
488 if (!s->backed) {
489 struct pipe_surface *backed_view;
490
491 SVGA_STATS_TIME_PUSH(svga_sws(svga),
492 SVGA_STATS_TIME_CREATEBACKEDSURFACEVIEW);
493
494 backed_view = svga_create_surface_view(&svga->pipe,
495 &tex->b.b,
496 &s->base,
497 TRUE);
498 if (!backed_view)
499 goto done;
500
501 s->backed = svga_surface(backed_view);
502
503 SVGA_STATS_TIME_POP(svga_sws(svga));
504 }
505 else if (s->backed->age < tex->age) {
506 /*
507 * There is already an existing backing surface, but we still need to
508 * sync the backing resource if the original resource has been modified
509 * since the last copy.
510 */
511 struct svga_surface *bs = s->backed;
512 unsigned int layer, zslice;
513
514 assert(bs->handle);
515
516 switch (tex->b.b.target) {
517 case PIPE_TEXTURE_CUBE:
518 case PIPE_TEXTURE_CUBE_ARRAY:
519 case PIPE_TEXTURE_1D_ARRAY:
520 case PIPE_TEXTURE_2D_ARRAY:
521 layer = s->base.u.tex.first_layer;
522 zslice = 0;
523 break;
524 default:
525 layer = 0;
526 zslice = s->base.u.tex.first_layer;
527 }
528
529 svga_texture_copy_handle_resource(svga, tex, bs->handle,
530 bs->key.numMipLevels,
531 bs->key.numFaces * bs->key.arraySize,
532 zslice, s->base.u.tex.level, layer);
533 }
534
535 svga_mark_surface_dirty(&s->backed->base);
536 s->backed->age = tex->age;
537
538 done:
539 return s->backed;
540 }
541
542 /**
543 * Create a DX RenderTarget/DepthStencil View for the given surface,
544 * if needed.
545 */
546 struct pipe_surface *
547 svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
548 {
549 enum pipe_error ret = PIPE_OK;
550 enum pipe_shader_type shader;
551
552 assert(svga_have_vgpu10(svga));
553 assert(s);
554
555 SVGA_STATS_TIME_PUSH(svga_sws(svga),
556 SVGA_STATS_TIME_VALIDATESURFACEVIEW);
557
558 /**
559 * DX spec explicitly specifies that no resource can be bound to a render
560 * target view and a shader resource view simultanously.
561 * So first check if the resource bound to this surface view collides with
562 * a sampler view. If so, then we will clone this surface view and its
563 * associated resource. We will then use the cloned surface view for
564 * render target.
565 */
566 for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
567 if (svga_check_sampler_view_resource_collision(svga, s->handle, shader)) {
568 SVGA_DBG(DEBUG_VIEWS,
569 "same resource used in shaderResource and renderTarget 0x%x\n",
570 s->handle);
571 s = create_backed_surface_view(svga, s);
572
573 if (s)
574 svga->state.hw_draw.has_backed_views = TRUE;
575
576 /* s may be null here if the function failed */
577 break;
578 }
579 }
580
581 if (s && s->view_id == SVGA3D_INVALID_ID) {
582 SVGA3dResourceType resType;
583 SVGA3dRenderTargetViewDesc desc;
584 struct svga_texture *stex = svga_texture(s->base.texture);
585
586 if (stex->validated == FALSE) {
587 assert(stex->handle);
588
589 /* We are about to render into a surface that has not been validated.
590 * First invalidate the surface so that the device does not
591 * need to update the host-side copy with the invalid
592 * content when the associated mob is first bound to the surface.
593 */
594 if (SVGA3D_InvalidateGBSurface(svga->swc, stex->handle) != PIPE_OK) {
595 svga_context_flush(svga, NULL);
596 ret = SVGA3D_InvalidateGBSurface(svga->swc, stex->handle);
597 assert(ret == PIPE_OK);
598 }
599 stex->validated = TRUE;
600 }
601
602 desc.tex.mipSlice = s->real_level;
603 desc.tex.firstArraySlice = s->real_layer + s->real_zslice;
604 desc.tex.arraySize =
605 s->base.u.tex.last_layer - s->base.u.tex.first_layer + 1;
606
607 s->view_id = util_bitmask_add(svga->surface_view_id_bm);
608
609 resType = svga_resource_type(s->base.texture->target);
610
611 if (util_format_is_depth_or_stencil(s->base.format)) {
612 ret = SVGA3D_vgpu10_DefineDepthStencilView(svga->swc,
613 s->view_id,
614 s->handle,
615 s->key.format,
616 resType,
617 &desc);
618 }
619 else {
620 SVGA3dSurfaceFormat view_format = s->key.format;
621 const struct svga_texture *stex = svga_texture(s->base.texture);
622
623 /* Can't create RGBA render target view of a RGBX surface so adjust
624 * the view format. We do something similar for texture samplers in
625 * svga_validate_pipe_sampler_view().
626 */
627 if (view_format == SVGA3D_B8G8R8A8_UNORM &&
628 (stex->key.format == SVGA3D_B8G8R8X8_UNORM ||
629 stex->key.format == SVGA3D_B8G8R8X8_TYPELESS)) {
630 view_format = SVGA3D_B8G8R8X8_UNORM;
631 }
632
633 ret = SVGA3D_vgpu10_DefineRenderTargetView(svga->swc,
634 s->view_id,
635 s->handle,
636 view_format,
637 resType,
638 &desc);
639 }
640
641 if (ret != PIPE_OK) {
642 util_bitmask_clear(svga->surface_view_id_bm, s->view_id);
643 s->view_id = SVGA3D_INVALID_ID;
644 s = NULL;
645 }
646 }
647
648 SVGA_STATS_TIME_POP(svga_sws(svga));
649
650 return s ? &s->base : NULL;
651 }
652
653
654
655 static void
656 svga_surface_destroy(struct pipe_context *pipe,
657 struct pipe_surface *surf)
658 {
659 struct svga_context *svga = svga_context(pipe);
660 struct svga_surface *s = svga_surface(surf);
661 struct svga_texture *t = svga_texture(surf->texture);
662 struct svga_screen *ss = svga_screen(surf->texture->screen);
663 enum pipe_error ret = PIPE_OK;
664
665 SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_DESTROYSURFACE);
666
667 /* Destroy the backed view surface if it exists */
668 if (s->backed) {
669 svga_surface_destroy(pipe, &s->backed->base);
670 s->backed = NULL;
671 }
672
673 /* Destroy the surface handle if this is a backed handle and
674 * it is not being cached in the texture.
675 */
676 if (s->handle != t->handle && s->handle != t->backed_handle) {
677 SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
678 svga_screen_surface_destroy(ss, &s->key, &s->handle);
679 }
680
681 if (s->view_id != SVGA3D_INVALID_ID) {
682 unsigned try;
683
684 /* The SVGA3D device will generate a device error if the
685 * render target view or depth stencil view is destroyed from
686 * a context other than the one it was created with.
687 * Similar to shader resource view, in this case, we will skip
688 * the destroy for now.
689 */
690 if (surf->context != pipe) {
691 _debug_printf("context mismatch in %s\n", __func__);
692 }
693 else {
694 assert(svga_have_vgpu10(svga));
695 for (try = 0; try < 2; try++) {
696 if (util_format_is_depth_or_stencil(s->base.format)) {
697 ret = SVGA3D_vgpu10_DestroyDepthStencilView(svga->swc, s->view_id);
698 }
699 else {
700 ret = SVGA3D_vgpu10_DestroyRenderTargetView(svga->swc, s->view_id);
701 }
702 if (ret == PIPE_OK)
703 break;
704 svga_context_flush(svga, NULL);
705 }
706 assert(ret == PIPE_OK);
707 util_bitmask_clear(svga->surface_view_id_bm, s->view_id);
708 }
709 }
710
711 pipe_resource_reference(&surf->texture, NULL);
712 FREE(surf);
713
714 svga->hud.num_surface_views--;
715 SVGA_STATS_TIME_POP(ss->sws);
716 }
717
718
719 static void
720 svga_mark_surface_dirty(struct pipe_surface *surf)
721 {
722 struct svga_surface *s = svga_surface(surf);
723 struct svga_texture *tex = svga_texture(surf->texture);
724
725 if (!s->dirty) {
726 s->dirty = TRUE;
727
728 if (s->handle == tex->handle) {
729 /* hmm so 3d textures always have all their slices marked ? */
730 svga_define_texture_level(tex, surf->u.tex.first_layer,
731 surf->u.tex.level);
732 }
733 else {
734 /* this will happen later in svga_propagate_surface */
735 }
736 }
737
738 /* Increment the view_age and texture age for this surface's mipmap
739 * level so that any sampler views into the texture are re-validated too.
740 * Note: we age the texture for backed surface view only when the
741 * backed surface is propagated to the original surface.
742 */
743 if (s->handle == tex->handle)
744 svga_age_texture_view(tex, surf->u.tex.level);
745 }
746
747
748 void
749 svga_mark_surfaces_dirty(struct svga_context *svga)
750 {
751 unsigned i;
752 struct svga_hw_clear_state *hw = &svga->state.hw_clear;
753
754 if (svga_have_vgpu10(svga)) {
755
756 /* For VGPU10, mark the dirty bit in the rendertarget/depth stencil view surface.
757 * This surface can be the backed surface.
758 */
759 for (i = 0; i < hw->num_rendertargets; i++) {
760 if (hw->rtv[i])
761 svga_mark_surface_dirty(hw->rtv[i]);
762 }
763 if (hw->dsv)
764 svga_mark_surface_dirty(hw->dsv);
765 } else {
766 for (i = 0; i < svga->curr.framebuffer.nr_cbufs; i++) {
767 if (svga->curr.framebuffer.cbufs[i])
768 svga_mark_surface_dirty(svga->curr.framebuffer.cbufs[i]);
769 }
770 if (svga->curr.framebuffer.zsbuf)
771 svga_mark_surface_dirty(svga->curr.framebuffer.zsbuf);
772 }
773 }
774
775
776 /**
777 * Progagate any changes from surfaces to texture.
778 * pipe is optional context to inline the blit command in.
779 */
780 void
781 svga_propagate_surface(struct svga_context *svga, struct pipe_surface *surf,
782 boolean reset)
783 {
784 struct svga_surface *s = svga_surface(surf);
785 struct svga_texture *tex = svga_texture(surf->texture);
786 struct svga_screen *ss = svga_screen(surf->texture->screen);
787
788 if (!s->dirty)
789 return;
790
791 SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_PROPAGATESURFACE);
792
793 /* Reset the dirty flag if specified. This is to ensure that
794 * the dirty flag will not be reset and stay unset when the backing
795 * surface is still being bound and rendered to.
796 * The reset flag will be set to TRUE when the surface is propagated
797 * and will be unbound.
798 */
799 s->dirty = !reset;
800
801 ss->texture_timestamp++;
802 svga_age_texture_view(tex, surf->u.tex.level);
803
804 if (s->handle != tex->handle) {
805 unsigned zslice, layer;
806 unsigned nlayers = 1;
807 unsigned i;
808 unsigned numMipLevels = tex->b.b.last_level + 1;
809 unsigned srcLevel = s->real_level;
810 unsigned dstLevel = surf->u.tex.level;
811 unsigned width = u_minify(tex->b.b.width0, dstLevel);
812 unsigned height = u_minify(tex->b.b.height0, dstLevel);
813
814 if (surf->texture->target == PIPE_TEXTURE_CUBE) {
815 zslice = 0;
816 layer = surf->u.tex.first_layer;
817 }
818 else if (surf->texture->target == PIPE_TEXTURE_1D_ARRAY ||
819 surf->texture->target == PIPE_TEXTURE_2D_ARRAY ||
820 surf->texture->target == PIPE_TEXTURE_CUBE_ARRAY) {
821 zslice = 0;
822 layer = surf->u.tex.first_layer;
823 nlayers = surf->u.tex.last_layer - surf->u.tex.first_layer + 1;
824 }
825 else {
826 zslice = surf->u.tex.first_layer;
827 layer = 0;
828 }
829
830 SVGA_DBG(DEBUG_VIEWS,
831 "Propagate surface %p to resource %p, level %u\n",
832 surf, tex, surf->u.tex.level);
833
834 if (svga_have_vgpu10(svga)) {
835 unsigned srcSubResource, dstSubResource;
836
837 for (i = 0; i < nlayers; i++) {
838 srcSubResource = (s->real_layer + i) * numMipLevels + srcLevel;
839 dstSubResource = (layer + i) * numMipLevels + dstLevel;
840
841 svga_texture_copy_region(svga,
842 s->handle, srcSubResource, 0, 0, 0,
843 tex->handle, dstSubResource, 0, 0, zslice,
844 width, height, 1);
845 svga_define_texture_level(tex, layer + i, dstLevel);
846 }
847 }
848 else {
849 for (i = 0; i < nlayers; i++) {
850 svga_texture_copy_handle(svga,
851 s->handle, 0, 0, 0, srcLevel,
852 s->real_layer + i,
853 tex->handle, 0, 0, zslice, dstLevel,
854 layer + i,
855 width, height, 1);
856
857 svga_define_texture_level(tex, layer + i, dstLevel);
858 }
859 }
860
861 /* Sync the surface view age with the texture age */
862 s->age = tex->age;
863
864 /* If this backed surface is cached in the texture,
865 * update the backed age as well.
866 */
867 if (tex->backed_handle == s->handle) {
868 tex->backed_age = tex->age;
869 }
870 }
871
872 SVGA_STATS_TIME_POP(ss->sws);
873 }
874
875
876 /**
877 * If any of the render targets are in backing texture views, propagate any
878 * changes to them back to the original texture.
879 */
880 void
881 svga_propagate_rendertargets(struct svga_context *svga)
882 {
883 unsigned i;
884
885 /* Early exit if there is no backing texture views in use */
886 if (!svga->state.hw_draw.has_backed_views)
887 return;
888
889 /* Note that we examine the svga->state.hw_draw.framebuffer surfaces,
890 * not the svga->curr.framebuffer surfaces, because it's the former
891 * surfaces which may be backing surface views (the actual render targets).
892 */
893 for (i = 0; i < svga->state.hw_clear.num_rendertargets; i++) {
894 struct pipe_surface *s = svga->state.hw_clear.rtv[i];
895 if (s) {
896 svga_propagate_surface(svga, s, FALSE);
897 }
898 }
899
900 if (svga->state.hw_clear.dsv) {
901 svga_propagate_surface(svga, svga->state.hw_clear.dsv, FALSE);
902 }
903 }
904
905
906 /**
907 * Check if we should call svga_propagate_surface on the surface.
908 */
909 boolean
910 svga_surface_needs_propagation(const struct pipe_surface *surf)
911 {
912 const struct svga_surface *s = svga_surface_const(surf);
913 struct svga_texture *tex = svga_texture(surf->texture);
914
915 return s->dirty && s->handle != tex->handle;
916 }
917
918
919 static void
920 svga_get_sample_position(struct pipe_context *context,
921 unsigned sample_count, unsigned sample_index,
922 float *pos_out)
923 {
924 /* We can't actually query the device to learn the sample positions.
925 * These were grabbed from nvidia's driver.
926 */
927 static const float pos1[1][2] = {
928 { 0.5, 0.5 }
929 };
930 static const float pos2[2][2] = {
931 { 0.75, 0.75 },
932 { 0.25, 0.25 }
933 };
934 static const float pos4[4][2] = {
935 { 0.375000, 0.125000 },
936 { 0.875000, 0.375000 },
937 { 0.125000, 0.625000 },
938 { 0.625000, 0.875000 }
939 };
940 static const float pos8[8][2] = {
941 { 0.562500, 0.312500 },
942 { 0.437500, 0.687500 },
943 { 0.812500, 0.562500 },
944 { 0.312500, 0.187500 },
945 { 0.187500, 0.812500 },
946 { 0.062500, 0.437500 },
947 { 0.687500, 0.937500 },
948 { 0.937500, 0.062500 }
949 };
950 static const float pos16[16][2] = {
951 { 0.187500, 0.062500 },
952 { 0.437500, 0.187500 },
953 { 0.062500, 0.312500 },
954 { 0.312500, 0.437500 },
955 { 0.687500, 0.062500 },
956 { 0.937500, 0.187500 },
957 { 0.562500, 0.312500 },
958 { 0.812500, 0.437500 },
959 { 0.187500, 0.562500 },
960 { 0.437500, 0.687500 },
961 { 0.062500, 0.812500 },
962 { 0.312500, 0.937500 },
963 { 0.687500, 0.562500 },
964 { 0.937500, 0.687500 },
965 { 0.562500, 0.812500 },
966 { 0.812500, 0.937500 }
967 };
968 const float (*positions)[2];
969
970 switch (sample_count) {
971 case 2:
972 positions = pos2;
973 break;
974 case 4:
975 positions = pos4;
976 break;
977 case 8:
978 positions = pos8;
979 break;
980 case 16:
981 positions = pos16;
982 break;
983 default:
984 positions = pos1;
985 }
986
987 pos_out[0] = positions[sample_index][0];
988 pos_out[1] = positions[sample_index][1];
989 }
990
991
992 void
993 svga_init_surface_functions(struct svga_context *svga)
994 {
995 svga->pipe.create_surface = svga_create_surface;
996 svga->pipe.surface_destroy = svga_surface_destroy;
997 svga->pipe.get_sample_position = svga_get_sample_position;
998 }