Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/freedreno/a6xx/fd6_vsc.c
4574 views
1
/*
2
* Copyright © 2020 Google, 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 (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
* SOFTWARE.
22
*/
23
24
#include "pipe/p_state.h"
25
#include "util/u_prim.h"
26
27
#include "freedreno_batch.h"
28
#include "freedreno_gmem.h"
29
30
#include "fd6_vsc.h"
31
32
/*
33
* Helper util to update expected vsc draw and primitive stream sizes, see
34
* https://github.com/freedreno/freedreno/wiki/Visibility-Stream-Format
35
*/
36
37
enum {
38
byte = 8,
39
dword = 4 * byte,
40
} bits_per;
41
42
/**
43
* Determine # of bits required to store a given number, see
44
* https://github.com/freedreno/freedreno/wiki/Visibility-Stream-Format#numbers
45
*/
46
static unsigned
47
number_size_bits(unsigned nr)
48
{
49
unsigned n = util_last_bit(nr);
50
assert(n); /* encoding 0 is not possible */
51
return n + (n - 1);
52
}
53
54
/**
55
* Determine # of bits requred to store a given bitfield, see
56
* https://github.com/freedreno/freedreno/wiki/Visibility-Stream-Format#bitfields
57
*/
58
static unsigned
59
bitfield_size_bits(unsigned n)
60
{
61
return n + 1; /* worst case is always 1 + nr of bits */
62
}
63
64
static unsigned
65
prim_count(const struct pipe_draw_info *info,
66
const struct pipe_draw_start_count_bias *draw)
67
{
68
/* PIPE_PRIM_MAX used internally for RECTLIST blits on 3d pipe: */
69
unsigned vtx_per_prim =
70
(info->mode == PIPE_PRIM_MAX) ? 2 : u_vertices_per_prim(info->mode);
71
return MAX2(1, (draw->count * info->instance_count) / vtx_per_prim);
72
}
73
74
/**
75
* The primitive stream uses a run-length encoding, where each packet contains a
76
* bitfield of bins covered and then the number of primitives which have the
77
* same bitfield. Each packet consists of the following, in order:
78
*
79
* - The (compressed) bitfield of bins covered
80
* - The number of primitives with this bitset
81
* - Checksum
82
*
83
* The worst case would be that each primitive has a different bitmask. In
84
* practice, assuming ever other primitive has a different bitmask still gets us
85
* conservatively large primitive stream sizes. (Ie. 10x what is needed, vs.
86
* 20x)
87
*
88
* https://github.com/freedreno/freedreno/wiki/Visibility-Stream-Format#primitive-streams
89
*/
90
static unsigned
91
primitive_stream_size_bits(const struct pipe_draw_info *info,
92
const struct pipe_draw_start_count_bias *draw,
93
unsigned num_bins)
94
{
95
unsigned num_prims = prim_count(info, draw);
96
unsigned nbits =
97
(bitfield_size_bits(num_bins) /* bitfield of bins covered */
98
+ number_size_bits(1) /* number of primitives with this bitset */
99
+ 1 /* checksum */
100
) *
101
DIV_ROUND_UP(num_prims, 2);
102
return align(nbits, dword);
103
}
104
105
/**
106
* Each draw stream packet contains the following:
107
*
108
* - Bin bitfield
109
* - Last instance bit
110
* - If bitfield is empty, the number of draws it is empty for, otherwise
111
* the size of the corresponding primitive stream in DWORD's.
112
* - Checksum
113
*
114
* https://github.com/freedreno/freedreno/wiki/Visibility-Stream-Format#draw-streams
115
*/
116
static unsigned
117
draw_stream_size_bits(const struct pipe_draw_info *info, unsigned num_bins,
118
unsigned prim_strm_bits)
119
{
120
unsigned ndwords = prim_strm_bits / dword;
121
return (bitfield_size_bits(num_bins) /* bitfield of bins */
122
+ 1 /* last-instance-bit */
123
+ number_size_bits(ndwords) /* size of corresponding prim strm */
124
+ 1 /* checksum */
125
) *
126
MAX2(1, info->instance_count);
127
}
128
129
void
130
fd6_vsc_update_sizes(struct fd_batch *batch, const struct pipe_draw_info *info,
131
const struct pipe_draw_start_count_bias *draw)
132
{
133
if (!batch->num_bins_per_pipe) {
134
batch->num_bins_per_pipe = fd_gmem_estimate_bins_per_pipe(batch);
135
136
/* This is a convenient spot to add the size of the final draw-
137
* stream packet:
138
*
139
* If there are N bins, the final packet, after all the draws are
140
* done, consists of a 1 followed by N + 17 0's, plus a final 1.
141
* This uses the otherwise-unused pattern of a non-empty bitfield
142
* (initial 1) that is nontheless empty (has all 0's)
143
*/
144
unsigned final_pkt_sz = 1 + batch->num_bins_per_pipe + 17 + 1;
145
batch->prim_strm_bits = align(final_pkt_sz, dword);
146
}
147
148
unsigned prim_strm_bits =
149
primitive_stream_size_bits(info, draw, batch->num_bins_per_pipe);
150
unsigned draw_strm_bits =
151
draw_stream_size_bits(info, batch->num_bins_per_pipe, prim_strm_bits);
152
153
#if 0
154
mesa_logd("vsc: prim_strm_bits=%d, draw_strm_bits=%d, nb=%u, ic=%u, c=%u, pc=%u (%s)",
155
prim_strm_bits, draw_strm_bits, batch->num_bins_per_pipe,
156
info->instance_count, info->count,
157
(info->count * info->instance_count) /
158
u_vertices_per_prim(info->mode),
159
u_prim_name(info->mode));
160
#endif
161
162
batch->prim_strm_bits += prim_strm_bits;
163
batch->draw_strm_bits += draw_strm_bits;
164
}
165
166