1848b8605Smrg/**************************************************************************
2848b8605Smrg *
3848b8605Smrg * Copyright 2007 VMware, Inc.
4848b8605Smrg * All Rights Reserved.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the
8848b8605Smrg * "Software"), to deal in the Software without restriction, including
9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish,
10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to
11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to
12848b8605Smrg * the following conditions:
13848b8605Smrg *
14848b8605Smrg * The above copyright notice and this permission notice (including the
15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions
16848b8605Smrg * of the Software.
17848b8605Smrg *
18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25848b8605Smrg *
26848b8605Smrg **************************************************************************/
27848b8605Smrg
28848b8605Smrg/* Authors:
29848b8605Smrg *    Brian Paul
30848b8605Smrg */
31848b8605Smrg
32848b8605Smrg
33848b8605Smrg#include "util/u_format.h"
34848b8605Smrg#include "util/u_pack_color.h"
35848b8605Smrg#include "i915_context.h"
36848b8605Smrg#include "i915_screen.h"
37848b8605Smrg#include "i915_reg.h"
38848b8605Smrg#include "i915_batch.h"
39848b8605Smrg#include "i915_resource.h"
40848b8605Smrg#include "i915_state.h"
41848b8605Smrg
42848b8605Smrgvoid
43848b8605Smrgi915_clear_emit(struct pipe_context *pipe, unsigned buffers,
44848b8605Smrg                const union pipe_color_union *color,
45848b8605Smrg                double depth, unsigned stencil,
46848b8605Smrg                unsigned destx, unsigned desty, unsigned width, unsigned height)
47848b8605Smrg{
48848b8605Smrg   struct i915_context *i915 = i915_context(pipe);
49848b8605Smrg   uint32_t clear_params, clear_color, clear_depth, clear_stencil,
50848b8605Smrg            clear_color8888, packed_z_stencil;
51848b8605Smrg   union util_color u_color;
52848b8605Smrg   float f_depth = depth;
53848b8605Smrg   struct i915_texture *cbuf_tex, *depth_tex;
54848b8605Smrg   int depth_clear_bbp, color_clear_bbp;
55848b8605Smrg
56848b8605Smrg   cbuf_tex = depth_tex = NULL;
57848b8605Smrg   clear_params = 0;
58848b8605Smrg   depth_clear_bbp = color_clear_bbp = 0;
59848b8605Smrg
60848b8605Smrg   if (buffers & PIPE_CLEAR_COLOR) {
61848b8605Smrg      struct pipe_surface *cbuf = i915->framebuffer.cbufs[0];
62848b8605Smrg
63848b8605Smrg      clear_params |= CLEARPARAM_WRITE_COLOR;
64848b8605Smrg      cbuf_tex = i915_texture(cbuf->texture);
65848b8605Smrg
66848b8605Smrg      util_pack_color(color->f, cbuf->format, &u_color);
67848b8605Smrg      if (util_format_get_blocksize(cbuf_tex->b.b.format) == 4) {
68848b8605Smrg         clear_color = u_color.ui[0];
69848b8605Smrg         color_clear_bbp = 32;
70848b8605Smrg      } else {
71848b8605Smrg         clear_color = (u_color.ui[0] & 0xffff) | (u_color.ui[0] << 16);
72848b8605Smrg         color_clear_bbp = 16;
73848b8605Smrg      }
74848b8605Smrg
75848b8605Smrg      /* correctly swizzle clear value */
76848b8605Smrg      if (i915->current.target_fixup_format)
77848b8605Smrg         util_pack_color(color->f, cbuf->format, &u_color);
78848b8605Smrg      else
79848b8605Smrg         util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color);
80848b8605Smrg      clear_color8888 = u_color.ui[0];
81848b8605Smrg   } else
82848b8605Smrg      clear_color = clear_color8888 = 0;
83848b8605Smrg
84848b8605Smrg   clear_depth = clear_stencil = 0;
85848b8605Smrg   if (buffers & PIPE_CLEAR_DEPTH) {
86848b8605Smrg      struct pipe_surface *zbuf = i915->framebuffer.zsbuf;
87848b8605Smrg
88848b8605Smrg      clear_params |= CLEARPARAM_WRITE_DEPTH;
89848b8605Smrg      depth_tex = i915_texture(zbuf->texture);
90848b8605Smrg      packed_z_stencil = util_pack_z_stencil(depth_tex->b.b.format, depth, stencil);
91848b8605Smrg
92848b8605Smrg      if (util_format_get_blocksize(depth_tex->b.b.format) == 4) {
93848b8605Smrg         /* Avoid read-modify-write if there's no stencil. */
94848b8605Smrg         if (buffers & PIPE_CLEAR_STENCIL
95848b8605Smrg               || depth_tex->b.b.format != PIPE_FORMAT_Z24_UNORM_S8_UINT) {
96848b8605Smrg            clear_params |= CLEARPARAM_WRITE_STENCIL;
97848b8605Smrg            clear_stencil = packed_z_stencil >> 24;
98848b8605Smrg         }
99848b8605Smrg
100848b8605Smrg         clear_depth = packed_z_stencil & 0xffffff;
101848b8605Smrg         depth_clear_bbp = 32;
102848b8605Smrg      } else {
103848b8605Smrg         clear_depth = (packed_z_stencil & 0xffff) | (packed_z_stencil << 16);
104848b8605Smrg         depth_clear_bbp = 16;
105848b8605Smrg      }
106848b8605Smrg   } else if (buffers & PIPE_CLEAR_STENCIL) {
107848b8605Smrg      struct pipe_surface *zbuf = i915->framebuffer.zsbuf;
108848b8605Smrg
109848b8605Smrg      clear_params |= CLEARPARAM_WRITE_STENCIL;
110848b8605Smrg      depth_tex = i915_texture(zbuf->texture);
111848b8605Smrg      assert(depth_tex->b.b.format == PIPE_FORMAT_Z24_UNORM_S8_UINT);
112848b8605Smrg
113848b8605Smrg      packed_z_stencil = util_pack_z_stencil(depth_tex->b.b.format, depth, stencil);
114848b8605Smrg      depth_clear_bbp = 32;
115848b8605Smrg      clear_stencil = packed_z_stencil >> 24;
116848b8605Smrg   }
117848b8605Smrg
118848b8605Smrg   /* hw can't fastclear both depth and color if their bbp mismatch. */
119848b8605Smrg   if (color_clear_bbp && depth_clear_bbp
120848b8605Smrg         && color_clear_bbp != depth_clear_bbp) {
121848b8605Smrg      if (i915->hardware_dirty)
122848b8605Smrg         i915_emit_hardware_state(i915);
123848b8605Smrg
124848b8605Smrg      if (!BEGIN_BATCH(1 + 2*(7 + 7))) {
125848b8605Smrg         FLUSH_BATCH(NULL, I915_FLUSH_ASYNC);
126848b8605Smrg
127848b8605Smrg         i915_emit_hardware_state(i915);
128848b8605Smrg         i915->vbo_flushed = 1;
129848b8605Smrg
130848b8605Smrg         assert(BEGIN_BATCH(1 + 2*(7 + 7)));
131848b8605Smrg      }
132848b8605Smrg
133848b8605Smrg      OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
134848b8605Smrg
135848b8605Smrg      OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS);
136848b8605Smrg      OUT_BATCH(CLEARPARAM_WRITE_COLOR | CLEARPARAM_CLEAR_RECT);
137848b8605Smrg      /* Used for zone init prim */
138848b8605Smrg      OUT_BATCH(clear_color);
139848b8605Smrg      OUT_BATCH(clear_depth);
140848b8605Smrg      /* Used for clear rect prim */
141848b8605Smrg      OUT_BATCH(clear_color8888);
142848b8605Smrg      OUT_BATCH_F(f_depth);
143848b8605Smrg      OUT_BATCH(clear_stencil);
144848b8605Smrg
145848b8605Smrg      OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5);
146848b8605Smrg      OUT_BATCH_F(destx + width);
147848b8605Smrg      OUT_BATCH_F(desty + height);
148848b8605Smrg      OUT_BATCH_F(destx);
149848b8605Smrg      OUT_BATCH_F(desty + height);
150848b8605Smrg      OUT_BATCH_F(destx);
151848b8605Smrg      OUT_BATCH_F(desty);
152848b8605Smrg
153848b8605Smrg      OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS);
154848b8605Smrg      OUT_BATCH((clear_params & ~CLEARPARAM_WRITE_COLOR) |
155848b8605Smrg                CLEARPARAM_CLEAR_RECT);
156848b8605Smrg      /* Used for zone init prim */
157848b8605Smrg      OUT_BATCH(clear_color);
158848b8605Smrg      OUT_BATCH(clear_depth);
159848b8605Smrg      /* Used for clear rect prim */
160848b8605Smrg      OUT_BATCH(clear_color8888);
161848b8605Smrg      OUT_BATCH_F(f_depth);
162848b8605Smrg      OUT_BATCH(clear_stencil);
163848b8605Smrg
164848b8605Smrg      OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5);
165848b8605Smrg      OUT_BATCH_F(destx + width);
166848b8605Smrg      OUT_BATCH_F(desty + height);
167848b8605Smrg      OUT_BATCH_F(destx);
168848b8605Smrg      OUT_BATCH_F(desty + height);
169848b8605Smrg      OUT_BATCH_F(destx);
170848b8605Smrg      OUT_BATCH_F(desty);
171848b8605Smrg   } else {
172848b8605Smrg      if (i915->hardware_dirty)
173848b8605Smrg         i915_emit_hardware_state(i915);
174848b8605Smrg
175848b8605Smrg      if (!BEGIN_BATCH(1 + 7 + 7)) {
176848b8605Smrg         FLUSH_BATCH(NULL, I915_FLUSH_ASYNC);
177848b8605Smrg
178848b8605Smrg         i915_emit_hardware_state(i915);
179848b8605Smrg         i915->vbo_flushed = 1;
180848b8605Smrg
181848b8605Smrg         assert(BEGIN_BATCH(1 + 7 + 7));
182848b8605Smrg      }
183848b8605Smrg
184848b8605Smrg      OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
185848b8605Smrg
186848b8605Smrg      OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS);
187848b8605Smrg      OUT_BATCH(clear_params | CLEARPARAM_CLEAR_RECT);
188848b8605Smrg      /* Used for zone init prim */
189848b8605Smrg      OUT_BATCH(clear_color);
190848b8605Smrg      OUT_BATCH(clear_depth);
191848b8605Smrg      /* Used for clear rect prim */
192848b8605Smrg      OUT_BATCH(clear_color8888);
193848b8605Smrg      OUT_BATCH_F(f_depth);
194848b8605Smrg      OUT_BATCH(clear_stencil);
195848b8605Smrg
196848b8605Smrg      OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5);
197848b8605Smrg      OUT_BATCH_F(destx + width);
198848b8605Smrg      OUT_BATCH_F(desty + height);
199848b8605Smrg      OUT_BATCH_F(destx);
200848b8605Smrg      OUT_BATCH_F(desty + height);
201848b8605Smrg      OUT_BATCH_F(destx);
202848b8605Smrg      OUT_BATCH_F(desty);
203848b8605Smrg   }
204848b8605Smrg
205848b8605Smrg   /* Flush after clear, its expected to be a costly operation.
206848b8605Smrg    * This is not required, just a heuristic, but without the flush we'd need to
207848b8605Smrg    * clobber the SCISSOR_ENABLE dynamic state. */
208848b8605Smrg   FLUSH_BATCH(NULL, I915_FLUSH_ASYNC);
209848b8605Smrg
210848b8605Smrg   i915->last_fired_vertices = i915->fired_vertices;
211848b8605Smrg   i915->fired_vertices = 0;
212848b8605Smrg}
213848b8605Smrg
214848b8605Smrg/**
215848b8605Smrg * Clear the given buffers to the specified values.
216848b8605Smrg * No masking, no scissor (clear entire buffer).
217848b8605Smrg */
218848b8605Smrgvoid
219848b8605Smrgi915_clear_blitter(struct pipe_context *pipe, unsigned buffers,
220848b8605Smrg                   const union pipe_color_union *color,
221848b8605Smrg                   double depth, unsigned stencil)
222848b8605Smrg{
223b8e80941Smrg   struct pipe_framebuffer_state *framebuffer =
224b8e80941Smrg      &i915_context(pipe)->framebuffer;
225b8e80941Smrg   unsigned i;
226b8e80941Smrg
227b8e80941Smrg   for (i = 0; i < framebuffer->nr_cbufs; i++) {
228b8e80941Smrg      if (buffers & (PIPE_CLEAR_COLOR0 << i)) {
229b8e80941Smrg         struct pipe_surface *ps = framebuffer->cbufs[i];
230b8e80941Smrg
231b8e80941Smrg         if (ps) {
232b8e80941Smrg            pipe->clear_render_target(pipe, ps, color, 0, 0, ps->width,
233b8e80941Smrg                                      ps->height, true);
234b8e80941Smrg         }
235b8e80941Smrg      }
236b8e80941Smrg   }
237b8e80941Smrg
238b8e80941Smrg   if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
239b8e80941Smrg      struct pipe_surface *ps = framebuffer->zsbuf;
240b8e80941Smrg      pipe->clear_depth_stencil(pipe, ps, buffers & PIPE_CLEAR_DEPTHSTENCIL,
241b8e80941Smrg                                depth, stencil,
242b8e80941Smrg                                0, 0, ps->width, ps->height, true);
243b8e80941Smrg   }
244848b8605Smrg}
245848b8605Smrg
246848b8605Smrgvoid
247848b8605Smrgi915_clear_render(struct pipe_context *pipe, unsigned buffers,
248848b8605Smrg                  const union pipe_color_union *color,
249848b8605Smrg                  double depth, unsigned stencil)
250848b8605Smrg{
251848b8605Smrg   struct i915_context *i915 = i915_context(pipe);
252848b8605Smrg
253848b8605Smrg   if (i915->dirty)
254848b8605Smrg      i915_update_derived(i915);
255848b8605Smrg
256848b8605Smrg   i915_clear_emit(pipe, buffers, color, depth, stencil,
257848b8605Smrg                   0, 0, i915->framebuffer.width, i915->framebuffer.height);
258848b8605Smrg}
259