2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **********************************************************************/
29 * Keith Whitwell <keith@tungstengraphics.com>
32 #include "util/u_memory.h"
33 #include "util/u_simple_list.h"
34 #include "util/u_math.h"
36 #include "pipe/p_screen.h"
37 #include "brw_screen.h"
38 #include "brw_context.h"
39 #include "brw_defines.h"
40 #include "brw_resource.h"
41 #include "brw_winsys.h"
49 static boolean
need_linear_view( struct brw_screen
*brw_screen
,
50 struct brw_texture
*brw_texture
,
51 union brw_surface_id id
,
55 /* XXX: what about IDGNG?
57 if (!BRW_IS_G4X(brw
->brw_screen
->pci_id
))
59 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_ColorDrawBuffers
[i
];
60 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
62 /* The original gen4 hardware couldn't set up WM surfaces pointing
63 * at an offset within a tile, which can happen when rendering to
64 * anything but the base level of a texture or the +X face/0 depth.
65 * This was fixed with the 4 Series hardware.
67 * For these original chips, you would have to make the depth and
68 * color destination surfaces include information on the texture
69 * type, LOD, face, and various limits to use them as a destination.
71 * This is easy in Gallium as surfaces are all backed by
72 * textures, but there's also a nasty requirement that the depth
73 * and the color surfaces all be of the same LOD, which is
74 * harder to get around as we can't look at a surface in
75 * isolation and decide if it's legal.
77 * Instead, end up being pessimistic and say that for i965,
80 if (brw_tex
->tiling
!= I915_TILING_NONE
&&
81 (brw_tex_image_offset(brw_tex
, face
, level
, zslize
) & 4095)) {
82 if (BRW_DEBUG
& DEBUG_VIEW
)
83 debug_printf("%s: need surface view for non-aligned tex image\n",
90 /* Tiled 3d textures don't have subsets that look like 2d surfaces:
93 /* Everything else should be fine to render to in-place:
98 /* Look at all texture views and figure out if any of them need to be
99 * back-copied into the texture for sampling
101 void brw_update_texture( struct brw_screen
*brw_screen
,
102 struct brw_texture
*tex
)
104 /* currently nothing to do */
108 /* Create a new surface with linear layout to serve as a render-target
109 * where it would be illegal (perhaps due to tiling constraints) to do
112 * Currently not implemented, not sure if it's needed.
114 static struct brw_surface
*create_linear_view( struct brw_screen
*brw_screen
,
115 struct pipe_context
*pipe
,
116 struct brw_texture
*tex
,
117 union brw_surface_id id
,
124 /* Create a pipe_surface that just points directly into the existing
127 static struct brw_surface
*create_in_place_view( struct brw_screen
*brw_screen
,
128 struct pipe_context
*pipe
,
129 struct brw_texture
*tex
,
130 union brw_surface_id id
,
133 struct brw_surface
*surface
;
135 surface
= CALLOC_STRUCT(brw_surface
);
139 pipe_reference_init(&surface
->base
.reference
, 1);
141 /* XXX: ignoring render-to-slice-of-3d-texture
143 assert(tex
->b
.b
.target
!= PIPE_TEXTURE_3D
|| id
.bits
.layer
== 0);
145 surface
->base
.context
= pipe
;
146 surface
->base
.format
= tex
->b
.b
.format
;
147 surface
->base
.width
= u_minify(tex
->b
.b
.width0
, id
.bits
.level
);
148 surface
->base
.height
= u_minify(tex
->b
.b
.height0
, id
.bits
.level
);
149 surface
->base
.usage
= usage
;
150 surface
->base
.u
.tex
.first_layer
= id
.bits
.layer
;
151 surface
->base
.u
.tex
.last_layer
= surface
->base
.u
.tex
.first_layer
;
152 surface
->base
.u
.tex
.level
= id
.bits
.level
;
154 surface
->offset
= tex
->image_offset
[id
.bits
.level
][id
.bits
.layer
];
155 surface
->cpp
= tex
->cpp
;
156 surface
->pitch
= tex
->pitch
;
157 surface
->tiling
= tex
->tiling
;
159 bo_reference( &surface
->bo
, tex
->bo
);
160 pipe_resource_reference( &surface
->base
.texture
, &tex
->b
.b
);
162 surface
->ss
.ss0
.surface_format
= tex
->ss
.ss0
.surface_format
;
163 surface
->ss
.ss0
.surface_type
= BRW_SURFACE_2D
;
165 if (tex
->tiling
== BRW_TILING_NONE
) {
166 surface
->ss
.ss1
.base_addr
= surface
->offset
;
168 uint32_t tile_offset
= surface
->offset
% 4096;
170 surface
->ss
.ss1
.base_addr
= surface
->offset
- tile_offset
;
172 if (tex
->tiling
== BRW_TILING_X
) {
173 /* Note that the low bits of these fields are missing, so
174 * there's the possibility of getting in trouble.
176 surface
->ss
.ss5
.x_offset
= (tile_offset
% 512) / tex
->cpp
/ 4;
177 surface
->ss
.ss5
.y_offset
= tile_offset
/ 512 / 2;
179 surface
->ss
.ss5
.x_offset
= (tile_offset
% 128) / tex
->cpp
/ 4;
180 surface
->ss
.ss5
.y_offset
= tile_offset
/ 128 / 2;
185 if (region_bo
!= NULL
)
186 surface
->ss
.ss1
.base_addr
+= region_bo
->offset
; /* reloc */
189 surface
->ss
.ss2
.width
= surface
->base
.width
- 1;
190 surface
->ss
.ss2
.height
= surface
->base
.height
- 1;
191 surface
->ss
.ss3
.tiled_surface
= tex
->ss
.ss3
.tiled_surface
;
192 surface
->ss
.ss3
.tile_walk
= tex
->ss
.ss3
.tile_walk
;
193 surface
->ss
.ss3
.pitch
= tex
->ss
.ss3
.pitch
;
198 /* Get a surface which is view into a texture
200 static struct pipe_surface
*brw_create_surface(struct pipe_context
*pipe
,
201 struct pipe_resource
*pt
,
202 const struct pipe_surface
*surf_tmpl
)
204 struct brw_texture
*tex
= brw_texture(pt
);
205 struct brw_screen
*bscreen
= brw_screen(pipe
->screen
);
206 struct brw_surface
*surface
;
207 union brw_surface_id id
;
210 assert(surf_tmpl
->u
.tex
.first_layer
== surf_tmpl
->u
.tex
.last_layer
);
211 id
.bits
.level
= surf_tmpl
->u
.tex
.level
;
212 id
.bits
.layer
= surf_tmpl
->u
.tex
.first_layer
;
214 if (need_linear_view(bscreen
, tex
, id
, surf_tmpl
->usage
))
215 type
= BRW_VIEW_LINEAR
;
217 type
= BRW_VIEW_IN_PLACE
;
220 foreach (surface
, &tex
->views
[type
]) {
221 if (id
.value
== surface
->id
.value
)
222 return &surface
->base
;
226 case BRW_VIEW_LINEAR
:
227 surface
= create_linear_view( bscreen
, pipe
, tex
, id
, surf_tmpl
->usage
);
229 case BRW_VIEW_IN_PLACE
:
230 surface
= create_in_place_view( bscreen
, pipe
, tex
, id
, surf_tmpl
->usage
);
234 insert_at_head( &tex
->views
[type
], surface
);
235 return &surface
->base
;
239 static void brw_surface_destroy( struct pipe_context
*pipe
,
240 struct pipe_surface
*surf
)
242 struct brw_surface
*surface
= brw_surface(surf
);
244 /* Unreference texture, shared buffer:
246 remove_from_list(surface
);
247 bo_reference(&surface
->bo
, NULL
);
248 pipe_resource_reference( &surface
->base
.texture
, NULL
);
254 void brw_pipe_surface_init( struct brw_context
*brw
)
256 brw
->base
.create_surface
= brw_create_surface
;
257 brw
->base
.surface_destroy
= brw_surface_destroy
;