• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 2014 LunarG, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the 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
22  * DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Chia-I Wu <olv@lunarg.com>
26  */
27 
28 #ifndef ILO_BUILDER_MEDIA_H
29 #define ILO_BUILDER_MEDIA_H
30 
31 #include "genhw/genhw.h"
32 #include "intel_winsys.h"
33 
34 #include "ilo_core.h"
35 #include "ilo_dev.h"
36 #include "ilo_state_compute.h"
37 #include "ilo_builder.h"
38 
39 static inline void
gen6_MEDIA_VFE_STATE(struct ilo_builder * builder,const struct ilo_state_compute * compute)40 gen6_MEDIA_VFE_STATE(struct ilo_builder *builder,
41                      const struct ilo_state_compute *compute)
42 {
43    const uint8_t cmd_len = 8;
44    uint32_t *dw;
45 
46    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
47 
48    ilo_builder_batch_pointer(builder, cmd_len, &dw);
49 
50    dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_VFE_STATE) | (cmd_len - 2);
51    /* see compute_set_gen6_MEDIA_VFE_STATE() */
52    dw[1] = compute->vfe[0];
53    dw[2] = compute->vfe[1];
54    dw[3] = 0;
55    dw[4] = compute->vfe[2];
56    dw[5] = 0;
57    dw[6] = 0;
58    dw[7] = 0;
59 }
60 
61 static inline void
gen6_MEDIA_CURBE_LOAD(struct ilo_builder * builder,uint32_t offset,unsigned size)62 gen6_MEDIA_CURBE_LOAD(struct ilo_builder *builder,
63                       uint32_t offset, unsigned size)
64 {
65    const uint8_t cmd_len = 4;
66    uint32_t *dw;
67 
68    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
69 
70    assert(offset % 32 == 0 && size % 32 == 0);
71    /* GPU hangs if size is zero */
72    assert(size);
73 
74    ilo_builder_batch_pointer(builder, cmd_len, &dw);
75 
76    dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_CURBE_LOAD) | (cmd_len - 2);
77    dw[1] = 0;
78    dw[2] = size;
79    dw[3] = offset;
80 }
81 
82 static inline void
gen6_MEDIA_INTERFACE_DESCRIPTOR_LOAD(struct ilo_builder * builder,uint32_t offset,unsigned size)83 gen6_MEDIA_INTERFACE_DESCRIPTOR_LOAD(struct ilo_builder *builder,
84                                      uint32_t offset, unsigned size)
85 {
86    const uint8_t cmd_len = 4;
87    const unsigned idrt_alloc =
88       ((ilo_dev_gen(builder->dev) >= ILO_GEN(7.5)) ? 64 : 32) * 32;
89    uint32_t *dw;
90 
91    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
92 
93    assert(offset % 32 == 0 && size % 32 == 0);
94    assert(size && size <= idrt_alloc);
95 
96    ilo_builder_batch_pointer(builder, cmd_len, &dw);
97 
98    dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_INTERFACE_DESCRIPTOR_LOAD) |
99            (cmd_len - 2);
100    dw[1] = 0;
101    dw[2] = size;
102    dw[3] = offset;
103 }
104 
105 static inline void
gen6_MEDIA_STATE_FLUSH(struct ilo_builder * builder)106 gen6_MEDIA_STATE_FLUSH(struct ilo_builder *builder)
107 {
108    const uint8_t cmd_len = 2;
109    uint32_t *dw;
110 
111    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
112 
113    ilo_builder_batch_pointer(builder, cmd_len, &dw);
114 
115    dw[0] = GEN6_RENDER_CMD(MEDIA, MEDIA_STATE_FLUSH) | (cmd_len - 2);
116    dw[1] = 0;
117 }
118 
119 static inline void
gen7_GPGPU_WALKER(struct ilo_builder * builder,const unsigned thread_group_offset[3],const unsigned thread_group_dim[3],unsigned thread_group_size,unsigned simd_size)120 gen7_GPGPU_WALKER(struct ilo_builder *builder,
121                   const unsigned thread_group_offset[3],
122                   const unsigned thread_group_dim[3],
123                   unsigned thread_group_size,
124                   unsigned simd_size)
125 {
126    const uint8_t cmd_len = 11;
127    uint32_t right_execmask, bottom_execmask;
128    unsigned thread_count;
129    uint32_t *dw;
130 
131    ILO_DEV_ASSERT(builder->dev, 7, 7.5);
132 
133    assert(simd_size == 16 || simd_size == 8);
134 
135    thread_count = (thread_group_size + simd_size - 1) / simd_size;
136    assert(thread_count <= 64);
137 
138    right_execmask = thread_group_size % simd_size;
139    if (right_execmask)
140       right_execmask = (1 << right_execmask) - 1;
141    else
142       right_execmask = (1 << simd_size) - 1;
143 
144    bottom_execmask = 0xffffffff;
145 
146    ilo_builder_batch_pointer(builder, cmd_len, &dw);
147 
148    dw[0] = GEN7_RENDER_CMD(MEDIA, GPGPU_WALKER) | (cmd_len - 2);
149    dw[1] = 0; /* always first IDRT */
150 
151    dw[2] = (thread_count - 1) << GEN7_GPGPU_DW2_THREAD_MAX_X__SHIFT;
152    if (simd_size == 16)
153       dw[2] |= GEN7_GPGPU_DW2_SIMD_SIZE_SIMD16;
154    else
155       dw[2] |= GEN7_GPGPU_DW2_SIMD_SIZE_SIMD8;
156 
157    dw[3] = thread_group_offset[0];
158    dw[4] = thread_group_dim[0];
159    dw[5] = thread_group_offset[1];
160    dw[6] = thread_group_dim[1];
161    dw[7] = thread_group_offset[2];
162    dw[8] = thread_group_dim[2];
163 
164    dw[9] = right_execmask;
165    dw[10] = bottom_execmask;
166 }
167 
168 static inline uint32_t
gen6_INTERFACE_DESCRIPTOR_DATA(struct ilo_builder * builder,const struct ilo_state_compute * compute,const uint32_t * kernel_offsets,const uint32_t * sampler_offsets,const uint32_t * binding_table_offsets)169 gen6_INTERFACE_DESCRIPTOR_DATA(struct ilo_builder *builder,
170                                const struct ilo_state_compute *compute,
171                                const uint32_t *kernel_offsets,
172                                const uint32_t *sampler_offsets,
173                                const uint32_t *binding_table_offsets)
174 {
175    /*
176     * From the Sandy Bridge PRM, volume 2 part 2, page 34:
177     *
178     *     "(Interface Descriptor Total Length) This field must have the same
179     *      alignment as the Interface Descriptor Data Start Address.
180     *
181     *      It must be DQWord (32-byte) aligned..."
182     *
183     * From the Sandy Bridge PRM, volume 2 part 2, page 35:
184     *
185     *     "(Interface Descriptor Data Start Address) Specifies the 32-byte
186     *      aligned address of the Interface Descriptor data."
187     */
188    const int state_align = 32;
189    const int state_len = (32 / 4) * compute->idrt_count;
190    uint32_t state_offset, *dw;
191    int i;
192 
193    ILO_DEV_ASSERT(builder->dev, 6, 7.5);
194 
195    state_offset = ilo_builder_dynamic_pointer(builder,
196          ILO_BUILDER_ITEM_INTERFACE_DESCRIPTOR, state_align, state_len, &dw);
197 
198    for (i = 0; i < compute->idrt_count; i++) {
199       /* see compute_set_gen6_INTERFACE_DESCRIPTOR_DATA() */
200       dw[0] = compute->idrt[i][0] + kernel_offsets[i];
201       dw[1] = 0;
202       dw[2] = compute->idrt[i][1] |
203               sampler_offsets[i];
204       dw[3] = compute->idrt[i][2] |
205               binding_table_offsets[i];
206       dw[4] = compute->idrt[i][3];
207       dw[5] = compute->idrt[i][4];
208       dw[6] = compute->idrt[i][5];
209       dw[7] = 0;
210 
211       dw += 8;
212    }
213 
214    return state_offset;
215 }
216 
217 #endif /* ILO_BUILDER_MEDIA_H */
218