2 * Mesa 3-D graphics library
4 * Copyright (C) 2014 LunarG, Inc.
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
25 * Chia-I Wu <olv@lunarg.com>
28 #ifndef ILO_BUILDER_RENDER_H
29 #define ILO_BUILDER_RENDER_H
31 #include "genhw/genhw.h"
32 #include "core/intel_winsys.h"
34 #include "ilo_common.h"
35 #include "ilo_builder.h"
38 gen6_STATE_SIP(struct ilo_builder
*builder
, uint32_t sip
)
40 const uint8_t cmd_len
= (ilo_dev_gen(builder
->dev
) >= ILO_GEN(8)) ? 3 : 2;
43 ILO_DEV_ASSERT(builder
->dev
, 6, 8);
45 ilo_builder_batch_pointer(builder
, cmd_len
, &dw
);
47 dw
[0] = GEN6_RENDER_CMD(COMMON
, STATE_SIP
) | (cmd_len
- 2);
49 if (ilo_dev_gen(builder
->dev
) >= ILO_GEN(8))
54 gen6_PIPELINE_SELECT(struct ilo_builder
*builder
, int pipeline
)
56 const uint8_t cmd_len
= 1;
57 const uint32_t dw0
= GEN6_RENDER_CMD(SINGLE_DW
, PIPELINE_SELECT
) |
60 ILO_DEV_ASSERT(builder
->dev
, 6, 8);
63 case GEN6_PIPELINE_SELECT_DW0_SELECT_3D
:
64 case GEN6_PIPELINE_SELECT_DW0_SELECT_MEDIA
:
66 case GEN7_PIPELINE_SELECT_DW0_SELECT_GPGPU
:
67 assert(ilo_dev_gen(builder
->dev
) >= ILO_GEN(7));
70 assert(!"unknown pipeline");
74 ilo_builder_batch_write(builder
, cmd_len
, &dw0
);
78 gen6_PIPE_CONTROL(struct ilo_builder
*builder
, uint32_t dw1
,
79 struct intel_bo
*bo
, uint32_t bo_offset
,
82 const uint8_t cmd_len
= (ilo_dev_gen(builder
->dev
) >= ILO_GEN(8)) ? 6 : 5;
83 uint32_t reloc_flags
= INTEL_RELOC_WRITE
;
87 ILO_DEV_ASSERT(builder
->dev
, 6, 8);
89 if (dw1
& GEN6_PIPE_CONTROL_CS_STALL
) {
91 * From the Sandy Bridge PRM, volume 2 part 1, page 73:
93 * "1 of the following must also be set (when CS stall is set):
95 * * Depth Cache Flush Enable ([0] of DW1)
96 * * Stall at Pixel Scoreboard ([1] of DW1)
97 * * Depth Stall ([13] of DW1)
98 * * Post-Sync Operation ([13] of DW1)
99 * * Render Target Cache Flush Enable ([12] of DW1)
100 * * Notify Enable ([8] of DW1)"
102 * From the Ivy Bridge PRM, volume 2 part 1, page 61:
104 * "One of the following must also be set (when CS stall is set):
106 * * Render Target Cache Flush Enable ([12] of DW1)
107 * * Depth Cache Flush Enable ([0] of DW1)
108 * * Stall at Pixel Scoreboard ([1] of DW1)
109 * * Depth Stall ([13] of DW1)
110 * * Post-Sync Operation ([13] of DW1)"
112 uint32_t bit_test
= GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH
|
113 GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH
|
114 GEN6_PIPE_CONTROL_PIXEL_SCOREBOARD_STALL
|
115 GEN6_PIPE_CONTROL_DEPTH_STALL
;
118 bit_test
|= GEN6_PIPE_CONTROL_WRITE_IMM
|
119 GEN6_PIPE_CONTROL_WRITE_PS_DEPTH_COUNT
|
120 GEN6_PIPE_CONTROL_WRITE_TIMESTAMP
;
122 if (ilo_dev_gen(builder
->dev
) == ILO_GEN(6))
123 bit_test
|= GEN6_PIPE_CONTROL_NOTIFY_ENABLE
;
125 assert(dw1
& bit_test
);
128 if (dw1
& GEN6_PIPE_CONTROL_DEPTH_STALL
) {
130 * From the Sandy Bridge PRM, volume 2 part 1, page 73:
132 * "Following bits must be clear (when Depth Stall is set):
134 * * Render Target Cache Flush Enable ([12] of DW1)
135 * * Depth Cache Flush Enable ([0] of DW1)"
137 assert(!(dw1
& (GEN6_PIPE_CONTROL_RENDER_CACHE_FLUSH
|
138 GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH
)));
141 switch (dw1
& GEN6_PIPE_CONTROL_WRITE__MASK
) {
142 case GEN6_PIPE_CONTROL_WRITE_PS_DEPTH_COUNT
:
143 case GEN6_PIPE_CONTROL_WRITE_TIMESTAMP
:
150 assert(bo_offset
% 8 == 0);
152 pos
= ilo_builder_batch_pointer(builder
, cmd_len
, &dw
);
154 dw
[0] = GEN6_RENDER_CMD(3D
, PIPE_CONTROL
) | (cmd_len
- 2);
157 if (ilo_dev_gen(builder
->dev
) >= ILO_GEN(8)) {
158 dw
[4] = (uint32_t) imm
;
159 dw
[5] = (uint32_t) (imm
>> 32);
162 ilo_builder_batch_reloc64(builder
, pos
+ 2,
163 bo
, bo_offset
, reloc_flags
);
170 dw
[3] = (uint32_t) imm
;
171 dw
[4] = (uint32_t) (imm
>> 32);
175 * From the Sandy Bridge PRM, volume 1 part 3, page 19:
177 * "[DevSNB] PPGTT memory writes by MI_* (such as
178 * MI_STORE_DATA_IMM) and PIPE_CONTROL are not supported."
180 if (ilo_dev_gen(builder
->dev
) == ILO_GEN(6)) {
181 bo_offset
|= GEN6_PIPE_CONTROL_DW2_USE_GGTT
;
182 reloc_flags
|= INTEL_RELOC_GGTT
;
185 ilo_builder_batch_reloc(builder
, pos
+ 2,
186 bo
, bo_offset
, reloc_flags
);
194 ilo_builder_batch_patch_sba(struct ilo_builder
*builder
)
196 const struct ilo_builder_writer
*inst
=
197 &builder
->writers
[ILO_BUILDER_WRITER_INSTRUCTION
];
199 if (!builder
->sba_instruction_pos
)
202 if (ilo_dev_gen(builder
->dev
) >= ILO_GEN(8)) {
203 ilo_builder_batch_reloc64(builder
, builder
->sba_instruction_pos
,
205 builder
->mocs
<< GEN8_SBA_MOCS__SHIFT
| GEN6_SBA_ADDR_MODIFIED
,
208 ilo_builder_batch_reloc(builder
, builder
->sba_instruction_pos
, inst
->bo
,
209 builder
->mocs
<< GEN6_SBA_MOCS__SHIFT
| GEN6_SBA_ADDR_MODIFIED
,
215 * Add a STATE_BASE_ADDRESS to the batch buffer. The relocation entry for the
216 * instruction buffer is not added until ilo_builder_end() or next
217 * gen6_state_base_address().
220 gen6_state_base_address(struct ilo_builder
*builder
, bool init_all
)
222 const uint8_t cmd_len
= 10;
223 const struct ilo_builder_writer
*bat
=
224 &builder
->writers
[ILO_BUILDER_WRITER_BATCH
];
228 ILO_DEV_ASSERT(builder
->dev
, 6, 7.5);
230 pos
= ilo_builder_batch_pointer(builder
, cmd_len
, &dw
);
232 dw
[0] = GEN6_RENDER_CMD(COMMON
, STATE_BASE_ADDRESS
) | (cmd_len
- 2);
233 dw
[1] = builder
->mocs
<< GEN6_SBA_MOCS__SHIFT
|
234 builder
->mocs
<< GEN6_SBA_DW1_GENERAL_STATELESS_MOCS__SHIFT
|
237 ilo_builder_batch_reloc(builder
, pos
+ 2, bat
->bo
,
238 builder
->mocs
<< GEN6_SBA_MOCS__SHIFT
| GEN6_SBA_ADDR_MODIFIED
,
240 ilo_builder_batch_reloc(builder
, pos
+ 3, bat
->bo
,
241 builder
->mocs
<< GEN6_SBA_MOCS__SHIFT
| GEN6_SBA_ADDR_MODIFIED
,
244 dw
[4] = builder
->mocs
<< GEN6_SBA_MOCS__SHIFT
| init_all
;
247 * Since the instruction writer has WRITER_FLAG_APPEND set, it is tempting
248 * not to set Instruction Base Address. The problem is that we do not know
249 * if the bo has been or will be moved by the kernel. We need a relocation
250 * entry because of that.
252 * And since we also set WRITER_FLAG_GROW, we have to wait until
253 * ilo_builder_end(), when the final bo is known, to add the relocation
256 ilo_builder_batch_patch_sba(builder
);
257 builder
->sba_instruction_pos
= pos
+ 5;
259 /* skip range checks */
261 dw
[7] = 0xfffff000 + init_all
;
262 dw
[8] = 0xfffff000 + init_all
;
267 gen8_state_base_address(struct ilo_builder
*builder
, bool init_all
)
269 const uint8_t cmd_len
= 16;
270 const struct ilo_builder_writer
*bat
=
271 &builder
->writers
[ILO_BUILDER_WRITER_BATCH
];
275 ILO_DEV_ASSERT(builder
->dev
, 8, 8);
277 pos
= ilo_builder_batch_pointer(builder
, cmd_len
, &dw
);
279 dw
[0] = GEN6_RENDER_CMD(COMMON
, STATE_BASE_ADDRESS
) | (cmd_len
- 2);
280 dw
[1] = builder
->mocs
<< GEN8_SBA_MOCS__SHIFT
| init_all
;
282 dw
[3] = builder
->mocs
<< GEN8_SBA_DW3_STATELESS_MOCS__SHIFT
;
283 ilo_builder_batch_reloc64(builder
, pos
+ 4, bat
->bo
,
284 builder
->mocs
<< GEN8_SBA_MOCS__SHIFT
| GEN6_SBA_ADDR_MODIFIED
,
286 ilo_builder_batch_reloc64(builder
, pos
+ 6, bat
->bo
,
287 builder
->mocs
<< GEN8_SBA_MOCS__SHIFT
| GEN6_SBA_ADDR_MODIFIED
,
289 dw
[8] = builder
->mocs
<< GEN8_SBA_MOCS__SHIFT
| init_all
;
292 ilo_builder_batch_patch_sba(builder
);
293 builder
->sba_instruction_pos
= pos
+ 10;
295 /* skip range checks */
296 dw
[12] = 0xfffff000 + init_all
;
297 dw
[13] = 0xfffff000 + init_all
;
298 dw
[14] = 0xfffff000 + init_all
;
299 dw
[15] = 0xfffff000 + init_all
;
302 #endif /* ILO_BUILDER_RENDER_H */