nvc0_accel.c revision 16ee1e9a
1/*
2 * Copyright 2008 Ben Skeggs
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#include "nv_include.h"
24#include "nvc0_accel.h"
25
26#include "shader/xfrm2nvc0.vp"
27#include "shader/videonvc0.fp"
28
29#include "shader/exascnvc0.fp"
30#include "shader/exacmnvc0.fp"
31#include "shader/exacanvc0.fp"
32#include "shader/exasanvc0.fp"
33#include "shader/exas8nvc0.fp"
34#include "shader/exac8nvc0.fp"
35
36#include "shader/xfrm2nve0.vp"
37#include "shader/videonve0.fp"
38
39#include "shader/exascnve0.fp"
40#include "shader/exacmnve0.fp"
41#include "shader/exacanve0.fp"
42#include "shader/exasanve0.fp"
43#include "shader/exas8nve0.fp"
44#include "shader/exac8nve0.fp"
45
46#include "shader/xfrm2nvf0.vp"
47#include "shader/videonvf0.fp"
48
49#include "shader/exascnvf0.fp"
50#include "shader/exacmnvf0.fp"
51#include "shader/exacanvf0.fp"
52#include "shader/exasanvf0.fp"
53#include "shader/exas8nvf0.fp"
54#include "shader/exac8nvf0.fp"
55
56#define NVC0PushProgram(pNv,addr,code) do {                                    \
57	const unsigned size = sizeof(code) / sizeof(code[0]);                  \
58	PUSH_DATAu((pNv)->pushbuf, (pNv)->scratch, (addr), size);              \
59	PUSH_DATAp((pNv)->pushbuf, (code), size);                              \
60} while(0)
61
62void
63NVC0SyncToVBlank(PixmapPtr ppix, BoxPtr box)
64{
65	ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
66	NVPtr pNv = NVPTR(pScrn);
67	struct nouveau_pushbuf *push = pNv->pushbuf;
68	int head;
69	xf86CrtcPtr crtc;
70
71	if (!pNv->NvSW || !nouveau_exa_pixmap_is_onscreen(ppix))
72		return;
73
74	crtc = nouveau_pick_best_crtc(pScrn, FALSE, box->x1, box->y1,
75                                  box->x2 - box->x1,
76                                  box->y2 - box->y1);
77	if (!crtc)
78		return;
79
80	if (!PUSH_SPACE(push, 32))
81		return;
82
83	head = drmmode_head(crtc);
84
85	BEGIN_NVC0(push, NV01_SUBC(NVSW, OBJECT), 1);
86	PUSH_DATA (push, pNv->NvSW->handle);
87	BEGIN_NVC0(push, NV84_SUBC(NVSW, SEMAPHORE_ADDRESS_HIGH), 4);
88	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET) >> 32);
89	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET));
90	PUSH_DATA (push, 0x22222222);
91	PUSH_DATA (push, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG);
92	BEGIN_NVC0(push, SUBC_NVSW(0x0400), 4);
93	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET) >> 32);
94	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET));
95	PUSH_DATA (push, 0x11111111);
96	PUSH_DATA (push, head);
97	BEGIN_NVC0(push, NV84_SUBC(NVSW, SEMAPHORE_ADDRESS_HIGH), 4);
98	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET) >> 32);
99	PUSH_DATA (push, (pNv->scratch->offset + SEMA_OFFSET));
100	PUSH_DATA (push, 0x11111111);
101	PUSH_DATA (push, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL);
102}
103
104Bool
105NVAccelInitM2MF_NVC0(ScrnInfoPtr pScrn)
106{
107	NVPtr pNv = NVPTR(pScrn);
108	struct nouveau_pushbuf *push = pNv->pushbuf;
109	int ret;
110
111	ret = nouveau_object_new(pNv->channel, 0x00009039, 0x9039,
112				 NULL, 0, &pNv->NvMemFormat);
113	if (ret)
114		return FALSE;
115
116	BEGIN_NVC0(push, NV01_SUBC(M2MF, OBJECT), 1);
117	PUSH_DATA (push, pNv->NvMemFormat->handle);
118	BEGIN_NVC0(push, NVC0_M2MF(QUERY_ADDRESS_HIGH), 3);
119	PUSH_DATA (push, (pNv->scratch->offset + NTFY_OFFSET) >> 32);
120	PUSH_DATA (push, (pNv->scratch->offset + NTFY_OFFSET));
121	PUSH_DATA (push, 0);
122
123	return TRUE;
124}
125
126Bool
127NVAccelInitP2MF_NVE0(ScrnInfoPtr pScrn)
128{
129	NVPtr pNv = NVPTR(pScrn);
130	struct nouveau_pushbuf *push = pNv->pushbuf;
131	uint32_t class = (pNv->dev->chipset < 0xf0) ? 0xa040 : 0xa140;
132	int ret;
133
134	ret = nouveau_object_new(pNv->channel, class, class, NULL, 0,
135				&pNv->NvMemFormat);
136	if (ret)
137		return FALSE;
138
139	BEGIN_NVC0(push, NV01_SUBC(P2MF, OBJECT), 1);
140	PUSH_DATA (push, pNv->NvMemFormat->handle);
141	return TRUE;
142}
143
144Bool
145NVAccelInitCOPY_NVE0(ScrnInfoPtr pScrn)
146{
147	NVPtr pNv = NVPTR(pScrn);
148	struct nouveau_pushbuf *push = pNv->pushbuf;
149	int ret;
150
151	ret = nouveau_object_new(pNv->channel, 0x0000a0b5, 0xa0b5,
152				 NULL, 0, &pNv->NvCOPY);
153	if (ret)
154		return FALSE;
155
156	BEGIN_NVC0(push, NV01_SUBC(COPY, OBJECT), 1);
157	PUSH_DATA (push, pNv->NvCOPY->handle);
158	return TRUE;
159}
160
161Bool
162NVAccelInit2D_NVC0(ScrnInfoPtr pScrn)
163{
164	NVPtr pNv = NVPTR(pScrn);
165	struct nouveau_pushbuf *push = pNv->pushbuf;
166	int ret;
167
168	ret = nouveau_object_new(pNv->channel, 0x0000902d, 0x902d,
169				 NULL, 0, &pNv->Nv2D);
170	if (ret)
171		return FALSE;
172
173	if (!PUSH_SPACE(push, 64))
174		return FALSE;
175
176	BEGIN_NVC0(push, NV01_SUBC(2D, OBJECT), 1);
177	PUSH_DATA (push, pNv->Nv2D->handle);
178
179	BEGIN_NVC0(push, NV50_2D(CLIP_ENABLE), 1);
180	PUSH_DATA (push, 1);
181	BEGIN_NVC0(push, NV50_2D(COLOR_KEY_ENABLE), 1);
182	PUSH_DATA (push, 0);
183	BEGIN_NVC0(push, NV50_2D(UNK0884), 1);
184	PUSH_DATA (push, 0x3f);
185	BEGIN_NVC0(push, NV50_2D(UNK0888), 1);
186	PUSH_DATA (push, 1);
187	BEGIN_NVC0(push, NV50_2D(ROP), 1);
188	PUSH_DATA (push, 0x55);
189	BEGIN_NVC0(push, NV50_2D(OPERATION), 1);
190	PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY);
191
192	BEGIN_NVC0(push, NV50_2D(BLIT_DU_DX_FRACT), 4);
193	PUSH_DATA (push, 0);
194	PUSH_DATA (push, 1);
195	PUSH_DATA (push, 0);
196	PUSH_DATA (push, 1);
197	BEGIN_NVC0(push, NV50_2D(DRAW_SHAPE), 2);
198	PUSH_DATA (push, 4);
199	PUSH_DATA (push, NV50_SURFACE_FORMAT_B5G6R5_UNORM);
200	BEGIN_NVC0(push, NV50_2D(PATTERN_COLOR_FORMAT), 2);
201	PUSH_DATA (push, 2);
202	PUSH_DATA (push, 1);
203
204	pNv->currentRop = 0xfffffffa;
205	return TRUE;
206}
207
208Bool
209NVAccelInit3D_NVC0(ScrnInfoPtr pScrn)
210{
211	NVPtr pNv = NVPTR(pScrn);
212	struct nouveau_pushbuf *push = pNv->pushbuf;
213	struct nouveau_bo *bo = pNv->scratch;
214	uint32_t class, handle;
215	int ret;
216
217	if (pNv->Architecture < NV_KEPLER) {
218		class  = 0x9097;
219		handle = 0x001f906e;
220	} else if (pNv->dev->chipset == 0xea) {
221		class = 0xa297;
222		handle = 0x0000906e;
223	} else if (pNv->dev->chipset < 0xf0) {
224		class  = 0xa097;
225		handle = 0x0000906e;
226	} else {
227		class  = 0xa197;
228		handle = 0x0000906e;
229	}
230
231	ret = nouveau_object_new(pNv->channel, class, class,
232				 NULL, 0, &pNv->Nv3D);
233	if (ret)
234		return FALSE;
235
236	ret = nouveau_object_new(pNv->channel, handle, 0x906e,
237				 NULL, 0, &pNv->NvSW);
238	if (ret) {
239		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
240			   "DRM doesn't support sync-to-vblank\n");
241	}
242
243	if (nouveau_pushbuf_space(push, 512, 0, 0) ||
244	    nouveau_pushbuf_refn (push, &(struct nouveau_pushbuf_refn) {
245					pNv->scratch, NOUVEAU_BO_VRAM |
246					NOUVEAU_BO_WR }, 1))
247		return FALSE;
248
249	BEGIN_NVC0(push, NV01_SUBC(3D, OBJECT), 1);
250	PUSH_DATA (push, pNv->Nv3D->handle);
251	BEGIN_NVC0(push, NVC0_3D(COND_MODE), 1);
252	PUSH_DATA (push, NVC0_3D_COND_MODE_ALWAYS);
253	BEGIN_NVC0(push, SUBC_3D(NVC0_GRAPH_NOTIFY_ADDRESS_HIGH), 3);
254	PUSH_DATA (push, (pNv->scratch->offset + NTFY_OFFSET) >> 32);
255	PUSH_DATA (push, (pNv->scratch->offset + NTFY_OFFSET));
256	PUSH_DATA (push, 0);
257	BEGIN_NVC0(push, NVC0_3D(CSAA_ENABLE), 1);
258	PUSH_DATA (push, 0);
259	BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
260	PUSH_DATA (push, 0);
261	BEGIN_NVC0(push, NVC0_3D(RT_SEPARATE_FRAG_DATA), 1);
262	PUSH_DATA (push, 0);
263
264	BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2);
265	PUSH_DATA (push, (8192 << 16) | 0);
266	PUSH_DATA (push, (8192 << 16) | 0);
267	BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
268	PUSH_DATA (push, (8192 << 16) | 0);
269	PUSH_DATA (push, (8192 << 16) | 0);
270	BEGIN_NVC0(push, NVC0_3D(SCISSOR_ENABLE(0)), 1);
271	PUSH_DATA (push, 1);
272	BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
273	PUSH_DATA (push, 0);
274	BEGIN_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 1);
275	PUSH_DATA (push, 0);
276
277	BEGIN_NVC0(push, NVC0_3D(TIC_ADDRESS_HIGH), 3);
278	PUSH_DATA (push, (bo->offset + TIC_OFFSET) >> 32);
279	PUSH_DATA (push, (bo->offset + TIC_OFFSET));
280	PUSH_DATA (push, 15);
281	BEGIN_NVC0(push, NVC0_3D(TSC_ADDRESS_HIGH), 3);
282	PUSH_DATA (push, (bo->offset + TSC_OFFSET) >> 32);
283	PUSH_DATA (push, (bo->offset + TSC_OFFSET));
284	PUSH_DATA (push, 0);
285	BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1);
286	PUSH_DATA (push, 1);
287	if (pNv->Architecture < NV_KEPLER) {
288		BEGIN_NVC0(push, NVC0_3D(TEX_LIMITS(4)), 1);
289		PUSH_DATA (push, 0x54);
290		BEGIN_NIC0(push, NVC0_3D(BIND_TIC(4)), 2);
291		PUSH_DATA (push, (0 << 9) | (0 << 1) | NVC0_3D_BIND_TIC_ACTIVE);
292		PUSH_DATA (push, (1 << 9) | (1 << 1) | NVC0_3D_BIND_TIC_ACTIVE);
293	} else {
294		BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 6);
295		PUSH_DATA (push, 256);
296		PUSH_DATA (push, (bo->offset + TB_OFFSET) >> 32);
297		PUSH_DATA (push, (bo->offset + TB_OFFSET));
298		PUSH_DATA (push, 0);
299		PUSH_DATA (push, 0x00000000);
300		PUSH_DATA (push, 0x00000001);
301		BEGIN_NVC0(push, NVC0_3D(CB_BIND(4)), 1);
302		PUSH_DATA (push, 0x11);
303		BEGIN_NVC0(push, SUBC_3D(0x2608), 1);
304		PUSH_DATA (push, 1);
305	}
306
307	BEGIN_NVC0(push, NVC0_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3);
308	PUSH_DATA (push, (bo->offset + MISC_OFFSET) >> 32);
309	PUSH_DATA (push, (bo->offset + MISC_OFFSET));
310	PUSH_DATA (push, 1);
311
312	BEGIN_NVC0(push, NVC0_3D(CODE_ADDRESS_HIGH), 2);
313	PUSH_DATA (push, (bo->offset + CODE_OFFSET) >> 32);
314	PUSH_DATA (push, (bo->offset + CODE_OFFSET));
315	if (pNv->Architecture < NV_KEPLER) {
316		NVC0PushProgram(pNv, PVP_PASS, NVC0VP_Transform2);
317		NVC0PushProgram(pNv, PFP_S, NVC0FP_Source);
318		NVC0PushProgram(pNv, PFP_C, NVC0FP_Composite);
319		NVC0PushProgram(pNv, PFP_CCA, NVC0FP_CAComposite);
320		NVC0PushProgram(pNv, PFP_CCASA, NVC0FP_CACompositeSrcAlpha);
321		NVC0PushProgram(pNv, PFP_S_A8, NVC0FP_Source_A8);
322		NVC0PushProgram(pNv, PFP_C_A8, NVC0FP_Composite_A8);
323		NVC0PushProgram(pNv, PFP_NV12, NVC0FP_NV12);
324
325		BEGIN_NVC0(push, NVC0_3D(MEM_BARRIER), 1);
326		PUSH_DATA (push, 0x1111);
327	} else
328	if (pNv->dev->chipset < 0xf0 && pNv->dev->chipset != 0xea) {
329		NVC0PushProgram(pNv, PVP_PASS, NVE0VP_Transform2);
330		NVC0PushProgram(pNv, PFP_S, NVE0FP_Source);
331		NVC0PushProgram(pNv, PFP_C, NVE0FP_Composite);
332		NVC0PushProgram(pNv, PFP_CCA, NVE0FP_CAComposite);
333		NVC0PushProgram(pNv, PFP_CCASA, NVE0FP_CACompositeSrcAlpha);
334		NVC0PushProgram(pNv, PFP_S_A8, NVE0FP_Source_A8);
335		NVC0PushProgram(pNv, PFP_C_A8, NVE0FP_Composite_A8);
336		NVC0PushProgram(pNv, PFP_NV12, NVE0FP_NV12);
337	} else {
338		NVC0PushProgram(pNv, PVP_PASS, NVF0VP_Transform2);
339		NVC0PushProgram(pNv, PFP_S, NVF0FP_Source);
340		NVC0PushProgram(pNv, PFP_C, NVF0FP_Composite);
341		NVC0PushProgram(pNv, PFP_CCA, NVF0FP_CAComposite);
342		NVC0PushProgram(pNv, PFP_CCASA, NVF0FP_CACompositeSrcAlpha);
343		NVC0PushProgram(pNv, PFP_S_A8, NVF0FP_Source_A8);
344		NVC0PushProgram(pNv, PFP_C_A8, NVF0FP_Composite_A8);
345		NVC0PushProgram(pNv, PFP_NV12, NVF0FP_NV12);
346	}
347
348	BEGIN_NVC0(push, NVC0_3D(SP_SELECT(1)), 4);
349	PUSH_DATA (push, NVC0_3D_SP_SELECT_PROGRAM_VP_B |
350			 NVC0_3D_SP_SELECT_ENABLE);
351	PUSH_DATA (push, PVP_PASS);
352	PUSH_DATA (push, 0x00000000);
353	PUSH_DATA (push, 8);
354	BEGIN_NVC0(push, NVC0_3D(VERT_COLOR_CLAMP_EN), 1);
355	PUSH_DATA (push, 1);
356	BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
357	PUSH_DATA (push, 256);
358	PUSH_DATA (push, (bo->offset + PVP_DATA) >> 32);
359	PUSH_DATA (push, (bo->offset + PVP_DATA));
360	BEGIN_NVC0(push, NVC0_3D(CB_BIND(0)), 1);
361	PUSH_DATA (push, 0x01);
362
363	BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 4);
364	PUSH_DATA (push, NVC0_3D_SP_SELECT_PROGRAM_FP |
365			 NVC0_3D_SP_SELECT_ENABLE);
366	PUSH_DATA (push, PFP_S);
367	PUSH_DATA (push, 0x00000000);
368	PUSH_DATA (push, 8);
369	BEGIN_NVC0(push, NVC0_3D(FRAG_COLOR_CLAMP_EN), 1);
370	PUSH_DATA (push, 0x11111111);
371	BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
372	PUSH_DATA (push, 256);
373	PUSH_DATA (push, (bo->offset + PFP_DATA) >> 32);
374	PUSH_DATA (push, (bo->offset + PFP_DATA));
375	BEGIN_NVC0(push, NVC0_3D(CB_BIND(4)), 1);
376	PUSH_DATA (push, 0x01);
377
378	return TRUE;
379}
380
381