Commit 99238276 authored by Roland Scheidegger's avatar Roland Scheidegger

Merge branch 'gallium-newclear'

Conflicts:
	src/gallium/state_trackers/python/p_context.i
parents 05863c48 a6e5c6c0
......@@ -26,8 +26,8 @@
/**
* @file
* Blitter utility to facilitate acceleration of the clear, resource_copy_region,
* and resource_fill_region functions.
* Blitter utility to facilitate acceleration of the clear, clear_render_target, clear_depth_stencil
* resource_copy_region functions.
*
* @author Marek Olšák
*/
......@@ -88,6 +88,7 @@ struct blitter_context_priv
void *dsa_write_depth_stencil;
void *dsa_write_depth_keep_stencil;
void *dsa_keep_depth_stencil;
void *dsa_keep_depth_write_stencil;
void *velem_state;
......@@ -161,8 +162,12 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
dsa.stencil[0].writemask = 0xff;
ctx->dsa_write_depth_stencil =
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
/* The DSA state objects which write depth and stencil are created
* on-demand. */
dsa.depth.enabled = 0;
dsa.depth.writemask = 0;
ctx->dsa_keep_depth_write_stencil =
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
/* sampler state */
sampler_state = &ctx->template_sampler_state;
......@@ -234,6 +239,7 @@ void util_blitter_destroy(struct blitter_context *blitter)
pipe->delete_depth_stencil_alpha_state(pipe,
ctx->dsa_write_depth_keep_stencil);
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
pipe->delete_rasterizer_state(pipe, ctx->rs_state);
pipe->delete_vs_state(pipe, ctx->vs_col);
......@@ -596,11 +602,19 @@ void util_blitter_clear(struct blitter_context *blitter,
else
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
sr.ref_value[0] = stencil & 0xff;
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
pipe->set_stencil_ref(pipe, &sr);
}
else if (clear_buffers & PIPE_CLEAR_DEPTH) {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
}
else if (clear_buffers & PIPE_CLEAR_STENCIL) {
sr.ref_value[0] = stencil & 0xff;
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
pipe->set_stencil_ref(pipe, &sr);
}
else
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
......@@ -757,48 +771,21 @@ void util_blitter_copy_region(struct blitter_context *blitter,
pipe_surface_reference(&dstsurf, NULL);
}
/* Fill a region of a surface with a constant value. */
void util_blitter_fill_region(struct blitter_context *blitter,
struct pipe_resource *dst,
struct pipe_subresource subdst,
unsigned dstx, unsigned dsty, unsigned dstz,
unsigned width, unsigned height,
unsigned value)
/* Clear a region of a color surface to a constant value. */
void util_blitter_clear_render_target(struct blitter_context *blitter,
struct pipe_surface *dstsurf,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_surface *dstsurf;
struct pipe_framebuffer_state fb_state;
float rgba[4];
ubyte ub_rgba[4] = {0};
union util_color color;
int i;
assert(dst);
if (!dst)
assert(dstsurf->texture);
if (!dstsurf->texture)
return;
/* check if we can render to the surface */
if (util_format_is_depth_or_stencil(dst->format) || /* unlikely, but you never know */
!screen->is_format_supported(screen, dst->format, dst->target,
dst->nr_samples,
PIPE_BIND_RENDER_TARGET, 0)) {
util_resource_fill_region(pipe, dst, subdst, dstx, dsty, dstz,
width, height, value);
return;
}
dstsurf = screen->get_tex_surface(screen, dst, subdst.face, subdst.level,
dstz, PIPE_BIND_RENDER_TARGET);
/* unpack the color */
color.ui = value;
util_unpack_color_ub(dst->format, &color,
ub_rgba, ub_rgba+1, ub_rgba+2, ub_rgba+3);
for (i = 0; i < 4; i++)
rgba[i] = ubyte_to_float(ub_rgba[i]);
/* check the saved state */
blitter_check_saved_CSOs(ctx);
assert(blitter->saved_fb_state.nr_cbufs != ~0);
......@@ -823,6 +810,63 @@ void util_blitter_fill_region(struct blitter_context *blitter,
blitter_set_rectangle(ctx, 0, 0, width, height, dstsurf->width, dstsurf->height, 0);
blitter_draw_quad(ctx);
blitter_restore_CSOs(ctx);
}
pipe_surface_reference(&dstsurf, NULL);
/* Clear a region of a depth stencil surface. */
void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
struct pipe_surface *dstsurf,
unsigned clear_flags,
double depth,
unsigned stencil,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->pipe;
struct pipe_framebuffer_state fb_state;
struct pipe_stencil_ref sr = { { 0 } };
assert(dstsurf->texture);
if (!dstsurf->texture)
return;
/* check the saved state */
blitter_check_saved_CSOs(ctx);
assert(blitter->saved_fb_state.nr_cbufs != ~0);
/* bind CSOs */
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
sr.ref_value[0] = stencil & 0xff;
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
pipe->set_stencil_ref(pipe, &sr);
}
else if (clear_flags & PIPE_CLEAR_DEPTH) {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
}
else if (clear_flags & PIPE_CLEAR_STENCIL) {
sr.ref_value[0] = stencil & 0xff;
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
pipe->set_stencil_ref(pipe, &sr);
}
else
/* hmm that should be illegal probably, or make it a no-op somewhere */
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0));
pipe->bind_vs_state(pipe, ctx->vs_col);
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
/* set a framebuffer state */
fb_state.width = dstsurf->width;
fb_state.height = dstsurf->height;
fb_state.nr_cbufs = 0;
fb_state.cbufs[0] = 0;
fb_state.zsbuf = dstsurf;
pipe->set_framebuffer_state(pipe, &fb_state);
blitter_set_rectangle(ctx, 0, 0, width, height, dstsurf->width, dstsurf->height, depth);
blitter_draw_quad(ctx);
blitter_restore_CSOs(ctx);
}
......@@ -123,22 +123,33 @@ void util_blitter_copy_region(struct blitter_context *blitter,
boolean ignore_stencil);
/**
* Fill a region of a surface with a constant value.
*
* If the surface cannot be rendered to or it's a depth-stencil format,
* a software fallback path is taken.
* Clear a region of a (color) surface to a constant value.
*
* These states must be saved in the blitter in addition to the state objects
* already required to be saved:
* - framebuffer state
*/
void util_blitter_fill_region(struct blitter_context *blitter,
struct pipe_resource *dst,
struct pipe_subresource subdst,
unsigned dstx, unsigned dsty, unsigned dstz,
unsigned width, unsigned height,
unsigned value);
void util_blitter_clear_render_target(struct blitter_context *blitter,
struct pipe_surface *dst,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height);
/**
* Clear a region of a depth-stencil surface, both stencil and depth
* or only one of them if this is a combined depth-stencil surface.
*
* These states must be saved in the blitter in addition to the state objects
* already required to be saved:
* - framebuffer state
*/
void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
struct pipe_surface *dst,
unsigned clear_flags,
double depth,
unsigned stencil,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height);
/* The functions below should be used to save currently bound constant state
* objects inside a driver. The objects are automatically restored at the end
......
......@@ -31,9 +31,6 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "util/u_pack_color.h"
#include "util/u_rect.h"
#include "util/u_surface.h"
/**
......@@ -46,25 +43,17 @@ util_clear(struct pipe_context *pipe,
const float *rgba, double depth, unsigned stencil)
{
if (buffers & PIPE_CLEAR_COLOR) {
struct pipe_surface *ps = framebuffer->cbufs[0];
struct pipe_subresource subdst;
union util_color uc;
subdst.face = ps->face;
subdst.level = ps->level;
util_pack_color(rgba, ps->format, &uc);
pipe->resource_fill_region(pipe, ps->texture, subdst, 0, 0, ps->zslice,
ps->width, ps->height, uc.ui);
unsigned i;
for (i = 0; i < framebuffer->nr_cbufs; i++) {
struct pipe_surface *ps = framebuffer->cbufs[i];
pipe->clear_render_target(pipe, ps, rgba, 0, 0, ps->width, ps->height);
}
}
if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
struct pipe_surface *ps = framebuffer->zsbuf;
struct pipe_subresource subdst;
subdst.face = ps->face;
subdst.level = ps->level;
pipe->resource_fill_region(pipe, ps->texture, subdst, 0, 0, ps->zslice,
ps->width, ps->height,
util_pack_z_stencil(ps->format, depth, stencil));
pipe->clear_depth_stencil(pipe, ps, buffers & PIPE_CLEAR_DEPTHSTENCIL,
depth, stencil,
0, 0, ps->width, ps->height);
}
}
......@@ -40,6 +40,7 @@
#include "util/u_inlines.h"
#include "util/u_rect.h"
#include "util/u_surface.h"
#include "util/u_pack_color.h"
/**
......@@ -195,26 +196,33 @@ util_resource_copy_region(struct pipe_context *pipe,
/**
* Fallback for pipe->resource_fill_region() function.
* Fallback for pipe->clear_render_target() function.
* XXX this looks too hackish to be really useful.
* cpp > 4 looks like a gross hack at best...
* and we're missing the equivalent clear_depth_stencil fallback.
* Plus can't use these transfer fallbacks when clearing
* multisampled surfaces for instance.
*/
void
util_resource_fill_region(struct pipe_context *pipe,
struct pipe_resource *dst,
struct pipe_subresource subdst,
unsigned dstx, unsigned dsty, unsigned dstz,
unsigned width, unsigned height, unsigned value)
util_clear_render_target(struct pipe_context *pipe,
struct pipe_surface *dst,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
struct pipe_transfer *dst_trans;
void *dst_map;
union util_color uc;
assert(dst);
if (!dst)
assert(dst->texture);
if (!dst->texture)
return;
util_pack_color(rgba, dst->texture->format, &uc);
dst_trans = pipe_get_transfer(pipe,
dst,
subdst.face,
subdst.level,
dstz,
dst->texture,
dst->face,
dst->level,
dst->zslice,
PIPE_TRANSFER_WRITE,
dstx, dsty, width, height);
......@@ -225,22 +233,26 @@ util_resource_fill_region(struct pipe_context *pipe,
if (dst_map) {
assert(dst_trans->stride > 0);
switch (util_format_get_blocksize(dst->format)) {
switch (util_format_get_blocksize(dst->texture->format)) {
case 1:
case 2:
case 4:
util_fill_rect(dst_map, dst->format,
dst_trans->stride,
0, 0, width, height, value);
util_pack_color(rgba, dst->texture->format, &uc);
util_fill_rect(dst_map, dst->texture->format,
dst_trans->stride,
0, 0, width, height, uc.ui);
break;
case 8:
{
/* expand the 4-byte clear value to an 8-byte value */
/* should probably not convert back from ubyte but not
sure what this code really achieved since it doesn't even
check for format type... */
ushort *row = (ushort *) dst_map;
ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff);
ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff);
ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
ushort val0 = UBYTE_TO_USHORT((uc.ui >> 0) & 0xff);
ushort val1 = UBYTE_TO_USHORT((uc.ui >> 8) & 0xff);
ushort val2 = UBYTE_TO_USHORT((uc.ui >> 16) & 0xff);
ushort val3 = UBYTE_TO_USHORT((uc.ui >> 24) & 0xff);
unsigned i, j;
val0 = (val0 << 8) | val0;
val1 = (val1 << 8) | val1;
......
......@@ -57,11 +57,11 @@ util_resource_copy_region(struct pipe_context *pipe,
unsigned w, unsigned h);
extern void
util_resource_fill_region(struct pipe_context *pipe,
struct pipe_resource *dst,
struct pipe_subresource subdst,
unsigned dstx, unsigned dsty, unsigned dstz,
unsigned width, unsigned height, unsigned value);
util_clear_render_target(struct pipe_context *pipe,
struct pipe_surface *dst,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height);
......
......@@ -79,7 +79,7 @@ set_clip_state
set_polygon_stipple
+ Gallium supports polygon stipple
resource_fill_region
clearRT/clearDS
+ Gallium supports subrectangle fills of surfaces, D3D10 only supports full clears of views
* DirectX 10/11 DDI functions and Gallium equivalents
......
......@@ -102,14 +102,29 @@ the LOD range the texture is going to be constrained to.
Clearing
^^^^^^^^
Clear is one of the most difficult concepts to nail down to a single
interface (due to both different requirements from APIs and also driver/hw
specific differences).
``clear`` initializes some or all of the surfaces currently bound to
the framebuffer to particular RGBA, depth, or stencil values.
Currently, this does not take into account color or stencil write masks (as
used by GL), and always clears the whole surfaces (no scissoring as used by
GL clear or explicit rectangles like d3d9 uses). It can, however, also clear
only depth or stencil in a combined depth/stencil surface, if the driver
supports PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE.
If a surface includes several layers/slices (XXX: not yet...) then all layers
will be cleared.
Clear is one of the most difficult concepts to nail down to a single
interface and it seems likely that we will want to add additional
clear paths, for instance clearing surfaces not bound to the
framebuffer, or read-modify-write clears such as depth-only or
stencil-only clears of packed depth-stencil buffers.
``clear_render_target`` clears a single color rendertarget with the specified
color value. While it is only possible to clear one surface at a time (which can
include several layers), this surface need not be bound to the framebuffer.
``clear_depth_stencil``clears a single depth, stencil or depth/stencil surface
with the specified depth and stencil values (for combined depth/stencil buffers,
is is also possible to only clear one or the other part). While it is only
possible to clear one surface at a time (which can include several layers),
this surface need not be bound to the framebuffer.
Drawing
......@@ -266,8 +281,6 @@ These methods operate directly on ``pipe_resource`` objects, and stand
apart from any 3D state in the context. Blitting functionality may be
moved to a separate abstraction at some point in the future.
``resource_fill_region`` performs a fill operation on a section of a resource.
``resource_copy_region`` blits a region of a subresource of a resource to a
region of another subresource of a resource, provided that both resources have the
same format. The source and destination may be the same resource, but overlapping
......
......@@ -34,5 +34,4 @@ void
cell_init_surface_functions(struct cell_context *cell)
{
cell->pipe.resource_copy_region = util_resource_copy_region;
cell->pipe.resource_fill_region = util_resource_fill_region;
}
......@@ -146,6 +146,8 @@ struct pipe_context *failover_create( struct pipe_context *hw,
failover->pipe.draw_arrays = failover_draw_arrays;
failover->pipe.draw_elements = failover_draw_elements;
failover->pipe.clear = hw->clear;
failover->pipe.clear_render_target = hw->clear_render_target;
failover->pipe.clear_depth_stencil = hw->clear_depth_stencil;
/* No software occlusion fallback (or other optional functionality)
* at this point - if the hardware doesn't support it, don't
......@@ -157,7 +159,6 @@ struct pipe_context *failover_create( struct pipe_context *hw,
failover_init_state_functions( failover );
failover->pipe.resource_copy_region = hw->resource_copy_region;
failover->pipe.resource_fill_region = hw->resource_fill_region;
#if 0
failover->pipe.texture_create = hw->texture_create;
......
......@@ -36,6 +36,7 @@
void
i915_fill_blit(struct i915_context *i915,
unsigned cpp,
unsigned rgba_mask,
unsigned short dst_pitch,
struct i915_winsys_buffer *dst_buffer,
unsigned dst_offset,
......@@ -62,8 +63,7 @@ i915_fill_blit(struct i915_context *i915,
case 4:
BR13 = (((int) dst_pitch) & 0xffff) |
(0xF0 << 16) | (1 << 24) | (1 << 25);
CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB);
CMD = (XY_COLOR_BLT_CMD | rgba_mask);
break;
default:
return;
......
......@@ -44,6 +44,7 @@ extern void i915_copy_blit(struct i915_context *i915,
extern void i915_fill_blit(struct i915_context *i915,
unsigned cpp,
unsigned rgba_mask,
unsigned short dst_pitch,
struct i915_winsys_buffer *dst_buffer,
unsigned dst_offset,
......
......@@ -40,7 +40,7 @@
*/
void
i915_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
double depth, unsigned stencil)
double depth, unsigned stencil)
{
util_clear(pipe, &i915_context(pipe)->framebuffer, buffers, rgba, depth,
stencil);
......
......@@ -129,6 +129,9 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
/* disable for now */
return 0;
default:
return 0;
}
......@@ -181,6 +184,9 @@ i915_is_format_supported(struct pipe_screen *screen,
PIPE_FORMAT_L8A8_UNORM,
PIPE_FORMAT_UYVY,
PIPE_FORMAT_YUYV,
/* XXX why not?
PIPE_FORMAT_Z16_UNORM, */
PIPE_FORMAT_Z24X8_UNORM,
PIPE_FORMAT_Z24_UNORM_S8_USCALED,
PIPE_FORMAT_NONE /* list terminator */
};
......@@ -190,6 +196,9 @@ i915_is_format_supported(struct pipe_screen *screen,
PIPE_FORMAT_NONE /* list terminator */
};
static const enum pipe_format depth_supported[] = {
/* XXX why not?
PIPE_FORMAT_Z16_UNORM, */
PIPE_FORMAT_Z24X8_UNORM,
PIPE_FORMAT_Z24_UNORM_S8_USCALED,
PIPE_FORMAT_NONE /* list terminator */
};
......
......@@ -51,6 +51,7 @@ static unsigned translate_format( enum pipe_format format )
static unsigned translate_depth_format( enum pipe_format zformat )
{
switch (zformat) {
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
return DEPTH_FRMT_24_FIXED_8_OTHER;
case PIPE_FORMAT_Z16_UNORM:
......
......@@ -222,6 +222,7 @@ translate_texture_format(enum pipe_format pipeFormat)
return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
#endif
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
case PIPE_FORMAT_Z24X8_UNORM:
return (MAPSURF_32BIT | MT_32BIT_xI824);
default:
debug_printf("i915: translate_texture_format() bad image format %x\n",
......
......@@ -28,12 +28,14 @@
#include "i915_surface.h"
#include "i915_resource.h"
#include "i915_blit.h"
#include "i915_reg.h"
#include "i915_screen.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_pack_color.h"
/* Assumes all values are within bounds -- no checking at this level -
......@@ -41,11 +43,11 @@
*/
static void
i915_surface_copy(struct pipe_context *pipe,
struct pipe_resource *dst, struct pipe_subresource subdst,
unsigned dstx, unsigned dsty, unsigned dstz,
struct pipe_resource *src, struct pipe_subresource subsrc,
unsigned srcx, unsigned srcy, unsigned srcz,
unsigned width, unsigned height)
struct pipe_resource *dst, struct pipe_subresource subdst,
unsigned dstx, unsigned dsty, unsigned dstz,
struct pipe_resource *src, struct pipe_subresource subsrc,
unsigned srcx, unsigned srcy, unsigned srcz,
unsigned width, unsigned height)
{
struct i915_texture *dst_tex = i915_texture(dst);
struct i915_texture *src_tex = i915_texture(src);
......@@ -93,39 +95,67 @@ i915_surface_copy(struct pipe_context *pipe,
static void
i915_surface_fill(struct pipe_context *pipe,
struct pipe_resource *dst, struct pipe_subresource subdst,
unsigned dstx, unsigned dsty, unsigned dstz,
unsigned width, unsigned height, unsigned value)
i915_clear_render_target(struct pipe_context *pipe,
struct pipe_surface *dst,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
struct i915_texture *tex = i915_texture(dst);
struct i915_texture *tex = i915_texture(dst->texture);
struct pipe_resource *pt = &tex->b.b;
unsigned dst_offset; /* in bytes */
if (dst->target == PIPE_TEXTURE_CUBE) {
dst_offset = tex->image_offset[subdst.level][subdst.face];
}
else if (dst->target == PIPE_TEXTURE_3D) {
dst_offset = tex->image_offset[subdst.level][dstz];
}
else {
dst_offset = tex->image_offset[subdst.level][0];
assert(subdst.face == 0);
assert(dstz == 0);
}
union util_color uc;
assert(util_format_get_blockwidth(pt->format) == 1);
assert(util_format_get_blockheight(pt->format) == 1);
util_pack_color(rgba, dst->format, &uc);
i915_fill_blit( i915_context(pipe),
util_format_get_blocksize(pt->format),
XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB,
(unsigned short) tex->stride,
tex->buffer, dst_offset,
tex->buffer, dst->offset,
(short) dstx, (short) dsty,
(short) width, (short) height,
value );
uc.ui );
}
static void
i915_clear_depth_stencil(struct pipe_context *pipe,
struct pipe_surface *dst,
unsigned clear_flags,
double depth,
unsigned stencil,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
struct i915_texture *tex = i915_texture(dst->texture);
struct pipe_resource *pt = &tex->b.b;
unsigned packedds;
unsigned mask = 0;
assert(util_format_get_blockwidth(pt->format) == 1);
assert(util_format_get_blockheight(pt->format) == 1);
packedds = util_pack_z_stencil(dst->format, depth, stencil);
if (clear_flags & PIPE_CLEAR_DEPTH)
mask |= XY_COLOR_BLT_WRITE_RGB;
/* XXX presumably this does read-modify-write
(otherwise this won't work anyway). Hence will only want to
do it if really have stencil and it isn't cleared */
if (!((clear_flags & PIPE_CLEAR_STENCIL) ||
(dst->format != PIPE_FORMAT_Z24_UNORM_S8_USCALED)))
mask |= XY_COLOR_BLT_WRITE_ALPHA;
i915_fill_blit( i915_context(pipe),
util_format_get_blocksize(pt->format),
mask,
(unsigned short) tex->stride,
tex->buffer, dst->offset,
(short) dstx, (short) dsty,
(short) width, (short) height,
packedds );
}
/*
* Screen surface functions
......@@ -179,7 +209,8 @@ void
i915_init_surface_functions(struct i915_context *i915)
{
i915->base.resource_copy_region = i915_surface_copy;
i915->base.resource_fill_region = i915_surface_fill;
i915->base.clear_render_target = i915_clear_render_target;
i915->base.clear_depth_stencil = i915_clear_depth_stencil;
}
/* No good reason for these to be in the screen.
......
......@@ -26,6 +26,7 @@
**************************************************************************/
#include "util/u_pack_color.h"
#include "util/u_math.h"
#include "pipe/p_state.h"
......@@ -42,12 +43,12 @@
* Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferIndexes field
* since that might include software renderbuffers or renderbuffers
* which we're clearing with triangles.
* \param mask bitmask of BUFFER_BIT_* values indicating buffers to clear
*/
static enum pipe_error
try_clear( struct brw_context *brw,
struct brw_surface *surface,
unsigned value )
unsigned value,
unsigned rgba_mask)
{
uint32_t BR13, CMD;
int x1 = 0;
......@@ -67,12 +68,11 @@ try_clear( struct brw_context *brw,
x1, y1, x2 - x1, y2 - y1);
BR13 = 0xf0 << 16;
CMD = XY_COLOR_BLT_CMD | XY_BLT_WRITE_RGB | XY_BLT_WRITE_ALPHA;
CMD = XY_COLOR_BLT_CMD | rgba_mask;
/* Setup the blit command */
if (cpp == 4) {
BR13