Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/i915/i915_clear.c
4570 views
1
/**************************************************************************
2
*
3
* Copyright 2007 VMware, Inc.
4
* All Rights Reserved.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the
8
* "Software"), to deal in the Software without restriction, including
9
* without limitation the rights to use, copy, modify, merge, publish,
10
* distribute, sub license, and/or sell copies of the Software, and to
11
* permit persons to whom the Software is furnished to do so, subject to
12
* the following conditions:
13
*
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
16
* of the Software.
17
*
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
*
26
**************************************************************************/
27
28
/* Authors:
29
* Brian Paul
30
*/
31
32
#include "util/format/u_format.h"
33
#include "util/u_pack_color.h"
34
#include "i915_batch.h"
35
#include "i915_context.h"
36
#include "i915_reg.h"
37
#include "i915_resource.h"
38
#include "i915_screen.h"
39
#include "i915_state.h"
40
41
void
42
i915_clear_emit(struct pipe_context *pipe, unsigned buffers,
43
const union pipe_color_union *color, double depth,
44
unsigned stencil, unsigned destx, unsigned desty,
45
unsigned width, unsigned height)
46
{
47
struct i915_context *i915 = i915_context(pipe);
48
uint32_t clear_params, clear_color, clear_depth, clear_stencil,
49
clear_color8888, packed_z_stencil;
50
union util_color u_color;
51
float f_depth = depth;
52
struct i915_texture *cbuf_tex, *depth_tex;
53
int depth_clear_bbp, color_clear_bbp;
54
55
cbuf_tex = depth_tex = NULL;
56
clear_params = 0;
57
depth_clear_bbp = color_clear_bbp = 0;
58
59
if (buffers & PIPE_CLEAR_COLOR) {
60
struct pipe_surface *cbuf = i915->framebuffer.cbufs[0];
61
62
clear_params |= CLEARPARAM_WRITE_COLOR;
63
cbuf_tex = i915_texture(cbuf->texture);
64
65
util_pack_color(color->f, cbuf->format, &u_color);
66
if (util_format_get_blocksize(cbuf_tex->b.format) == 4) {
67
clear_color = u_color.ui[0];
68
color_clear_bbp = 32;
69
} else {
70
clear_color = (u_color.ui[0] & 0xffff) | (u_color.ui[0] << 16);
71
color_clear_bbp = 16;
72
}
73
74
/* correctly swizzle clear value */
75
if (i915->current.fixup_swizzle)
76
util_pack_color(color->f, cbuf->format, &u_color);
77
else
78
util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color);
79
clear_color8888 = u_color.ui[0];
80
} else
81
clear_color = clear_color8888 = 0;
82
83
clear_depth = clear_stencil = 0;
84
if (buffers & PIPE_CLEAR_DEPTH) {
85
struct pipe_surface *zbuf = i915->framebuffer.zsbuf;
86
87
clear_params |= CLEARPARAM_WRITE_DEPTH;
88
depth_tex = i915_texture(zbuf->texture);
89
packed_z_stencil =
90
util_pack_z_stencil(depth_tex->b.format, depth, stencil);
91
92
if (util_format_get_blocksize(depth_tex->b.format) == 4) {
93
/* Avoid read-modify-write if there's no stencil. */
94
if (buffers & PIPE_CLEAR_STENCIL ||
95
depth_tex->b.format != PIPE_FORMAT_Z24_UNORM_S8_UINT) {
96
clear_params |= CLEARPARAM_WRITE_STENCIL;
97
clear_stencil = packed_z_stencil >> 24;
98
}
99
100
clear_depth = packed_z_stencil & 0xffffff;
101
depth_clear_bbp = 32;
102
} else {
103
clear_depth = (packed_z_stencil & 0xffff) | (packed_z_stencil << 16);
104
depth_clear_bbp = 16;
105
}
106
} else if (buffers & PIPE_CLEAR_STENCIL) {
107
struct pipe_surface *zbuf = i915->framebuffer.zsbuf;
108
109
clear_params |= CLEARPARAM_WRITE_STENCIL;
110
depth_tex = i915_texture(zbuf->texture);
111
assert(depth_tex->b.format == PIPE_FORMAT_Z24_UNORM_S8_UINT);
112
113
packed_z_stencil =
114
util_pack_z_stencil(depth_tex->b.format, depth, stencil);
115
depth_clear_bbp = 32;
116
clear_stencil = packed_z_stencil >> 24;
117
}
118
119
/* hw can't fastclear both depth and color if their bbp mismatch. */
120
if (color_clear_bbp && depth_clear_bbp &&
121
color_clear_bbp != depth_clear_bbp) {
122
if (i915->hardware_dirty)
123
i915_emit_hardware_state(i915);
124
125
if (!BEGIN_BATCH(1 + 2 * (7 + 7))) {
126
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC);
127
128
i915_emit_hardware_state(i915);
129
i915->vbo_flushed = 1;
130
131
assert(BEGIN_BATCH(1 + 2 * (7 + 7)));
132
}
133
134
OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
135
136
OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS);
137
OUT_BATCH(CLEARPARAM_WRITE_COLOR | CLEARPARAM_CLEAR_RECT);
138
/* Used for zone init prim */
139
OUT_BATCH(clear_color);
140
OUT_BATCH(clear_depth);
141
/* Used for clear rect prim */
142
OUT_BATCH(clear_color8888);
143
OUT_BATCH_F(f_depth);
144
OUT_BATCH(clear_stencil);
145
146
OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5);
147
OUT_BATCH_F(destx + width);
148
OUT_BATCH_F(desty + height);
149
OUT_BATCH_F(destx);
150
OUT_BATCH_F(desty + height);
151
OUT_BATCH_F(destx);
152
OUT_BATCH_F(desty);
153
154
OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS);
155
OUT_BATCH((clear_params & ~CLEARPARAM_WRITE_COLOR) |
156
CLEARPARAM_CLEAR_RECT);
157
/* Used for zone init prim */
158
OUT_BATCH(clear_color);
159
OUT_BATCH(clear_depth);
160
/* Used for clear rect prim */
161
OUT_BATCH(clear_color8888);
162
OUT_BATCH_F(f_depth);
163
OUT_BATCH(clear_stencil);
164
165
OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5);
166
OUT_BATCH_F(destx + width);
167
OUT_BATCH_F(desty + height);
168
OUT_BATCH_F(destx);
169
OUT_BATCH_F(desty + height);
170
OUT_BATCH_F(destx);
171
OUT_BATCH_F(desty);
172
} else {
173
if (i915->hardware_dirty)
174
i915_emit_hardware_state(i915);
175
176
if (!BEGIN_BATCH(1 + 7 + 7)) {
177
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC);
178
179
i915_emit_hardware_state(i915);
180
i915->vbo_flushed = 1;
181
182
assert(BEGIN_BATCH(1 + 7 + 7));
183
}
184
185
OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
186
187
OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS);
188
OUT_BATCH(clear_params | CLEARPARAM_CLEAR_RECT);
189
/* Used for zone init prim */
190
OUT_BATCH(clear_color);
191
OUT_BATCH(clear_depth);
192
/* Used for clear rect prim */
193
OUT_BATCH(clear_color8888);
194
OUT_BATCH_F(f_depth);
195
OUT_BATCH(clear_stencil);
196
197
OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5);
198
OUT_BATCH_F(destx + width);
199
OUT_BATCH_F(desty + height);
200
OUT_BATCH_F(destx);
201
OUT_BATCH_F(desty + height);
202
OUT_BATCH_F(destx);
203
OUT_BATCH_F(desty);
204
}
205
206
/* Flush after clear, its expected to be a costly operation.
207
* This is not required, just a heuristic, but without the flush we'd need to
208
* clobber the SCISSOR_ENABLE dynamic state. */
209
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC);
210
211
i915->last_fired_vertices = i915->fired_vertices;
212
i915->fired_vertices = 0;
213
}
214
215
/**
216
* Clear the given buffers to the specified values.
217
* No masking, no scissor (clear entire buffer).
218
*/
219
void
220
i915_clear_blitter(struct pipe_context *pipe, unsigned buffers,
221
const struct pipe_scissor_state *scissor_state,
222
const union pipe_color_union *color, double depth,
223
unsigned stencil)
224
{
225
struct pipe_framebuffer_state *framebuffer =
226
&i915_context(pipe)->framebuffer;
227
unsigned i;
228
229
for (i = 0; i < framebuffer->nr_cbufs; i++) {
230
if (buffers & (PIPE_CLEAR_COLOR0 << i)) {
231
struct pipe_surface *ps = framebuffer->cbufs[i];
232
233
if (ps) {
234
pipe->clear_render_target(pipe, ps, color, 0, 0, ps->width,
235
ps->height, true);
236
}
237
}
238
}
239
240
if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
241
struct pipe_surface *ps = framebuffer->zsbuf;
242
pipe->clear_depth_stencil(pipe, ps, buffers & PIPE_CLEAR_DEPTHSTENCIL,
243
depth, stencil, 0, 0, ps->width, ps->height,
244
true);
245
}
246
}
247
248
void
249
i915_clear_render(struct pipe_context *pipe, unsigned buffers,
250
const struct pipe_scissor_state *scissor_state,
251
const union pipe_color_union *color, double depth,
252
unsigned stencil)
253
{
254
struct i915_context *i915 = i915_context(pipe);
255
256
if (i915->dirty)
257
i915_update_derived(i915);
258
259
i915_clear_emit(pipe, buffers, color, depth, stencil, 0, 0,
260
i915->framebuffer.width, i915->framebuffer.height);
261
}
262
263