blob: fdddc83246c622cb91a097d0485a1f5f591e190e [file] [log] [blame]
Chia-I Wu00a23b22014-08-20 15:28:08 +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.
23 */
24
25#ifndef CMD_PRIV_H
26#define CMD_PRIV_H
27
Chia-I Wue24c3292014-08-21 14:05:23 +080028#include "genhw/genhw.h"
Chia-I Wu32710d72014-08-20 16:05:22 +080029#include "dev.h"
30#include "gpu.h"
Chia-I Wu00a23b22014-08-20 15:28:08 +080031#include "cmd.h"
32
Chia-I Wu32710d72014-08-20 16:05:22 +080033#define CMD_ASSERT(cmd, min_gen, max_gen) \
34 INTEL_GPU_ASSERT((cmd)->dev->gpu, (min_gen), (max_gen))
35
Chia-I Wu958d1b72014-08-21 11:28:11 +080036struct intel_cmd_reloc {
Chia-I Wue24c3292014-08-21 14:05:23 +080037 struct intel_cmd_writer *writer;
Chia-I Wu958d1b72014-08-21 11:28:11 +080038 XGL_UINT pos;
39
40 uint32_t val;
41 const struct intel_mem *mem;
42
43 /*
44 * With application state tracking promised by XGL, we should be able to
45 * set
46 *
47 * I915_EXEC_NO_RELOC
48 * I915_EXEC_HANDLE_LUT
49 * I915_EXEC_IS_PINNED
50 *
51 * once we figure them out.
52 */
53 uint16_t read_domains;
54 uint16_t write_domain;
55};
56
Chia-I Wu9f039862014-08-20 15:39:56 +080057static inline int cmd_gen(const struct intel_cmd *cmd)
58{
59 return intel_gpu_gen(cmd->dev->gpu);
60}
61
Chia-I Wucdff0592014-08-22 09:27:36 +080062static inline void cmd_reserve_reloc(struct intel_cmd *cmd,
63 XGL_UINT reloc_len)
64{
65 /* fail silently */
66 if (cmd->reloc_used + reloc_len > cmd->reloc_count) {
67 cmd->reloc_used = 0;
68 cmd->result = XGL_ERROR_TOO_MANY_MEMORY_REFERENCES;
69 }
70 assert(cmd->reloc_used + reloc_len <= cmd->reloc_count);
71}
72
Chia-I Wue24c3292014-08-21 14:05:23 +080073void cmd_writer_grow(struct intel_cmd *cmd,
74 struct intel_cmd_writer *writer);
Chia-I Wu00a23b22014-08-20 15:28:08 +080075
Chia-I Wu32710d72014-08-20 16:05:22 +080076/**
Chia-I Wucdff0592014-08-22 09:27:36 +080077 * Add a reloc at \p offset, relative to the current writer position. No
78 * error checking.
79 */
80static inline void cmd_writer_add_reloc(struct intel_cmd *cmd,
81 struct intel_cmd_writer *writer,
82 XGL_INT offset, uint32_t val,
83 const struct intel_mem *mem,
84 uint16_t read_domains,
85 uint16_t write_domain)
86{
87 struct intel_cmd_reloc *reloc = &cmd->relocs[cmd->reloc_used];
88
89 assert(cmd->reloc_used < cmd->reloc_count);
90
91 reloc->writer = writer;
92 reloc->pos = writer->used + offset;
93 reloc->val = val;
94 reloc->mem = mem;
95 reloc->read_domains = read_domains;
96 reloc->write_domain = write_domain;
97
98 cmd->reloc_used++;
99}
100
101/**
102 * Reserve \p len DWords in the batch buffer for building a hardware command.
Chia-I Wue24c3292014-08-21 14:05:23 +0800103 */
104static inline void cmd_batch_reserve(struct intel_cmd *cmd, XGL_UINT len)
105{
106 struct intel_cmd_writer *writer = &cmd->batch;
107
108 if (writer->used + len > writer->size)
109 cmd_writer_grow(cmd, writer);
110 assert(writer->used + len <= writer->size);
111}
112
113/**
Chia-I Wucdff0592014-08-22 09:27:36 +0800114 * Reserve \p len DWords in the batch buffer and \p reloc_len relocs for
115 * building a hardware command.
116 */
117static inline void cmd_batch_reserve_reloc(struct intel_cmd *cmd,
118 XGL_UINT len, XGL_UINT reloc_len)
119{
120 cmd_reserve_reloc(cmd, reloc_len);
121 cmd_batch_reserve(cmd, len);
122}
123
124/**
125 * Add a DWord to the hardware command being built. No error checking.
Chia-I Wue24c3292014-08-21 14:05:23 +0800126 */
127static inline void cmd_batch_write(struct intel_cmd *cmd, uint32_t val)
128{
129 struct intel_cmd_writer *writer = &cmd->batch;
130
131 assert(writer->used < writer->size);
132 ((uint32_t *) writer->ptr_opaque)[writer->used++] = val;
133}
134
135/**
Chia-I Wucdff0592014-08-22 09:27:36 +0800136 * Add \p len DWords to the hardware command being built. No error checking.
137 */
138static inline void cmd_batch_write_n(struct intel_cmd *cmd,
139 const uint32_t *vals, XGL_UINT len)
140{
141 struct intel_cmd_writer *writer = &cmd->batch;
142
143 assert(writer->used + len <= writer->size);
144
145 memcpy((uint32_t *) writer->ptr_opaque + writer->used,
146 vals, sizeof(uint32_t) * len);
147 writer->used += len;
148}
149
150/**
151 * Add a reloc to the hardware command being built. No error checking.
Chia-I Wue24c3292014-08-21 14:05:23 +0800152 */
153static inline void cmd_batch_reloc(struct intel_cmd *cmd,
154 uint32_t val, const struct intel_mem *mem,
155 uint16_t read_domains,
156 uint16_t write_domain)
157{
158 struct intel_cmd_writer *writer = &cmd->batch;
159
Chia-I Wucdff0592014-08-22 09:27:36 +0800160 cmd_writer_add_reloc(cmd, writer, 0, val,
161 mem, read_domains, write_domain);
Chia-I Wu5e25c272014-08-21 20:19:12 +0800162
Chia-I Wue24c3292014-08-21 14:05:23 +0800163 writer->used++;
164}
165
166/**
167 * End the batch buffer.
168 */
169static inline void cmd_batch_end(struct intel_cmd *cmd)
170{
171 if (cmd->batch.used & 1) {
172 cmd_batch_reserve(cmd, 1);
173 cmd_batch_write(cmd, GEN_MI_CMD(MI_BATCH_BUFFER_END));
174 } else {
175 cmd_batch_reserve(cmd, 2);
176 cmd_batch_write(cmd, GEN_MI_CMD(MI_BATCH_BUFFER_END));
177 cmd_batch_write(cmd, GEN_MI_CMD(MI_NOOP));
178 }
Chia-I Wu343b1372014-08-20 16:39:20 +0800179}
180
Chia-I Wu24565ee2014-08-21 20:24:31 +0800181/**
Chia-I Wucdff0592014-08-22 09:27:36 +0800182 * Reserve \p len DWords in the state buffer for building a hardware state.
183 * The current writer position is aligned to \p alignment first. Both the
184 * pointer to the reserved region and the aligned position are returned.
185 *
186 * Note that the returned pointer is only valid until the next reserve call.
Chia-I Wu24565ee2014-08-21 20:24:31 +0800187 */
188static inline uint32_t *cmd_state_reserve(struct intel_cmd *cmd, XGL_UINT len,
189 XGL_UINT alignment, XGL_UINT *pos)
190{
191 struct intel_cmd_writer *writer = &cmd->state;
192 XGL_UINT aligned;
193
194 assert(alignment && u_is_pow2(alignment));
195 aligned = u_align(writer->used, alignment);
196
197 if (aligned + len > writer->size)
198 cmd_writer_grow(cmd, writer);
199 assert(aligned + len <= writer->size);
200
201 writer->used = aligned;
202 *pos = aligned;
203
204 return &((uint32_t *) writer->ptr_opaque)[writer->used];
205}
206
207/**
Chia-I Wucdff0592014-08-22 09:27:36 +0800208 * Similar to \p cmd_state_reserve, except that \p reloc_len relocs are also
209 * reserved.
Chia-I Wu24565ee2014-08-21 20:24:31 +0800210 */
Chia-I Wucdff0592014-08-22 09:27:36 +0800211static inline uint32_t *cmd_state_reserve_reloc(struct intel_cmd *cmd,
212 XGL_UINT len,
213 XGL_UINT reloc_len,
214 XGL_UINT alignment,
215 XGL_UINT *pos)
Chia-I Wu24565ee2014-08-21 20:24:31 +0800216{
Chia-I Wucdff0592014-08-22 09:27:36 +0800217 cmd_reserve_reloc(cmd, reloc_len);
218 return cmd_state_reserve(cmd, len, alignment, pos);
Chia-I Wu24565ee2014-08-21 20:24:31 +0800219}
220
221/**
Chia-I Wucdff0592014-08-22 09:27:36 +0800222 * Advance the writer position of the state buffer. No error checking.
Chia-I Wu24565ee2014-08-21 20:24:31 +0800223 */
224static inline void cmd_state_advance(struct intel_cmd *cmd, XGL_UINT len)
225{
226 struct intel_cmd_writer *writer = &cmd->state;
227
228 assert(writer->used + len <= writer->size);
229 writer->used += len;
230}
231
232/**
Chia-I Wucdff0592014-08-22 09:27:36 +0800233 * A convenient function to copy a hardware state of \p len DWords into the
234 * state buffer. The position of the state is returned.
Chia-I Wu24565ee2014-08-21 20:24:31 +0800235 */
236static inline XGL_UINT cmd_state_copy(struct intel_cmd *cmd,
237 const uint32_t *vals, XGL_UINT len,
238 XGL_UINT alignment)
239{
240 uint32_t *dst;
241 XGL_UINT pos;
242
243 dst = cmd_state_reserve(cmd, len, alignment, &pos);
244 memcpy(dst, vals, sizeof(uint32_t) * len);
245 cmd_state_advance(cmd, len);
246
247 return pos;
248}
249
Chia-I Wu00a23b22014-08-20 15:28:08 +0800250#endif /* CMD_PRIV_H */