Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / i965 / gen6_urb.c
1 /*
2  * Copyright © 2009 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Eric Anholt <eric@anholt.net>
25  *
26  */
27
28 #include "main/macros.h"
29 #include "intel_batchbuffer.h"
30 #include "brw_context.h"
31 #include "brw_state.h"
32 #include "brw_defines.h"
33
34 static void
35 prepare_urb( struct brw_context *brw )
36 {
37    int nr_vs_entries;
38
39    /* CACHE_NEW_VS_PROG */
40    brw->urb.vs_size = MAX2(brw->vs.prog_data->urb_entry_size, 1);
41
42    /* Calculate how many VS URB entries fit in the total URB size */
43    nr_vs_entries = (brw->urb.size * 1024) / (brw->urb.vs_size * 128);
44
45    if (nr_vs_entries > brw->urb.max_vs_entries)
46       nr_vs_entries = brw->urb.max_vs_entries;
47
48    /* According to volume 2a, nr_vs_entries must be a multiple of 4. */
49    brw->urb.nr_vs_entries = ROUND_DOWN_TO(nr_vs_entries, 4);
50
51    /* Since we currently don't support Geometry Shaders, we always put the
52     * GS unit in passthrough mode and don't allocate it any URB space.
53     */
54    brw->urb.nr_gs_entries = 0;
55    brw->urb.gs_size = 1; /* Incorrect, but with 0 GS entries it doesn't matter. */
56 }
57
58 static void
59 upload_urb(struct brw_context *brw)
60 {
61    struct intel_context *intel = &brw->intel;
62
63    assert(brw->urb.nr_vs_entries >= 24);
64    assert(brw->urb.nr_vs_entries % 4 == 0);
65    assert(brw->urb.nr_gs_entries % 4 == 0);
66    /* GS requirement */
67    assert(!brw->gs.prog_active || brw->urb.vs_size < 5);
68
69    BEGIN_BATCH(3);
70    OUT_BATCH(_3DSTATE_URB << 16 | (3 - 2));
71    OUT_BATCH(((brw->urb.vs_size - 1) << GEN6_URB_VS_SIZE_SHIFT) |
72              ((brw->urb.nr_vs_entries) << GEN6_URB_VS_ENTRIES_SHIFT));
73    OUT_BATCH(((brw->urb.gs_size - 1) << GEN6_URB_GS_SIZE_SHIFT) |
74              ((brw->urb.nr_gs_entries) << GEN6_URB_GS_ENTRIES_SHIFT));
75    ADVANCE_BATCH();
76 }
77
78 const struct brw_tracked_state gen6_urb = {
79    .dirty = {
80       .mesa = 0,
81       .brw = BRW_NEW_CONTEXT,
82       .cache = (CACHE_NEW_VS_PROG | CACHE_NEW_GS_PROG),
83    },
84    .prepare = prepare_urb,
85    .emit = upload_urb,
86 };