2 #include "pipe/p_screen.h"
3 #include "brw_screen.h"
7 * Sets up a surface state structure to point at the given region.
8 * While it is only used for the front/back buffer currently, it should be
9 * usable for further buffers when doing ARB_draw_buffer support.
12 brw_update_renderbuffer_surface(struct brw_context
*brw
,
13 struct gl_renderbuffer
*rb
,
16 struct brw_winsys_buffer
*region_bo
= NULL
;
17 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
18 struct intel_region
*region
= irb
? irb
->region
: NULL
;
20 unsigned int surface_type
;
21 unsigned int surface_format
;
22 unsigned int width
, height
, pitch
, cpp
;
23 GLubyte color_mask
[4];
24 GLboolean color_blend
;
29 memset(&key
, 0, sizeof(key
));
32 region_bo
= region
->buffer
;
34 key
.surface_type
= BRW_SURFACE_2D
;
35 switch (irb
->texformat
->MesaFormat
) {
36 case PIPE_FORMAT_ARGB8888
:
37 key
.surface_format
= BRW_SURFACEFORMAT_B8G8R8A8_UNORM
;
39 case PIPE_FORMAT_RGB565
:
40 key
.surface_format
= BRW_SURFACEFORMAT_B5G6R5_UNORM
;
42 case PIPE_FORMAT_ARGB1555
:
43 key
.surface_format
= BRW_SURFACEFORMAT_B5G5R5A1_UNORM
;
45 case PIPE_FORMAT_ARGB4444
:
46 key
.surface_format
= BRW_SURFACEFORMAT_B4G4R4A4_UNORM
;
49 debug_printf("Bad renderbuffer format: %d\n",
50 irb
->texformat
->MesaFormat
);
52 key
.surface_format
= BRW_SURFACEFORMAT_B8G8R8A8_UNORM
;
55 key
.tiling
= region
->tiling
;
56 if (brw
->intel
.intelScreen
->driScrnPriv
->dri2
.enabled
) {
57 key
.width
= rb
->Width
;
58 key
.height
= rb
->Height
;
60 key
.width
= region
->width
;
61 key
.height
= region
->height
;
63 key
.pitch
= region
->pitch
;
64 key
.cpp
= region
->cpp
;
65 key
.draw_offset
= region
->draw_offset
; /* cur 3d or cube face offset */
68 memcpy(key
.color_mask
, ctx
->Color
.ColorMask
,
69 sizeof(key
.color_mask
));
71 key
.color_blend
= (!ctx
->Color
._LogicOpEnabled
&&
72 ctx
->Color
.BlendEnabled
);
74 brw
->sws
->bo_unreference(brw
->wm
.surf_bo
[unit
]);
75 brw
->wm
.surf_bo
[unit
] = brw_search_cache(&brw
->surface_cache
,
81 if (brw
->wm
.surf_bo
[unit
] == NULL
) {
82 struct brw_surface_state surf
;
84 memset(&surf
, 0, sizeof(surf
));
86 surf
.ss0
.surface_format
= key
.surface_format
;
87 surf
.ss0
.surface_type
= key
.surface_type
;
88 if (key
.tiling
== I915_TILING_NONE
) {
89 surf
.ss1
.base_addr
= key
.draw_offset
;
91 uint32_t tile_offset
= key
.draw_offset
% 4096;
93 surf
.ss1
.base_addr
= key
.draw_offset
- tile_offset
;
95 assert(BRW_IS_G4X(brw
) || tile_offset
== 0);
96 if (BRW_IS_G4X(brw
)) {
97 if (key
.tiling
== I915_TILING_X
) {
98 /* Note that the low bits of these fields are missing, so
99 * there's the possibility of getting in trouble.
101 surf
.ss5
.x_offset
= (tile_offset
% 512) / key
.cpp
/ 4;
102 surf
.ss5
.y_offset
= tile_offset
/ 512 / 2;
104 surf
.ss5
.x_offset
= (tile_offset
% 128) / key
.cpp
/ 4;
105 surf
.ss5
.y_offset
= tile_offset
/ 128 / 2;
110 if (region_bo
!= NULL
)
111 surf
.ss1
.base_addr
+= region_bo
->offset
; /* reloc */
113 surf
.ss2
.width
= key
.width
- 1;
114 surf
.ss2
.height
= key
.height
- 1;
115 brw_set_surface_tiling(&surf
, key
.tiling
);
116 surf
.ss3
.pitch
= (key
.pitch
* key
.cpp
) - 1;
122 struct brw_surface_id
{
128 static boolean
need_linear_view( struct brw_screen
*brw_screen
,
129 struct brw_texture
*brw_texture
,
135 /* XXX: what about IDGNG?
137 if (!BRW_IS_G4X(brw
->brw_screen
->pci_id
))
139 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_ColorDrawBuffers
[i
];
140 struct intel_renderbuffer
*irb
= intel_renderbuffer(rb
);
142 /* The original gen4 hardware couldn't set up WM surfaces pointing
143 * at an offset within a tile, which can happen when rendering to
144 * anything but the base level of a texture or the +X face/0 depth.
145 * This was fixed with the 4 Series hardware.
147 * For these original chips, you would have to make the depth and
148 * color destination surfaces include information on the texture
149 * type, LOD, face, and various limits to use them as a destination.
151 * This is easy in Gallium as surfaces are all backed by
152 * textures, but there's also a nasty requirement that the depth
153 * and the color surfaces all be of the same LOD, which is
154 * harder to get around as we can't look at a surface in
155 * isolation and decide if it's legal.
157 * Instead, end up being pessimistic and say that for i965,
160 if (brw_tex
->tiling
!= I915_TILING_NONE
&&
161 (brw_tex_image_offset(brw_tex
, face
, level
, zslize
) & 4095)) {
162 if (BRW_DEBUG
& DEBUG_VIEW
)
163 debug_printf("%s: need surface view for non-aligned tex image\n",
170 /* Tiled 3d textures don't have subsets that look like 2d surfaces:
173 /* Everything else should be fine to render to in-place:
178 /* Look at all texture views and figure out if any of them need to be
179 * back-copied into the texture for sampling
181 void brw_update_texture( struct pipe_screen
*screen
,
182 struct pipe_texture
*texture
)
184 /* currently nothing to do */
188 static struct pipe_surface
*create_linear_view( struct brw_screen
*brw_screen
,
189 struct brw_texture
*brw_tex
,
190 struct brw_surface_id id
)
195 static struct pipe_surface
*create_in_place_view( struct brw_screen
*brw_screen
,
196 struct brw_texture
*brw_tex
,
197 struct brw_surface_id id
)
199 struct brw_surface
*surface
= CALLOC_STRUCT(brw_surface
);
204 /* Get a surface which is view into a texture
206 struct pipe_surface
*brw_get_tex_surface(struct pipe_screen
*screen
,
207 struct pipe_texture
*texture
,
208 unsigned face
, unsigned level
,
212 struct brw_screen
*bscreen
= brw_screen(screen
);
213 struct brw_surface_id id
;
219 if (need_linear_view(brw_screen
, brw_tex
, id
))
220 type
= BRW_VIEW_LINEAR
;
222 type
= BRW_VIEW_IN_PLACE
;
225 foreach (surface
, texture
->views
[type
]) {
226 if (id
.value
== surface
->id
.value
)
231 case BRW_VIEW_LINEAR
:
232 surface
= create_linear_view( texture
, id
, type
);
234 case BRW_VIEW_IN_PLACE
:
235 surface
= create_in_place_view( texture
, id
, type
);
241 insert_at_head( texture
->views
[type
], surface
);
246 void brw_tex_surface_destroy( struct pipe_surface
*surface
)