1 /**********************************************************
2 * Copyright 2008-2009 VMware, Inc. All rights reserved.
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:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
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
24 **********************************************************/
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"
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"
45 static void svga_mark_surface_dirty(struct pipe_surface
*surf
);
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
)
60 assert(svga_have_vgpu10(svga
));
72 ret
= SVGA3D_vgpu10_PredCopyRegion(svga
->swc
,
73 dst_handle
, dstSubResource
,
74 src_handle
, srcSubResource
, &box
);
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
);
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
)
95 struct svga_surface dst
, src
;
97 SVGA3dCopyBox box
, *boxes
;
101 src
.handle
= src_handle
;
102 src
.real_level
= src_level
;
103 src
.real_layer
= src_layer
;
106 dst
.handle
= dst_handle
;
107 dst
.real_level
= dst_level
;
108 dst
.real_layer
= dst_layer
;
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);
127 ret
= SVGA3D_BeginSurfaceCopy(svga
->swc
,
131 if (ret
!= PIPE_OK
) {
132 svga_context_flush(svga
, NULL
);
133 ret
= SVGA3D_BeginSurfaceCopy(svga
->swc
,
137 assert(ret
== PIPE_OK
);
140 SVGA_FIFOCommitAll(svga
->swc
);
144 /* A helper function to sync up the two surface handles.
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
,
153 unsigned int mipoffset
,
154 unsigned int layeroffset
)
157 unsigned int zoffset
= 0;
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.
162 if (zslice_pick
>= 0)
163 zoffset
= zslice_pick
;
165 for (i
= 0; i
< numMipLevels
; i
++) {
166 unsigned int miplevel
= i
+ mipoffset
;
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);
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
);
181 svga_texture_copy_handle(svga
,
187 u_minify(src_tex
->b
.b
.width0
, miplevel
),
188 u_minify(src_tex
->b
.b
.height0
, miplevel
),
197 struct svga_winsys_surface
*
198 svga_texture_view_surface(struct svga_context
*svga
,
199 struct svga_texture
*tex
,
201 SVGA3dSurfaceAllFlags flags
,
202 SVGA3dSurfaceFormat format
,
209 struct svga_host_surface_cache_key
*key
) /* OUT */
211 struct svga_screen
*ss
= svga_screen(svga
->pipe
.screen
);
212 struct svga_winsys_surface
*handle
= NULL
;
214 boolean needCopyResource
;
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);
220 SVGA_STATS_TIME_PUSH(ss
->sws
, SVGA_STATS_TIME_EMULATESURFACEVIEW
);
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;
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;
235 if (key
->sampleCount
> 1) {
236 assert(ss
->sws
->have_sm4_1
);
237 key
->flags
|= SVGA3D_SURFACE_MULTISAMPLE
;
240 if (tex
->b
.b
.target
== PIPE_TEXTURE_CUBE
&& layer_pick
< 0) {
241 key
->flags
|= SVGA3D_SURFACE_CUBEMAP
;
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
;
248 if (key
->format
== SVGA3D_FORMAT_INVALID
) {
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
;
258 SVGA_DBG(DEBUG_DMA
, "surface_create for texture view\n");
259 handle
= svga_screen_surface_create(ss
, bind_flags
, PIPE_USAGE_DEFAULT
,
261 needCopyResource
= TRUE
;
263 if (cacheable
&& !tex
->backed_handle
) {
264 tex
->backed_handle
= handle
;
265 memcpy(&tex
->backed_key
, key
, sizeof *key
);
274 SVGA_DBG(DEBUG_DMA
, " --> got sid %p (texture view)\n", handle
);
279 if (needCopyResource
) {
280 svga_texture_copy_handle_resource(svga
, tex
, handle
,
282 key
->numFaces
* key
->arraySize
,
283 zslice_pick
, start_mip
, layer_pick
);
284 tex
->backed_age
= tex
->age
;
288 SVGA_STATS_TIME_POP(ss
->sws
);
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.
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
,
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
;
316 s
= CALLOC_STRUCT(svga_surface
);
320 SVGA_STATS_TIME_PUSH(ss
->sws
, SVGA_STATS_TIME_CREATESURFACEVIEW
);
322 if (pt
->target
== PIPE_TEXTURE_CUBE
) {
323 layer
= surf_tmpl
->u
.tex
.first_layer
;
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
;
331 nlayers
= surf_tmpl
->u
.tex
.last_layer
- surf_tmpl
->u
.tex
.first_layer
+ 1;
335 zslice
= surf_tmpl
->u
.tex
.first_layer
;
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
;
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
;
357 flags
= SVGA3D_SURFACE_HINT_RENDERTARGET
|
358 SVGA3D_SURFACE_BIND_RENDER_TARGET
;
359 bind
= PIPE_BIND_RENDER_TARGET
;
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
);
371 format
= svga_translate_format(ss
, surf_tmpl
->format
, bind
);
374 assert(format
!= SVGA3D_FORMAT_INVALID
);
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
);
381 if (svga_have_vgpu10(svga
)) {
382 switch (pt
->target
) {
383 case PIPE_TEXTURE_1D
:
384 flags
|= SVGA3D_SURFACE_1D
;
386 case PIPE_TEXTURE_1D_ARRAY
:
387 flags
|= SVGA3D_SURFACE_1D
| SVGA3D_SURFACE_ARRAY
;
389 case PIPE_TEXTURE_2D_ARRAY
:
390 flags
|= SVGA3D_SURFACE_ARRAY
;
392 case PIPE_TEXTURE_3D
:
393 flags
|= SVGA3D_SURFACE_VOLUME
;
395 case PIPE_TEXTURE_CUBE
:
397 flags
|= SVGA3D_SURFACE_CUBEMAP
;
399 case PIPE_TEXTURE_CUBE_ARRAY
:
400 if (nlayers
% 6 == 0)
401 flags
|= SVGA3D_SURFACE_CUBEMAP
| SVGA3D_SURFACE_ARRAY
;
408 /* When we clone the surface view resource, use the format used in
409 * the creation of the original resource.
411 s
->handle
= svga_texture_view_surface(svga
, tex
, bind
, flags
,
413 surf_tmpl
->u
.tex
.level
, 1,
414 layer
, nlayers
, zslice
,
421 s
->key
.format
= format
;
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
);
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
;
438 svga
->hud
.num_surface_views
++;
442 SVGA_STATS_TIME_POP(ss
->sws
);
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
)
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
;
457 SVGA_STATS_TIME_PUSH(svga_sws(svga
), SVGA_STATS_TIME_CREATESURFACE
);
459 if (svga_screen(screen
)->debug
.force_surface_view
)
462 if (surf_tmpl
->u
.tex
.level
!= 0 &&
463 svga_screen(screen
)->debug
.force_level_surface_view
)
466 if (pt
->target
== PIPE_TEXTURE_3D
)
469 if (svga_have_vgpu10(svga
) || svga_screen(screen
)->debug
.no_surface_view
)
472 surf
= svga_create_surface_view(pipe
, pt
, surf_tmpl
, view
);
474 SVGA_STATS_TIME_POP(svga_sws(svga
));
481 * Clone the surface view and its associated resource.
483 static struct svga_surface
*
484 create_backed_surface_view(struct svga_context
*svga
, struct svga_surface
*s
)
486 struct svga_texture
*tex
= svga_texture(s
->base
.texture
);
489 struct pipe_surface
*backed_view
;
491 SVGA_STATS_TIME_PUSH(svga_sws(svga
),
492 SVGA_STATS_TIME_CREATEBACKEDSURFACEVIEW
);
494 backed_view
= svga_create_surface_view(&svga
->pipe
,
501 s
->backed
= svga_surface(backed_view
);
503 SVGA_STATS_TIME_POP(svga_sws(svga
));
505 else if (s
->backed
->age
< tex
->age
) {
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.
511 struct svga_surface
*bs
= s
->backed
;
512 unsigned int layer
, zslice
;
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
;
526 zslice
= s
->base
.u
.tex
.first_layer
;
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
);
535 svga_mark_surface_dirty(&s
->backed
->base
);
536 s
->backed
->age
= tex
->age
;
543 * Create a DX RenderTarget/DepthStencil View for the given surface,
546 struct pipe_surface
*
547 svga_validate_surface_view(struct svga_context
*svga
, struct svga_surface
*s
)
549 enum pipe_error ret
= PIPE_OK
;
550 enum pipe_shader_type shader
;
552 assert(svga_have_vgpu10(svga
));
555 SVGA_STATS_TIME_PUSH(svga_sws(svga
),
556 SVGA_STATS_TIME_VALIDATESURFACEVIEW
);
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
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",
571 s
= create_backed_surface_view(svga
, s
);
574 svga
->state
.hw_draw
.has_backed_views
= TRUE
;
576 /* s may be null here if the function failed */
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
);
586 if (stex
->validated
== FALSE
) {
587 assert(stex
->handle
);
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.
594 if (svga
->swc
->surface_invalidate(svga
->swc
, stex
->handle
) != PIPE_OK
) {
595 svga_context_flush(svga
, NULL
);
596 ret
= svga
->swc
->surface_invalidate(svga
->swc
, stex
->handle
);
597 assert(ret
== PIPE_OK
);
599 stex
->validated
= TRUE
;
602 desc
.tex
.mipSlice
= s
->real_level
;
603 desc
.tex
.firstArraySlice
= s
->real_layer
+ s
->real_zslice
;
605 s
->base
.u
.tex
.last_layer
- s
->base
.u
.tex
.first_layer
+ 1;
607 s
->view_id
= util_bitmask_add(svga
->surface_view_id_bm
);
609 resType
= svga_resource_type(s
->base
.texture
->target
);
611 if (util_format_is_depth_or_stencil(s
->base
.format
)) {
612 ret
= SVGA3D_vgpu10_DefineDepthStencilView(svga
->swc
,
620 SVGA3dSurfaceFormat view_format
= s
->key
.format
;
621 const struct svga_texture
*stex
= svga_texture(s
->base
.texture
);
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().
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
;
633 ret
= SVGA3D_vgpu10_DefineRenderTargetView(svga
->swc
,
641 if (ret
!= PIPE_OK
) {
642 util_bitmask_clear(svga
->surface_view_id_bm
, s
->view_id
);
643 s
->view_id
= SVGA3D_INVALID_ID
;
648 SVGA_STATS_TIME_POP(svga_sws(svga
));
650 return s
? &s
->base
: NULL
;
656 svga_surface_destroy(struct pipe_context
*pipe
,
657 struct pipe_surface
*surf
)
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
;
665 SVGA_STATS_TIME_PUSH(ss
->sws
, SVGA_STATS_TIME_DESTROYSURFACE
);
667 /* Destroy the backed view surface if it exists */
669 svga_surface_destroy(pipe
, &s
->backed
->base
);
673 /* Destroy the surface handle if this is a backed handle and
674 * it is not being cached in the texture.
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
);
681 if (s
->view_id
!= SVGA3D_INVALID_ID
) {
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.
690 if (surf
->context
!= pipe
) {
691 _debug_printf("context mismatch in %s\n", __func__
);
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
);
700 ret
= SVGA3D_vgpu10_DestroyRenderTargetView(svga
->swc
, s
->view_id
);
704 svga_context_flush(svga
, NULL
);
706 assert(ret
== PIPE_OK
);
707 util_bitmask_clear(svga
->surface_view_id_bm
, s
->view_id
);
711 pipe_resource_reference(&surf
->texture
, NULL
);
714 svga
->hud
.num_surface_views
--;
715 SVGA_STATS_TIME_POP(ss
->sws
);
720 svga_mark_surface_dirty(struct pipe_surface
*surf
)
722 struct svga_surface
*s
= svga_surface(surf
);
723 struct svga_texture
*tex
= svga_texture(surf
->texture
);
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
,
734 /* this will happen later in svga_propagate_surface */
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.
743 if (s
->handle
== tex
->handle
)
744 svga_age_texture_view(tex
, surf
->u
.tex
.level
);
749 svga_mark_surfaces_dirty(struct svga_context
*svga
)
752 struct svga_hw_clear_state
*hw
= &svga
->state
.hw_clear
;
754 if (svga_have_vgpu10(svga
)) {
756 /* For VGPU10, mark the dirty bit in the rendertarget/depth stencil view surface.
757 * This surface can be the backed surface.
759 for (i
= 0; i
< hw
->num_rendertargets
; i
++) {
761 svga_mark_surface_dirty(hw
->rtv
[i
]);
764 svga_mark_surface_dirty(hw
->dsv
);
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
]);
770 if (svga
->curr
.framebuffer
.zsbuf
)
771 svga_mark_surface_dirty(svga
->curr
.framebuffer
.zsbuf
);
777 * Progagate any changes from surfaces to texture.
778 * pipe is optional context to inline the blit command in.
781 svga_propagate_surface(struct svga_context
*svga
, struct pipe_surface
*surf
,
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
);
791 SVGA_STATS_TIME_PUSH(ss
->sws
, SVGA_STATS_TIME_PROPAGATESURFACE
);
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.
801 ss
->texture_timestamp
++;
802 svga_age_texture_view(tex
, surf
->u
.tex
.level
);
804 if (s
->handle
!= tex
->handle
) {
805 unsigned zslice
, layer
;
806 unsigned nlayers
= 1;
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
);
814 if (surf
->texture
->target
== PIPE_TEXTURE_CUBE
) {
816 layer
= surf
->u
.tex
.first_layer
;
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
) {
822 layer
= surf
->u
.tex
.first_layer
;
823 nlayers
= surf
->u
.tex
.last_layer
- surf
->u
.tex
.first_layer
+ 1;
826 zslice
= surf
->u
.tex
.first_layer
;
830 SVGA_DBG(DEBUG_VIEWS
,
831 "Propagate surface %p to resource %p, level %u\n",
832 surf
, tex
, surf
->u
.tex
.level
);
834 if (svga_have_vgpu10(svga
)) {
835 unsigned srcSubResource
, dstSubResource
;
837 for (i
= 0; i
< nlayers
; i
++) {
838 srcSubResource
= (s
->real_layer
+ i
) * numMipLevels
+ srcLevel
;
839 dstSubResource
= (layer
+ i
) * numMipLevels
+ dstLevel
;
841 svga_texture_copy_region(svga
,
842 s
->handle
, srcSubResource
, 0, 0, 0,
843 tex
->handle
, dstSubResource
, 0, 0, zslice
,
845 svga_define_texture_level(tex
, layer
+ i
, dstLevel
);
849 for (i
= 0; i
< nlayers
; i
++) {
850 svga_texture_copy_handle(svga
,
851 s
->handle
, 0, 0, 0, srcLevel
,
853 tex
->handle
, 0, 0, zslice
, dstLevel
,
857 svga_define_texture_level(tex
, layer
+ i
, dstLevel
);
861 /* Sync the surface view age with the texture age */
864 /* If this backed surface is cached in the texture,
865 * update the backed age as well.
867 if (tex
->backed_handle
== s
->handle
) {
868 tex
->backed_age
= tex
->age
;
872 SVGA_STATS_TIME_POP(ss
->sws
);
877 * If any of the render targets are in backing texture views, propagate any
878 * changes to them back to the original texture.
881 svga_propagate_rendertargets(struct svga_context
*svga
)
885 /* Early exit if there is no backing texture views in use */
886 if (!svga
->state
.hw_draw
.has_backed_views
)
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).
893 for (i
= 0; i
< svga
->state
.hw_clear
.num_rendertargets
; i
++) {
894 struct pipe_surface
*s
= svga
->state
.hw_clear
.rtv
[i
];
896 svga_propagate_surface(svga
, s
, FALSE
);
900 if (svga
->state
.hw_clear
.dsv
) {
901 svga_propagate_surface(svga
, svga
->state
.hw_clear
.dsv
, FALSE
);
907 * Check if we should call svga_propagate_surface on the surface.
910 svga_surface_needs_propagation(const struct pipe_surface
*surf
)
912 const struct svga_surface
*s
= svga_surface_const(surf
);
913 struct svga_texture
*tex
= svga_texture(surf
->texture
);
915 return s
->dirty
&& s
->handle
!= tex
->handle
;
920 svga_get_sample_position(struct pipe_context
*context
,
921 unsigned sample_count
, unsigned sample_index
,
924 /* We can't actually query the device to learn the sample positions.
925 * These were grabbed from nvidia's driver.
927 static const float pos1
[1][2] = {
930 static const float pos2
[2][2] = {
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 }
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 }
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 }
968 const float (*positions
)[2];
970 switch (sample_count
) {
987 pos_out
[0] = positions
[sample_index
][0];
988 pos_out
[1] = positions
[sample_index
][1];
993 svga_init_surface_functions(struct svga_context
*svga
)
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
;