1 /* 2 * Copyright 2016 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 24 static inline struct blorp_address 25 dynamic_state_address(struct blorp_batch *batch, uint32_t offset) 26 { 27 assert(batch->blorp->driver_ctx == batch->driver_batch); 28 struct brw_context *brw = batch->driver_batch; 29 30 return (struct blorp_address) { 31 .buffer = brw->batch.state.bo, 32 .offset = offset, 33 }; 34 } 35 36 static inline struct blorp_address 37 instruction_state_address(struct blorp_batch *batch, uint32_t offset) 38 { 39 assert(batch->blorp->driver_ctx == batch->driver_batch); 40 struct brw_context *brw = batch->driver_batch; 41 42 return (struct blorp_address) { 43 .buffer = brw->cache.bo, 44 .offset = offset, 45 }; 46 } 47 48 static struct blorp_address 49 blorp_emit_vs_state(struct blorp_batch *batch, 50 const struct blorp_params *params) 51 { 52 assert(batch->blorp->driver_ctx == batch->driver_batch); 53 struct brw_context *brw = batch->driver_batch; 54 55 uint32_t offset; 56 blorp_emit_dynamic(batch, GENX(VS_STATE), vs, 64, &offset) { 57 vs.Enable = false; 58 vs.URBEntryAllocationSize = brw->urb.vsize - 1; 59 #if GEN_GEN == 5 60 vs.NumberofURBEntries = brw->urb.nr_vs_entries >> 2; 61 #else 62 vs.NumberofURBEntries = brw->urb.nr_vs_entries; 63 #endif 64 } 65 66 return dynamic_state_address(batch, offset); 67 } 68 69 static struct blorp_address 70 blorp_emit_sf_state(struct blorp_batch *batch, 71 const struct blorp_params *params) 72 { 73 assert(batch->blorp->driver_ctx == batch->driver_batch); 74 struct brw_context *brw = batch->driver_batch; 75 const struct brw_sf_prog_data *prog_data = params->sf_prog_data; 76 77 uint32_t offset; 78 blorp_emit_dynamic(batch, GENX(SF_STATE), sf, 64, &offset) { 79 #if GEN_GEN == 4 80 sf.KernelStartPointer = 81 instruction_state_address(batch, params->sf_prog_kernel); 82 #else 83 sf.KernelStartPointer = params->sf_prog_kernel; 84 #endif 85 sf.GRFRegisterCount = DIV_ROUND_UP(prog_data->total_grf, 16) - 1; 86 sf.VertexURBEntryReadLength = prog_data->urb_read_length; 87 sf.VertexURBEntryReadOffset = BRW_SF_URB_ENTRY_READ_OFFSET; 88 sf.DispatchGRFStartRegisterForURBData = 3; 89 90 sf.URBEntryAllocationSize = brw->urb.sfsize - 1; 91 sf.NumberofURBEntries = brw->urb.nr_sf_entries; 92 93 #if GEN_GEN == 5 94 sf.MaximumNumberofThreads = MIN2(48, brw->urb.nr_sf_entries) - 1; 95 #else 96 sf.MaximumNumberofThreads = MIN2(24, brw->urb.nr_sf_entries) - 1; 97 #endif 98 99 sf.ViewportTransformEnable = false; 100 101 sf.CullMode = CULLMODE_NONE; 102 } 103 104 return dynamic_state_address(batch, offset); 105 } 106 107 static struct blorp_address 108 blorp_emit_wm_state(struct blorp_batch *batch, 109 const struct blorp_params *params) 110 { 111 const struct brw_wm_prog_data *prog_data = params->wm_prog_data; 112 113 uint32_t offset; 114 blorp_emit_dynamic(batch, GENX(WM_STATE), wm, 64, &offset) { 115 if (params->src.enabled) { 116 /* Iron Lake can't do sampler prefetch */ 117 wm.SamplerCount = (GEN_GEN != 5); 118 wm.BindingTableEntryCount = 2; 119 uint32_t sampler = blorp_emit_sampler_state(batch, params); 120 wm.SamplerStatePointer = dynamic_state_address(batch, sampler); 121 } 122 123 if (prog_data) { 124 wm.DispatchGRFStartRegisterForConstantSetupData0 = 125 prog_data->base.dispatch_grf_start_reg; 126 wm.SetupURBEntryReadLength = prog_data->num_varying_inputs * 2; 127 wm.SetupURBEntryReadOffset = 0; 128 129 wm.DepthCoefficientURBReadOffset = 1; 130 wm.PixelShaderKillsPixel = prog_data->uses_kill; 131 wm.ThreadDispatchEnable = true; 132 wm.EarlyDepthTestEnable = true; 133 134 wm._8PixelDispatchEnable = prog_data->dispatch_8; 135 wm._16PixelDispatchEnable = prog_data->dispatch_16; 136 137 #if GEN_GEN == 4 138 wm.KernelStartPointer0 = 139 instruction_state_address(batch, params->wm_prog_kernel); 140 wm.GRFRegisterCount0 = prog_data->reg_blocks_0; 141 #else 142 wm.KernelStartPointer0 = params->wm_prog_kernel; 143 wm.GRFRegisterCount0 = prog_data->reg_blocks_0; 144 wm.KernelStartPointer2 = 145 params->wm_prog_kernel + prog_data->prog_offset_2; 146 wm.GRFRegisterCount2 = prog_data->reg_blocks_2; 147 #endif 148 } 149 150 wm.MaximumNumberofThreads = 151 batch->blorp->compiler->devinfo->max_wm_threads - 1; 152 } 153 154 return dynamic_state_address(batch, offset); 155 } 156 157 static struct blorp_address 158 blorp_emit_color_calc_state(struct blorp_batch *batch, 159 const struct blorp_params *params) 160 { 161 uint32_t cc_viewport = blorp_emit_cc_viewport(batch, params); 162 163 uint32_t offset; 164 blorp_emit_dynamic(batch, GENX(COLOR_CALC_STATE), cc, 64, &offset) { 165 cc.CCViewportStatePointer = dynamic_state_address(batch, cc_viewport); 166 } 167 168 return dynamic_state_address(batch, offset); 169 } 170 171 static void 172 blorp_emit_pipeline(struct blorp_batch *batch, 173 const struct blorp_params *params) 174 { 175 assert(batch->blorp->driver_ctx == batch->driver_batch); 176 struct brw_context *brw = batch->driver_batch; 177 178 emit_urb_config(batch, params); 179 180 blorp_emit(batch, GENX(3DSTATE_PIPELINED_POINTERS), pp) { 181 pp.PointertoVSState = blorp_emit_vs_state(batch, params); 182 pp.GSEnable = false; 183 pp.ClipEnable = false; 184 pp.PointertoSFState = blorp_emit_sf_state(batch, params); 185 pp.PointertoWMState = blorp_emit_wm_state(batch, params); 186 pp.PointertoColorCalcState = blorp_emit_color_calc_state(batch, params); 187 } 188 189 brw_upload_urb_fence(brw); 190 191 blorp_emit(batch, GENX(CS_URB_STATE), curb); 192 blorp_emit(batch, GENX(CONSTANT_BUFFER), curb); 193 } 194