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