mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-27 06:50:30 +01:00
nvfx: so->RING_3D: fb
This commit is contained in:
parent
b3cc1adc14
commit
f320176b71
3 changed files with 117 additions and 77 deletions
|
|
@ -111,6 +111,12 @@ struct nvfx_vtxelt_state {
|
|||
unsigned num_elements;
|
||||
};
|
||||
|
||||
struct nvfx_render_target {
|
||||
struct nouveau_bo* bo;
|
||||
unsigned offset;
|
||||
unsigned pitch;
|
||||
};
|
||||
|
||||
struct nvfx_context {
|
||||
struct pipe_context pipe;
|
||||
|
||||
|
|
@ -169,6 +175,8 @@ struct nvfx_context {
|
|||
unsigned hw_vtxelt_nr;
|
||||
uint8_t hw_samplers;
|
||||
uint32_t hw_txf[8];
|
||||
struct nvfx_render_target hw_rt[4];
|
||||
struct nvfx_render_target hw_zeta;
|
||||
};
|
||||
|
||||
static INLINE struct nvfx_context *
|
||||
|
|
@ -218,6 +226,10 @@ extern void nvfx_draw_elements_swtnl(struct pipe_context *pipe,
|
|||
unsigned ib_size, unsigned mode,
|
||||
unsigned start, unsigned count);
|
||||
|
||||
/* nvfx_fb.c */
|
||||
void
|
||||
nvfx_framebuffer_relocate(struct nvfx_context *nvfx);
|
||||
|
||||
/* nvfx_fragprog.c */
|
||||
extern void nvfx_fragprog_destroy(struct nvfx_context *,
|
||||
struct nvfx_fragment_program *);
|
||||
|
|
|
|||
|
|
@ -98,9 +98,7 @@ nvfx_state_emit(struct nvfx_context *nvfx)
|
|||
void
|
||||
nvfx_state_relocate(struct nvfx_context *nvfx)
|
||||
{
|
||||
struct nouveau_channel *chan = nvfx->screen->base.channel;
|
||||
struct nvfx_state *state = &nvfx->state;
|
||||
so_emit_reloc_markers(chan, state->hw[NVFX_STATE_FB]);
|
||||
nvfx_framebuffer_relocate(nvfx);
|
||||
nvfx_fragtex_relocate(nvfx);
|
||||
nvfx_fragprog_relocate(nvfx);
|
||||
if (nvfx->render_mode == HW)
|
||||
|
|
|
|||
|
|
@ -4,17 +4,14 @@
|
|||
|
||||
|
||||
|
||||
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;
|
||||
|
|
@ -26,14 +23,18 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
|
|||
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))
|
||||
|
|
@ -41,20 +42,24 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
|
|||
|
||||
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;
|
||||
|
|
@ -62,17 +67,17 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
|
|||
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) {
|
||||
|
|
@ -108,115 +113,140 @@ nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
|
|||
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); \
|
||||
}
|
||||
|
||||
so_ref(so, &nvfx->state.hw[NVFX_STATE_FB]);
|
||||
so_ref(NULL, &so);
|
||||
return TRUE;
|
||||
#define DO(pfx, num) DO_(nvfx->hw_rt[num], pfx, COLOR##num)
|
||||
DO(NV34, 0);
|
||||
DO(NV34, 1);
|
||||
DO(NV40, 2);
|
||||
DO(NV40, 3);
|
||||
|
||||
DO_(nvfx->hw_zeta, NV34, ZETA);
|
||||
}
|
||||
|
||||
struct nvfx_state_entry nvfx_state_framebuffer = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue