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