~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/gallium/drivers/nvfx/nvfx_state_fb.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "nvfx_context.h"
 
2
#include "nvfx_resource.h"
 
3
#include "util/u_format.h"
 
4
 
 
5
static inline boolean
 
6
nvfx_surface_linear_renderable(struct pipe_surface* surf)
 
7
{
 
8
        /* TODO: precompute this in nvfx_surface creation */
 
9
        return (surf->texture->flags & NVFX_RESOURCE_FLAG_LINEAR)
 
10
                && !(surf->offset & 63)
 
11
                && !(((struct nvfx_surface*)surf)->pitch & 63);
 
12
}
 
13
 
 
14
static inline boolean
 
15
nvfx_surface_swizzled_renderable(struct pipe_framebuffer_state* fb, struct pipe_surface* surf)
 
16
{
 
17
        /* TODO: precompute this in nvfx_surface creation */
 
18
        return !((struct nvfx_miptree*)surf->texture)->linear_pitch
 
19
                && (surf->texture->target != PIPE_TEXTURE_3D || u_minify(surf->texture->depth0, surf->level) <= 1)
 
20
                && !(surf->offset & 127)
 
21
                && (surf->width == fb->width)
 
22
                && (surf->height == fb->height)
 
23
                && !((struct nvfx_surface*)surf)->temp
 
24
                && (surf->format == PIPE_FORMAT_B8G8R8A8_UNORM || surf->format == PIPE_FORMAT_B8G8R8X8_UNORM || surf->format == PIPE_FORMAT_B5G6R5_UNORM);
 
25
}
 
26
 
 
27
static boolean
 
28
nvfx_surface_get_render_target(struct pipe_surface* surf, int all_swizzled, struct nvfx_render_target* target)
 
29
{
 
30
        struct nvfx_surface* ns = (struct nvfx_surface*)surf;
 
31
        if(!ns->temp)
 
32
        {
 
33
                target->bo = ((struct nvfx_miptree*)surf->texture)->base.bo;
 
34
                target->offset = surf->offset;
 
35
                target->pitch = align(ns->pitch, 64);
 
36
                assert(target->pitch);
 
37
                return FALSE;
 
38
        }
 
39
        else
 
40
        {
 
41
                target->offset = 0;
 
42
                target->pitch = ns->temp->linear_pitch;
 
43
                target->bo = ns->temp->base.bo;
 
44
                assert(target->pitch);
 
45
                return TRUE;
 
46
        }
 
47
}
 
48
 
 
49
int
 
50
nvfx_framebuffer_prepare(struct nvfx_context *nvfx)
 
51
{
 
52
        struct pipe_framebuffer_state *fb = &nvfx->framebuffer;
 
53
        int i, color_format = 0, zeta_format = 0;
 
54
        int all_swizzled = 1;
 
55
 
 
56
        if(!nvfx->is_nv4x)
 
57
                assert(fb->nr_cbufs <= 2);
 
58
        else
 
59
                assert(fb->nr_cbufs <= 4);
 
60
 
 
61
        for (i = 0; i < fb->nr_cbufs; i++) {
 
62
                if (color_format) {
 
63
                        if(color_format != fb->cbufs[i]->format)
 
64
                                return -1;
 
65
                } else
 
66
                        color_format = fb->cbufs[i]->format;
 
67
 
 
68
                if(!nvfx_surface_swizzled_renderable(fb, fb->cbufs[i]))
 
69
                        all_swizzled = 0;
 
70
        }
 
71
 
 
72
        if (fb->zsbuf) {
 
73
                /* TODO: return FALSE if we have a format not supporting a depth buffer (e.g. r8); currently those are not supported at all */
 
74
                if(!nvfx_surface_swizzled_renderable(fb, fb->zsbuf))
 
75
                        all_swizzled = 0;
 
76
 
 
77
                if(all_swizzled && util_format_get_blocksize(color_format) != util_format_get_blocksize(zeta_format))
 
78
                        all_swizzled = 0;
 
79
        }
 
80
 
 
81
        for (i = 0; i < fb->nr_cbufs; i++) {
 
82
                if(!((struct nvfx_surface*)fb->cbufs[i])->temp && !all_swizzled && !nvfx_surface_linear_renderable(fb->cbufs[i]))
 
83
                        nvfx_surface_create_temp(&nvfx->pipe, fb->cbufs[i]);
 
84
        }
 
85
 
 
86
        if(fb->zsbuf) {
 
87
                if(!((struct nvfx_surface*)fb->zsbuf)->temp && !all_swizzled && !nvfx_surface_linear_renderable(fb->zsbuf))
 
88
                        nvfx_surface_create_temp(&nvfx->pipe, fb->zsbuf);
 
89
        }
 
90
 
 
91
        return all_swizzled;
 
92
}
 
93
 
 
94
void
 
95
nvfx_framebuffer_validate(struct nvfx_context *nvfx, unsigned prepare_result)
 
96
{
 
97
        struct pipe_framebuffer_state *fb = &nvfx->framebuffer;
 
98
        struct nouveau_channel *chan = nvfx->screen->base.channel;
 
99
        uint32_t rt_enable, rt_format;
 
100
        int i;
 
101
        unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
 
102
        unsigned w = fb->width;
 
103
        unsigned h = fb->height;
 
104
 
 
105
        rt_enable = (NV30_3D_RT_ENABLE_COLOR0 << fb->nr_cbufs) - 1;
 
106
        if (rt_enable & (NV30_3D_RT_ENABLE_COLOR1 |
 
107
                         NV40_3D_RT_ENABLE_COLOR2 | NV40_3D_RT_ENABLE_COLOR3))
 
108
                rt_enable |= NV30_3D_RT_ENABLE_MRT;
 
109
 
 
110
        nvfx->state.render_temps = 0;
 
111
 
 
112
        for (i = 0; i < fb->nr_cbufs; i++)
 
113
                nvfx->state.render_temps |= nvfx_surface_get_render_target(fb->cbufs[i], prepare_result, &nvfx->hw_rt[i]) << i;
 
114
 
 
115
        for(; i < 4; ++i)
 
116
                nvfx->hw_rt[i].bo = 0;
 
117
 
 
118
        if (fb->zsbuf) {
 
119
                nvfx->state.render_temps |= nvfx_surface_get_render_target(fb->zsbuf, prepare_result, &nvfx->hw_zeta) << 7;
 
120
 
 
121
                assert(util_format_get_stride(fb->zsbuf->format, fb->width) <= nvfx->hw_zeta.pitch);
 
122
                assert(nvfx->hw_zeta.offset + nvfx->hw_zeta.pitch * fb->height <= nvfx->hw_zeta.bo->size);
 
123
        }
 
124
 
 
125
        if (prepare_result) {
 
126
                assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
 
127
 
 
128
                rt_format = NV30_3D_RT_FORMAT_TYPE_SWIZZLED |
 
129
                        (util_logbase2(fb->width) << NV30_3D_RT_FORMAT_LOG2_WIDTH__SHIFT) |
 
130
                        (util_logbase2(fb->height) << NV30_3D_RT_FORMAT_LOG2_HEIGHT__SHIFT);
 
131
        } else
 
132
                rt_format = NV30_3D_RT_FORMAT_TYPE_LINEAR;
 
133
 
 
134
        if(fb->nr_cbufs > 0) {
 
135
                switch (fb->cbufs[0]->format) {
 
136
                case PIPE_FORMAT_B8G8R8X8_UNORM:
 
137
                        rt_format |= NV30_3D_RT_FORMAT_COLOR_X8R8G8B8;
 
138
                        break;
 
139
                case PIPE_FORMAT_B8G8R8A8_UNORM:
 
140
                case 0:
 
141
                        rt_format |= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8;
 
142
                        break;
 
143
                case PIPE_FORMAT_B5G6R5_UNORM:
 
144
                        rt_format |= NV30_3D_RT_FORMAT_COLOR_R5G6B5;
 
145
                        break;
 
146
                case PIPE_FORMAT_R32G32B32A32_FLOAT:
 
147
                        rt_format |= NV30_3D_RT_FORMAT_COLOR_A32B32G32R32_FLOAT;
 
148
                        break;
 
149
                case PIPE_FORMAT_R16G16B16A16_FLOAT:
 
150
                        rt_format |= NV30_3D_RT_FORMAT_COLOR_A16B16G16R16_FLOAT;
 
151
                        break;
 
152
                default:
 
153
                        assert(0);
 
154
                }
 
155
        } else if(fb->zsbuf && util_format_get_blocksize(fb->zsbuf->format) == 2)
 
156
                rt_format |= NV30_3D_RT_FORMAT_COLOR_R5G6B5;
 
157
        else
 
158
                rt_format |= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8;
 
159
 
 
160
        if(fb->zsbuf) {
 
161
                switch (fb->zsbuf->format) {
 
162
                case PIPE_FORMAT_Z16_UNORM:
 
163
                        rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16;
 
164
                        break;
 
165
                case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
 
166
                case PIPE_FORMAT_X8Z24_UNORM:
 
167
                case 0:
 
168
                        rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8;
 
169
                        break;
 
170
                default:
 
171
                        assert(0);
 
172
                }
 
173
        } else if(fb->nr_cbufs && util_format_get_blocksize(fb->cbufs[0]->format) == 2)
 
174
                rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16;
 
175
        else
 
176
                rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8;
 
177
 
 
178
        MARK_RING(chan, 42, 10);
 
179
 
 
180
        if ((rt_enable & NV30_3D_RT_ENABLE_COLOR0) || fb->zsbuf) {
 
181
                struct nvfx_render_target *rt0 = &nvfx->hw_rt[0];
 
182
                uint32_t pitch;
 
183
 
 
184
                if(!(rt_enable & NV30_3D_RT_ENABLE_COLOR0))
 
185
                        rt0 = &nvfx->hw_zeta;
 
186
 
 
187
                pitch = rt0->pitch;
 
188
 
 
189
                if(!nvfx->is_nv4x)
 
190
                {
 
191
                        if (nvfx->hw_zeta.bo)
 
192
                                pitch |= (nvfx->hw_zeta.pitch << 16);
 
193
                        else
 
194
                                pitch |= (pitch << 16);
 
195
                }
 
196
 
 
197
                //printf("rendering to bo %p [%i] at offset %i with pitch %i\n", rt0->bo, rt0->bo->handle, rt0->offset, pitch);
 
198
 
 
199
                OUT_RING(chan, RING_3D(NV30_3D_DMA_COLOR0, 1));
 
200
                OUT_RELOC(chan, rt0->bo, 0,
 
201
                              rt_flags | NOUVEAU_BO_OR,
 
202
                              chan->vram->handle, chan->gart->handle);
 
203
                OUT_RING(chan, RING_3D(NV30_3D_COLOR0_PITCH, 2));
 
204
                OUT_RING(chan, pitch);
 
205
                OUT_RELOC(chan, rt0->bo,
 
206
                              rt0->offset, rt_flags | NOUVEAU_BO_LOW,
 
207
                              0, 0);
 
208
        }
 
209
 
 
210
        if (rt_enable & NV30_3D_RT_ENABLE_COLOR1) {
 
211
                OUT_RING(chan, RING_3D(NV30_3D_DMA_COLOR1, 1));
 
212
                OUT_RELOC(chan, nvfx->hw_rt[1].bo, 0,
 
213
                              rt_flags | NOUVEAU_BO_OR,
 
214
                              chan->vram->handle, chan->gart->handle);
 
215
                OUT_RING(chan, RING_3D(NV30_3D_COLOR1_OFFSET, 2));
 
216
                OUT_RELOC(chan, nvfx->hw_rt[1].bo,
 
217
                                nvfx->hw_rt[1].offset, rt_flags | NOUVEAU_BO_LOW,
 
218
                              0, 0);
 
219
                OUT_RING(chan, nvfx->hw_rt[1].pitch);
 
220
        }
 
221
 
 
222
        if(nvfx->is_nv4x)
 
223
        {
 
224
                if (rt_enable & NV40_3D_RT_ENABLE_COLOR2) {
 
225
                        OUT_RING(chan, RING_3D(NV40_3D_DMA_COLOR2, 1));
 
226
                        OUT_RELOC(chan, nvfx->hw_rt[2].bo, 0,
 
227
                                      rt_flags | NOUVEAU_BO_OR,
 
228
                                      chan->vram->handle, chan->gart->handle);
 
229
                        OUT_RING(chan, RING_3D(NV40_3D_COLOR2_OFFSET, 1));
 
230
                        OUT_RELOC(chan, nvfx->hw_rt[2].bo,
 
231
                                      nvfx->hw_rt[2].offset, rt_flags | NOUVEAU_BO_LOW,
 
232
                                      0, 0);
 
233
                        OUT_RING(chan, RING_3D(NV40_3D_COLOR2_PITCH, 1));
 
234
                        OUT_RING(chan, nvfx->hw_rt[2].pitch);
 
235
                }
 
236
 
 
237
                if (rt_enable & NV40_3D_RT_ENABLE_COLOR3) {
 
238
                        OUT_RING(chan, RING_3D(NV40_3D_DMA_COLOR3, 1));
 
239
                        OUT_RELOC(chan, nvfx->hw_rt[3].bo, 0,
 
240
                                      rt_flags | NOUVEAU_BO_OR,
 
241
                                      chan->vram->handle, chan->gart->handle);
 
242
                        OUT_RING(chan, RING_3D(NV40_3D_COLOR3_OFFSET, 1));
 
243
                        OUT_RELOC(chan, nvfx->hw_rt[3].bo,
 
244
                                        nvfx->hw_rt[3].offset, rt_flags | NOUVEAU_BO_LOW,
 
245
                                      0, 0);
 
246
                        OUT_RING(chan, RING_3D(NV40_3D_COLOR3_PITCH, 1));
 
247
                        OUT_RING(chan, nvfx->hw_rt[3].pitch);
 
248
                }
 
249
        }
 
250
 
 
251
        if (fb->zsbuf) {
 
252
                OUT_RING(chan, RING_3D(NV30_3D_DMA_ZETA, 1));
 
253
                OUT_RELOC(chan, nvfx->hw_zeta.bo, 0,
 
254
                              rt_flags | NOUVEAU_BO_OR,
 
255
                              chan->vram->handle, chan->gart->handle);
 
256
                OUT_RING(chan, RING_3D(NV30_3D_ZETA_OFFSET, 1));
 
257
                /* TODO: reverse engineer LMA */
 
258
                OUT_RELOC(chan, nvfx->hw_zeta.bo,
 
259
                             nvfx->hw_zeta.offset, rt_flags | NOUVEAU_BO_LOW, 0, 0);
 
260
                if(nvfx->is_nv4x) {
 
261
                        OUT_RING(chan, RING_3D(NV40_3D_ZETA_PITCH, 1));
 
262
                        OUT_RING(chan, nvfx->hw_zeta.pitch);
 
263
                }
 
264
        }
 
265
        else if(nvfx->is_nv4x) {
 
266
                OUT_RING(chan, RING_3D(NV40_3D_ZETA_PITCH, 1));
 
267
                OUT_RING(chan, 64);
 
268
        }
 
269
 
 
270
        OUT_RING(chan, RING_3D(NV30_3D_RT_ENABLE, 1));
 
271
        OUT_RING(chan, rt_enable);
 
272
        OUT_RING(chan, RING_3D(NV30_3D_RT_HORIZ, 3));
 
273
        OUT_RING(chan, (w << 16) | 0);
 
274
        OUT_RING(chan, (h << 16) | 0);
 
275
        OUT_RING(chan, rt_format);
 
276
        OUT_RING(chan, RING_3D(NV30_3D_VIEWPORT_HORIZ, 2));
 
277
        OUT_RING(chan, (w << 16) | 0);
 
278
        OUT_RING(chan, (h << 16) | 0);
 
279
        OUT_RING(chan, RING_3D(NV30_3D_VIEWPORT_CLIP_HORIZ(0), 2));
 
280
        OUT_RING(chan, ((w - 1) << 16) | 0);
 
281
        OUT_RING(chan, ((h - 1) << 16) | 0);
 
282
 
 
283
        if(!nvfx->is_nv4x) {
 
284
                /* Wonder why this is needed, context should all be set to zero on init */
 
285
                /* TODO: we can most likely remove this, after putting it in context init */
 
286
                OUT_RING(chan, RING_3D(NV30_3D_VIEWPORT_TX_ORIGIN, 1));
 
287
                OUT_RING(chan, 0);
 
288
        }
 
289
        nvfx->relocs_needed &=~ NVFX_RELOCATE_FRAMEBUFFER;
 
290
}
 
291
 
 
292
void
 
293
nvfx_framebuffer_relocate(struct nvfx_context *nvfx)
 
294
{
 
295
        struct nouveau_channel *chan = nvfx->screen->base.channel;
 
296
        unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
 
297
        rt_flags |= NOUVEAU_BO_DUMMY;
 
298
        MARK_RING(chan, 20, 20);
 
299
 
 
300
#define DO_(var, pfx, name) \
 
301
        if(var.bo) { \
 
302
                OUT_RELOC(chan, var.bo, RING_3D(pfx##_3D_DMA_##name, 1), rt_flags, 0, 0); \
 
303
                OUT_RELOC(chan, var.bo, 0, \
 
304
                        rt_flags | NOUVEAU_BO_OR, \
 
305
                        chan->vram->handle, chan->gart->handle); \
 
306
                OUT_RELOC(chan, var.bo, RING_3D(pfx##_3D_##name##_OFFSET, 1), rt_flags, 0, 0); \
 
307
                OUT_RELOC(chan, var.bo, \
 
308
                        var.offset, rt_flags | NOUVEAU_BO_LOW, \
 
309
                        0, 0); \
 
310
        }
 
311
 
 
312
#define DO(pfx, num) DO_(nvfx->hw_rt[num], pfx, COLOR##num)
 
313
        DO(NV30, 0);
 
314
        DO(NV30, 1);
 
315
        DO(NV40, 2);
 
316
        DO(NV40, 3);
 
317
 
 
318
        DO_(nvfx->hw_zeta, NV30, ZETA);
 
319
        nvfx->relocs_needed &=~ NVFX_RELOCATE_FRAMEBUFFER;
 
320
}