Merge branch 'upstream-gallium-0.1' into nouveau-gallium-0.1
[mesa.git] / src / mesa / drivers / dri / nouveau_winsys / nv50_surface.c
1 #include "pipe/p_context.h"
2
3 #include "nouveau_context.h"
4
5 static INLINE int
6 nv50_format(int cpp)
7 {
8 switch (cpp) {
9 case 4: return NV50_2D_DST_FORMAT_32BPP;
10 case 3: return NV50_2D_DST_FORMAT_24BPP;
11 case 2: return NV50_2D_DST_FORMAT_16BPP;
12 case 1: return NV50_2D_DST_FORMAT_8BPP;
13 default:
14 return -1;
15 }
16 }
17
18 static int
19 nv50_surface_copy_prep(struct nouveau_context *nv,
20 struct pipe_surface *dst, struct pipe_surface *src)
21 {
22 int surf_format;
23
24 assert(src->cpp == dst->cpp);
25
26 surf_format = nv50_format(dst->cpp);
27 assert(surf_format >= 0);
28
29 BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2);
30 OUT_RELOCo(src->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
31 OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
32
33 BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2);
34 OUT_RING (surf_format);
35 OUT_RING (1);
36 BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5);
37 OUT_RING (dst->pitch * dst->cpp);
38 OUT_RING (dst->pitch);
39 OUT_RING (dst->height);
40 OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
41 OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
42 BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4);
43 OUT_RING (0);
44 OUT_RING (0);
45 OUT_RING (dst->pitch);
46 OUT_RING (dst->height);
47
48 BEGIN_RING(Nv2D, NV50_2D_SRC_FORMAT, 2);
49 OUT_RING (surf_format);
50 OUT_RING (1);
51 BEGIN_RING(Nv2D, NV50_2D_SRC_PITCH, 5);
52 OUT_RING (src->pitch * src->cpp);
53 OUT_RING (src->pitch);
54 OUT_RING (src->height);
55 OUT_RELOCh(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
56 OUT_RELOCl(src->buffer, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
57
58 return 0;
59 }
60
61 static void
62 nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy,
63 unsigned sx, unsigned sy, unsigned w, unsigned h)
64 {
65 BEGIN_RING(Nv2D, 0x0110, 1);
66 OUT_RING (0);
67 BEGIN_RING(Nv2D, NV50_2D_BLIT_DST_X, 12);
68 OUT_RING (dx);
69 OUT_RING (dy);
70 OUT_RING (w);
71 OUT_RING (h);
72 OUT_RING (0);
73 OUT_RING (1);
74 OUT_RING (0);
75 OUT_RING (1);
76 OUT_RING (0);
77 OUT_RING (sx);
78 OUT_RING (0);
79 OUT_RING (sy);
80 }
81
82 static void
83 nv50_surface_copy_done(struct nouveau_context *nv)
84 {
85 FIRE_RING();
86 }
87
88 static int
89 nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst,
90 unsigned dx, unsigned dy, unsigned w, unsigned h,
91 unsigned value)
92 {
93 int surf_format, rect_format;
94
95 surf_format = nv50_format(dst->cpp);
96 if (surf_format < 0)
97 return 1;
98
99 rect_format = nv50_format(dst->cpp);
100 if (rect_format < 0)
101 return 1;
102
103 BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY1, 1);
104 OUT_RELOCo(dst->buffer, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
105 BEGIN_RING(Nv2D, NV50_2D_DST_FORMAT, 2);
106 OUT_RING (surf_format);
107 OUT_RING (1);
108 BEGIN_RING(Nv2D, NV50_2D_DST_PITCH, 5);
109 OUT_RING (dst->pitch * dst->cpp);
110 OUT_RING (dst->pitch);
111 OUT_RING (dst->height);
112 OUT_RELOCh(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
113 OUT_RELOCl(dst->buffer, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
114 BEGIN_RING(Nv2D, NV50_2D_CLIP_X, 4);
115 OUT_RING (0);
116 OUT_RING (0);
117 OUT_RING (dst->pitch);
118 OUT_RING (dst->height);
119
120 BEGIN_RING(Nv2D, 0x0580, 3);
121 OUT_RING (4);
122 OUT_RING (rect_format);
123 OUT_RING (value);
124
125 BEGIN_RING(Nv2D, NV50_2D_RECT_X1, 4);
126 OUT_RING (dx);
127 OUT_RING (dy);
128 OUT_RING (dx + w);
129 OUT_RING (dy + h);
130
131 FIRE_RING();
132
133 return 0;
134 }
135
136 int
137 nouveau_surface_init_nv50(struct nouveau_context *nv)
138 {
139 int ret;
140
141 ret = nouveau_grobj_alloc(nv->channel, nv->next_handle++, NV50_2D,
142 &nv->Nv2D);
143 if (ret)
144 return ret;
145 BIND_RING (Nv2D, 0);
146 BEGIN_RING(Nv2D, NV50_2D_DMA_NOTIFY, 1);
147 OUT_RING (nv->sync_notifier->handle);
148 BEGIN_RING(Nv2D, NV50_2D_DMA_IN_MEMORY0, 2);
149 OUT_RING (nv->channel->vram->handle);
150 OUT_RING (nv->channel->vram->handle);
151 BEGIN_RING(Nv2D, NV50_2D_OPERATION, 1);
152 OUT_RING (NV50_2D_OPERATION_SRCCOPY);
153
154 nv->surface_copy_prep = nv50_surface_copy_prep;
155 nv->surface_copy = nv50_surface_copy;
156 nv->surface_copy_done = nv50_surface_copy_done;
157 nv->surface_fill = nv50_surface_fill;
158 return 0;
159 }
160