Merge branch 'gallium-newclear'
Conflicts: src/gallium/state_trackers/python/p_context.i
This commit is contained in:
commit
992382762a
|
@ -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 |= 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue