• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 * batch,uint32_t offset)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
instruction_state_address(struct blorp_batch * batch,uint32_t offset)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
blorp_emit_vs_state(struct blorp_batch * batch,const struct blorp_params * params)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
blorp_emit_sf_state(struct blorp_batch * batch,const struct blorp_params * params)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
blorp_emit_wm_state(struct blorp_batch * batch,const struct blorp_params * params)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
blorp_emit_color_calc_state(struct blorp_batch * batch,const struct blorp_params * params)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
blorp_emit_pipeline(struct blorp_batch * batch,const struct blorp_params * params)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