~ubuntu-branches/ubuntu/raring/mesa/raring-proposed

« back to all changes in this revision

Viewing changes to src/gallium/drivers/r600/r600_translate.c

  • Committer: Bazaar Package Importer
  • Author(s): Cyril Brulebois
  • Date: 2011-06-19 21:26:00 UTC
  • mfrom: (1.6.1 upstream) (3.3.18 sid)
  • mto: (3.3.20 sid)
  • mto: This revision was merged to the branch mainline in revision 145.
  • Revision ID: james.westby@ubuntu.com-20110619212600-rleaapdmnbtstekb
Tags: 7.11~0-2
Thank you sbuild for giving a green light when that's not actually the
case. Fix missing Pre-Depends for the libegl1-mesa-drivers package
(multiarch-support).

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 *
23
23
 * Authors: Dave Airlie <airlied@redhat.com>
24
24
 */
25
 
#include "translate/translate_cache.h"
26
 
#include "translate/translate.h"
27
 
#include <pipebuffer/pb_buffer.h>
 
25
 
28
26
#include <util/u_index_modify.h>
 
27
#include "util/u_inlines.h"
 
28
#include "util/u_upload_mgr.h"
29
29
#include "r600_pipe.h"
30
30
 
31
 
void r600_begin_vertex_translate(struct r600_pipe_context *rctx)
32
 
{
33
 
        struct pipe_context *pipe = &rctx->context;
34
 
        struct translate_key key = {0};
35
 
        struct translate_element *te;
36
 
        unsigned tr_elem_index[PIPE_MAX_ATTRIBS] = {0};
37
 
        struct translate *tr;
38
 
        struct r600_vertex_element *ve = rctx->vertex_elements;
39
 
        boolean vb_translated[PIPE_MAX_ATTRIBS] = {0};
40
 
        void *vb_map[PIPE_MAX_ATTRIBS] = {0}, *out_map;
41
 
        struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}, *out_transfer;
42
 
        struct pipe_resource *out_buffer;
43
 
        unsigned i, num_verts;
44
 
        struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS];
45
 
        void *tmp;
46
 
 
47
 
        /* Initialize the translate key, i.e. the recipe how vertices should be
48
 
         * translated. */
49
 
        for (i = 0; i < ve->count; i++) {
50
 
                struct pipe_vertex_buffer *vb =
51
 
                        &rctx->vertex_buffer[ve->elements[i].vertex_buffer_index];
52
 
                enum pipe_format output_format = ve->hw_format[i];
53
 
                unsigned output_format_size = ve->hw_format_size[i];
54
 
 
55
 
                /* Check for support. */
56
 
                if (ve->elements[i].src_format == ve->hw_format[i]) {
57
 
                        continue;
58
 
                }
59
 
 
60
 
                /* Workaround for translate: output floats instead of halfs. */
61
 
                switch (output_format) {
62
 
                case PIPE_FORMAT_R16_FLOAT:
63
 
                        output_format = PIPE_FORMAT_R32_FLOAT;
64
 
                        output_format_size = 4;
65
 
                        break;
66
 
                case PIPE_FORMAT_R16G16_FLOAT:
67
 
                        output_format = PIPE_FORMAT_R32G32_FLOAT;
68
 
                        output_format_size = 8;
69
 
                        break;
70
 
                case PIPE_FORMAT_R16G16B16_FLOAT:
71
 
                        output_format = PIPE_FORMAT_R32G32B32_FLOAT;
72
 
                        output_format_size = 12;
73
 
                        break;
74
 
                case PIPE_FORMAT_R16G16B16A16_FLOAT:
75
 
                        output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
76
 
                        output_format_size = 16;
77
 
                        break;
78
 
                default:;
79
 
                }
80
 
 
81
 
                /* Add this vertex element. */
82
 
                te = &key.element[key.nr_elements];
83
 
                /*te->type;
84
 
                  te->instance_divisor;*/
85
 
                te->input_buffer = ve->elements[i].vertex_buffer_index;
86
 
                te->input_format = ve->elements[i].src_format;
87
 
                te->input_offset = vb->buffer_offset + ve->elements[i].src_offset;
88
 
                te->output_format = output_format;
89
 
                te->output_offset = key.output_stride;
90
 
 
91
 
                key.output_stride += output_format_size;
92
 
                vb_translated[ve->elements[i].vertex_buffer_index] = TRUE;
93
 
                tr_elem_index[i] = key.nr_elements;
94
 
                key.nr_elements++;
95
 
        }
96
 
 
97
 
        /* Get a translate object. */
98
 
        tr = translate_cache_find(rctx->tran.translate_cache, &key);
99
 
 
100
 
        /* Map buffers we want to translate. */
101
 
        for (i = 0; i < rctx->nvertex_buffer; i++) {
102
 
                if (vb_translated[i]) {
103
 
                        struct pipe_vertex_buffer *vb = &rctx->vertex_buffer[i];
104
 
 
105
 
                        vb_map[i] = pipe_buffer_map(pipe, vb->buffer,
106
 
                                                    PIPE_TRANSFER_READ, &vb_transfer[i]);
107
 
 
108
 
                        tr->set_buffer(tr, i, vb_map[i], vb->stride, vb->max_index);
109
 
                }
110
 
        }
111
 
 
112
 
        /* Create and map the output buffer. */
113
 
        num_verts = rctx->vb_max_index + 1;
114
 
 
115
 
        out_buffer = pipe_buffer_create(&rctx->screen->screen,
116
 
                                        PIPE_BIND_VERTEX_BUFFER,
117
 
                                        key.output_stride * num_verts);
118
 
 
119
 
        out_map = pipe_buffer_map(pipe, out_buffer, PIPE_TRANSFER_WRITE,
120
 
                                  &out_transfer);
121
 
 
122
 
        /* Translate. */
123
 
        tr->run(tr, 0, num_verts, 0, out_map);
124
 
 
125
 
        /* Unmap all buffers. */
126
 
        for (i = 0; i < rctx->nvertex_buffer; i++) {
127
 
                if (vb_translated[i]) {
128
 
                        pipe_buffer_unmap(pipe, rctx->vertex_buffer[i].buffer,
129
 
                                          vb_transfer[i]);
130
 
                }
131
 
        }
132
 
 
133
 
        pipe_buffer_unmap(pipe, out_buffer, out_transfer);
134
 
 
135
 
        /* Setup the new vertex buffer in the first free slot. */
136
 
        for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
137
 
                struct pipe_vertex_buffer *vb = &rctx->vertex_buffer[i];
138
 
 
139
 
                if (!vb->buffer) {
140
 
                        pipe_resource_reference(&vb->buffer, out_buffer);
141
 
                        vb->buffer_offset = 0;
142
 
                        vb->max_index = num_verts - 1;
143
 
                        vb->stride = key.output_stride;
144
 
                        rctx->tran.vb_slot = i;
145
 
                        break;
146
 
                }
147
 
        }
148
 
 
149
 
        /* Save and replace vertex elements. */
150
 
        for (i = 0; i < ve->count; i++) {
151
 
                if (vb_translated[ve->elements[i].vertex_buffer_index]) {
152
 
                        te = &key.element[tr_elem_index[i]];
153
 
                        new_velems[i].instance_divisor = ve->elements[i].instance_divisor;
154
 
                        new_velems[i].src_format = te->output_format;
155
 
                        new_velems[i].src_offset = te->output_offset;
156
 
                        new_velems[i].vertex_buffer_index = rctx->tran.vb_slot;
157
 
                } else {
158
 
                        memcpy(&new_velems[i], &ve->elements[i],
159
 
                                        sizeof(struct pipe_vertex_element));
160
 
                }
161
 
        }
162
 
 
163
 
        tmp = pipe->create_vertex_elements_state(pipe, ve->count, new_velems);
164
 
        pipe->bind_vertex_elements_state(pipe, tmp);
165
 
        rctx->tran.new_velems = tmp;
166
 
 
167
 
        pipe_resource_reference(&out_buffer, NULL);
168
 
}
169
 
 
170
 
void r600_end_vertex_translate(struct r600_pipe_context *rctx)
171
 
{
172
 
        struct pipe_context *pipe = &rctx->context;
173
 
 
174
 
        if (rctx->tran.new_velems == NULL) {
175
 
                return;
176
 
        }
177
 
        /* Restore vertex elements. */
178
 
        pipe->delete_vertex_elements_state(pipe, rctx->tran.new_velems);
179
 
        rctx->tran.new_velems = NULL;
180
 
 
181
 
        /* Delete the now-unused VBO. */
182
 
        pipe_resource_reference(&rctx->vertex_buffer[rctx->tran.vb_slot].buffer, NULL);
183
 
}
184
31
 
185
32
void r600_translate_index_buffer(struct r600_pipe_context *r600,
186
 
                                        struct pipe_resource **index_buffer,
187
 
                                        unsigned *index_size,
188
 
                                        unsigned *start, unsigned count)
 
33
                                 struct pipe_resource **index_buffer,
 
34
                                 unsigned *index_size,
 
35
                                 unsigned *start, unsigned count)
189
36
{
 
37
        struct pipe_resource *out_buffer = NULL;
 
38
        unsigned out_offset;
 
39
        void *ptr;
 
40
        boolean flushed;
 
41
 
190
42
        switch (*index_size) {
191
43
        case 1:
192
 
                util_shorten_ubyte_elts(&r600->context, index_buffer, 0, *start, count);
 
44
                u_upload_alloc(r600->vbuf_mgr->uploader, 0, count * 2,
 
45
                               &out_offset, &out_buffer, &flushed, &ptr);
 
46
 
 
47
                util_shorten_ubyte_elts_to_userptr(
 
48
                                &r600->context, *index_buffer, 0, *start, count, ptr);
 
49
 
 
50
                pipe_resource_reference(index_buffer, out_buffer);
 
51
                pipe_resource_reference(&out_buffer, NULL);
193
52
                *index_size = 2;
194
 
                *start = 0;
195
 
                break;
196
 
        case 2:
197
 
        case 4:
 
53
                *start = out_offset / 2;
198
54
                break;
199
55
        }
200
56
}