~ubuntu-branches/ubuntu/trusty/mesa-lts-utopic/trusty-proposed

« back to all changes in this revision

Viewing changes to src/gallium/drivers/vc4/vc4_draw.c

  • Committer: Package Import Robot
  • Author(s): Maarten Lankhorst
  • Date: 2015-01-06 10:38:32 UTC
  • Revision ID: package-import@ubuntu.com-20150106103832-u6rqp9wfmojb1gnu
Tags: upstream-10.3.2
ImportĀ upstreamĀ versionĀ 10.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2014 Scott Mansell
 
3
 * Copyright Ā© 2014 Broadcom
 
4
 *
 
5
 * Permission is hereby granted, free of charge, to any person obtaining a
 
6
 * copy of this software and associated documentation files (the "Software"),
 
7
 * to deal in the Software without restriction, including without limitation
 
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
9
 * and/or sell copies of the Software, and to permit persons to whom the
 
10
 * Software is furnished to do so, subject to the following conditions:
 
11
 *
 
12
 * The above copyright notice and this permission notice (including the next
 
13
 * paragraph) shall be included in all copies or substantial portions of the
 
14
 * Software.
 
15
 *
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 
22
 * IN THE SOFTWARE.
 
23
 */
 
24
 
 
25
#include <stdio.h>
 
26
 
 
27
#include "util/u_format.h"
 
28
#include "util/u_pack_color.h"
 
29
#include "indices/u_primconvert.h"
 
30
 
 
31
#include "vc4_context.h"
 
32
#include "vc4_resource.h"
 
33
 
 
34
/**
 
35
 * Does the initial bining command list setup for drawing to a given FBO.
 
36
 */
 
37
static void
 
38
vc4_start_draw(struct vc4_context *vc4)
 
39
{
 
40
        if (vc4->needs_flush)
 
41
                return;
 
42
 
 
43
        uint32_t width = vc4->framebuffer.width;
 
44
        uint32_t height = vc4->framebuffer.height;
 
45
        uint32_t tilew = align(width, 64) / 64;
 
46
        uint32_t tileh = align(height, 64) / 64;
 
47
 
 
48
        /* Tile alloc memory setup: We use an initial alloc size of 32b.  The
 
49
         * hardware then aligns that to 256b (we use 4096, because all of our
 
50
         * BO allocations align to that anyway), then for some reason the
 
51
         * simulator wants an extra page available, even if you have overflow
 
52
         * memory set up.
 
53
         */
 
54
        uint32_t tile_alloc_size = 32 * tilew * tileh;
 
55
        tile_alloc_size = align(tile_alloc_size, 4096);
 
56
        tile_alloc_size += 4096;
 
57
        uint32_t tile_state_size = 48 * tilew * tileh;
 
58
        if (!vc4->tile_alloc || vc4->tile_alloc->size < tile_alloc_size) {
 
59
                vc4_bo_unreference(&vc4->tile_alloc);
 
60
                vc4->tile_alloc = vc4_bo_alloc(vc4->screen, tile_alloc_size,
 
61
                                               "tile_alloc");
 
62
        }
 
63
        if (!vc4->tile_state || vc4->tile_state->size < tile_state_size) {
 
64
                vc4_bo_unreference(&vc4->tile_state);
 
65
                vc4->tile_state = vc4_bo_alloc(vc4->screen, tile_state_size,
 
66
                                               "tile_state");
 
67
        }
 
68
 
 
69
        //   Tile state data is 48 bytes per tile, I think it can be thrown away
 
70
        //   as soon as binning is finished.
 
71
        cl_start_reloc(&vc4->bcl, 2);
 
72
        cl_u8(&vc4->bcl, VC4_PACKET_TILE_BINNING_MODE_CONFIG);
 
73
        cl_reloc(vc4, &vc4->bcl, vc4->tile_alloc, 0);
 
74
        cl_u32(&vc4->bcl, vc4->tile_alloc->size);
 
75
        cl_reloc(vc4, &vc4->bcl, vc4->tile_state, 0);
 
76
        cl_u8(&vc4->bcl, tilew);
 
77
        cl_u8(&vc4->bcl, tileh);
 
78
        cl_u8(&vc4->bcl,
 
79
              VC4_BIN_CONFIG_AUTO_INIT_TSDA |
 
80
              VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_32 |
 
81
              VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_32);
 
82
 
 
83
        cl_u8(&vc4->bcl, VC4_PACKET_START_TILE_BINNING);
 
84
 
 
85
        vc4->needs_flush = true;
 
86
        vc4->draw_call_queued = true;
 
87
}
 
88
 
 
89
static void
 
90
vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 
91
{
 
92
        struct vc4_context *vc4 = vc4_context(pctx);
 
93
 
 
94
        if (info->mode >= PIPE_PRIM_QUADS) {
 
95
                util_primconvert_save_index_buffer(vc4->primconvert, &vc4->indexbuf);
 
96
                util_primconvert_save_rasterizer_state(vc4->primconvert, &vc4->rasterizer->base);
 
97
                util_primconvert_draw_vbo(vc4->primconvert, info);
 
98
                return;
 
99
        }
 
100
 
 
101
        vc4_start_draw(vc4);
 
102
        vc4_update_compiled_shaders(vc4, info->mode);
 
103
 
 
104
        vc4_emit_state(pctx);
 
105
 
 
106
        /* the actual draw call. */
 
107
        struct vc4_vertex_stateobj *vtx = vc4->vtx;
 
108
        struct vc4_vertexbuf_stateobj *vertexbuf = &vc4->vertexbuf;
 
109
        cl_u8(&vc4->bcl, VC4_PACKET_GL_SHADER_STATE);
 
110
        assert(vtx->num_elements <= 8);
 
111
        /* Note that number of attributes == 0 in the packet means 8
 
112
         * attributes.  This field also contains the offset into shader_rec.
 
113
         */
 
114
        cl_u32(&vc4->bcl, vtx->num_elements & 0x7);
 
115
 
 
116
        /* Note that the primitive type fields match with OpenGL/gallium
 
117
         * definitions, up to but not including QUADS.
 
118
         */
 
119
        if (info->indexed) {
 
120
                struct vc4_resource *rsc = vc4_resource(vc4->indexbuf.buffer);
 
121
 
 
122
                assert(vc4->indexbuf.index_size == 1 ||
 
123
                       vc4->indexbuf.index_size == 2);
 
124
 
 
125
                cl_start_reloc(&vc4->bcl, 1);
 
126
                cl_u8(&vc4->bcl, VC4_PACKET_GL_INDEXED_PRIMITIVE);
 
127
                cl_u8(&vc4->bcl,
 
128
                      info->mode |
 
129
                      (vc4->indexbuf.index_size == 2 ?
 
130
                       VC4_INDEX_BUFFER_U16:
 
131
                       VC4_INDEX_BUFFER_U8));
 
132
                cl_u32(&vc4->bcl, info->count);
 
133
                cl_reloc(vc4, &vc4->bcl, rsc->bo, vc4->indexbuf.offset);
 
134
                cl_u32(&vc4->bcl, info->max_index);
 
135
        } else {
 
136
                cl_u8(&vc4->bcl, VC4_PACKET_GL_ARRAY_PRIMITIVE);
 
137
                cl_u8(&vc4->bcl, info->mode);
 
138
                cl_u32(&vc4->bcl, info->count);
 
139
                cl_u32(&vc4->bcl, info->start);
 
140
        }
 
141
 
 
142
// Shader Record
 
143
 
 
144
        vc4_write_uniforms(vc4, vc4->prog.fs,
 
145
                           &vc4->constbuf[PIPE_SHADER_FRAGMENT],
 
146
                           &vc4->fragtex,
 
147
                           0);
 
148
        vc4_write_uniforms(vc4, vc4->prog.vs,
 
149
                           &vc4->constbuf[PIPE_SHADER_VERTEX],
 
150
                           &vc4->verttex,
 
151
                           0);
 
152
        vc4_write_uniforms(vc4, vc4->prog.vs,
 
153
                           &vc4->constbuf[PIPE_SHADER_VERTEX],
 
154
                           &vc4->verttex,
 
155
                           1);
 
156
 
 
157
        cl_start_shader_reloc(&vc4->shader_rec, 3 + vtx->num_elements);
 
158
        cl_u16(&vc4->shader_rec, VC4_SHADER_FLAG_ENABLE_CLIPPING);
 
159
        cl_u8(&vc4->shader_rec, 0); /* fs num uniforms (unused) */
 
160
        cl_u8(&vc4->shader_rec, vc4->prog.fs->num_inputs);
 
161
        cl_reloc(vc4, &vc4->shader_rec, vc4->prog.fs->bo, 0);
 
162
        cl_u32(&vc4->shader_rec, 0); /* UBO offset written by kernel */
 
163
 
 
164
        cl_u16(&vc4->shader_rec, 0); /* vs num uniforms */
 
165
        cl_u8(&vc4->shader_rec, (1 << vtx->num_elements) - 1); /* vs attribute array bitfield */
 
166
        cl_u8(&vc4->shader_rec, 16 * vtx->num_elements); /* vs total attribute size */
 
167
        cl_reloc(vc4, &vc4->shader_rec, vc4->prog.vs->bo, 0);
 
168
        cl_u32(&vc4->shader_rec, 0); /* UBO offset written by kernel */
 
169
 
 
170
        cl_u16(&vc4->shader_rec, 0); /* cs num uniforms */
 
171
        cl_u8(&vc4->shader_rec, (1 << vtx->num_elements) - 1); /* cs attribute array bitfield */
 
172
        cl_u8(&vc4->shader_rec, 16 * vtx->num_elements); /* vs total attribute size */
 
173
        cl_reloc(vc4, &vc4->shader_rec, vc4->prog.vs->bo,
 
174
                vc4->prog.vs->coord_shader_offset);
 
175
        cl_u32(&vc4->shader_rec, 0); /* UBO offset written by kernel */
 
176
 
 
177
        for (int i = 0; i < vtx->num_elements; i++) {
 
178
                struct pipe_vertex_element *elem = &vtx->pipe[i];
 
179
                struct pipe_vertex_buffer *vb =
 
180
                        &vertexbuf->vb[elem->vertex_buffer_index];
 
181
                struct vc4_resource *rsc = vc4_resource(vb->buffer);
 
182
 
 
183
                cl_reloc(vc4, &vc4->shader_rec, rsc->bo,
 
184
                         vb->buffer_offset + elem->src_offset);
 
185
                cl_u8(&vc4->shader_rec,
 
186
                      util_format_get_blocksize(elem->src_format) - 1);
 
187
                cl_u8(&vc4->shader_rec, vb->stride);
 
188
                cl_u8(&vc4->shader_rec, i * 16); /* VS VPM offset */
 
189
                cl_u8(&vc4->shader_rec, i * 16); /* CS VPM offset */
 
190
        }
 
191
 
 
192
        if (vc4->zsa && vc4->zsa->base.depth.enabled) {
 
193
                vc4->resolve |= PIPE_CLEAR_DEPTH;
 
194
        }
 
195
        vc4->resolve |= PIPE_CLEAR_COLOR0;
 
196
 
 
197
        vc4->shader_rec_count++;
 
198
}
 
199
 
 
200
static uint32_t
 
201
pack_rgba(enum pipe_format format, const float *rgba)
 
202
{
 
203
        union util_color uc;
 
204
        util_pack_color(rgba, format, &uc);
 
205
        return uc.ui[0];
 
206
}
 
207
 
 
208
static void
 
209
vc4_clear(struct pipe_context *pctx, unsigned buffers,
 
210
          const union pipe_color_union *color, double depth, unsigned stencil)
 
211
{
 
212
        struct vc4_context *vc4 = vc4_context(pctx);
 
213
 
 
214
        /* We can't flag new buffers for clearing once we've queued draws.  We
 
215
         * could avoid this by using the 3d engine to clear.
 
216
         */
 
217
        if (vc4->draw_call_queued)
 
218
                vc4_flush(pctx);
 
219
 
 
220
        if (buffers & PIPE_CLEAR_COLOR0) {
 
221
                vc4->clear_color[0] = vc4->clear_color[1] =
 
222
                        pack_rgba(vc4->framebuffer.cbufs[0]->format,
 
223
                                  color->f);
 
224
        }
 
225
 
 
226
        if (buffers & PIPE_CLEAR_DEPTH)
 
227
                vc4->clear_depth = util_pack_z(PIPE_FORMAT_Z24X8_UNORM, depth);
 
228
 
 
229
        vc4->cleared |= buffers;
 
230
        vc4->resolve |= buffers;
 
231
 
 
232
        vc4_start_draw(vc4);
 
233
}
 
234
 
 
235
static void
 
236
vc4_clear_render_target(struct pipe_context *pctx, struct pipe_surface *ps,
 
237
                        const union pipe_color_union *color,
 
238
                        unsigned x, unsigned y, unsigned w, unsigned h)
 
239
{
 
240
        fprintf(stderr, "unimpl: clear RT\n");
 
241
}
 
242
 
 
243
static void
 
244
vc4_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *ps,
 
245
                        unsigned buffers, double depth, unsigned stencil,
 
246
                        unsigned x, unsigned y, unsigned w, unsigned h)
 
247
{
 
248
        fprintf(stderr, "unimpl: clear DS\n");
 
249
}
 
250
 
 
251
void
 
252
vc4_draw_init(struct pipe_context *pctx)
 
253
{
 
254
        pctx->draw_vbo = vc4_draw_vbo;
 
255
        pctx->clear = vc4_clear;
 
256
        pctx->clear_render_target = vc4_clear_render_target;
 
257
        pctx->clear_depth_stencil = vc4_clear_depth_stencil;
 
258
}