Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / drivers / cell / ppu / cell_fence.c
1 /**************************************************************************
2  * 
3  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4  * All Rights Reserved.
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  * 
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  * 
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  * 
26  **************************************************************************/
27
28 #include <unistd.h>
29 #include "util/u_memory.h"
30 #include "util/u_inlines.h"
31 #include "cell_context.h"
32 #include "cell_batch.h"
33 #include "cell_fence.h"
34 #include "cell_texture.h"
35
36
37 void
38 cell_fence_init(struct cell_fence *fence)
39 {
40    uint i;
41    ASSERT_ALIGN16(fence->status);
42    for (i = 0; i < CELL_MAX_SPUS; i++) {
43       fence->status[i][0] = CELL_FENCE_IDLE;
44    }
45 }
46
47
48 boolean
49 cell_fence_signalled(const struct cell_context *cell,
50                      const struct cell_fence *fence)
51 {
52    uint i;
53    for (i = 0; i < cell->num_spus; i++) {
54       if (fence->status[i][0] != CELL_FENCE_SIGNALLED)
55          return FALSE;
56       /*assert(fence->status[i][0] == CELL_FENCE_EMITTED);*/
57    }
58    return TRUE;
59 }
60
61
62 boolean
63 cell_fence_finish(const struct cell_context *cell,
64                   const struct cell_fence *fence,
65                   uint64_t timeout)
66 {
67    while (!cell_fence_signalled(cell, fence)) {
68       usleep(10);
69    }
70
71 #ifdef DEBUG
72    {
73       uint i;
74       for (i = 0; i < cell->num_spus; i++) {
75          assert(fence->status[i][0] == CELL_FENCE_SIGNALLED);
76       }
77    }
78 #endif
79    return TRUE;
80 }
81
82
83
84
85 struct cell_buffer_node
86 {
87    struct pipe_resource *buffer;
88    struct cell_buffer_node *next;
89 };
90
91
92 #if 0
93 static void
94 cell_add_buffer_to_list(struct cell_context *cell,
95                         struct cell_buffer_list *list,
96                         struct pipe_resource *buffer)
97 {
98    struct cell_buffer_node *node = CALLOC_STRUCT(cell_buffer_node);
99    /* create new list node which references the buffer, insert at head */
100    if (node) {
101       pipe_resource_reference(&node->buffer, buffer);
102       node->next = list->head;
103       list->head = node;
104    }
105 }
106 #endif
107
108
109 /**
110  * Wait for completion of the given fence, then unreference any buffers
111  * on the list.
112  * This typically unrefs/frees texture buffers after any rendering which uses
113  * them has completed.
114  */
115 void
116 cell_free_fenced_buffers(struct cell_context *cell,
117                          struct cell_buffer_list *list)
118 {
119    if (list->head) {
120       /*struct pipe_screen *ps = cell->pipe.screen;*/
121       struct cell_buffer_node *node;
122
123       cell_fence_finish(cell, &list->fence);
124
125       /* traverse the list, unreferencing buffers, freeing nodes */
126       node = list->head;
127       while (node) {
128          struct cell_buffer_node *next = node->next;
129          assert(node->buffer);
130          /* XXX need this? pipe_buffer_unmap(ps, node->buffer);*/
131 #if 0
132          printf("Unref buffer %p\n", node->buffer);
133          if (node->buffer->reference.count == 1)
134             printf("   Delete!\n");
135 #endif
136          pipe_resource_reference(&node->buffer, NULL);
137          FREE(node);
138          node = next;
139       }
140       list->head = NULL;
141    }
142 }
143
144
145 /**
146  * This should be called for each render command.
147  * Any texture buffers that are current bound will be added to a fenced
148  * list to be freed later when the fence is executed/signalled.
149  */
150 void
151 cell_add_fenced_textures(struct cell_context *cell)
152 {
153    /*struct cell_buffer_list *list = &cell->fenced_buffers[cell->cur_batch];*/
154    uint i;
155
156    for (i = 0; i < cell->num_textures; i++) {
157       struct cell_resource *ct = cell->texture[i];
158       if (ct) {
159 #if 0
160          printf("Adding texture %p buffer %p to list\n",
161                 ct, ct->tiled_buffer[level]);
162 #endif
163 #if 00
164          /* XXX this needs to be fixed/restored!
165           * Maybe keep pointers to textures, not buffers.
166           */
167          if (ct->base.buffer)
168             cell_add_buffer_to_list(cell, list, ct->buffer);
169 #endif
170       }
171    }
172 }