1 #include "pipe/p_context.h"
2 #include "pipe/p_format.h"
4 #include "nouveau_context.h"
7 nv04_surface_format(enum pipe_format format
)
10 case PIPE_FORMAT_A8_UNORM
:
11 return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8
;
12 case PIPE_FORMAT_R5G6B5_UNORM
:
13 return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5
;
14 case PIPE_FORMAT_A8R8G8B8_UNORM
:
15 case PIPE_FORMAT_Z24S8_UNORM
:
16 return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32
;
23 nv04_rect_format(enum pipe_format format
)
26 case PIPE_FORMAT_A8_UNORM
:
27 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8
;
28 case PIPE_FORMAT_R5G6B5_UNORM
:
29 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5
;
30 case PIPE_FORMAT_A8R8G8B8_UNORM
:
31 case PIPE_FORMAT_Z24S8_UNORM
:
32 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8
;
39 nv04_surface_copy_m2mf(struct nouveau_context
*nv
, unsigned dx
, unsigned dy
,
40 unsigned sx
, unsigned sy
, unsigned w
, unsigned h
)
42 struct nouveau_channel
*chan
= nv
->nvc
->channel
;
43 struct pipe_surface
*dst
= nv
->surf_dst
;
44 struct pipe_surface
*src
= nv
->surf_src
;
45 unsigned dst_offset
, src_offset
;
47 dst_offset
= dst
->offset
+ (dy
* dst
->stride
) + (dx
* dst
->block
.size
);
48 src_offset
= src
->offset
+ (sy
* src
->stride
) + (sx
* src
->block
.size
);
51 int count
= (h
> 2047) ? 2047 : h
;
53 BEGIN_RING(chan
, nv
->nvc
->NvM2MF
,
54 NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN
, 8);
55 OUT_RELOCl(chan
, nouveau_buffer(src
->buffer
)->bo
, src_offset
,
56 NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
);
57 OUT_RELOCl(chan
, nouveau_buffer(dst
->buffer
)->bo
, dst_offset
,
58 NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_WR
);
59 OUT_RING (chan
, src
->stride
);
60 OUT_RING (chan
, dst
->stride
);
61 OUT_RING (chan
, w
* src
->block
.size
);
62 OUT_RING (chan
, count
);
63 OUT_RING (chan
, 0x0101);
67 src_offset
+= src
->stride
* count
;
68 dst_offset
+= dst
->stride
* count
;
73 nv04_surface_copy_blit(struct nouveau_context
*nv
, unsigned dx
, unsigned dy
,
74 unsigned sx
, unsigned sy
, unsigned w
, unsigned h
)
76 struct nouveau_channel
*chan
= nv
->nvc
->channel
;
78 BEGIN_RING(chan
, nv
->nvc
->NvImageBlit
, 0x0300, 3);
79 OUT_RING (chan
, (sy
<< 16) | sx
);
80 OUT_RING (chan
, (dy
<< 16) | dx
);
81 OUT_RING (chan
, ( h
<< 16) | w
);
85 nv04_surface_copy_prep(struct nouveau_context
*nv
, struct pipe_surface
*dst
,
86 struct pipe_surface
*src
)
88 struct nouveau_channel
*chan
= nv
->nvc
->channel
;
91 if (src
->format
!= dst
->format
)
94 /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback
95 * to NV_MEMORY_TO_MEMORY_FORMAT in this case.
97 if ((src
->offset
& 63) || (dst
->offset
& 63)) {
98 BEGIN_RING(nv
->nvc
->channel
, nv
->nvc
->NvM2MF
,
99 NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN
, 2);
100 OUT_RELOCo(chan
, nouveau_buffer(src
->buffer
)->bo
,
101 NOUVEAU_BO_GART
| NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
102 OUT_RELOCo(chan
, nouveau_buffer(dst
->buffer
)->bo
,
103 NOUVEAU_BO_GART
| NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
105 nv
->surface_copy
= nv04_surface_copy_m2mf
;
112 if ((format
= nv04_surface_format(dst
->format
)) < 0) {
113 NOUVEAU_ERR("Bad surface format 0x%x\n", dst
->format
);
116 nv
->surface_copy
= nv04_surface_copy_blit
;
118 BEGIN_RING(chan
, nv
->nvc
->NvCtxSurf2D
,
119 NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE
, 2);
120 OUT_RELOCo(chan
, nouveau_buffer(src
->buffer
)->bo
,
121 NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
122 OUT_RELOCo(chan
, nouveau_buffer(dst
->buffer
)->bo
,
123 NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
125 BEGIN_RING(chan
, nv
->nvc
->NvCtxSurf2D
,
126 NV04_CONTEXT_SURFACES_2D_FORMAT
, 4);
127 OUT_RING (chan
, format
);
128 OUT_RING (chan
, (dst
->stride
<< 16) | src
->stride
);
129 OUT_RELOCl(chan
, nouveau_buffer(src
->buffer
)->bo
, src
->offset
,
130 NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
);
131 OUT_RELOCl(chan
, nouveau_buffer(dst
->buffer
)->bo
, dst
->offset
,
132 NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
138 nv04_surface_copy_done(struct nouveau_context
*nv
)
140 FIRE_RING(nv
->nvc
->channel
);
144 nv04_surface_fill(struct nouveau_context
*nv
, struct pipe_surface
*dst
,
145 unsigned dx
, unsigned dy
, unsigned w
, unsigned h
,
148 struct nouveau_channel
*chan
= nv
->nvc
->channel
;
149 struct nouveau_grobj
*surf2d
= nv
->nvc
->NvCtxSurf2D
;
150 struct nouveau_grobj
*rect
= nv
->nvc
->NvGdiRect
;
151 int cs2d_format
, gdirect_format
;
153 if ((cs2d_format
= nv04_surface_format(dst
->format
)) < 0) {
154 NOUVEAU_ERR("Bad format = %d\n", dst
->format
);
158 if ((gdirect_format
= nv04_rect_format(dst
->format
)) < 0) {
159 NOUVEAU_ERR("Bad format = %d\n", dst
->format
);
163 BEGIN_RING(chan
, surf2d
, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE
, 2);
164 OUT_RELOCo(chan
, nouveau_buffer(dst
->buffer
)->bo
,
165 NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
166 OUT_RELOCo(chan
, nouveau_buffer(dst
->buffer
)->bo
,
167 NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
168 BEGIN_RING(chan
, surf2d
, NV04_CONTEXT_SURFACES_2D_FORMAT
, 4);
169 OUT_RING (chan
, cs2d_format
);
170 OUT_RING (chan
, (dst
->stride
<< 16) | dst
->stride
);
171 OUT_RELOCl(chan
, nouveau_buffer(dst
->buffer
)->bo
, dst
->offset
,
172 NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
173 OUT_RELOCl(chan
, nouveau_buffer(dst
->buffer
)->bo
, dst
->offset
,
174 NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
176 BEGIN_RING(chan
, rect
, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT
, 1);
177 OUT_RING (chan
, gdirect_format
);
178 BEGIN_RING(chan
, rect
, NV04_GDI_RECTANGLE_TEXT_COLOR1_A
, 1);
179 OUT_RING (chan
, value
);
180 BEGIN_RING(chan
, rect
,
181 NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2);
182 OUT_RING (chan
, (dx
<< 16) | dy
);
183 OUT_RING (chan
, ( w
<< 16) | h
);
190 nouveau_surface_channel_create_nv04(struct nouveau_channel_context
*nvc
)
192 struct nouveau_channel
*chan
= nvc
->channel
;
193 unsigned chipset
= nvc
->channel
->device
->chipset
, class;
196 if ((ret
= nouveau_grobj_alloc(chan
, nvc
->next_handle
++, 0x39,
198 NOUVEAU_ERR("Error creating m2mf object: %d\n", ret
);
201 BIND_RING (chan
, nvc
->NvM2MF
, nvc
->next_subchannel
++);
202 BEGIN_RING(chan
, nvc
->NvM2MF
,
203 NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY
, 1);
204 OUT_RING (chan
, nvc
->sync_notifier
->handle
);
206 class = chipset
< 0x10 ? NV04_CONTEXT_SURFACES_2D
:
207 NV10_CONTEXT_SURFACES_2D
;
208 if ((ret
= nouveau_grobj_alloc(chan
, nvc
->next_handle
++, class,
209 &nvc
->NvCtxSurf2D
))) {
210 NOUVEAU_ERR("Error creating 2D surface object: %d\n", ret
);
213 BIND_RING (chan
, nvc
->NvCtxSurf2D
, nvc
->next_subchannel
++);
214 BEGIN_RING(chan
, nvc
->NvCtxSurf2D
,
215 NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE
, 2);
216 OUT_RING (chan
, nvc
->channel
->vram
->handle
);
217 OUT_RING (chan
, nvc
->channel
->vram
->handle
);
219 class = chipset
< 0x10 ? NV04_IMAGE_BLIT
: NV12_IMAGE_BLIT
;
220 if ((ret
= nouveau_grobj_alloc(chan
, nvc
->next_handle
++, class,
221 &nvc
->NvImageBlit
))) {
222 NOUVEAU_ERR("Error creating blit object: %d\n", ret
);
225 BIND_RING (chan
, nvc
->NvImageBlit
, nvc
->next_subchannel
++);
226 BEGIN_RING(chan
, nvc
->NvImageBlit
, NV04_IMAGE_BLIT_DMA_NOTIFY
, 1);
227 OUT_RING (chan
, nvc
->sync_notifier
->handle
);
228 BEGIN_RING(chan
, nvc
->NvImageBlit
, NV04_IMAGE_BLIT_SURFACE
, 1);
229 OUT_RING (chan
, nvc
->NvCtxSurf2D
->handle
);
230 BEGIN_RING(chan
, nvc
->NvImageBlit
, NV04_IMAGE_BLIT_OPERATION
, 1);
231 OUT_RING (chan
, NV04_IMAGE_BLIT_OPERATION_SRCCOPY
);
233 class = NV04_GDI_RECTANGLE_TEXT
;
234 if ((ret
= nouveau_grobj_alloc(chan
, nvc
->next_handle
++, class,
236 NOUVEAU_ERR("Error creating rect object: %d\n", ret
);
239 BIND_RING (chan
, nvc
->NvGdiRect
, nvc
->next_subchannel
++);
240 BEGIN_RING(chan
, nvc
->NvGdiRect
, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY
, 1);
241 OUT_RING (chan
, nvc
->sync_notifier
->handle
);
242 BEGIN_RING(chan
, nvc
->NvGdiRect
, NV04_GDI_RECTANGLE_TEXT_SURFACE
, 1);
243 OUT_RING (chan
, nvc
->NvCtxSurf2D
->handle
);
244 BEGIN_RING(chan
, nvc
->NvGdiRect
, NV04_GDI_RECTANGLE_TEXT_OPERATION
, 1);
245 OUT_RING (chan
, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY
);
246 BEGIN_RING(chan
, nvc
->NvGdiRect
,
247 NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT
, 1);
248 OUT_RING (chan
, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE
);
250 switch (chipset
& 0xf0) {
253 class = NV04_SWIZZLED_SURFACE
;
256 class = NV20_SWIZZLED_SURFACE
;
259 class = NV30_SWIZZLED_SURFACE
;
263 class = NV40_SWIZZLED_SURFACE
;
266 /* Famous last words: this really can't happen.. */
271 ret
= nouveau_grobj_alloc(chan
, nvc
->next_handle
++, class,
274 NOUVEAU_ERR("Error creating swizzled surface: %d\n", ret
);
278 BIND_RING (chan
, nvc
->NvSwzSurf
, nvc
->next_subchannel
++);
279 BEGIN_RING(chan
, nvc
->NvSwzSurf
, NV04_SWIZZLED_SURFACE_DMA_NOTIFY
, 1);
280 OUT_RING (chan
, nvc
->sync_notifier
->handle
);
281 BEGIN_RING(chan
, nvc
->NvSwzSurf
, NV04_SWIZZLED_SURFACE_DMA_IMAGE
, 1);
282 OUT_RING (chan
, nvc
->channel
->vram
->handle
);
284 if (chipset
< 0x10) {
285 class = NV04_SCALED_IMAGE_FROM_MEMORY
;
287 if (chipset
< 0x40) {
288 class = NV10_SCALED_IMAGE_FROM_MEMORY
;
290 class = NV40_SCALED_IMAGE_FROM_MEMORY
;
293 ret
= nouveau_grobj_alloc(chan
, nvc
->next_handle
++, class,
296 NOUVEAU_ERR("Error creating scaled image object: %d\n", ret
);
300 BIND_RING (chan
, nvc
->NvSIFM
, nvc
->next_subchannel
++);
306 nouveau_surface_init_nv04(struct nouveau_context
*nv
)
308 nv
->surface_copy_prep
= nv04_surface_copy_prep
;
309 nv
->surface_copy
= nv04_surface_copy_blit
;
310 nv
->surface_copy_done
= nv04_surface_copy_done
;
311 nv
->surface_fill
= nv04_surface_fill
;