blob: 529503acfaa220932e8c2f62baf114842e23e8ba [file] [log] [blame]
Chia-I Wu759fa2e2014-08-30 18:44:47 +08001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
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.
Chia-I Wu44e42362014-09-02 08:32:09 +080023 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
Chia-I Wu759fa2e2014-08-30 18:44:47 +080026 */
27
Chia-I Wu714df452015-01-01 07:55:04 +080028#include "kmd/winsys.h"
29#include "buf.h"
Chia-I Wue9115ee2014-08-31 12:58:35 +080030#include "event.h"
Chia-I Wu714df452015-01-01 07:55:04 +080031#include "mem.h"
Chia-I Wu759fa2e2014-08-30 18:44:47 +080032#include "obj.h"
33#include "query.h"
34#include "cmd_priv.h"
35
36static void gen6_MI_STORE_REGISTER_MEM(struct intel_cmd *cmd,
37 struct intel_bo *bo,
38 uint32_t offset,
39 uint32_t reg)
40{
41 const uint8_t cmd_len = 3;
42 uint32_t dw0 = GEN6_MI_CMD(MI_STORE_REGISTER_MEM) |
43 (cmd_len - 2);
Chia-I Wu2caf7492014-08-31 12:28:38 +080044 uint32_t reloc_flags = INTEL_RELOC_WRITE;
Chia-I Wu72292b72014-09-09 10:48:33 +080045 uint32_t *dw;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060046 uint32_t pos;
Chia-I Wu759fa2e2014-08-30 18:44:47 +080047
Chia-I Wu2caf7492014-08-31 12:28:38 +080048 if (cmd_gen(cmd) == INTEL_GEN(6)) {
Chia-I Wu759fa2e2014-08-30 18:44:47 +080049 dw0 |= GEN6_MI_STORE_REGISTER_MEM_DW0_USE_GGTT;
Chia-I Wu2caf7492014-08-31 12:28:38 +080050 reloc_flags |= INTEL_RELOC_GGTT;
51 }
Chia-I Wu759fa2e2014-08-30 18:44:47 +080052
Chia-I Wu72292b72014-09-09 10:48:33 +080053 pos = cmd_batch_pointer(cmd, cmd_len, &dw);
54 dw[0] = dw0;
55 dw[1] = reg;
56
57 cmd_reserve_reloc(cmd, 1);
58 cmd_batch_reloc(cmd, pos + 2, bo, offset, reloc_flags);
Chia-I Wu759fa2e2014-08-30 18:44:47 +080059}
60
61static void gen6_MI_STORE_DATA_IMM(struct intel_cmd *cmd,
62 struct intel_bo *bo,
63 uint32_t offset,
64 uint64_t val)
65{
66 const uint8_t cmd_len = 5;
67 uint32_t dw0 = GEN6_MI_CMD(MI_STORE_DATA_IMM) |
68 (cmd_len - 2);
Chia-I Wu2caf7492014-08-31 12:28:38 +080069 uint32_t reloc_flags = INTEL_RELOC_WRITE;
Chia-I Wu72292b72014-09-09 10:48:33 +080070 uint32_t *dw;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -060071 uint32_t pos;
Chia-I Wu759fa2e2014-08-30 18:44:47 +080072
Chia-I Wu2caf7492014-08-31 12:28:38 +080073 if (cmd_gen(cmd) == INTEL_GEN(6)) {
Chia-I Wu759fa2e2014-08-30 18:44:47 +080074 dw0 |= GEN6_MI_STORE_DATA_IMM_DW0_USE_GGTT;
Chia-I Wu2caf7492014-08-31 12:28:38 +080075 reloc_flags |= INTEL_RELOC_GGTT;
76 }
Chia-I Wu759fa2e2014-08-30 18:44:47 +080077
Chia-I Wu72292b72014-09-09 10:48:33 +080078 pos = cmd_batch_pointer(cmd, cmd_len, &dw);
79 dw[0] = dw0;
80 dw[1] = 0;
81 dw[3] = (uint32_t) val;
82 dw[4] = (uint32_t) (val >> 32);
83
84 cmd_reserve_reloc(cmd, 1);
85 cmd_batch_reloc(cmd, pos + 2, bo, offset, reloc_flags);
Chia-I Wu759fa2e2014-08-30 18:44:47 +080086}
87
88static void cmd_query_pipeline_statistics(struct intel_cmd *cmd,
89 struct intel_bo *bo,
90 XGL_GPU_SIZE offset)
91{
92 const uint32_t regs[] = {
93 GEN6_REG_PS_INVOCATION_COUNT,
94 GEN6_REG_CL_PRIMITIVES_COUNT,
95 GEN6_REG_CL_INVOCATION_COUNT,
96 GEN6_REG_VS_INVOCATION_COUNT,
97 GEN6_REG_GS_INVOCATION_COUNT,
98 GEN6_REG_GS_PRIMITIVES_COUNT,
Chia-I Wu8a927bd2014-08-31 00:06:36 +080099 /* well, we do not enable 3DSTATE_VF_STATISTICS yet */
Chia-I Wu759fa2e2014-08-30 18:44:47 +0800100 GEN6_REG_IA_PRIMITIVES_COUNT,
101 GEN6_REG_IA_VERTICES_COUNT,
Chia-I Wue6073342014-11-30 09:43:42 +0800102 (cmd_gen(cmd) >= INTEL_GEN(7)) ? GEN7_REG_HS_INVOCATION_COUNT : 0,
103 (cmd_gen(cmd) >= INTEL_GEN(7)) ? GEN7_REG_DS_INVOCATION_COUNT : 0,
Chia-I Wu759fa2e2014-08-30 18:44:47 +0800104 0,
105 };
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600106 uint32_t i;
Chia-I Wu759fa2e2014-08-30 18:44:47 +0800107
108 cmd_batch_flush(cmd, GEN6_PIPE_CONTROL_CS_STALL);
109
110 for (i = 0; i < ARRAY_SIZE(regs); i++) {
111 if (regs[i]) {
112 /* store lower 32 bits */
113 gen6_MI_STORE_REGISTER_MEM(cmd, bo, offset, regs[i]);
114 /* store higher 32 bits */
115 gen6_MI_STORE_REGISTER_MEM(cmd, bo, offset + 4, regs[i] + 4);
116 } else {
117 gen6_MI_STORE_DATA_IMM(cmd, bo, offset, 0);
118 }
Chia-I Wu8a927bd2014-08-31 00:06:36 +0800119
120 offset += sizeof(uint64_t);
Chia-I Wu759fa2e2014-08-30 18:44:47 +0800121 }
122}
123
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600124ICD_EXPORT void XGLAPI xglCmdBeginQuery(
Chia-I Wu759fa2e2014-08-30 18:44:47 +0800125 XGL_CMD_BUFFER cmdBuffer,
126 XGL_QUERY_POOL queryPool,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600127 uint32_t slot,
Chia-I Wu759fa2e2014-08-30 18:44:47 +0800128 XGL_FLAGS flags)
129{
130 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
131 struct intel_query *query = intel_query(queryPool);
132 struct intel_bo *bo = query->obj.mem->bo;
133 const XGL_GPU_SIZE offset = query->slot_stride * slot;
134
135 switch (query->type) {
136 case XGL_QUERY_OCCLUSION:
137 cmd_batch_depth_count(cmd, bo, offset);
138 break;
139 case XGL_QUERY_PIPELINE_STATISTICS:
140 cmd_query_pipeline_statistics(cmd, bo, offset);
141 break;
142 default:
143 cmd->result = XGL_ERROR_UNKNOWN;
144 break;
145 }
146}
147
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600148ICD_EXPORT void XGLAPI xglCmdEndQuery(
Chia-I Wu759fa2e2014-08-30 18:44:47 +0800149 XGL_CMD_BUFFER cmdBuffer,
150 XGL_QUERY_POOL queryPool,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600151 uint32_t slot)
Chia-I Wu759fa2e2014-08-30 18:44:47 +0800152{
153 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
154 struct intel_query *query = intel_query(queryPool);
155 struct intel_bo *bo = query->obj.mem->bo;
156 const XGL_GPU_SIZE offset = query->slot_stride * slot;
157
158 switch (query->type) {
159 case XGL_QUERY_OCCLUSION:
160 cmd_batch_depth_count(cmd, bo, offset + sizeof(uint64_t));
161 break;
162 case XGL_QUERY_PIPELINE_STATISTICS:
163 cmd_query_pipeline_statistics(cmd, bo,
164 offset + sizeof(XGL_PIPELINE_STATISTICS_DATA));
165 break;
166 default:
167 cmd->result = XGL_ERROR_UNKNOWN;
168 break;
169 }
170}
171
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600172ICD_EXPORT void XGLAPI xglCmdResetQueryPool(
Chia-I Wu759fa2e2014-08-30 18:44:47 +0800173 XGL_CMD_BUFFER cmdBuffer,
174 XGL_QUERY_POOL queryPool,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600175 uint32_t startQuery,
176 uint32_t queryCount)
Chia-I Wu759fa2e2014-08-30 18:44:47 +0800177{
Chia-I Wue9115ee2014-08-31 12:58:35 +0800178 /* no-op */
179}
180
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600181ICD_EXPORT void XGLAPI xglCmdSetEvent(
Chia-I Wue9115ee2014-08-31 12:58:35 +0800182 XGL_CMD_BUFFER cmdBuffer,
Mike Stroyan55658c22014-12-04 11:08:39 +0000183 XGL_EVENT event_,
184 XGL_SET_EVENT pipeEvent)
Chia-I Wue9115ee2014-08-31 12:58:35 +0800185{
186 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
187 struct intel_event *event = intel_event(event_);
Mike Stroyan55658c22014-12-04 11:08:39 +0000188 uint32_t pipe_control_flags;
Chia-I Wue9115ee2014-08-31 12:58:35 +0800189
Mike Stroyan55658c22014-12-04 11:08:39 +0000190 /* Event setting is done with PIPE_CONTROL post-sync write immediate.
191 * With no other PIPE_CONTROL flags set, it behaves as XGL_SET_EVENT_TOP_OF_PIPE.
192 * All other pipeEvent values will behave as XGL_SET_EVENT_GPU_COMMANDS_COMPLETE.
193 */
194 switch(pipeEvent)
195 {
196 case XGL_SET_EVENT_TOP_OF_PIPE:
197 pipe_control_flags = 0;
198 break;
199 case XGL_SET_EVENT_VERTEX_PROCESSING_COMPLETE:
200 case XGL_SET_EVENT_FRAGMENT_PROCESSING_COMPLETE:
201 case XGL_SET_EVENT_GRAPHICS_PIPELINE_COMPLETE:
202 case XGL_SET_EVENT_COMPUTE_PIPELINE_COMPLETE:
203 case XGL_SET_EVENT_TRANSFER_COMPLETE:
204 case XGL_SET_EVENT_GPU_COMMANDS_COMPLETE:
205 pipe_control_flags = GEN6_PIPE_CONTROL_CS_STALL;
206 break;
207 default:
208 cmd->result = XGL_ERROR_UNKNOWN;
209 return;
210 break;
211 }
212 cmd_batch_immediate(cmd, pipe_control_flags, event->obj.mem->bo, 0, 1);
Chia-I Wue9115ee2014-08-31 12:58:35 +0800213}
214
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600215ICD_EXPORT void XGLAPI xglCmdResetEvent(
Chia-I Wue9115ee2014-08-31 12:58:35 +0800216 XGL_CMD_BUFFER cmdBuffer,
217 XGL_EVENT event_)
218{
219 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
220 struct intel_event *event = intel_event(event_);
221
Mike Stroyan55658c22014-12-04 11:08:39 +0000222 /* The timing of event reset is not well specifed.
223 * Event reset is done like XGL_SET_EVENT_TOP_OF_PIPE.
224 */
225 cmd_batch_immediate(cmd, 0, event->obj.mem->bo, 0, 0);
Chia-I Wue9115ee2014-08-31 12:58:35 +0800226}
227
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600228ICD_EXPORT void XGLAPI xglCmdWriteTimestamp(
Chia-I Wue9115ee2014-08-31 12:58:35 +0800229 XGL_CMD_BUFFER cmdBuffer,
230 XGL_TIMESTAMP_TYPE timestampType,
Chia-I Wu714df452015-01-01 07:55:04 +0800231 XGL_BUFFER destBuffer,
Chia-I Wue9115ee2014-08-31 12:58:35 +0800232 XGL_GPU_SIZE destOffset)
233{
234 struct intel_cmd *cmd = intel_cmd(cmdBuffer);
Chia-I Wu714df452015-01-01 07:55:04 +0800235 struct intel_buf *buf = intel_buf(destBuffer);
Chia-I Wue9115ee2014-08-31 12:58:35 +0800236
237 switch (timestampType) {
238 case XGL_TIMESTAMP_TOP:
239 /* XXX we are not supposed to use two commands... */
Chia-I Wu714df452015-01-01 07:55:04 +0800240 gen6_MI_STORE_REGISTER_MEM(cmd, buf->obj.mem->bo,
241 destOffset, GEN6_REG_TIMESTAMP);
242 gen6_MI_STORE_REGISTER_MEM(cmd, buf->obj.mem->bo,
243 destOffset + 4, GEN6_REG_TIMESTAMP + 4);
Chia-I Wue9115ee2014-08-31 12:58:35 +0800244 break;
245 case XGL_TIMESTAMP_BOTTOM:
Chia-I Wu714df452015-01-01 07:55:04 +0800246 cmd_batch_timestamp(cmd, buf->obj.mem->bo, destOffset);
Chia-I Wue9115ee2014-08-31 12:58:35 +0800247 break;
248 default:
249 cmd->result = XGL_ERROR_INVALID_VALUE;
250 break;
251 }
Chia-I Wu759fa2e2014-08-30 18:44:47 +0800252}