1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2012-2013 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 #include "toy_compiler.h" 29 #include "toy_helpers.h" 30 #include "toy_legalize.h" 31 #include "toy_optimize.h" 32 #include "ilo_shader_internal.h" 33 34 struct cs_compile_context { 35 struct ilo_shader *shader; 36 const struct ilo_shader_variant *variant; 37 38 struct toy_compiler tc; 39 40 int first_free_grf; 41 int last_free_grf; 42 43 int num_grf_per_vrf; 44 45 int first_free_mrf; 46 int last_free_mrf; 47 }; 48 49 /** 50 * Compile the shader. 51 */ 52 static bool 53 cs_compile(struct cs_compile_context *ccc) 54 { 55 struct toy_compiler *tc = &ccc->tc; 56 struct ilo_shader *sh = ccc->shader; 57 58 toy_compiler_legalize_for_ra(tc); 59 toy_compiler_optimize(tc); 60 toy_compiler_allocate_registers(tc, 61 ccc->first_free_grf, 62 ccc->last_free_grf, 63 ccc->num_grf_per_vrf); 64 toy_compiler_legalize_for_asm(tc); 65 66 if (tc->fail) { 67 ilo_err("failed to legalize FS instructions: %s\n", tc->reason); 68 return false; 69 } 70 71 if (ilo_debug & ILO_DEBUG_CS) { 72 ilo_printf("legalized instructions:\n"); 73 toy_compiler_dump(tc); 74 ilo_printf("\n"); 75 } 76 77 if (true) { 78 sh->kernel = toy_compiler_assemble(tc, &sh->kernel_size); 79 } else { 80 static const uint32_t microcode[] = { 81 /* fill in the microcode here */ 82 0x0, 0x0, 0x0, 0x0, 83 }; 84 const bool swap = true; 85 86 sh->kernel_size = sizeof(microcode); 87 sh->kernel = MALLOC(sh->kernel_size); 88 89 if (sh->kernel) { 90 const int num_dwords = sizeof(microcode) / 4; 91 const uint32_t *src = microcode; 92 uint32_t *dst = (uint32_t *) sh->kernel; 93 int i; 94 95 for (i = 0; i < num_dwords; i += 4) { 96 if (swap) { 97 dst[i + 0] = src[i + 3]; 98 dst[i + 1] = src[i + 2]; 99 dst[i + 2] = src[i + 1]; 100 dst[i + 3] = src[i + 0]; 101 } 102 else { 103 memcpy(dst, src, 16); 104 } 105 } 106 } 107 } 108 109 if (!sh->kernel) { 110 ilo_err("failed to compile CS: %s\n", tc->reason); 111 return false; 112 } 113 114 if (ilo_debug & ILO_DEBUG_CS) { 115 ilo_printf("disassembly:\n"); 116 toy_compiler_disassemble(tc->dev, sh->kernel, sh->kernel_size, false); 117 ilo_printf("\n"); 118 } 119 120 return true; 121 } 122 123 static void 124 cs_dummy(struct cs_compile_context *ccc) 125 { 126 struct toy_compiler *tc = &ccc->tc; 127 struct toy_dst header; 128 struct toy_src r0, desc; 129 struct toy_inst *inst; 130 131 header = tdst_ud(tdst(TOY_FILE_MRF, ccc->first_free_mrf, 0)); 132 r0 = tsrc_ud(tsrc(TOY_FILE_GRF, 0, 0)); 133 134 inst = tc_MOV(tc, header, r0); 135 inst->exec_size = GEN6_EXECSIZE_8; 136 inst->mask_ctrl = GEN6_MASKCTRL_NOMASK; 137 138 desc = tsrc_imm_mdesc(tc, true, 1, 0, true, 139 GEN6_MSG_TS_RESOURCE_SELECT_NO_DEREF | 140 GEN6_MSG_TS_REQUESTER_TYPE_ROOT | 141 GEN6_MSG_TS_OPCODE_DEREF); 142 143 tc_SEND(tc, tdst_null(), tsrc_from(header), desc, GEN6_SFID_SPAWNER); 144 } 145 146 static bool 147 cs_setup(struct cs_compile_context *ccc, 148 const struct ilo_shader_state *state, 149 const struct ilo_shader_variant *variant) 150 { 151 memset(ccc, 0, sizeof(*ccc)); 152 153 ccc->shader = CALLOC_STRUCT(ilo_shader); 154 if (!ccc->shader) 155 return false; 156 157 ccc->variant = variant; 158 159 toy_compiler_init(&ccc->tc, state->info.dev); 160 161 ccc->tc.templ.access_mode = GEN6_ALIGN_1; 162 ccc->tc.templ.qtr_ctrl = GEN6_QTRCTRL_1H; 163 ccc->tc.templ.exec_size = GEN6_EXECSIZE_16; 164 ccc->tc.rect_linear_width = 8; 165 166 ccc->first_free_grf = 1; 167 ccc->last_free_grf = 127; 168 169 /* m0 is reserved for system routines */ 170 ccc->first_free_mrf = 1; 171 ccc->last_free_mrf = 15; 172 173 /* instructions are compressed with GEN6_EXECSIZE_16 */ 174 ccc->num_grf_per_vrf = 2; 175 176 if (ilo_dev_gen(ccc->tc.dev) >= ILO_GEN(7)) { 177 ccc->last_free_grf -= 15; 178 ccc->first_free_mrf = ccc->last_free_grf + 1; 179 ccc->last_free_mrf = ccc->first_free_mrf + 14; 180 } 181 182 ccc->shader->in.start_grf = 1; 183 ccc->shader->dispatch_16 = true; 184 185 /* INPUT */ 186 ccc->shader->bt.const_base = 0; 187 ccc->shader->bt.const_count = 1; 188 189 /* a GLOBAL */ 190 ccc->shader->bt.global_base = 1; 191 ccc->shader->bt.global_count = 1; 192 193 ccc->shader->bt.total_count = 2; 194 195 return true; 196 } 197 198 /** 199 * Compile the compute shader. 200 */ 201 struct ilo_shader * 202 ilo_shader_compile_cs(const struct ilo_shader_state *state, 203 const struct ilo_shader_variant *variant) 204 { 205 struct cs_compile_context ccc; 206 207 ILO_DEV_ASSERT(state->info.dev, 7, 7.5); 208 209 if (!cs_setup(&ccc, state, variant)) 210 return NULL; 211 212 cs_dummy(&ccc); 213 214 if (!cs_compile(&ccc)) { 215 FREE(ccc.shader); 216 ccc.shader = NULL; 217 } 218 219 toy_compiler_cleanup(&ccc.tc); 220 221 return ccc.shader; 222 } 223