Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5563 | serge | 1 | /************************************************************************** |
2 | * |
||
3 | * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. |
||
4 | * All Rights Reserved. |
||
5 | * |
||
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
7 | * 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, sub license, 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: |
||
13 | * |
||
14 | * The above copyright notice and this permission notice (including the |
||
15 | * next paragraph) shall be included in all copies or substantial portions |
||
16 | * of the Software. |
||
17 | * |
||
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
||
21 | * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR |
||
22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
||
23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
||
24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||
25 | * |
||
26 | **************************************************************************/ |
||
27 | |||
28 | /* Authors: |
||
29 | * Brian Paul |
||
30 | */ |
||
31 | |||
32 | |||
33 | #include "util/u_clear.h" |
||
34 | #include "util/u_format.h" |
||
35 | #include "util/u_pack_color.h" |
||
36 | #include "i915_context.h" |
||
37 | #include "i915_screen.h" |
||
38 | #include "i915_reg.h" |
||
39 | #include "i915_batch.h" |
||
40 | #include "i915_resource.h" |
||
41 | #include "i915_state.h" |
||
42 | |||
43 | void |
||
44 | i915_clear_emit(struct pipe_context *pipe, unsigned buffers, |
||
45 | const union pipe_color_union *color, |
||
46 | double depth, unsigned stencil, |
||
47 | unsigned destx, unsigned desty, unsigned width, unsigned height) |
||
48 | { |
||
49 | struct i915_context *i915 = i915_context(pipe); |
||
50 | uint32_t clear_params, clear_color, clear_depth, clear_stencil, |
||
51 | clear_color8888, packed_z_stencil; |
||
52 | union util_color u_color; |
||
53 | float f_depth = depth; |
||
54 | struct i915_texture *cbuf_tex, *depth_tex; |
||
55 | int depth_clear_bbp, color_clear_bbp; |
||
56 | |||
57 | cbuf_tex = depth_tex = NULL; |
||
58 | clear_params = 0; |
||
59 | depth_clear_bbp = color_clear_bbp = 0; |
||
60 | |||
61 | if (buffers & PIPE_CLEAR_COLOR) { |
||
62 | struct pipe_surface *cbuf = i915->framebuffer.cbufs[0]; |
||
63 | |||
64 | clear_params |= CLEARPARAM_WRITE_COLOR; |
||
65 | cbuf_tex = i915_texture(cbuf->texture); |
||
66 | |||
67 | util_pack_color(color->f, cbuf->format, &u_color); |
||
68 | if (util_format_get_blocksize(cbuf_tex->b.b.format) == 4) { |
||
69 | clear_color = u_color.ui; |
||
70 | color_clear_bbp = 32; |
||
71 | } else { |
||
72 | clear_color = (u_color.ui & 0xffff) | (u_color.ui << 16); |
||
73 | color_clear_bbp = 16; |
||
74 | } |
||
75 | |||
76 | /* correctly swizzle clear value */ |
||
77 | if (i915->current.target_fixup_format) |
||
78 | util_pack_color(color->f, cbuf->format, &u_color); |
||
79 | else |
||
80 | util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color); |
||
81 | clear_color8888 = u_color.ui; |
||
82 | } else |
||
83 | clear_color = clear_color8888 = 0; |
||
84 | |||
85 | clear_depth = clear_stencil = 0; |
||
86 | if (buffers & PIPE_CLEAR_DEPTH) { |
||
87 | struct pipe_surface *zbuf = i915->framebuffer.zsbuf; |
||
88 | |||
89 | clear_params |= CLEARPARAM_WRITE_DEPTH; |
||
90 | depth_tex = i915_texture(zbuf->texture); |
||
91 | packed_z_stencil = util_pack_z_stencil(depth_tex->b.b.format, depth, stencil); |
||
92 | |||
93 | if (util_format_get_blocksize(depth_tex->b.b.format) == 4) { |
||
94 | /* Avoid read-modify-write if there's no stencil. */ |
||
95 | if (buffers & PIPE_CLEAR_STENCIL |
||
96 | || depth_tex->b.b.format != PIPE_FORMAT_Z24_UNORM_S8_UINT) { |
||
97 | clear_params |= CLEARPARAM_WRITE_STENCIL; |
||
98 | clear_stencil = packed_z_stencil >> 24; |
||
99 | } |
||
100 | |||
101 | clear_depth = packed_z_stencil & 0xffffff; |
||
102 | depth_clear_bbp = 32; |
||
103 | } else { |
||
104 | clear_depth = (packed_z_stencil & 0xffff) | (packed_z_stencil << 16); |
||
105 | depth_clear_bbp = 16; |
||
106 | } |
||
107 | } else if (buffers & PIPE_CLEAR_STENCIL) { |
||
108 | struct pipe_surface *zbuf = i915->framebuffer.zsbuf; |
||
109 | |||
110 | clear_params |= CLEARPARAM_WRITE_STENCIL; |
||
111 | depth_tex = i915_texture(zbuf->texture); |
||
112 | assert(depth_tex->b.b.format == PIPE_FORMAT_Z24_UNORM_S8_UINT); |
||
113 | |||
114 | packed_z_stencil = util_pack_z_stencil(depth_tex->b.b.format, depth, stencil); |
||
115 | depth_clear_bbp = 32; |
||
116 | clear_stencil = packed_z_stencil >> 24; |
||
117 | } |
||
118 | |||
119 | /* hw can't fastclear both depth and color if their bbp mismatch. */ |
||
120 | if (color_clear_bbp && depth_clear_bbp |
||
121 | && color_clear_bbp != depth_clear_bbp) { |
||
122 | if (i915->hardware_dirty) |
||
123 | i915_emit_hardware_state(i915); |
||
124 | |||
125 | if (!BEGIN_BATCH(1 + 2*(7 + 7))) { |
||
126 | FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
||
127 | |||
128 | i915_emit_hardware_state(i915); |
||
129 | i915->vbo_flushed = 1; |
||
130 | |||
131 | assert(BEGIN_BATCH(1 + 2*(7 + 7))); |
||
132 | } |
||
133 | |||
134 | OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); |
||
135 | |||
136 | OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); |
||
137 | OUT_BATCH(CLEARPARAM_WRITE_COLOR | CLEARPARAM_CLEAR_RECT); |
||
138 | /* Used for zone init prim */ |
||
139 | OUT_BATCH(clear_color); |
||
140 | OUT_BATCH(clear_depth); |
||
141 | /* Used for clear rect prim */ |
||
142 | OUT_BATCH(clear_color8888); |
||
143 | OUT_BATCH_F(f_depth); |
||
144 | OUT_BATCH(clear_stencil); |
||
145 | |||
146 | OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); |
||
147 | OUT_BATCH_F(destx + width); |
||
148 | OUT_BATCH_F(desty + height); |
||
149 | OUT_BATCH_F(destx); |
||
150 | OUT_BATCH_F(desty + height); |
||
151 | OUT_BATCH_F(destx); |
||
152 | OUT_BATCH_F(desty); |
||
153 | |||
154 | OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); |
||
155 | OUT_BATCH((clear_params & ~CLEARPARAM_WRITE_COLOR) | |
||
156 | CLEARPARAM_CLEAR_RECT); |
||
157 | /* Used for zone init prim */ |
||
158 | OUT_BATCH(clear_color); |
||
159 | OUT_BATCH(clear_depth); |
||
160 | /* Used for clear rect prim */ |
||
161 | OUT_BATCH(clear_color8888); |
||
162 | OUT_BATCH_F(f_depth); |
||
163 | OUT_BATCH(clear_stencil); |
||
164 | |||
165 | OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); |
||
166 | OUT_BATCH_F(destx + width); |
||
167 | OUT_BATCH_F(desty + height); |
||
168 | OUT_BATCH_F(destx); |
||
169 | OUT_BATCH_F(desty + height); |
||
170 | OUT_BATCH_F(destx); |
||
171 | OUT_BATCH_F(desty); |
||
172 | } else { |
||
173 | if (i915->hardware_dirty) |
||
174 | i915_emit_hardware_state(i915); |
||
175 | |||
176 | if (!BEGIN_BATCH(1 + 7 + 7)) { |
||
177 | FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
||
178 | |||
179 | i915_emit_hardware_state(i915); |
||
180 | i915->vbo_flushed = 1; |
||
181 | |||
182 | assert(BEGIN_BATCH(1 + 7 + 7)); |
||
183 | } |
||
184 | |||
185 | OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); |
||
186 | |||
187 | OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); |
||
188 | OUT_BATCH(clear_params | CLEARPARAM_CLEAR_RECT); |
||
189 | /* Used for zone init prim */ |
||
190 | OUT_BATCH(clear_color); |
||
191 | OUT_BATCH(clear_depth); |
||
192 | /* Used for clear rect prim */ |
||
193 | OUT_BATCH(clear_color8888); |
||
194 | OUT_BATCH_F(f_depth); |
||
195 | OUT_BATCH(clear_stencil); |
||
196 | |||
197 | OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); |
||
198 | OUT_BATCH_F(destx + width); |
||
199 | OUT_BATCH_F(desty + height); |
||
200 | OUT_BATCH_F(destx); |
||
201 | OUT_BATCH_F(desty + height); |
||
202 | OUT_BATCH_F(destx); |
||
203 | OUT_BATCH_F(desty); |
||
204 | } |
||
205 | |||
206 | /* Flush after clear, its expected to be a costly operation. |
||
207 | * This is not required, just a heuristic, but without the flush we'd need to |
||
208 | * clobber the SCISSOR_ENABLE dynamic state. */ |
||
209 | FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
||
210 | |||
211 | i915->last_fired_vertices = i915->fired_vertices; |
||
212 | i915->fired_vertices = 0; |
||
213 | } |
||
214 | |||
215 | /** |
||
216 | * Clear the given buffers to the specified values. |
||
217 | * No masking, no scissor (clear entire buffer). |
||
218 | */ |
||
219 | void |
||
220 | i915_clear_blitter(struct pipe_context *pipe, unsigned buffers, |
||
221 | const union pipe_color_union *color, |
||
222 | double depth, unsigned stencil) |
||
223 | { |
||
224 | util_clear(pipe, &i915_context(pipe)->framebuffer, buffers, color, depth, |
||
225 | stencil); |
||
226 | } |
||
227 | |||
228 | void |
||
229 | i915_clear_render(struct pipe_context *pipe, unsigned buffers, |
||
230 | const union pipe_color_union *color, |
||
231 | double depth, unsigned stencil) |
||
232 | { |
||
233 | struct i915_context *i915 = i915_context(pipe); |
||
234 | |||
235 | if (i915->dirty) |
||
236 | i915_update_derived(i915); |
||
237 | |||
238 | i915_clear_emit(pipe, buffers, color, depth, stencil, |
||
239 | 0, 0, i915->framebuffer.width, i915->framebuffer.height); |
||
240 | }><>><> |