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

« back to all changes in this revision

Viewing changes to src/gallium/drivers/nvfx/nvfx_query.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 "pipe/p_context.h"
 
2
 
 
3
#include "nvfx_context.h"
 
4
 
 
5
struct nvfx_query {
 
6
        struct list_head list;
 
7
        struct nouveau_resource *object;
 
8
        unsigned type;
 
9
        boolean ready;
 
10
        uint64_t result;
 
11
};
 
12
 
 
13
static INLINE struct nvfx_query *
 
14
nvfx_query(struct pipe_query *pipe)
 
15
{
 
16
        return (struct nvfx_query *)pipe;
 
17
}
 
18
 
 
19
static struct pipe_query *
 
20
nvfx_query_create(struct pipe_context *pipe, unsigned query_type)
 
21
{
 
22
        struct nvfx_query *q;
 
23
 
 
24
        q = CALLOC(1, sizeof(struct nvfx_query));
 
25
        q->type = query_type;
 
26
 
 
27
        assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
 
28
 
 
29
        return (struct pipe_query *)q;
 
30
}
 
31
 
 
32
static void
 
33
nvfx_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
 
34
{
 
35
        struct nvfx_query *q = nvfx_query(pq);
 
36
 
 
37
        if (q->object)
 
38
        {
 
39
                nouveau_resource_free(&q->object);
 
40
                LIST_DEL(&q->list);
 
41
        }
 
42
        FREE(q);
 
43
}
 
44
 
 
45
static void
 
46
nvfx_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
 
47
{
 
48
        struct nvfx_context *nvfx = nvfx_context(pipe);
 
49
        struct nvfx_query *q = nvfx_query(pq);
 
50
        struct nvfx_screen *screen = nvfx->screen;
 
51
        struct nouveau_channel *chan = screen->base.channel;
 
52
        uint64_t tmp;
 
53
 
 
54
        assert(!nvfx->query);
 
55
 
 
56
        /* Happens when end_query() is called, then another begin_query()
 
57
         * without querying the result in-between.  For now we'll wait for
 
58
         * the existing query to notify completion, but it could be better.
 
59
         */
 
60
        if (q->object)
 
61
                pipe->get_query_result(pipe, pq, 1, &tmp);
 
62
 
 
63
        while (nouveau_resource_alloc(nvfx->screen->query_heap, 1, NULL, &q->object))
 
64
        {
 
65
                struct nvfx_query* oldestq;
 
66
                assert(!LIST_IS_EMPTY(&nvfx->screen->query_list));
 
67
                oldestq = LIST_ENTRY(struct nvfx_query, nvfx->screen->query_list.next, list);
 
68
                pipe->get_query_result(pipe, (struct pipe_query*)oldestq, 1, &tmp);
 
69
        }
 
70
 
 
71
        LIST_ADDTAIL(&q->list, &nvfx->screen->query_list);
 
72
 
 
73
        nouveau_notifier_reset(nvfx->screen->query, q->object->start);
 
74
 
 
75
        WAIT_RING(chan, 4);
 
76
        OUT_RING(chan, RING_3D(NV30_3D_QUERY_RESET, 1));
 
77
        OUT_RING(chan, 1);
 
78
        OUT_RING(chan, RING_3D(NV30_3D_QUERY_ENABLE, 1));
 
79
        OUT_RING(chan, 1);
 
80
 
 
81
        q->ready = FALSE;
 
82
 
 
83
        nvfx->query = pq;
 
84
}
 
85
 
 
86
static void
 
87
nvfx_query_end(struct pipe_context *pipe, struct pipe_query *pq)
 
88
{
 
89
        struct nvfx_context *nvfx = nvfx_context(pipe);
 
90
        struct nouveau_channel *chan = nvfx->screen->base.channel;
 
91
        struct nvfx_query *q = nvfx_query(pq);
 
92
 
 
93
        assert(nvfx->query == pq);
 
94
 
 
95
        WAIT_RING(chan, 4);
 
96
        OUT_RING(chan, RING_3D(NV30_3D_QUERY_GET, 1));
 
97
        OUT_RING  (chan, (0x01 << NV30_3D_QUERY_GET_UNK24__SHIFT) |
 
98
                   ((q->object->start * 32) << NV30_3D_QUERY_GET_OFFSET__SHIFT));
 
99
        OUT_RING(chan, RING_3D(NV30_3D_QUERY_ENABLE, 1));
 
100
        OUT_RING(chan, 0);
 
101
        FIRE_RING(chan);
 
102
 
 
103
        nvfx->query = 0;
 
104
}
 
105
 
 
106
static boolean
 
107
nvfx_query_result(struct pipe_context *pipe, struct pipe_query *pq,
 
108
                  boolean wait, void *vresult)
 
109
{
 
110
        uint64_t *result = (uint64_t *)vresult;
 
111
        struct nvfx_context *nvfx = nvfx_context(pipe);
 
112
        struct nvfx_query *q = nvfx_query(pq);
 
113
 
 
114
        if (!q->ready) {
 
115
                unsigned status;
 
116
 
 
117
                status = nouveau_notifier_status(nvfx->screen->query,
 
118
                                                 q->object->start);
 
119
                if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
 
120
                        if (wait == FALSE)
 
121
                                return FALSE;
 
122
 
 
123
                        nouveau_notifier_wait_status(nvfx->screen->query,
 
124
                                        q->object->start,
 
125
                                        NV_NOTIFY_STATE_STATUS_COMPLETED, 0);
 
126
                }
 
127
 
 
128
                q->result = nouveau_notifier_return_val(nvfx->screen->query,
 
129
                                                        q->object->start);
 
130
                q->ready = TRUE;
 
131
                nouveau_resource_free(&q->object);
 
132
                LIST_DEL(&q->list);
 
133
        }
 
134
 
 
135
        *result = q->result;
 
136
        return TRUE;
 
137
}
 
138
 
 
139
void
 
140
nvfx_init_query_functions(struct nvfx_context *nvfx)
 
141
{
 
142
        nvfx->pipe.create_query = nvfx_query_create;
 
143
        nvfx->pipe.destroy_query = nvfx_query_destroy;
 
144
        nvfx->pipe.begin_query = nvfx_query_begin;
 
145
        nvfx->pipe.end_query = nvfx_query_end;
 
146
        nvfx->pipe.get_query_result = nvfx_query_result;
 
147
}