Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nv30/nv30_clear.c
4574 views
1
/*
2
* Copyright 2012 Red Hat Inc.
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 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.
21
*
22
* Authors: Ben Skeggs
23
*
24
*/
25
26
#include "pipe/p_defines.h"
27
#include "util/u_pack_color.h"
28
29
#include "nouveau_gldefs.h"
30
#include "nv_object.xml.h"
31
#include "nv30/nv30-40_3d.xml.h"
32
#include "nv30/nv30_context.h"
33
#include "nv30/nv30_format.h"
34
35
static inline uint32_t
36
pack_rgba(enum pipe_format format, const float *rgba)
37
{
38
union util_color uc;
39
util_pack_color(rgba, format, &uc);
40
return uc.ui[0];
41
}
42
43
static inline uint32_t
44
pack_zeta(enum pipe_format format, double depth, unsigned stencil)
45
{
46
uint32_t zuint = (uint32_t)(depth * 4294967295.0);
47
if (format != PIPE_FORMAT_Z16_UNORM)
48
return (zuint & 0xffffff00) | (stencil & 0xff);
49
return zuint >> 16;
50
}
51
52
static void
53
nv30_clear(struct pipe_context *pipe, unsigned buffers, const struct pipe_scissor_state *scissor_state,
54
const union pipe_color_union *color, double depth, unsigned stencil)
55
{
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;
60
61
if (!nv30_state_validate(nv30, NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR, true))
62
return;
63
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;
70
}
71
72
if (fb->zsbuf) {
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;
78
BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(0)), 2);
79
PUSH_DATA (push, 0);
80
PUSH_DATA (push, 0x000000ff);
81
nv30->dirty |= NV30_NEW_ZSA;
82
}
83
}
84
85
/*XXX: wtf? fixes clears sometimes not clearing on nv3x... */
86
if (nv30->screen->eng3d->oclass < NV40_3D_CLASS) {
87
BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 3);
88
PUSH_DATA (push, zeta);
89
PUSH_DATA (push, colr);
90
PUSH_DATA (push, mode);
91
}
92
93
BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 3);
94
PUSH_DATA (push, zeta);
95
PUSH_DATA (push, colr);
96
PUSH_DATA (push, mode);
97
98
nv30_state_release(nv30);
99
}
100
101
static void
102
nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps,
103
const union pipe_color_union *color,
104
unsigned x, unsigned y, unsigned w, unsigned h,
105
bool render_condition_enabled)
106
{
107
struct nv30_context *nv30 = nv30_context(pipe);
108
struct nv30_surface *sf = nv30_surface(ps);
109
struct nv30_miptree *mt = nv30_miptree(ps->texture);
110
struct nouveau_pushbuf *push = nv30->base.pushbuf;
111
struct nouveau_object *eng3d = nv30->screen->eng3d;
112
struct nouveau_pushbuf_refn refn;
113
uint32_t rt_format;
114
115
rt_format = nv30_format(pipe->screen, ps->format)->hw;
116
if (util_format_get_blocksize(ps->format) == 4)
117
rt_format |= NV30_3D_RT_FORMAT_ZETA_Z24S8;
118
else
119
rt_format |= NV30_3D_RT_FORMAT_ZETA_Z16;
120
121
if (nv30_miptree(ps->texture)->swizzled) {
122
rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
123
rt_format |= util_logbase2(sf->width) << 16;
124
rt_format |= util_logbase2(sf->height) << 24;
125
} else {
126
rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
127
}
128
129
refn.bo = mt->base.bo;
130
refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
131
if (nouveau_pushbuf_space(push, 32, 1, 0) ||
132
nouveau_pushbuf_refn (push, &refn, 1))
133
return;
134
135
BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
136
PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0);
137
BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
138
PUSH_DATA (push, sf->width << 16);
139
PUSH_DATA (push, sf->height << 16);
140
PUSH_DATA (push, rt_format);
141
BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 2);
142
if (eng3d->oclass < NV40_3D_CLASS)
143
PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);
144
else
145
PUSH_DATA (push, sf->pitch);
146
PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);
147
BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
148
PUSH_DATA (push, (w << 16) | x);
149
PUSH_DATA (push, (h << 16) | y);
150
151
BEGIN_NV04(push, NV30_3D(CLEAR_COLOR_VALUE), 2);
152
PUSH_DATA (push, pack_rgba(ps->format, color->f));
153
PUSH_DATA (push, NV30_3D_CLEAR_BUFFERS_COLOR_R |
154
NV30_3D_CLEAR_BUFFERS_COLOR_G |
155
NV30_3D_CLEAR_BUFFERS_COLOR_B |
156
NV30_3D_CLEAR_BUFFERS_COLOR_A);
157
158
nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
159
}
160
161
static void
162
nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps,
163
unsigned buffers, double depth, unsigned stencil,
164
unsigned x, unsigned y, unsigned w, unsigned h,
165
bool render_condition_enabled)
166
{
167
struct nv30_context *nv30 = nv30_context(pipe);
168
struct nv30_surface *sf = nv30_surface(ps);
169
struct nv30_miptree *mt = nv30_miptree(ps->texture);
170
struct nouveau_pushbuf *push = nv30->base.pushbuf;
171
struct nouveau_object *eng3d = nv30->screen->eng3d;
172
struct nouveau_pushbuf_refn refn;
173
uint32_t rt_format, mode = 0;
174
175
rt_format = nv30_format(pipe->screen, ps->format)->hw;
176
if (util_format_get_blocksize(ps->format) == 4)
177
rt_format |= NV30_3D_RT_FORMAT_COLOR_A8R8G8B8;
178
else
179
rt_format |= NV30_3D_RT_FORMAT_COLOR_R5G6B5;
180
181
if (nv30_miptree(ps->texture)->swizzled) {
182
rt_format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
183
rt_format |= util_logbase2(sf->width) << 16;
184
rt_format |= util_logbase2(sf->height) << 24;
185
} else {
186
rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
187
}
188
189
if (buffers & PIPE_CLEAR_DEPTH)
190
mode |= NV30_3D_CLEAR_BUFFERS_DEPTH;
191
if (buffers & PIPE_CLEAR_STENCIL)
192
mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;
193
194
refn.bo = mt->base.bo;
195
refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
196
if (nouveau_pushbuf_space(push, 32, 1, 0) ||
197
nouveau_pushbuf_refn (push, &refn, 1))
198
return;
199
200
BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
201
PUSH_DATA (push, 0);
202
BEGIN_NV04(push, NV30_3D(RT_HORIZ), 3);
203
PUSH_DATA (push, sf->width << 16);
204
PUSH_DATA (push, sf->height << 16);
205
PUSH_DATA (push, rt_format);
206
if (eng3d->oclass < NV40_3D_CLASS) {
207
BEGIN_NV04(push, NV30_3D(COLOR0_PITCH), 1);
208
PUSH_DATA (push, (sf->pitch << 16) | sf->pitch);
209
} else {
210
BEGIN_NV04(push, NV40_3D(ZETA_PITCH), 1);
211
PUSH_DATA (push, sf->pitch);
212
}
213
BEGIN_NV04(push, NV30_3D(ZETA_OFFSET), 1);
214
PUSH_RELOC(push, mt->base.bo, sf->offset, NOUVEAU_BO_LOW, 0, 0);
215
BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
216
PUSH_DATA (push, (w << 16) | x);
217
PUSH_DATA (push, (h << 16) | y);
218
219
BEGIN_NV04(push, NV30_3D(CLEAR_DEPTH_VALUE), 1);
220
PUSH_DATA (push, pack_zeta(ps->format, depth, stencil));
221
BEGIN_NV04(push, NV30_3D(CLEAR_BUFFERS), 1);
222
PUSH_DATA (push, mode);
223
224
nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
225
}
226
227
void
228
nv30_clear_init(struct pipe_context *pipe)
229
{
230
pipe->clear = nv30_clear;
231
pipe->clear_render_target = nv30_clear_render_target;
232
pipe->clear_depth_stencil = nv30_clear_depth_stencil;
233
}
234
235