-static boolean
+static void
nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
{
struct pipe_framebuffer_state *fb = &nvfx->framebuffer;
struct nouveau_channel *chan = nvfx->screen->base.channel;
- struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
- struct nv04_surface *rt[4], *zeta = NULL;
uint32_t rt_enable = 0, rt_format = 0;
int i, colour_format = 0, zeta_format = 0;
int depth_only = 0;
- struct nouveau_stateobj *so = so_new(18, 24, 10);
unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
unsigned w = fb->width;
unsigned h = fb->height;
assert(fb->nr_cbufs <= 4);
for (i = 0; i < fb->nr_cbufs; i++) {
- if (colour_format) {
+ if (colour_format)
assert(colour_format == fb->cbufs[i]->format);
- } else {
+ else
colour_format = fb->cbufs[i]->format;
- rt_enable |= (NV34TCL_RT_ENABLE_COLOR0 << i);
- rt[i] = (struct nv04_surface *)fb->cbufs[i];
- }
+
+ rt_enable |= (NV34TCL_RT_ENABLE_COLOR0 << i);
+ nvfx->hw_rt[i].bo = nvfx_surface_buffer(fb->cbufs[i]);
+ nvfx->hw_rt[i].offset = fb->cbufs[i]->offset;
+ nvfx->hw_rt[i].pitch = ((struct nv04_surface *)fb->cbufs[i])->pitch;
}
+ for(; i < 4; ++i)
+ nvfx->hw_rt[i].bo = 0;
if (rt_enable & (NV34TCL_RT_ENABLE_COLOR1 |
NV40TCL_RT_ENABLE_COLOR2 | NV40TCL_RT_ENABLE_COLOR3))
if (fb->zsbuf) {
zeta_format = fb->zsbuf->format;
- zeta = (struct nv04_surface *)fb->zsbuf;
+ nvfx->hw_zeta.bo = nvfx_surface_buffer(fb->zsbuf);
+ nvfx->hw_zeta.offset = fb->zsbuf->offset;
+ nvfx->hw_zeta.pitch = ((struct nv04_surface *)fb->zsbuf)->pitch;
}
+ else
+ nvfx->hw_zeta.bo = 0;
if (rt_enable & (NV34TCL_RT_ENABLE_COLOR0 | NV34TCL_RT_ENABLE_COLOR1 |
NV40TCL_RT_ENABLE_COLOR2 | NV40TCL_RT_ENABLE_COLOR3)) {
/* Render to at least a colour buffer */
- if (!(rt[0]->base.texture->flags & NVFX_RESOURCE_FLAG_LINEAR)) {
+ if (!(fb->cbufs[0]->texture->flags & NVFX_RESOURCE_FLAG_LINEAR)) {
assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
for (i = 1; i < fb->nr_cbufs; i++)
- assert(!(rt[i]->base.texture->flags & NVFX_RESOURCE_FLAG_LINEAR));
+ assert(!(fb->cbufs[i]->texture->flags & NVFX_RESOURCE_FLAG_LINEAR));
rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED |
- (log2i(rt[0]->base.width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) |
- (log2i(rt[0]->base.height) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT);
+ (log2i(fb->cbufs[0]->width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) |
+ (log2i(fb->cbufs[0]->height) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT);
}
else
rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR;
depth_only = 1;
/* Render to depth buffer only */
- if (!(zeta->base.texture->flags & NVFX_RESOURCE_FLAG_LINEAR)) {
+ if (!(fb->zsbuf->texture->_usage & NVFX_RESOURCE_FLAG_LINEAR)) {
assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED |
- (log2i(zeta->base.width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) |
- (log2i(zeta->base.height) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT);
+ (log2i(fb->zsbuf->width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) |
+ (log2i(fb->zsbuf->height) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT);
}
else
rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR;
} else {
- return FALSE;
+ return;
}
switch (colour_format) {
if ((!nvfx->is_nv4x) && colour_bits > zeta_bits) {
/* TODO: does this limitation really exist?
TODO: can it be worked around somehow? */
- return FALSE;
+ assert(0);
}
if ((rt_enable & NV34TCL_RT_ENABLE_COLOR0)
|| ((!nvfx->is_nv4x) && depth_only)) {
- struct nv04_surface *rt0 = (depth_only ? zeta : rt[0]);
+ struct nvfx_render_target *rt0 = (depth_only ? &nvfx->hw_zeta : &nvfx->hw_rt[0]);
uint32_t pitch = rt0->pitch;
if(!nvfx->is_nv4x)
{
- if (zeta) {
- pitch |= (zeta->pitch << 16);
+ if (nvfx->hw_zeta.bo) {
+ pitch |= (nvfx->hw_zeta.pitch << 16);
} else {
pitch |= (pitch << 16);
}
}
- so_method(so, eng3d, NV34TCL_DMA_COLOR0, 1);
- so_reloc (so, nvfx_surface_buffer(&rt0->base), 0,
+ OUT_RING(chan, RING_3D(NV34TCL_DMA_COLOR0, 1));
+ OUT_RELOC(chan, rt0->bo, 0,
rt_flags | NOUVEAU_BO_OR,
chan->vram->handle, chan->gart->handle);
- so_method(so, eng3d, NV34TCL_COLOR0_PITCH, 2);
- so_data (so, pitch);
- so_reloc (so, nvfx_surface_buffer(&rt[0]->base),
- rt0->base.offset, rt_flags | NOUVEAU_BO_LOW,
+ OUT_RING(chan, RING_3D(NV34TCL_COLOR0_PITCH, 2));
+ OUT_RING(chan, pitch);
+ OUT_RELOC(chan, rt0->bo,
+ rt0->offset, rt_flags | NOUVEAU_BO_LOW,
0, 0);
}
if (rt_enable & NV34TCL_RT_ENABLE_COLOR1) {
- so_method(so, eng3d, NV34TCL_DMA_COLOR1, 1);
- so_reloc (so, nvfx_surface_buffer(&rt[1]->base), 0,
+ OUT_RING(chan, RING_3D(NV34TCL_DMA_COLOR1, 1));
+ OUT_RELOC(chan, nvfx->hw_rt[1].bo, 0,
rt_flags | NOUVEAU_BO_OR,
chan->vram->handle, chan->gart->handle);
- so_method(so, eng3d, NV34TCL_COLOR1_OFFSET, 2);
- so_reloc (so, nvfx_surface_buffer(&rt[1]->base),
- rt[1]->base.offset, rt_flags | NOUVEAU_BO_LOW,
+ OUT_RING(chan, RING_3D(NV34TCL_COLOR1_OFFSET, 2));
+ OUT_RELOC(chan, nvfx->hw_rt[1].bo,
+ nvfx->hw_rt[1].offset, rt_flags | NOUVEAU_BO_LOW,
0, 0);
- so_data (so, rt[1]->pitch);
+ OUT_RING(chan, nvfx->hw_rt[1].pitch);
}
if(nvfx->is_nv4x)
{
if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) {
- so_method(so, eng3d, NV40TCL_DMA_COLOR2, 1);
- so_reloc (so, nvfx_surface_buffer(&rt[2]->base), 0,
+ OUT_RING(chan, RING_3D(NV40TCL_DMA_COLOR2, 1));
+ OUT_RELOC(chan, nvfx->hw_rt[2].bo, 0,
rt_flags | NOUVEAU_BO_OR,
chan->vram->handle, chan->gart->handle);
- so_method(so, eng3d, NV40TCL_COLOR2_OFFSET, 1);
- so_reloc (so, nvfx_surface_buffer(&rt[2]->base),
- rt[2]->base.offset, rt_flags | NOUVEAU_BO_LOW,
+ OUT_RING(chan, RING_3D(NV40TCL_COLOR2_OFFSET, 1));
+ OUT_RELOC(chan, nvfx->hw_rt[2].bo,
+ nvfx->hw_rt[2].offset, rt_flags | NOUVEAU_BO_LOW,
0, 0);
- so_method(so, eng3d, NV40TCL_COLOR2_PITCH, 1);
- so_data (so, rt[2]->pitch);
+ OUT_RING(chan, RING_3D(NV40TCL_COLOR2_PITCH, 1));
+ OUT_RING(chan, nvfx->hw_rt[2].pitch);
}
if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) {
- so_method(so, eng3d, NV40TCL_DMA_COLOR3, 1);
- so_reloc (so, nvfx_surface_buffer(&rt[3]->base), 0,
+ OUT_RING(chan, RING_3D(NV40TCL_DMA_COLOR3, 1));
+ OUT_RELOC(chan, nvfx->hw_rt[3].bo, 0,
rt_flags | NOUVEAU_BO_OR,
chan->vram->handle, chan->gart->handle);
- so_method(so, eng3d, NV40TCL_COLOR3_OFFSET, 1);
- so_reloc (so, nvfx_surface_buffer(&rt[3]->base),
- rt[3]->base.offset, rt_flags | NOUVEAU_BO_LOW,
+ OUT_RING(chan, RING_3D(NV40TCL_COLOR3_OFFSET, 1));
+ OUT_RELOC(chan, nvfx->hw_rt[3].bo,
+ nvfx->hw_rt[3].offset, rt_flags | NOUVEAU_BO_LOW,
0, 0);
- so_method(so, eng3d, NV40TCL_COLOR3_PITCH, 1);
- so_data (so, rt[3]->pitch);
+ OUT_RING(chan, RING_3D(NV40TCL_COLOR3_PITCH, 1));
+ OUT_RING(chan, nvfx->hw_rt[3].pitch);
}
}
if (zeta_format) {
- so_method(so, eng3d, NV34TCL_DMA_ZETA, 1);
- so_reloc (so, nvfx_surface_buffer(&zeta->base), 0,
+ OUT_RING(chan, RING_3D(NV34TCL_DMA_ZETA, 1));
+ OUT_RELOC(chan, nvfx->hw_zeta.bo, 0,
rt_flags | NOUVEAU_BO_OR,
chan->vram->handle, chan->gart->handle);
- so_method(so, eng3d, NV34TCL_ZETA_OFFSET, 1);
+ OUT_RING(chan, RING_3D(NV34TCL_ZETA_OFFSET, 1));
/* TODO: reverse engineer LMA */
- so_reloc (so, nvfx_surface_buffer(&zeta->base),
- zeta->base.offset, rt_flags | NOUVEAU_BO_LOW, 0, 0);
+ OUT_RELOC(chan, nvfx->hw_zeta.bo,
+ nvfx->hw_zeta.offset, rt_flags | NOUVEAU_BO_LOW, 0, 0);
if(nvfx->is_nv4x) {
- so_method(so, eng3d, NV40TCL_ZETA_PITCH, 1);
- so_data (so, zeta->pitch);
+ OUT_RING(chan, RING_3D(NV40TCL_ZETA_PITCH, 1));
+ OUT_RING(chan, nvfx->hw_zeta.pitch);
}
}
- so_method(so, eng3d, NV34TCL_RT_ENABLE, 1);
- so_data (so, rt_enable);
- so_method(so, eng3d, NV34TCL_RT_HORIZ, 3);
- so_data (so, (w << 16) | 0);
- so_data (so, (h << 16) | 0);
- so_data (so, rt_format);
- so_method(so, eng3d, NV34TCL_VIEWPORT_HORIZ, 2);
- so_data (so, (w << 16) | 0);
- so_data (so, (h << 16) | 0);
- so_method(so, eng3d, NV34TCL_VIEWPORT_CLIP_HORIZ(0), 2);
- so_data (so, ((w - 1) << 16) | 0);
- so_data (so, ((h - 1) << 16) | 0);
- so_method(so, eng3d, 0x1d88, 1);
- so_data (so, (1 << 12) | h);
+ OUT_RING(chan, RING_3D(NV34TCL_RT_ENABLE, 1));
+ OUT_RING(chan, rt_enable);
+ OUT_RING(chan, RING_3D(NV34TCL_RT_HORIZ, 3));
+ OUT_RING(chan, (w << 16) | 0);
+ OUT_RING(chan, (h << 16) | 0);
+ OUT_RING(chan, rt_format);
+ OUT_RING(chan, RING_3D(NV34TCL_VIEWPORT_HORIZ, 2));
+ OUT_RING(chan, (w << 16) | 0);
+ OUT_RING(chan, (h << 16) | 0);
+ OUT_RING(chan, RING_3D(NV34TCL_VIEWPORT_CLIP_HORIZ(0), 2));
+ OUT_RING(chan, ((w - 1) << 16) | 0);
+ OUT_RING(chan, ((h - 1) << 16) | 0);
+ OUT_RING(chan, RING_3D(0x1d88, 1));
+ OUT_RING(chan, (1 << 12) | h);
if(!nvfx->is_nv4x) {
/* Wonder why this is needed, context should all be set to zero on init */
/* TODO: we can most likely remove this, after putting it in context init */
- so_method(so, eng3d, NV34TCL_VIEWPORT_TX_ORIGIN, 1);
- so_data (so, 0);
+ OUT_RING(chan, RING_3D(NV34TCL_VIEWPORT_TX_ORIGIN, 1));
+ OUT_RING(chan, 0);
}
+}
+
+void
+nvfx_framebuffer_relocate(struct nvfx_context *nvfx)
+{
+ struct nouveau_channel *chan = nvfx->screen->base.channel;
+ unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
+ rt_flags |= NOUVEAU_BO_DUMMY;
+ MARK_RING(chan, 20, 20);
+
+#define DO_(var, pfx, name) \
+ if(var.bo) { \
+ OUT_RELOC(chan, var.bo, RING_3D(pfx##TCL_DMA_##name, 1), rt_flags, 0, 0); \
+ OUT_RELOC(chan, var.bo, 0, \
+ rt_flags | NOUVEAU_BO_OR, \
+ chan->vram->handle, chan->gart->handle); \
+ OUT_RELOC(chan, var.bo, RING_3D(pfx##TCL_##name##_OFFSET, 1), rt_flags, 0, 0); \
+ OUT_RELOC(chan, var.bo, \
+ var.offset, rt_flags | NOUVEAU_BO_LOW, \
+ 0, 0); \
+ }
+
+#define DO(pfx, num) DO_(nvfx->hw_rt[num], pfx, COLOR##num)
+ DO(NV34, 0);
+ DO(NV34, 1);
+ DO(NV40, 2);
+ DO(NV40, 3);
- so_ref(so, &nvfx->state.hw[NVFX_STATE_FB]);
- so_ref(NULL, &so);
- return TRUE;
+ DO_(nvfx->hw_zeta, NV34, ZETA);
}
struct nvfx_state_entry nvfx_state_framebuffer = {