2 * Copyright © 2016 Intel Corporation
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:
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
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
24 static inline struct blorp_address
25 dynamic_state_address(struct blorp_batch
*batch
, uint32_t offset
)
27 assert(batch
->blorp
->driver_ctx
== batch
->driver_batch
);
28 struct brw_context
*brw
= batch
->driver_batch
;
30 return (struct blorp_address
) {
31 .buffer
= brw
->batch
.state_bo
,
36 static inline struct blorp_address
37 instruction_state_address(struct blorp_batch
*batch
, uint32_t offset
)
39 assert(batch
->blorp
->driver_ctx
== batch
->driver_batch
);
40 struct brw_context
*brw
= batch
->driver_batch
;
42 return (struct blorp_address
) {
43 .buffer
= brw
->cache
.bo
,
48 static struct blorp_address
49 blorp_emit_vs_state(struct blorp_batch
*batch
,
50 const struct blorp_params
*params
)
52 assert(batch
->blorp
->driver_ctx
== batch
->driver_batch
);
53 struct brw_context
*brw
= batch
->driver_batch
;
56 blorp_emit_dynamic(batch
, GENX(VS_STATE
), vs
, 64, &offset
) {
58 vs
.URBEntryAllocationSize
= brw
->urb
.vsize
- 1;
60 vs
.NumberofURBEntries
= brw
->urb
.nr_vs_entries
>> 2;
62 vs
.NumberofURBEntries
= brw
->urb
.nr_vs_entries
;
66 return dynamic_state_address(batch
, offset
);
69 static struct blorp_address
70 blorp_emit_sf_state(struct blorp_batch
*batch
,
71 const struct blorp_params
*params
)
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
;
78 blorp_emit_dynamic(batch
, GENX(SF_STATE
), sf
, 64, &offset
) {
80 sf
.KernelStartPointer
=
81 instruction_state_address(batch
, params
->sf_prog_kernel
);
83 sf
.KernelStartPointer
= params
->sf_prog_kernel
;
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;
90 sf
.URBEntryAllocationSize
= brw
->urb
.sfsize
- 1;
91 sf
.NumberofURBEntries
= brw
->urb
.nr_sf_entries
;
94 sf
.MaximumNumberofThreads
= MIN2(48, brw
->urb
.nr_sf_entries
) - 1;
96 sf
.MaximumNumberofThreads
= MIN2(24, brw
->urb
.nr_sf_entries
) - 1;
99 sf
.ViewportTransformEnable
= false;
101 sf
.CullMode
= CULLMODE_NONE
;
104 return dynamic_state_address(batch
, offset
);
107 static struct blorp_address
108 blorp_emit_wm_state(struct blorp_batch
*batch
,
109 const struct blorp_params
*params
)
111 const struct brw_wm_prog_data
*prog_data
= params
->wm_prog_data
;
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
);
124 wm
.DispatchGRFStartRegisterForConstantSetupData0
=
125 prog_data
->base
.dispatch_grf_start_reg
;
126 wm
.SetupURBEntryReadLength
= prog_data
->num_varying_inputs
* 2;
127 wm
.SetupURBEntryReadOffset
= 0;
129 wm
.DepthCoefficientURBReadOffset
= 1;
130 wm
.PixelShaderKillsPixel
= prog_data
->uses_kill
;
131 wm
.ThreadDispatchEnable
= true;
132 wm
.EarlyDepthTestEnable
= true;
134 wm
._8PixelDispatchEnable
= prog_data
->dispatch_8
;
135 wm
._16PixelDispatchEnable
= prog_data
->dispatch_16
;
138 wm
.KernelStartPointer0
=
139 instruction_state_address(batch
, params
->wm_prog_kernel
);
140 wm
.GRFRegisterCount0
= prog_data
->reg_blocks_0
;
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
;
150 wm
.MaximumNumberofThreads
=
151 batch
->blorp
->compiler
->devinfo
->max_wm_threads
- 1;
154 return dynamic_state_address(batch
, offset
);
157 static struct blorp_address
158 blorp_emit_color_calc_state(struct blorp_batch
*batch
,
159 const struct blorp_params
*params
)
161 uint32_t cc_viewport
= blorp_emit_cc_viewport(batch
, params
);
164 blorp_emit_dynamic(batch
, GENX(COLOR_CALC_STATE
), cc
, 64, &offset
) {
165 cc
.CCViewportStatePointer
= dynamic_state_address(batch
, cc_viewport
);
168 return dynamic_state_address(batch
, offset
);
172 blorp_emit_pipeline(struct blorp_batch
*batch
,
173 const struct blorp_params
*params
)
175 assert(batch
->blorp
->driver_ctx
== batch
->driver_batch
);
176 struct brw_context
*brw
= batch
->driver_batch
;
178 emit_urb_config(batch
, params
);
180 blorp_emit(batch
, GENX(3DSTATE_PIPELINED_POINTERS
), pp
) {
181 pp
.PointertoVSState
= blorp_emit_vs_state(batch
, params
);
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
);
189 brw_upload_urb_fence(brw
);
191 blorp_emit(batch
, GENX(CS_URB_STATE
), curb
);
192 blorp_emit(batch
, GENX(CONSTANT_BUFFER
), curb
);