nv50: use CLEAR_BUFFERS for surface fills
The 2D engine's fill doesn't seem suited for RGBA32F or ZS buffers.
This commit is contained in:
parent
583bbfb3ae
commit
2ef1d759b3
|
@ -1018,6 +1018,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#define NV50TCL_FP_START_ID 0x00001414
|
#define NV50TCL_FP_START_ID 0x00001414
|
||||||
#define NV50TCL_GP_VERTEX_OUTPUT_COUNT 0x00001420
|
#define NV50TCL_GP_VERTEX_OUTPUT_COUNT 0x00001420
|
||||||
#define NV50TCL_VB_ELEMENT_BASE 0x00001434
|
#define NV50TCL_VB_ELEMENT_BASE 0x00001434
|
||||||
|
#define NV50TCL_CLEAR_FLAGS 0x0000143c
|
||||||
|
#define NV50TCL_CLEAR_FLAGS_OGL (1 << 0)
|
||||||
|
#define NV50TCL_CLEAR_FLAGS_D3D (1 << 4)
|
||||||
#define NV50TCL_INSTANCE_BASE 0x00001438
|
#define NV50TCL_INSTANCE_BASE 0x00001438
|
||||||
#define NV50TCL_CODE_CB_FLUSH 0x00001440
|
#define NV50TCL_CODE_CB_FLUSH 0x00001440
|
||||||
#define NV50TCL_BIND_TSC(x) (0x00001444+((x)*8))
|
#define NV50TCL_BIND_TSC(x) (0x00001444+((x)*8))
|
||||||
|
|
|
@ -457,6 +457,9 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
|
||||||
BEGIN_RING(chan, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
|
BEGIN_RING(chan, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
|
||||||
OUT_RING (chan, 8);
|
OUT_RING (chan, 8);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, screen->tesla, NV50TCL_CLEAR_FLAGS, 1);
|
||||||
|
OUT_RING (chan, NV50TCL_CLEAR_FLAGS_D3D);
|
||||||
|
|
||||||
/* constant buffers for immediates and VP/FP parameters */
|
/* constant buffers for immediates and VP/FP parameters */
|
||||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (32 * 4) * 4,
|
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (32 * 4) * 4,
|
||||||
&screen->constbuf_misc[0]);
|
&screen->constbuf_misc[0]);
|
||||||
|
|
|
@ -199,7 +199,6 @@ nv50_surface_copy(struct pipe_context *pipe,
|
||||||
nv50_miptree_surface_del(ps_dst);
|
nv50_miptree_surface_del(ps_dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX this should probably look more along the lines of nv50_clear */
|
|
||||||
static void
|
static void
|
||||||
nv50_clear_render_target(struct pipe_context *pipe,
|
nv50_clear_render_target(struct pipe_context *pipe,
|
||||||
struct pipe_surface *dst,
|
struct pipe_surface *dst,
|
||||||
|
@ -209,33 +208,99 @@ nv50_clear_render_target(struct pipe_context *pipe,
|
||||||
{
|
{
|
||||||
struct nv50_context *nv50 = nv50_context(pipe);
|
struct nv50_context *nv50 = nv50_context(pipe);
|
||||||
struct nv50_screen *screen = nv50->screen;
|
struct nv50_screen *screen = nv50->screen;
|
||||||
struct nouveau_channel *chan = screen->eng2d->channel;
|
struct nouveau_channel *chan = screen->base.channel;
|
||||||
struct nouveau_grobj *eng2d = screen->eng2d;
|
struct nouveau_grobj *tesla = screen->tesla;
|
||||||
int format, ret;
|
struct nv50_miptree *mt = nv50_miptree(dst->texture);
|
||||||
union util_color uc;
|
struct nouveau_bo *bo = mt->base.bo;
|
||||||
util_pack_color(rgba, dst->format, &uc);
|
|
||||||
|
|
||||||
format = nv50_2d_format(dst->format);
|
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_COLOR(0), 4);
|
||||||
if (!format)
|
OUT_RINGf (chan, rgba[0]);
|
||||||
|
OUT_RINGf (chan, rgba[1]);
|
||||||
|
OUT_RINGf (chan, rgba[2]);
|
||||||
|
OUT_RINGf (chan, rgba[3]);
|
||||||
|
|
||||||
|
if (MARK_RING(chan, 18, 2))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ret = MARK_RING (chan, 16 + 32, 2);
|
BEGIN_RING(chan, tesla, NV50TCL_RT_CONTROL, 1);
|
||||||
if (ret)
|
OUT_RING (chan, 1);
|
||||||
|
BEGIN_RING(chan, tesla, NV50TCL_RT_ADDRESS_HIGH(0), 5);
|
||||||
|
OUT_RELOCh(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||||
|
OUT_RELOCl(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||||
|
OUT_RING (chan, nv50_format_table[dst->format].rt);
|
||||||
|
OUT_RING (chan, mt->level[dst->level].tile_mode << 4);
|
||||||
|
OUT_RING (chan, 0);
|
||||||
|
BEGIN_RING(chan, tesla, NV50TCL_RT_HORIZ(0), 2);
|
||||||
|
OUT_RING (chan, dst->width);
|
||||||
|
OUT_RING (chan, dst->height);
|
||||||
|
BEGIN_RING(chan, tesla, NV50TCL_RT_ARRAY_MODE, 1);
|
||||||
|
OUT_RING (chan, 1);
|
||||||
|
|
||||||
|
/* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */
|
||||||
|
|
||||||
|
BEGIN_RING(chan, tesla, NV50TCL_VIEWPORT_HORIZ(0), 2);
|
||||||
|
OUT_RING (chan, (width << 16) | dstx);
|
||||||
|
OUT_RING (chan, (height << 16) | dsty);
|
||||||
|
|
||||||
|
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
|
||||||
|
OUT_RING (chan, 0x3c);
|
||||||
|
|
||||||
|
nv50->dirty |= NV50_NEW_FRAMEBUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nv50_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 nv50_context *nv50 = nv50_context(pipe);
|
||||||
|
struct nv50_screen *screen = nv50->screen;
|
||||||
|
struct nouveau_channel *chan = screen->base.channel;
|
||||||
|
struct nouveau_grobj *tesla = screen->tesla;
|
||||||
|
struct nv50_miptree *mt = nv50_miptree(dst->texture);
|
||||||
|
struct nouveau_bo *bo = mt->base.bo;
|
||||||
|
uint32_t mode = 0;
|
||||||
|
|
||||||
|
if (clear_flags & PIPE_CLEAR_DEPTH) {
|
||||||
|
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_DEPTH, 1);
|
||||||
|
OUT_RINGf (chan, depth);
|
||||||
|
mode |= NV50TCL_CLEAR_BUFFERS_Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clear_flags & PIPE_CLEAR_STENCIL) {
|
||||||
|
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_STENCIL, 1);
|
||||||
|
OUT_RING (chan, stencil & 0xff);
|
||||||
|
mode |= NV50TCL_CLEAR_BUFFERS_S;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MARK_RING(chan, 17, 2))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ret = nv50_surface_set(screen, dst, 1);
|
BEGIN_RING(chan, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5);
|
||||||
if (ret)
|
OUT_RELOCh(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||||
return;
|
OUT_RELOCl(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||||
|
OUT_RING (chan, nv50_format_table[dst->format].rt);
|
||||||
|
OUT_RING (chan, mt->level[dst->level].tile_mode << 4);
|
||||||
|
OUT_RING (chan, 0);
|
||||||
|
BEGIN_RING(chan, tesla, NV50TCL_ZETA_ENABLE, 1);
|
||||||
|
OUT_RING (chan, 1);
|
||||||
|
BEGIN_RING(chan, tesla, NV50TCL_ZETA_HORIZ, 3);
|
||||||
|
OUT_RING (chan, dst->width);
|
||||||
|
OUT_RING (chan, dst->height);
|
||||||
|
OUT_RING (chan, (1 << 16) | 1);
|
||||||
|
|
||||||
BEGIN_RING(chan, eng2d, NV50_2D_DRAW_SHAPE, 3);
|
BEGIN_RING(chan, tesla, NV50TCL_VIEWPORT_HORIZ(0), 2);
|
||||||
OUT_RING (chan, NV50_2D_DRAW_SHAPE_RECTANGLES);
|
OUT_RING (chan, (width << 16) | dstx);
|
||||||
OUT_RING (chan, format);
|
OUT_RING (chan, (height << 16) | dsty);
|
||||||
OUT_RING (chan, uc.ui);
|
|
||||||
BEGIN_RING(chan, eng2d, NV50_2D_DRAW_POINT32_X(0), 4);
|
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
|
||||||
OUT_RING (chan, dstx);
|
OUT_RING (chan, mode);
|
||||||
OUT_RING (chan, dsty);
|
|
||||||
OUT_RING (chan, width);
|
nv50->dirty |= NV50_NEW_FRAMEBUFFER;
|
||||||
OUT_RING (chan, height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -243,6 +308,7 @@ nv50_init_surface_functions(struct nv50_context *nv50)
|
||||||
{
|
{
|
||||||
nv50->pipe.resource_copy_region = nv50_surface_copy;
|
nv50->pipe.resource_copy_region = nv50_surface_copy;
|
||||||
nv50->pipe.clear_render_target = nv50_clear_render_target;
|
nv50->pipe.clear_render_target = nv50_clear_render_target;
|
||||||
|
nv50->pipe.clear_depth_stencil = nv50_clear_depth_stencil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue