nouveau_local.h revision fda9279d
1/*
2 * Copyright 2007 Nouveau Project
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 shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23#ifndef __NOUVEAU_LOCAL_H__
24#define __NOUVEAU_LOCAL_H__
25
26#include "compiler.h"
27#include "xf86_OSproc.h"
28
29#include <nouveau.h>
30
31/* Debug output */
32#define NOUVEAU_MSG(fmt,args...) ErrorF(fmt, ##args)
33#define NOUVEAU_ERR(fmt,args...) \
34	ErrorF("%s:%d - "fmt, __func__, __LINE__, ##args)
35#if 0
36#define NOUVEAU_FALLBACK(fmt,args...) do {    \
37	NOUVEAU_ERR("FALLBACK: "fmt, ##args); \
38	return FALSE;                         \
39} while(0)
40#else
41#define NOUVEAU_FALLBACK(fmt,args...) do {    \
42	return FALSE;                         \
43} while(0)
44#endif
45
46#define NOUVEAU_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
47
48#define NV50_TILE_PITCH(m) (64 << ((m) & 0xf))
49#define NV50_TILE_HEIGHT(m) (4 << ((m) >> 4))
50#define NVC0_TILE_PITCH(m) (64 << ((m) & 0xf))
51#define NVC0_TILE_HEIGHT(m) (8 << ((m) >> 4))
52
53static inline int log2i(int i)
54{
55	int r = 0;
56
57	if (i & 0xffff0000) {
58		i >>= 16;
59		r += 16;
60	}
61	if (i & 0x0000ff00) {
62		i >>= 8;
63		r += 8;
64	}
65	if (i & 0x000000f0) {
66		i >>= 4;
67		r += 4;
68	}
69	if (i & 0x0000000c) {
70		i >>= 2;
71		r += 2;
72	}
73	if (i & 0x00000002) {
74		r += 1;
75	}
76	return r;
77}
78
79static inline int round_down_pow2(int x)
80{
81	return 1 << log2i(x);
82}
83
84static inline int round_up_pow2(int x)
85{
86   int r = round_down_pow2(x);
87   if (r < x)
88      r <<= 1;
89   return r;
90}
91
92#define SWAP(x, y) do {			\
93		typeof(x) __z = (x);	\
94		(x) = (y);		\
95		(y) = __z;		\
96	} while (0)
97
98static inline uint32_t
99PUSH_AVAIL(struct nouveau_pushbuf *push)
100{
101	return push->end - push->cur;
102}
103
104static inline Bool
105PUSH_SPACE(struct nouveau_pushbuf *push, uint32_t size)
106{
107	if (PUSH_AVAIL(push) < size)
108		return nouveau_pushbuf_space(push, size, 0, 0) == 0;
109	return TRUE;
110}
111
112static inline void
113PUSH_DATA(struct nouveau_pushbuf *push, uint32_t data)
114{
115	*push->cur++ = data;
116}
117
118static inline void
119PUSH_DATAp(struct nouveau_pushbuf *push, const void *data, uint32_t size)
120{
121	memcpy(push->cur, data, size * 4);
122	push->cur += size;
123}
124
125static inline void
126PUSH_RELOC(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t offset,
127	   uint32_t flags, uint32_t vor, uint32_t tor)
128{
129	nouveau_pushbuf_reloc(push, bo, offset, flags, vor, tor);
130}
131
132static inline void
133PUSH_KICK(struct nouveau_pushbuf *push)
134{
135	nouveau_pushbuf_kick(push, push->channel);
136}
137
138static inline struct nouveau_bufctx *
139BUFCTX(struct nouveau_pushbuf *push)
140{
141	return push->user_priv;
142}
143
144static inline void
145PUSH_RESET(struct nouveau_pushbuf *push)
146{
147	nouveau_bufctx_reset(BUFCTX(push), 0);
148}
149
150static inline void
151PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t access)
152{
153	nouveau_bufctx_refn(BUFCTX(push), 0, bo, access);
154}
155
156static inline void
157PUSH_MTHDl(struct nouveau_pushbuf *push, int subc, int mthd,
158	   struct nouveau_bo *bo, uint32_t offset, uint32_t access)
159{
160	nouveau_bufctx_mthd(BUFCTX(push), 0, (1 << 18) | (subc << 13) | mthd,
161			    bo, offset, access | NOUVEAU_BO_LOW, 0, 0);
162	PUSH_DATA (push, bo->offset + offset);
163}
164
165static inline void
166PUSH_MTHDo(struct nouveau_pushbuf *push, int subc, int mthd,
167	   struct nouveau_bo *bo, uint32_t access, uint32_t vor, uint32_t tor)
168{
169	nouveau_bufctx_mthd(BUFCTX(push), 0, (1 << 18) | (subc << 13) | mthd,
170			    bo, 0, access | NOUVEAU_BO_OR, vor, tor);
171	if (bo->flags & NOUVEAU_BO_VRAM)
172		PUSH_DATA (push, vor);
173	else
174		PUSH_DATA (push, tor);
175}
176
177static inline void
178PUSH_MTHDs(struct nouveau_pushbuf *push, int subc, int mthd,
179	   struct nouveau_bo *bo, uint32_t data, uint32_t access,
180	   uint32_t vor, uint32_t tor)
181{
182	nouveau_bufctx_mthd(BUFCTX(push), 0, (1 << 18) | (subc << 13) | mthd,
183			    bo, data, access | NOUVEAU_BO_OR, vor, tor);
184	if (bo->flags & NOUVEAU_BO_VRAM)
185		PUSH_DATA (push, data | vor);
186	else
187		PUSH_DATA (push, data | tor);
188}
189
190static inline void
191PUSH_MTHD(struct nouveau_pushbuf *push, int subc, int mthd,
192	  struct nouveau_bo *bo, uint32_t data, uint32_t access,
193	  uint32_t vor, uint32_t tor)
194{
195	nouveau_bufctx_mthd(BUFCTX(push), 0, (1 << 18) | (subc << 13) | mthd,
196			    bo, data, access | NOUVEAU_BO_OR, vor, tor);
197	if (access & NOUVEAU_BO_LOW)
198		data += bo->offset;
199	if (access & NOUVEAU_BO_OR) {
200		if (bo->flags & NOUVEAU_BO_VRAM)
201			data |= vor;
202		else
203			data |= tor;
204	}
205	PUSH_DATA (push, data);
206}
207
208static inline void
209PUSH_DATAf(struct nouveau_pushbuf *push, float v)
210{
211	union { float f; uint32_t i; } d = { .f = v };
212	PUSH_DATA (push, d.i);
213}
214
215static inline void
216BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, int size)
217{
218	PUSH_DATA (push, 0x00000000 | (size << 18) | (subc << 13) | mthd);
219}
220
221static inline void
222BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, int size)
223{
224	PUSH_DATA (push, 0x40000000 | (size << 18) | (subc << 13) | mthd);
225}
226
227static inline void
228BEGIN_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, int size)
229{
230	PUSH_DATA (push, 0x20000000 | (size << 16) | (subc << 13) | (mthd / 4));
231}
232
233static inline void
234BEGIN_NIC0(struct nouveau_pushbuf *push, int subc, int mthd, int size)
235{
236	PUSH_DATA (push, 0x60000000 | (size << 16) | (subc << 13) | (mthd / 4));
237}
238
239static inline void
240BEGIN_IMC0(struct nouveau_pushbuf *push, int subc, int mthd, int data)
241{
242	PUSH_DATA (push, 0x80000000 | (data << 16) | (subc << 13) | (mthd / 4));
243}
244
245static inline void
246BEGIN_1IC0(struct nouveau_pushbuf *push, int subc, int mthd, int size)
247{
248	PUSH_DATA (push, 0xa0000000 | (size << 16) | (subc << 13) | (mthd / 4));
249}
250
251#define NV01_SUBC(subc, mthd) SUBC_##subc((NV01_SUBCHAN_##mthd))
252#define NV11_SUBC(subc, mthd) SUBC_##subc((NV11_SUBCHAN_##mthd))
253#define NV84_SUBC(subc, mthd) SUBC_##subc((NV84_SUBCHAN_##mthd))
254
255#define NV04_GRAPH(subc, mthd) SUBC_##subc((NV04_GRAPH_##mthd))
256#define NV50_GRAPH(subc, mthd) SUBC_##subc((NV50_GRAPH_##mthd))
257#define NVC0_GRAPH(subc, mthd) SUBC_##subc((NVC0_GRAPH_##mthd))
258
259#endif
260