2 * Copyright 2012 Red Hat Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
26 #include "pipe/p_defines.h"
27 #include "util/u_pack_color.h"
29 #include "nouveau/nouveau_gldefs.h"
30 #include "nouveau/nv_object.xml.h"
31 #include "nv30-40_3d.xml.h"
32 #include "nv30_context.h"
33 #include "nv30_format.h"
35 static INLINE
uint32_t
36 pack_rgba(enum pipe_format format
, const float *rgba
)
39 util_pack_color(rgba
, format
, &uc
);
43 static INLINE
uint32_t
44 pack_zeta(enum pipe_format format
, double depth
, unsigned stencil
)
46 uint32_t zuint
= (uint32_t)(depth
* 4294967295.0);
47 if (format
!= PIPE_FORMAT_Z16_UNORM
)
48 return (zuint
& 0xffffff00) | (stencil
& 0xff);
53 nv30_clear(struct pipe_context
*pipe
, unsigned buffers
,
54 const union pipe_color_union
*color
, double depth
, unsigned stencil
)
56 struct nv30_context
*nv30
= nv30_context(pipe
);
57 struct nouveau_pushbuf
*push
= nv30
->base
.pushbuf
;
58 struct pipe_framebuffer_state
*fb
= &nv30
->framebuffer
;
59 uint32_t colr
= 0, zeta
= 0, mode
= 0;
61 if (!nv30_state_validate(nv30
, TRUE
))
64 if (buffers
& PIPE_CLEAR_COLOR
&& fb
->nr_cbufs
) {
65 colr
= pack_rgba(fb
->cbufs
[0]->format
, color
->f
);
66 mode
|= NV30_3D_CLEAR_BUFFERS_COLOR_R
|
67 NV30_3D_CLEAR_BUFFERS_COLOR_G
|
68 NV30_3D_CLEAR_BUFFERS_COLOR_B
|
69 NV30_3D_CLEAR_BUFFERS_COLOR_A
;
73 zeta
= pack_zeta(fb
->zsbuf
->format
, depth
, stencil
);
74 if (buffers
& PIPE_CLEAR_DEPTH
)
75 mode
|= NV30_3D_CLEAR_BUFFERS_DEPTH
;
76 if (buffers
& PIPE_CLEAR_STENCIL
)
77 mode
|= NV30_3D_CLEAR_BUFFERS_STENCIL
;
80 /*XXX: wtf? fixes clears sometimes not clearing on nv3x... */
81 if (nv30
->screen
->eng3d
->oclass
< NV40_3D_CLASS
) {
82 BEGIN_NV04(push
, NV30_3D(CLEAR_DEPTH_VALUE
), 3);
83 PUSH_DATA (push
, zeta
);
84 PUSH_DATA (push
, colr
);
85 PUSH_DATA (push
, mode
);
88 BEGIN_NV04(push
, NV30_3D(CLEAR_DEPTH_VALUE
), 3);
89 PUSH_DATA (push
, zeta
);
90 PUSH_DATA (push
, colr
);
91 PUSH_DATA (push
, mode
);
93 nv30_state_release(nv30
);
97 nv30_clear_render_target(struct pipe_context
*pipe
, struct pipe_surface
*ps
,
98 const union pipe_color_union
*color
,
99 unsigned x
, unsigned y
, unsigned w
, unsigned h
)
101 struct nv30_context
*nv30
= nv30_context(pipe
);
102 struct nv30_surface
*sf
= nv30_surface(ps
);
103 struct nv30_miptree
*mt
= nv30_miptree(ps
->texture
);
104 struct nouveau_pushbuf
*push
= nv30
->base
.pushbuf
;
105 struct nouveau_object
*eng3d
= nv30
->screen
->eng3d
;
106 struct nouveau_pushbuf_refn refn
;
109 rt_format
= nv30_format(pipe
->screen
, ps
->format
)->hw
;
110 if (util_format_get_blocksize(ps
->format
) == 4)
111 rt_format
|= NV30_3D_RT_FORMAT_ZETA_Z24S8
;
113 rt_format
|= NV30_3D_RT_FORMAT_ZETA_Z16
;
115 if (nv30_miptree(ps
->texture
)->swizzled
) {
116 rt_format
|= NV30_3D_RT_FORMAT_TYPE_SWIZZLED
;
117 rt_format
|= util_logbase2(sf
->width
) << 16;
118 rt_format
|= util_logbase2(sf
->height
) << 24;
120 rt_format
|= NV30_3D_RT_FORMAT_TYPE_LINEAR
;
123 refn
.bo
= mt
->base
.bo
;
124 refn
.flags
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
;
125 if (nouveau_pushbuf_space(push
, 16, 1, 0) ||
126 nouveau_pushbuf_refn (push
, &refn
, 1))
129 BEGIN_NV04(push
, NV30_3D(RT_ENABLE
), 1);
130 PUSH_DATA (push
, NV30_3D_RT_ENABLE_COLOR0
);
131 BEGIN_NV04(push
, NV30_3D(RT_HORIZ
), 3);
132 PUSH_DATA (push
, sf
->width
<< 16);
133 PUSH_DATA (push
, sf
->height
<< 16);
134 PUSH_DATA (push
, rt_format
);
135 BEGIN_NV04(push
, NV30_3D(COLOR0_PITCH
), 2);
136 if (eng3d
->oclass
< NV40_3D_CLASS
)
137 PUSH_DATA (push
, (sf
->pitch
<< 16) | sf
->pitch
);
139 PUSH_DATA (push
, sf
->pitch
);
140 PUSH_RELOC(push
, mt
->base
.bo
, sf
->offset
, NOUVEAU_BO_LOW
, 0, 0);
141 BEGIN_NV04(push
, NV30_3D(SCISSOR_HORIZ
), 2);
142 PUSH_DATA (push
, (w
<< 16) | x
);
143 PUSH_DATA (push
, (h
<< 16) | y
);
145 BEGIN_NV04(push
, NV30_3D(CLEAR_COLOR_VALUE
), 2);
146 PUSH_DATA (push
, pack_rgba(ps
->format
, color
->f
));
147 PUSH_DATA (push
, NV30_3D_CLEAR_BUFFERS_COLOR_R
|
148 NV30_3D_CLEAR_BUFFERS_COLOR_G
|
149 NV30_3D_CLEAR_BUFFERS_COLOR_B
|
150 NV30_3D_CLEAR_BUFFERS_COLOR_A
);
152 nv30
->dirty
|= NV30_NEW_FRAMEBUFFER
| NV30_NEW_SCISSOR
;
156 nv30_clear_depth_stencil(struct pipe_context
*pipe
, struct pipe_surface
*ps
,
157 unsigned buffers
, double depth
, unsigned stencil
,
158 unsigned x
, unsigned y
, unsigned w
, unsigned h
)
160 struct nv30_context
*nv30
= nv30_context(pipe
);
161 struct nv30_surface
*sf
= nv30_surface(ps
);
162 struct nv30_miptree
*mt
= nv30_miptree(ps
->texture
);
163 struct nouveau_pushbuf
*push
= nv30
->base
.pushbuf
;
164 struct nouveau_object
*eng3d
= nv30
->screen
->eng3d
;
165 struct nouveau_pushbuf_refn refn
;
166 uint32_t rt_format
, mode
= 0;
168 rt_format
= nv30_format(pipe
->screen
, ps
->format
)->hw
;
169 if (util_format_get_blocksize(ps
->format
) == 4)
170 rt_format
|= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8
;
172 rt_format
|= NV30_3D_RT_FORMAT_COLOR_R5G6B5
;
174 if (nv30_miptree(ps
->texture
)->swizzled
) {
175 rt_format
|= NV30_3D_RT_FORMAT_TYPE_SWIZZLED
;
176 rt_format
|= util_logbase2(sf
->width
) << 16;
177 rt_format
|= util_logbase2(sf
->height
) << 24;
179 rt_format
|= NV30_3D_RT_FORMAT_TYPE_LINEAR
;
182 if (buffers
& PIPE_CLEAR_DEPTH
)
183 mode
|= NV30_3D_CLEAR_BUFFERS_DEPTH
;
184 if (buffers
& PIPE_CLEAR_STENCIL
)
185 mode
|= NV30_3D_CLEAR_BUFFERS_STENCIL
;
187 refn
.bo
= mt
->base
.bo
;
188 refn
.flags
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
;
189 if (nouveau_pushbuf_space(push
, 32, 1, 0) ||
190 nouveau_pushbuf_refn (push
, &refn
, 1))
193 BEGIN_NV04(push
, NV30_3D(RT_ENABLE
), 1);
195 BEGIN_NV04(push
, NV30_3D(RT_HORIZ
), 3);
196 PUSH_DATA (push
, sf
->width
<< 16);
197 PUSH_DATA (push
, sf
->height
<< 16);
198 PUSH_DATA (push
, rt_format
);
199 if (eng3d
->oclass
< NV40_3D_CLASS
) {
200 BEGIN_NV04(push
, NV30_3D(COLOR0_PITCH
), 1);
201 PUSH_DATA (push
, (sf
->pitch
<< 16) | sf
->pitch
);
203 BEGIN_NV04(push
, NV40_3D(ZETA_PITCH
), 1);
204 PUSH_DATA (push
, sf
->pitch
);
206 BEGIN_NV04(push
, NV30_3D(ZETA_OFFSET
), 1);
207 PUSH_RELOC(push
, mt
->base
.bo
, sf
->offset
, NOUVEAU_BO_LOW
, 0, 0);
208 BEGIN_NV04(push
, NV30_3D(SCISSOR_HORIZ
), 2);
209 PUSH_DATA (push
, (w
<< 16) | x
);
210 PUSH_DATA (push
, (h
<< 16) | y
);
212 BEGIN_NV04(push
, NV30_3D(CLEAR_DEPTH_VALUE
), 1);
213 PUSH_DATA (push
, pack_zeta(ps
->format
, depth
, stencil
));
214 BEGIN_NV04(push
, NV30_3D(CLEAR_BUFFERS
), 1);
215 PUSH_DATA (push
, mode
);
217 nv30
->dirty
|= NV30_NEW_FRAMEBUFFER
| NV30_NEW_SCISSOR
;
221 nv30_clear_init(struct pipe_context
*pipe
)
223 pipe
->clear
= nv30_clear
;
224 pipe
->clear_render_target
= nv30_clear_render_target
;
225 pipe
->clear_depth_stencil
= nv30_clear_depth_stencil
;