14a49301eSmrg/************************************************************************** 27ec681f3Smrg * 3af69d88dSmrg * Copyright 2007 VMware, Inc. 44a49301eSmrg * All Rights Reserved. 57ec681f3Smrg * 64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a 74a49301eSmrg * copy of this software and associated documentation files (the 84a49301eSmrg * "Software"), to deal in the Software without restriction, including 94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish, 104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to 114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to 124a49301eSmrg * the following conditions: 137ec681f3Smrg * 144a49301eSmrg * The above copyright notice and this permission notice (including the 154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions 164a49301eSmrg * of the Software. 177ec681f3Smrg * 184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 257ec681f3Smrg * 264a49301eSmrg **************************************************************************/ 274a49301eSmrg 284a49301eSmrg/* Authors: 294a49301eSmrg * Brian Paul 304a49301eSmrg */ 314a49301eSmrg 327ec681f3Smrg#include "util/format/u_format.h" 333464ebd5Sriastradh#include "util/u_pack_color.h" 347ec681f3Smrg#include "i915_batch.h" 354a49301eSmrg#include "i915_context.h" 363464ebd5Sriastradh#include "i915_reg.h" 373464ebd5Sriastradh#include "i915_resource.h" 387ec681f3Smrg#include "i915_screen.h" 393464ebd5Sriastradh#include "i915_state.h" 404a49301eSmrg 413464ebd5Sriastradhvoid 42af69d88dSmrgi915_clear_emit(struct pipe_context *pipe, unsigned buffers, 437ec681f3Smrg const union pipe_color_union *color, double depth, 447ec681f3Smrg unsigned stencil, unsigned destx, unsigned desty, 457ec681f3Smrg unsigned width, unsigned height) 463464ebd5Sriastradh{ 473464ebd5Sriastradh struct i915_context *i915 = i915_context(pipe); 483464ebd5Sriastradh uint32_t clear_params, clear_color, clear_depth, clear_stencil, 497ec681f3Smrg clear_color8888, packed_z_stencil; 503464ebd5Sriastradh union util_color u_color; 513464ebd5Sriastradh float f_depth = depth; 523464ebd5Sriastradh struct i915_texture *cbuf_tex, *depth_tex; 53af69d88dSmrg int depth_clear_bbp, color_clear_bbp; 543464ebd5Sriastradh 553464ebd5Sriastradh cbuf_tex = depth_tex = NULL; 563464ebd5Sriastradh clear_params = 0; 57af69d88dSmrg depth_clear_bbp = color_clear_bbp = 0; 583464ebd5Sriastradh 593464ebd5Sriastradh if (buffers & PIPE_CLEAR_COLOR) { 603464ebd5Sriastradh struct pipe_surface *cbuf = i915->framebuffer.cbufs[0]; 613464ebd5Sriastradh 623464ebd5Sriastradh clear_params |= CLEARPARAM_WRITE_COLOR; 633464ebd5Sriastradh cbuf_tex = i915_texture(cbuf->texture); 643464ebd5Sriastradh 65af69d88dSmrg util_pack_color(color->f, cbuf->format, &u_color); 667ec681f3Smrg if (util_format_get_blocksize(cbuf_tex->b.format) == 4) { 67af69d88dSmrg clear_color = u_color.ui[0]; 68af69d88dSmrg color_clear_bbp = 32; 69af69d88dSmrg } else { 70af69d88dSmrg clear_color = (u_color.ui[0] & 0xffff) | (u_color.ui[0] << 16); 71af69d88dSmrg color_clear_bbp = 16; 72af69d88dSmrg } 73af69d88dSmrg 74af69d88dSmrg /* correctly swizzle clear value */ 757ec681f3Smrg if (i915->current.fixup_swizzle) 76af69d88dSmrg util_pack_color(color->f, cbuf->format, &u_color); 77af69d88dSmrg else 78af69d88dSmrg util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color); 79af69d88dSmrg clear_color8888 = u_color.ui[0]; 803464ebd5Sriastradh } else 813464ebd5Sriastradh clear_color = clear_color8888 = 0; 823464ebd5Sriastradh 833464ebd5Sriastradh clear_depth = clear_stencil = 0; 843464ebd5Sriastradh if (buffers & PIPE_CLEAR_DEPTH) { 853464ebd5Sriastradh struct pipe_surface *zbuf = i915->framebuffer.zsbuf; 863464ebd5Sriastradh 873464ebd5Sriastradh clear_params |= CLEARPARAM_WRITE_DEPTH; 883464ebd5Sriastradh depth_tex = i915_texture(zbuf->texture); 897ec681f3Smrg packed_z_stencil = 907ec681f3Smrg util_pack_z_stencil(depth_tex->b.format, depth, stencil); 913464ebd5Sriastradh 927ec681f3Smrg if (util_format_get_blocksize(depth_tex->b.format) == 4) { 933464ebd5Sriastradh /* Avoid read-modify-write if there's no stencil. */ 947ec681f3Smrg if (buffers & PIPE_CLEAR_STENCIL || 957ec681f3Smrg depth_tex->b.format != PIPE_FORMAT_Z24_UNORM_S8_UINT) { 963464ebd5Sriastradh clear_params |= CLEARPARAM_WRITE_STENCIL; 97af69d88dSmrg clear_stencil = packed_z_stencil >> 24; 98af69d88dSmrg } 99af69d88dSmrg 100af69d88dSmrg clear_depth = packed_z_stencil & 0xffffff; 101af69d88dSmrg depth_clear_bbp = 32; 1023464ebd5Sriastradh } else { 103af69d88dSmrg clear_depth = (packed_z_stencil & 0xffff) | (packed_z_stencil << 16); 104af69d88dSmrg depth_clear_bbp = 16; 1053464ebd5Sriastradh } 106af69d88dSmrg } else if (buffers & PIPE_CLEAR_STENCIL) { 107af69d88dSmrg struct pipe_surface *zbuf = i915->framebuffer.zsbuf; 108af69d88dSmrg 109af69d88dSmrg clear_params |= CLEARPARAM_WRITE_STENCIL; 110af69d88dSmrg depth_tex = i915_texture(zbuf->texture); 1117ec681f3Smrg assert(depth_tex->b.format == PIPE_FORMAT_Z24_UNORM_S8_UINT); 112af69d88dSmrg 1137ec681f3Smrg packed_z_stencil = 1147ec681f3Smrg util_pack_z_stencil(depth_tex->b.format, depth, stencil); 115af69d88dSmrg depth_clear_bbp = 32; 116af69d88dSmrg clear_stencil = packed_z_stencil >> 24; 1173464ebd5Sriastradh } 1183464ebd5Sriastradh 119af69d88dSmrg /* hw can't fastclear both depth and color if their bbp mismatch. */ 1207ec681f3Smrg if (color_clear_bbp && depth_clear_bbp && 1217ec681f3Smrg color_clear_bbp != depth_clear_bbp) { 122af69d88dSmrg if (i915->hardware_dirty) 123af69d88dSmrg i915_emit_hardware_state(i915); 1243464ebd5Sriastradh 1257ec681f3Smrg if (!BEGIN_BATCH(1 + 2 * (7 + 7))) { 126af69d88dSmrg FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); 1273464ebd5Sriastradh 128af69d88dSmrg i915_emit_hardware_state(i915); 129af69d88dSmrg i915->vbo_flushed = 1; 1303464ebd5Sriastradh 1317ec681f3Smrg assert(BEGIN_BATCH(1 + 2 * (7 + 7))); 132af69d88dSmrg } 1333464ebd5Sriastradh 134af69d88dSmrg OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); 135af69d88dSmrg 136af69d88dSmrg OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); 137af69d88dSmrg OUT_BATCH(CLEARPARAM_WRITE_COLOR | CLEARPARAM_CLEAR_RECT); 138af69d88dSmrg /* Used for zone init prim */ 139af69d88dSmrg OUT_BATCH(clear_color); 140af69d88dSmrg OUT_BATCH(clear_depth); 141af69d88dSmrg /* Used for clear rect prim */ 142af69d88dSmrg OUT_BATCH(clear_color8888); 143af69d88dSmrg OUT_BATCH_F(f_depth); 144af69d88dSmrg OUT_BATCH(clear_stencil); 145af69d88dSmrg 146af69d88dSmrg OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); 147af69d88dSmrg OUT_BATCH_F(destx + width); 148af69d88dSmrg OUT_BATCH_F(desty + height); 149af69d88dSmrg OUT_BATCH_F(destx); 150af69d88dSmrg OUT_BATCH_F(desty + height); 151af69d88dSmrg OUT_BATCH_F(destx); 152af69d88dSmrg OUT_BATCH_F(desty); 153af69d88dSmrg 154af69d88dSmrg OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); 155af69d88dSmrg OUT_BATCH((clear_params & ~CLEARPARAM_WRITE_COLOR) | 156af69d88dSmrg CLEARPARAM_CLEAR_RECT); 157af69d88dSmrg /* Used for zone init prim */ 158af69d88dSmrg OUT_BATCH(clear_color); 159af69d88dSmrg OUT_BATCH(clear_depth); 160af69d88dSmrg /* Used for clear rect prim */ 161af69d88dSmrg OUT_BATCH(clear_color8888); 162af69d88dSmrg OUT_BATCH_F(f_depth); 163af69d88dSmrg OUT_BATCH(clear_stencil); 164af69d88dSmrg 165af69d88dSmrg OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); 166af69d88dSmrg OUT_BATCH_F(destx + width); 167af69d88dSmrg OUT_BATCH_F(desty + height); 168af69d88dSmrg OUT_BATCH_F(destx); 169af69d88dSmrg OUT_BATCH_F(desty + height); 170af69d88dSmrg OUT_BATCH_F(destx); 171af69d88dSmrg OUT_BATCH_F(desty); 172af69d88dSmrg } else { 173af69d88dSmrg if (i915->hardware_dirty) 174af69d88dSmrg i915_emit_hardware_state(i915); 175af69d88dSmrg 176af69d88dSmrg if (!BEGIN_BATCH(1 + 7 + 7)) { 177af69d88dSmrg FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); 178af69d88dSmrg 179af69d88dSmrg i915_emit_hardware_state(i915); 180af69d88dSmrg i915->vbo_flushed = 1; 181af69d88dSmrg 182af69d88dSmrg assert(BEGIN_BATCH(1 + 7 + 7)); 183af69d88dSmrg } 184af69d88dSmrg 185af69d88dSmrg OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); 186af69d88dSmrg 187af69d88dSmrg OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); 188af69d88dSmrg OUT_BATCH(clear_params | CLEARPARAM_CLEAR_RECT); 189af69d88dSmrg /* Used for zone init prim */ 190af69d88dSmrg OUT_BATCH(clear_color); 191af69d88dSmrg OUT_BATCH(clear_depth); 192af69d88dSmrg /* Used for clear rect prim */ 193af69d88dSmrg OUT_BATCH(clear_color8888); 194af69d88dSmrg OUT_BATCH_F(f_depth); 195af69d88dSmrg OUT_BATCH(clear_stencil); 196af69d88dSmrg 197af69d88dSmrg OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); 198af69d88dSmrg OUT_BATCH_F(destx + width); 199af69d88dSmrg OUT_BATCH_F(desty + height); 200af69d88dSmrg OUT_BATCH_F(destx); 201af69d88dSmrg OUT_BATCH_F(desty + height); 202af69d88dSmrg OUT_BATCH_F(destx); 203af69d88dSmrg OUT_BATCH_F(desty); 204af69d88dSmrg } 2053464ebd5Sriastradh 2063464ebd5Sriastradh /* Flush after clear, its expected to be a costly operation. 207af69d88dSmrg * This is not required, just a heuristic, but without the flush we'd need to 208af69d88dSmrg * clobber the SCISSOR_ENABLE dynamic state. */ 209af69d88dSmrg FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); 210af69d88dSmrg 211af69d88dSmrg i915->last_fired_vertices = i915->fired_vertices; 212af69d88dSmrg i915->fired_vertices = 0; 2133464ebd5Sriastradh} 2144a49301eSmrg 2154a49301eSmrg/** 2164a49301eSmrg * Clear the given buffers to the specified values. 2174a49301eSmrg * No masking, no scissor (clear entire buffer). 2184a49301eSmrg */ 2194a49301eSmrgvoid 220af69d88dSmrgi915_clear_blitter(struct pipe_context *pipe, unsigned buffers, 2217ec681f3Smrg const struct pipe_scissor_state *scissor_state, 2227ec681f3Smrg const union pipe_color_union *color, double depth, 2237ec681f3Smrg unsigned stencil) 2244a49301eSmrg{ 22501e04c3fSmrg struct pipe_framebuffer_state *framebuffer = 22601e04c3fSmrg &i915_context(pipe)->framebuffer; 22701e04c3fSmrg unsigned i; 22801e04c3fSmrg 22901e04c3fSmrg for (i = 0; i < framebuffer->nr_cbufs; i++) { 23001e04c3fSmrg if (buffers & (PIPE_CLEAR_COLOR0 << i)) { 23101e04c3fSmrg struct pipe_surface *ps = framebuffer->cbufs[i]; 23201e04c3fSmrg 23301e04c3fSmrg if (ps) { 23401e04c3fSmrg pipe->clear_render_target(pipe, ps, color, 0, 0, ps->width, 23501e04c3fSmrg ps->height, true); 23601e04c3fSmrg } 23701e04c3fSmrg } 23801e04c3fSmrg } 23901e04c3fSmrg 24001e04c3fSmrg if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { 24101e04c3fSmrg struct pipe_surface *ps = framebuffer->zsbuf; 24201e04c3fSmrg pipe->clear_depth_stencil(pipe, ps, buffers & PIPE_CLEAR_DEPTHSTENCIL, 2437ec681f3Smrg depth, stencil, 0, 0, ps->width, ps->height, 2447ec681f3Smrg true); 24501e04c3fSmrg } 2464a49301eSmrg} 2473464ebd5Sriastradh 2483464ebd5Sriastradhvoid 249af69d88dSmrgi915_clear_render(struct pipe_context *pipe, unsigned buffers, 2507ec681f3Smrg const struct pipe_scissor_state *scissor_state, 2517ec681f3Smrg const union pipe_color_union *color, double depth, 2527ec681f3Smrg unsigned stencil) 2533464ebd5Sriastradh{ 2543464ebd5Sriastradh struct i915_context *i915 = i915_context(pipe); 2553464ebd5Sriastradh 2563464ebd5Sriastradh if (i915->dirty) 2573464ebd5Sriastradh i915_update_derived(i915); 2583464ebd5Sriastradh 2597ec681f3Smrg i915_clear_emit(pipe, buffers, color, depth, stencil, 0, 0, 2607ec681f3Smrg i915->framebuffer.width, i915->framebuffer.height); 2613464ebd5Sriastradh} 262