Merge branch 'gallium-newclear'

Conflicts:
	src/gallium/state_trackers/python/p_context.i
This commit is contained in:
Roland Scheidegger 2010-06-03 17:46:14 +02:00
commit 992382762a
47 changed files with 773 additions and 346 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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 */
};

View File

@ -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:

View File

@ -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",

View File

@ -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.

View File

@ -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 |= BR13_8888;
CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
}
else {
assert(cpp == 2);
@ -121,24 +121,36 @@ static void color_clear(struct brw_context *brw,
if (bsurface->cpp == 2)
value.ui |= value.ui << 16;
ret = try_clear( brw, bsurface, value.ui );
ret = try_clear( brw, bsurface, value.ui,
XY_BLT_WRITE_RGB | XY_BLT_WRITE_ALPHA );
if (ret != 0) {
brw_context_flush( brw );
ret = try_clear( brw, bsurface, value.ui );
ret = try_clear( brw, bsurface, value.ui,
XY_BLT_WRITE_RGB | XY_BLT_WRITE_ALPHA );
assert( ret == 0 );
}
}
static void zstencil_clear(struct brw_context *brw,
static void zstencil_clear(struct brw_context *brw,
struct brw_surface *bsurface,
unsigned clear_flags,
double depth,
unsigned stencil )
{
enum pipe_error ret;
unsigned value;
unsigned mask = 0;
union fi tmp;
if (clear_flags & PIPE_CLEAR_DEPTH)
mask |= XY_BLT_WRITE_RGB;
switch (bsurface->base.format) {
case PIPE_FORMAT_Z32_FLOAT:
tmp.f = (float)depth;
value = tmp.ui;
break;
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
value = ((unsigned)(depth * MASK24) & MASK24);
@ -152,24 +164,31 @@ static void zstencil_clear(struct brw_context *brw,
}
switch (bsurface->base.format) {
case PIPE_FORMAT_Z32_FLOAT:
mask |= XY_BLT_WRITE_ALPHA;
break;
case PIPE_FORMAT_Z24X8_UNORM:
value = value | (stencil << 24);
mask |= XY_BLT_WRITE_ALPHA;
break;
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
value = value | (stencil << 24);
if (clear_flags & PIPE_CLEAR_STENCIL)
mask |= XY_BLT_WRITE_ALPHA;
break;
case PIPE_FORMAT_Z16_UNORM:
value = value | (value << 16);
mask |= XY_BLT_WRITE_ALPHA;
break;
default:
break;
}
ret = try_clear( brw, bsurface, value );
ret = try_clear( brw, bsurface, value, mask );
if (ret != 0) {
brw_context_flush( brw );
ret = try_clear( brw, bsurface, value );
ret = try_clear( brw, bsurface, value, mask );
assert( ret == 0 );
}
}
@ -201,15 +220,48 @@ static void brw_clear(struct pipe_context *pipe,
if (brw->curr.fb.zsbuf) {
zstencil_clear( brw,
brw_surface(brw->curr.fb.zsbuf),
buffers & PIPE_CLEAR_DEPTHSTENCIL,
depth, stencil );
}
}
}
/* XXX should respect region */
static void brw_clear_render_target(struct pipe_context *pipe,
struct pipe_surface *dst,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
struct brw_context *brw = brw_context( pipe );
color_clear( brw,
brw_surface(dst),
rgba );
}
/* XXX should respect region */
static void brw_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 brw_context *brw = brw_context( pipe );
zstencil_clear( brw,
brw_surface(dst),
clear_flags,
depth, stencil );
}
void brw_pipe_clear_init( struct brw_context *brw )
{
brw->base.clear = brw_clear;
brw->base.clear_render_target = brw_clear_render_target;
brw->base.clear_depth_stencil = brw_clear_depth_stencil;
}

View File

@ -39,7 +39,6 @@ brw_init_resource_functions(struct brw_context *brw )
brw->base.transfer_destroy = u_transfer_destroy_vtbl;
brw->base.transfer_inline_write = u_transfer_inline_write_vtbl;
brw->base.resource_copy_region = util_resource_copy_region;
brw->base.resource_fill_region = util_resource_fill_region;
}
void

View File

@ -188,6 +188,9 @@ brw_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;
}

View File

@ -648,33 +648,6 @@ identity_resource_copy_region(struct pipe_context *_pipe,
height);
}
static void
identity_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)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct identity_resource *id_resource_dst = identity_resource(_dst);
struct pipe_context *pipe = id_pipe->pipe;
struct pipe_resource *dst = id_resource_dst->resource;
pipe->resource_fill_region(pipe,
dst,
subdst,
dstx,
dsty,
dstz,
width,
height,
value);
}
static void
identity_clear(struct pipe_context *_pipe,
unsigned buffers,
@ -692,6 +665,52 @@ identity_clear(struct pipe_context *_pipe,
stencil);
}
static void
identity_clear_render_target(struct pipe_context *_pipe,
struct pipe_surface *_dst,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct identity_surface *id_surface_dst = identity_surface(_dst);
struct pipe_context *pipe = id_pipe->pipe;
struct pipe_surface *dst = id_surface_dst->surface;
pipe->clear_render_target(pipe,
dst,
rgba,
dstx,
dsty,
width,
height);
}
static void
identity_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 identity_context *id_pipe = identity_context(_pipe);
struct identity_surface *id_surface_dst = identity_surface(_dst);
struct pipe_context *pipe = id_pipe->pipe;
struct pipe_surface *dst = id_surface_dst->surface;
pipe->clear_depth_stencil(pipe,
dst,
clear_flags,
depth,
stencil,
dstx,
dsty,
width,
height);
}
static void
identity_flush(struct pipe_context *_pipe,
unsigned flags,
@ -913,8 +932,9 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views;
id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;
id_pipe->base.resource_copy_region = identity_resource_copy_region;
id_pipe->base.resource_fill_region = identity_resource_fill_region;
id_pipe->base.clear = identity_clear;
id_pipe->base.clear_render_target = identity_clear_render_target;
id_pipe->base.clear_depth_stencil = identity_clear_depth_stencil;
id_pipe->base.flush = identity_flush;
id_pipe->base.is_resource_referenced = identity_is_resource_referenced;
id_pipe->base.create_sampler_view = identity_context_create_sampler_view;

View File

@ -172,7 +172,7 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
if (zsbuf) {
struct llvmpipe_resource *lpt = llvmpipe_resource(zsbuf->texture);
if (scene->has_depth_clear)
if (scene->has_depthstencil_clear)
usage = LP_TEX_USAGE_WRITE_ALL;
else
usage = LP_TEX_USAGE_READ_WRITE;
@ -264,6 +264,9 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
const union lp_rast_cmd_arg arg)
{
struct lp_rasterizer *rast = task->rast;
const struct lp_rast_clearzs *clearzs = arg.clear_zstencil;
unsigned clear_value = clearzs->clearzs_value;
unsigned clear_mask = clearzs->clearzs_mask;
const unsigned height = TILE_SIZE / TILE_VECTOR_HEIGHT;
const unsigned width = TILE_SIZE * TILE_VECTOR_HEIGHT;
const unsigned block_size = rast->zsbuf.blocksize;
@ -271,7 +274,7 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
uint8_t *dst;
unsigned i, j;
LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil);
LP_DBG(DEBUG_RAST, "%s 0x%x%x\n", __FUNCTION__, clear_value, clear_mask);
/*
* Clear the aera of the swizzled depth/depth buffer matching this tile, in
@ -287,22 +290,34 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
switch (block_size) {
case 1:
memset(dst, (uint8_t) arg.clear_zstencil, height * width);
memset(dst, (uint8_t) clear_value, height * width);
break;
case 2:
for (i = 0; i < height; i++) {
uint16_t *row = (uint16_t *)dst;
for (j = 0; j < width; j++)
*row++ = (uint16_t) arg.clear_zstencil;
*row++ = (uint16_t) clear_value;
dst += dst_stride;
}
break;
case 4:
for (i = 0; i < height; i++) {
uint32_t *row = (uint32_t *)dst;
for (j = 0; j < width; j++)
*row++ = arg.clear_zstencil;
dst += dst_stride;
if (clear_mask == 0xffffffff) {
for (i = 0; i < height; i++) {
uint32_t *row = (uint32_t *)dst;
for (j = 0; j < width; j++)
*row++ = clear_value;
dst += dst_stride;
}
}
else {
for (i = 0; i < height; i++) {
uint32_t *row = (uint32_t *)dst;
for (j = 0; j < width; j++) {
uint32_t tmp = ~clear_mask & *row;
*row++ = (clear_value & clear_mask) | tmp;
}
dst += dst_stride;
}
}
break;
default:

View File

@ -88,6 +88,11 @@ struct lp_rast_shader_inputs {
PIPE_ALIGN_VAR(16) int step[3][16];
};
struct lp_rast_clearzs {
unsigned clearzs_value;
unsigned clearzs_mask;
};
/**
* Rasterization information for a triangle known to be in this bin,
@ -151,7 +156,7 @@ union lp_rast_cmd_arg {
const struct lp_rast_triangle *triangle;
const struct lp_rast_state *set_state;
uint8_t clear_color[4];
unsigned clear_zstencil;
const struct lp_rast_clearzs *clear_zstencil;
struct lp_fence *fence;
struct llvmpipe_query *query_obj;
};
@ -192,6 +197,14 @@ lp_rast_arg_fence( struct lp_fence *fence )
}
static INLINE union lp_rast_cmd_arg
lp_rast_arg_clearzs( const struct lp_rast_clearzs *clearzs )
{
union lp_rast_cmd_arg arg;
arg.clear_zstencil = clearzs;
return arg;
}
static INLINE union lp_rast_cmd_arg
lp_rast_arg_null( void )
{
@ -201,7 +214,6 @@ lp_rast_arg_null( void )
}
/**
* Binnable Commands.
* These get put into bins by the setup code and are called when

View File

@ -201,7 +201,7 @@ lp_scene_reset(struct lp_scene *scene )
scene->scene_size = 0;
scene->has_color_clear = FALSE;
scene->has_depth_clear = FALSE;
scene->has_depthstencil_clear = FALSE;
}

View File

@ -125,7 +125,7 @@ struct lp_scene {
unsigned scene_size;
boolean has_color_clear;
boolean has_depth_clear;
boolean has_depthstencil_clear;
/**
* Number of active tiles in each dimension.

View File

@ -162,6 +162,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_MAX_VS_PREDS:
case PIPE_CAP_MAX_FS_PREDS:
return LP_MAX_TGSI_PREDS;
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
return 1;
default:
assert(0);
return 0;

View File

@ -143,6 +143,7 @@ static void reset_context( struct lp_setup_context *setup )
/* Reset some state:
*/
setup->clear.flags = 0;
setup->clear.clearzs.clearzs_mask = 0;
/* Have an explicit "start-binning" call and get rid of this
* pointer twiddling?
@ -172,10 +173,15 @@ static void
begin_binning( struct lp_setup_context *setup )
{
struct lp_scene *scene = lp_setup_get_current_scene(setup);
boolean need_zsload = FALSE;
if (setup->fb.zsbuf &&
((setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
util_format_is_depth_and_stencil(setup->fb.zsbuf->format))
need_zsload = TRUE;
LP_DBG(DEBUG_SETUP, "%s color: %s depth: %s\n", __FUNCTION__,
(setup->clear.flags & PIPE_CLEAR_COLOR) ? "clear": "load",
(setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) ? "clear": "load");
need_zsload ? "clear": "load");
if (setup->fb.nr_cbufs) {
if (setup->clear.flags & PIPE_CLEAR_COLOR) {
@ -188,10 +194,11 @@ begin_binning( struct lp_setup_context *setup )
if (setup->fb.zsbuf) {
if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) {
lp_scene_bin_everywhere( scene,
lp_rast_clear_zstencil,
setup->clear.zstencil );
scene->has_depth_clear = TRUE;
if (!need_zsload)
scene->has_depthstencil_clear = TRUE;
lp_scene_bin_everywhere( scene,
lp_rast_clear_zstencil,
lp_rast_arg_clearzs(&setup->clear.clearzs) );
}
}
@ -306,6 +313,8 @@ lp_setup_clear( struct lp_setup_context *setup,
{
struct lp_scene *scene = lp_setup_get_current_scene(setup);
unsigned i;
boolean full_zs_clear = TRUE;
uint32_t mask = 0;
LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state);
@ -316,10 +325,53 @@ lp_setup_clear( struct lp_setup_context *setup,
}
if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
setup->clear.zstencil.clear_zstencil =
util_pack_z_stencil(setup->fb.zsbuf->format,
depth,
stencil);
if (setup->fb.zsbuf &&
((setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
util_format_is_depth_and_stencil(setup->fb.zsbuf->format))
full_zs_clear = FALSE;
if (full_zs_clear) {
setup->clear.clearzs.clearzs_value =
util_pack_z_stencil(setup->fb.zsbuf->format,
depth,
stencil);
setup->clear.clearzs.clearzs_mask = 0xffffffff;
}
else {
/* hmm */
uint32_t tmpval;
if (flags & PIPE_CLEAR_DEPTH) {
tmpval = util_pack_z(setup->fb.zsbuf->format,
depth);
switch (setup->fb.zsbuf->format) {
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
mask = 0xffffff;
break;
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
mask = 0xffffff00;
break;
default:
assert(0);
}
}
else {
switch (setup->fb.zsbuf->format) {
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
mask = 0xff000000;
tmpval = stencil << 24;
break;
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
mask = 0xff;
tmpval = stencil;
break;
default:
assert(0);
}
}
setup->clear.clearzs.clearzs_mask |= mask;
setup->clear.clearzs.clearzs_value =
(setup->clear.clearzs.clearzs_value & ~mask) | (tmpval & mask);
}
}
if (setup->state == SETUP_ACTIVE) {
@ -336,11 +388,16 @@ lp_setup_clear( struct lp_setup_context *setup,
scene->has_color_clear = TRUE;
}
if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) {
lp_scene_bin_everywhere( scene,
if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
if (full_zs_clear)
scene->has_depthstencil_clear = TRUE;
else
setup->clear.clearzs.clearzs_mask = mask;
lp_scene_bin_everywhere( scene,
lp_rast_clear_zstencil,
setup->clear.zstencil );
scene->has_depth_clear = TRUE;
lp_rast_arg_clearzs(&setup->clear.clearzs) );
}
}

View File

@ -97,7 +97,7 @@ struct lp_setup_context
struct {
unsigned flags;
union lp_rast_cmd_arg color; /**< lp_rast_clear_color() cmd */
union lp_rast_cmd_arg zstencil; /**< lp_rast_clear_zstencil() cmd */
struct lp_rast_clearzs clearzs; /**< lp_rast_clear_zstencil() cmd */
} clear;
enum setup_state {

View File

@ -153,5 +153,4 @@ void
llvmpipe_init_surface_functions(struct llvmpipe_context *lp)
{
lp->pipe.resource_copy_region = lp_resource_copy;
lp->pipe.resource_fill_region = util_resource_fill_region;
}

View File

@ -51,13 +51,15 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
mode |= 0x3c;
}
if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
if (buffers & PIPE_CLEAR_DEPTH) {
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_DEPTH, 1);
OUT_RING (chan, fui(depth));
mode |= NV50TCL_CLEAR_BUFFERS_Z;
}
if (buffers & PIPE_CLEAR_STENCIL) {
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_STENCIL, 1);
OUT_RING (chan, stencil & 0xff);
mode |= 0x03;
mode |= NV50TCL_CLEAR_BUFFERS_S;
}
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);

View File

@ -150,6 +150,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 1;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 0;
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
return 1;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;

View File

@ -27,6 +27,7 @@
#include "nv50_resource.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "util/u_pack_color.h"
#include "util/u_tile.h"
#include "util/u_format.h"
@ -221,50 +222,49 @@ nv50_surface_copy(struct pipe_context *pipe,
nv50_miptree_surface_del(ps_dst);
}
/* XXX this should probably look more along the lines of nv50_clear */
static void
nv50_surface_fill(struct pipe_context *pipe, struct pipe_resource *dest,
struct pipe_subresource subdst,
unsigned destx, unsigned desty, unsigned destz,
unsigned width, unsigned height, unsigned value)
nv50_clear_render_target(struct pipe_context *pipe,
struct pipe_surface *dst,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
struct nv50_context *nv50 = nv50_context(pipe);
struct pipe_surface *ps;
struct nv50_screen *screen = nv50->screen;
struct nouveau_channel *chan = screen->eng2d->channel;
struct nouveau_grobj *eng2d = screen->eng2d;
int format, ret;
union util_color uc;
util_pack_color(rgba, dst->format, &uc);
format = nv50_format(dest->format);
format = nv50_format(dst->format);
if (format < 0)
return;
ps = nv50_miptree_surface_new(pipe->screen, dest, subdst.face,
subdst.level, destz, 0 /* bind flags */);
WAIT_RING (chan, 32);
ret = nv50_surface_set(screen, ps, 1);
ret = nv50_surface_set(screen, dst, 1);
if (ret)
return;
BEGIN_RING(chan, eng2d, NV50_2D_DRAW_SHAPE, 3);
OUT_RING (chan, NV50_2D_DRAW_SHAPE_RECTANGLES);
OUT_RING (chan, format);
OUT_RING (chan, value);
OUT_RING (chan, uc.ui);
BEGIN_RING(chan, eng2d, NV50_2D_DRAW_POINT32_X(0), 4);
OUT_RING (chan, destx);
OUT_RING (chan, desty);
OUT_RING (chan, dstx);
OUT_RING (chan, dsty);
OUT_RING (chan, width);
OUT_RING (chan, height);
nv50_miptree_surface_del(ps);
}
void
nv50_init_surface_functions(struct nv50_context *nv50)
{
nv50->pipe.resource_copy_region = nv50_surface_copy;
nv50->pipe.resource_fill_region = nv50_surface_fill;
nv50->pipe.clear_render_target = nv50_clear_render_target;
}

View File

@ -80,6 +80,8 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 0;
case PIPE_CAP_INDEP_BLEND_FUNC:
return 0;
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
return 0;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;

View File

@ -30,6 +30,7 @@
#include "nvfx_resource.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "util/u_pack_color.h"
static void
nvfx_surface_copy(struct pipe_context *pipe,
@ -55,26 +56,41 @@ nvfx_surface_copy(struct pipe_context *pipe,
}
static void
nvfx_surface_fill(struct pipe_context *pipe, struct pipe_resource *dest,
struct pipe_subresource subdst,
unsigned destx, unsigned desty, unsigned destz,
unsigned width, unsigned height, unsigned value)
nvfx_clear_render_target(struct pipe_context *pipe,
struct pipe_surface *dst,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
struct nv04_surface_2d *eng2d = nvfx->screen->eng2d;
union util_color uc;
util_pack_color(rgba, dst->format, &uc);
eng2d->fill(eng2d, dst, dstx, dsty, width, height, uc.ui);
}
static void
nvfx_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 nvfx_context *nvfx = nvfx_context(pipe);
struct pipe_surface *ps;
struct nv04_surface_2d *eng2d = nvfx->screen->eng2d;
ps = nvfx_miptree_surface_new(pipe->screen, dest, subdst.face,
subdst.level, destz, 0 /* bind flags */);
eng2d->fill(eng2d, ps, destx, desty, width, height, value);
nvfx_miptree_surface_del(ps);
eng2d->fill(eng2d, dst, dstx, dsty, width, height,
util_pack_z_stencil(dst->format, depth, stencil));
}
void
nvfx_init_surface_functions(struct nvfx_context *nvfx)
{
nvfx->pipe.resource_copy_region = nvfx_surface_copy;
nvfx->pipe.resource_fill_region = nvfx_surface_fill;
nvfx->pipe.clear_render_target = nvfx_clear_render_target;
nvfx->pipe.clear_depth_stencil = nvfx_clear_depth_stencil;
}

View File

@ -188,26 +188,44 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
}
}
/* Fill a region of a surface with a constant value. */
static void r300_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)
/* Clear a region of a color surface to a constant value. */
static void r300_clear_render_target(struct pipe_context *pipe,
struct pipe_surface *dst,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
struct r300_context *r300 = r300_context(pipe);
r300_blitter_save_states(r300);
util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
util_blitter_fill_region(r300->blitter, dst, subdst,
dstx, dsty, dstz, width, height, value);
util_blitter_clear_render_target(r300->blitter, dst, rgba,
dstx, dsty, width, height);
}
/* Clear a region of a depth stencil surface. */
static void r300_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 r300_context *r300 = r300_context(pipe);
r300_blitter_save_states(r300);
util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
util_blitter_clear_depth_stencil(r300->blitter, dst, clear_flags, depth, stencil,
dstx, dsty, width, height);
}
void r300_init_blit_functions(struct r300_context *r300)
{
r300->context.clear = r300_clear;
r300->context.clear_render_target = r300_clear_render_target;
r300->context.clear_depth_stencil = r300_clear_depth_stencil;
r300->context.resource_copy_region = r300_resource_copy_region;
r300->context.resource_fill_region = r300_resource_fill_region;
}

View File

@ -147,6 +147,9 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_MAX_CONST_BUFFER_SIZE:
return 256;
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
return 1;
/* Fragment coordinate conventions. */
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:

View File

@ -799,33 +799,6 @@ rbug_resource_copy_region(struct pipe_context *_pipe,
height);
}
static void
rbug_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)
{
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct rbug_resource *rb_resource_dst = rbug_resource(_dst);
struct pipe_context *pipe = rb_pipe->pipe;
struct pipe_resource *dst = rb_resource_dst->resource;
pipe->resource_fill_region(pipe,
dst,
subdst,
dstx,
dsty,
dstz,
width,
height,
value);
}
static void
rbug_clear(struct pipe_context *_pipe,
unsigned buffers,
@ -843,6 +816,52 @@ rbug_clear(struct pipe_context *_pipe,
stencil);
}
static void
rbug_clear_render_target(struct pipe_context *_pipe,
struct pipe_surface *_dst,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct rbug_surface *rb_surface_dst = rbug_surface(_dst);
struct pipe_context *pipe = rb_pipe->pipe;
struct pipe_surface *dst = rb_surface_dst->surface;
pipe->clear_render_target(pipe,
dst,
rgba,
dstx,
dsty,
width,
height);
}
static void
rbug_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 rbug_context *rb_pipe = rbug_context(_pipe);
struct rbug_surface *rb_surface_dst = rbug_surface(_dst);
struct pipe_context *pipe = rb_pipe->pipe;
struct pipe_surface *dst = rb_surface_dst->surface;
pipe->clear_depth_stencil(pipe,
dst,
clear_flags,
depth,
stencil,
dstx,
dsty,
width,
height);
}
static void
rbug_flush(struct pipe_context *_pipe,
unsigned flags,
@ -1075,8 +1094,9 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers;
rb_pipe->base.set_sample_mask = rbug_set_sample_mask;
rb_pipe->base.resource_copy_region = rbug_resource_copy_region;
rb_pipe->base.resource_fill_region = rbug_resource_fill_region;
rb_pipe->base.clear = rbug_clear;
rb_pipe->base.clear_render_target = rbug_clear_render_target;
rb_pipe->base.clear_depth_stencil = rbug_clear_depth_stencil;
rb_pipe->base.flush = rbug_flush;
rb_pipe->base.is_resource_referenced = rbug_is_resource_referenced;
rb_pipe->base.create_sampler_view = rbug_context_create_sampler_view;

View File

@ -143,6 +143,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_MAX_FS_PREDS:
return TGSI_EXEC_NUM_PREDS;
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
return 0;
default:
return 0;
}

View File

@ -33,5 +33,4 @@ void
sp_init_surface_functions(struct softpipe_context *sp)
{
sp->pipe.resource_copy_region = util_resource_copy_region;
sp->pipe.resource_fill_region = util_resource_fill_region;
}

View File

@ -108,5 +108,4 @@ void
svga_init_blit_functions(struct svga_context *svga)
{
svga->pipe.resource_copy_region = svga_surface_copy;
svga->pipe.resource_fill_region = util_resource_fill_region;
}

View File

@ -61,9 +61,11 @@ try_clear(struct svga_context *svga,
}
if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && fb->zsbuf) {
flags |= SVGA3D_CLEAR_DEPTH;
if (buffers & PIPE_CLEAR_DEPTH)
flags |= SVGA3D_CLEAR_DEPTH;
if (svga->curr.framebuffer.zsbuf->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM)
if ((svga->curr.framebuffer.zsbuf->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM) &&
(buffers & PIPE_CLEAR_STENCIL))
flags |= SVGA3D_CLEAR_STENCIL;
rect.w = MAX2(rect.w, fb->zsbuf->width);
@ -100,7 +102,7 @@ svga_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
{
struct svga_context *svga = svga_context( pipe );
int ret;
if (buffers & PIPE_CLEAR_COLOR)
SVGA_DBG(DEBUG_DMA, "clear sid %p\n",
svga_surface(svga->curr.framebuffer.cbufs[0])->handle);

View File

@ -230,6 +230,9 @@ svga_get_paramf(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_MAX_VS_PREDS:
return svgascreen->use_vs30 ? 1 : 0;
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
return 1;
default:
return 0;
}

View File

@ -1084,38 +1084,6 @@ trace_context_resource_copy_region(struct pipe_context *_pipe,
}
static INLINE void
trace_context_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)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
dst = trace_resource_unwrap(tr_ctx, dst);
trace_dump_call_begin("pipe_context", "resource_fill_region");
trace_dump_arg(ptr, pipe);
trace_dump_arg(ptr, dst);
trace_dump_arg_struct(subresource, subdst);
trace_dump_arg(uint, dstx);
trace_dump_arg(uint, dsty);
trace_dump_arg(uint, dstz);
trace_dump_arg(uint, width);
trace_dump_arg(uint, height);
trace_dump_arg(uint, value);
pipe->resource_fill_region(pipe, dst, subdst, dstx, dsty, dstz,
width, height, value);
trace_dump_call_end();
}
static INLINE void
trace_context_clear(struct pipe_context *_pipe,
unsigned buffers,
@ -1140,6 +1108,65 @@ trace_context_clear(struct pipe_context *_pipe,
}
static INLINE void
trace_context_clear_render_target(struct pipe_context *_pipe,
struct pipe_surface *dst,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
dst = trace_surface_unwrap(tr_ctx, dst);
trace_dump_call_begin("pipe_context", "clear_render_target");
trace_dump_arg(ptr, pipe);
trace_dump_arg(ptr, dst);
trace_dump_arg_array(float, rgba, 4);
trace_dump_arg(uint, dstx);
trace_dump_arg(uint, dsty);
trace_dump_arg(uint, width);
trace_dump_arg(uint, height);
pipe->clear_render_target(pipe, dst, rgba, dstx, dsty, width, height);
trace_dump_call_end();
}
static INLINE void
trace_context_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 trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
dst = trace_surface_unwrap(tr_ctx, dst);
trace_dump_call_begin("pipe_context", "clear_depth_stencil");
trace_dump_arg(ptr, pipe);
trace_dump_arg(ptr, dst);
trace_dump_arg(uint, clear_flags);
trace_dump_arg(float, depth);
trace_dump_arg(uint, stencil);
trace_dump_arg(uint, dstx);
trace_dump_arg(uint, dsty);
trace_dump_arg(uint, width);
trace_dump_arg(uint, height);
pipe->clear_depth_stencil(pipe, dst, clear_flags, depth, stencil,
dstx, dsty, width, height);
trace_dump_call_end();
}
static INLINE void
trace_context_flush(struct pipe_context *_pipe,
unsigned flags,
@ -1451,8 +1478,9 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.sampler_view_destroy = trace_sampler_view_destroy;
tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
tr_ctx->base.resource_copy_region = trace_context_resource_copy_region;
tr_ctx->base.resource_fill_region = trace_context_resource_fill_region;
tr_ctx->base.clear = trace_context_clear;
tr_ctx->base.clear_render_target = trace_context_clear_render_target;
tr_ctx->base.clear_depth_stencil = trace_context_clear_depth_stencil;
tr_ctx->base.flush = trace_context_flush;
tr_ctx->base.is_resource_referenced = trace_is_resource_referenced;

View File

@ -256,17 +256,6 @@ struct pipe_context {
unsigned srcx, unsigned srcy, unsigned srcz,
unsigned width, unsigned height);
/**
* Fill a region of a resource with a constant value.
* Resources with nr_samples > 1 are not allowed.
*/
void (*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);
/**
* Resolve a multisampled resource into a non-multisampled one.
* Source and destination must have the same size and same format.
@ -290,9 +279,33 @@ struct pipe_context {
*/
void (*clear)(struct pipe_context *pipe,
unsigned buffers,
const float *rgba,
const float *rgba,
double depth,
unsigned stencil);
unsigned stencil);
/**
* Clear a color rendertarget surface.
* \param rgba pointer to an array of one float for each of r, g, b, a.
*/
void (*clear_render_target)(struct pipe_context *pipe,
struct pipe_surface *dst,
const float *rgba,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height);
/**
* Clear a depth-stencil surface.
* \param clear_flags bitfield of PIPE_CLEAR_DEPTH/STENCIL values.
* \param depth depth clear value in [0,1].
* \param stencil stencil clear value
*/
void (*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);
/** Flush rendering
* \param flags bitmask of PIPE_FLUSH_x tokens)

View File

@ -189,9 +189,10 @@ enum pipe_texture_target {
*/
/** All color buffers currently bound */
#define PIPE_CLEAR_COLOR (1 << 0)
#define PIPE_CLEAR_DEPTH (1 << 1)
#define PIPE_CLEAR_STENCIL (1 << 2)
/** Depth/stencil combined */
#define PIPE_CLEAR_DEPTHSTENCIL (1 << 1)
#define PIPE_CLEAR_DEPTHSTENCIL (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)
/**
* Transfer object usage flags
@ -453,6 +454,7 @@ enum pipe_cap {
PIPE_CAP_INDEP_BLEND_ENABLE,
/** different blend funcs per rendertarget */
PIPE_CAP_INDEP_BLEND_FUNC,
PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE,
PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT,
PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT,
PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER,

View File

@ -428,15 +428,42 @@ error1:
width, height);
}
void resource_fill_region(struct pipe_resource *dst,
struct pipe_subresource subdst,
unsigned dstx, unsigned dsty, unsigned dstz,
unsigned width, unsigned height,
unsigned value)
void clear_render_target(struct st_surface *dst,
float *rgba,
unsigned x, unsigned y,
unsigned width, unsigned height)
{
$self->pipe->resource_fill_region($self->pipe,
dst, subdst, dstx, dsty, dstz,
width, height, value);
struct pipe_surface *_dst = NULL;
_dst = st_pipe_surface(dst, PIPE_BIND_RENDER_TARGET);
if(!_dst)
SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing");
$self->pipe->clear_render_target($self->pipe, _dst, rgba, x, y, width, height);
fail:
pipe_surface_reference(&_dst, NULL);
}
void clear_depth_stencil(struct st_surface *dst,
unsigned clear_flags,
double depth,
unsigned stencil,
unsigned x, unsigned y,
unsigned width, unsigned height)
{
struct pipe_surface *_dst = NULL;
_dst = st_pipe_surface(dst, PIPE_BIND_DEPTH_STENCIL);
if(!_dst)
SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing");
$self->pipe->clear_depth_stencil($self->pipe, _dst, clear_flags, depth, stencil,
x, y, width, height);
fail:
pipe_surface_reference(&_dst, NULL);
}
%cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1));

View File

@ -62,10 +62,12 @@ void
st_init_clear(struct st_context *st)
{
struct pipe_context *pipe = st->pipe;
struct pipe_screen *pscreen = st->pipe->screen;
memset(&st->clear, 0, sizeof(st->clear));
st->clear.raster.gl_rasterization_rules = 1;
st->clear.enable_ds_separate = pscreen->get_param(pscreen, PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE);
/* fragment shader state: color pass-through program */
st->clear.fs = util_make_fragment_passthrough_shader(pipe);
@ -365,7 +367,8 @@ check_clear_depth_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
* Determine if we need to clear the depth buffer by drawing a quad.
*/
static INLINE GLboolean
check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb,
boolean ds_separate)
{
const struct st_renderbuffer *strb = st_renderbuffer(rb);
const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
@ -377,7 +380,7 @@ check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
ctx->Scissor.Height < rb->Height))
return GL_TRUE;
if (isDS && ctx->DrawBuffer->Visual.stencilBits > 0)
if (!ds_separate && isDS && ctx->DrawBuffer->Visual.stencilBits > 0)
return GL_TRUE;
return GL_FALSE;
@ -388,7 +391,8 @@ check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
* Determine if we need to clear the stencil buffer by drawing a quad.
*/
static INLINE GLboolean
check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb,
boolean ds_separate)
{
const struct st_renderbuffer *strb = st_renderbuffer(rb);
const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
@ -415,7 +419,7 @@ check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
* rather than taking depth and stencil clear values from the
* current state.
*/
if (isDS && ctx->DrawBuffer->Visual.depthBits > 0)
if (!ds_separate && isDS && ctx->DrawBuffer->Visual.depthBits > 0)
return GL_TRUE;
return GL_FALSE;
@ -495,24 +499,27 @@ st_Clear(GLcontext *ctx, GLbitfield mask)
}
else {
/* separate depth/stencil clears */
/* I don't think truly separate buffers are actually possible in gallium or hw? */
if (mask & BUFFER_BIT_DEPTH) {
struct st_renderbuffer *strb = st_renderbuffer(depthRb);
if (strb->surface) {
if (check_clear_depth_with_quad(ctx, depthRb))
quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
if (check_clear_depth_with_quad(ctx, depthRb,
st->clear.enable_ds_separate))
quad_buffers |= PIPE_CLEAR_DEPTH;
else
clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
clear_buffers |= PIPE_CLEAR_DEPTH;
}
}
if (mask & BUFFER_BIT_STENCIL) {
struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
if (strb->surface) {
if (check_clear_stencil_with_quad(ctx, stencilRb))
quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
if (check_clear_stencil_with_quad(ctx, stencilRb,
st->clear.enable_ds_separate))
quad_buffers |= PIPE_CLEAR_STENCIL;
else
clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
clear_buffers |= PIPE_CLEAR_STENCIL;
}
}
}
@ -525,12 +532,22 @@ st_Clear(GLcontext *ctx, GLbitfield mask)
quad_buffers |= clear_buffers;
clear_with_quad(ctx,
quad_buffers & PIPE_CLEAR_COLOR,
mask & BUFFER_BIT_DEPTH,
mask & BUFFER_BIT_STENCIL);
} else if (clear_buffers)
quad_buffers & PIPE_CLEAR_DEPTH,
quad_buffers & PIPE_CLEAR_STENCIL);
} else if (clear_buffers) {
/* driver cannot know it can clear everything if the buffer
* is a combined depth/stencil buffer but this wasn't actually
* required from the visual. Hence fix this up to avoid potential
* read-modify-write in the driver.
*/
if (((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
(depthRb == stencilRb) &&
(ctx->DrawBuffer->Visual.depthBits == 0 ||
ctx->DrawBuffer->Visual.stencilBits == 0))
clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
st->pipe->clear(st->pipe, clear_buffers, ctx->Color.ClearColor,
ctx->Depth.Clear, ctx->Stencil.Clear);
}
if (mask & BUFFER_BIT_ACCUM)
st_clear_accum_buffer(ctx,
ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);

View File

@ -175,6 +175,7 @@ struct st_context
float vertices[4][2][4]; /**< vertex pos + color */
struct pipe_resource *vbuf;
unsigned vbuf_slot;
boolean enable_ds_separate;
} clear;
/** used for anything using util_draw_vertex_buffer */