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 (at) 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 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 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 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 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 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 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