Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/virtio/vulkan/vn_cs.h
4560 views
1
/*
2
* Copyright 2019 Google LLC
3
* SPDX-License-Identifier: MIT
4
*/
5
6
#ifndef VN_CS_H
7
#define VN_CS_H
8
9
#include "vn_common.h"
10
11
#define VN_CS_ENCODER_INITIALIZER_LOCAL(storage, size) \
12
(struct vn_cs_encoder) \
13
{ \
14
.buffers = \
15
&(struct vn_cs_encoder_buffer){ \
16
.base = storage, \
17
}, \
18
.buffer_count = 1, .buffer_max = 1, .current_buffer_size = size, \
19
.cur = storage, .end = (const void *)(storage) + (size), \
20
}
21
22
#define VN_CS_DECODER_INITIALIZER(storage, size) \
23
(struct vn_cs_decoder) \
24
{ \
25
.cur = storage, .end = (const void *)(storage) + (size), \
26
}
27
28
struct vn_cs_encoder_buffer {
29
struct vn_renderer_shmem *shmem;
30
size_t offset;
31
void *base;
32
size_t committed_size;
33
};
34
35
struct vn_cs_encoder {
36
struct vn_instance *instance; /* TODO shmem cache */
37
size_t min_buffer_size;
38
bool indirect;
39
40
bool fatal_error;
41
42
struct vn_cs_encoder_buffer *buffers;
43
uint32_t buffer_count;
44
uint32_t buffer_max;
45
size_t total_committed_size;
46
47
/* the current buffer is buffers[buffer_count - 1].shmem */
48
size_t current_buffer_size;
49
uint32_t current_buffer_roundtrip;
50
51
/* cur is the write pointer. When cur passes end, the slow path is
52
* triggered.
53
*/
54
void *cur;
55
const void *end;
56
};
57
58
struct vn_cs_decoder {
59
const void *cur;
60
const void *end;
61
};
62
63
void
64
vn_cs_encoder_init_indirect(struct vn_cs_encoder *enc,
65
struct vn_instance *instance,
66
size_t min_size);
67
68
void
69
vn_cs_encoder_fini(struct vn_cs_encoder *enc);
70
71
void
72
vn_cs_encoder_reset(struct vn_cs_encoder *enc);
73
74
static inline void
75
vn_cs_encoder_set_fatal(const struct vn_cs_encoder *enc)
76
{
77
/* This is fatal and should be treated as VK_ERROR_DEVICE_LOST or even
78
* abort(). Note that vn_cs_encoder_reset does not clear this.
79
*/
80
((struct vn_cs_encoder *)enc)->fatal_error = true;
81
}
82
83
static inline bool
84
vn_cs_encoder_get_fatal(const struct vn_cs_encoder *enc)
85
{
86
return enc->fatal_error;
87
}
88
89
static inline bool
90
vn_cs_encoder_is_empty(const struct vn_cs_encoder *enc)
91
{
92
return !enc->buffer_count || enc->cur == enc->buffers[0].base;
93
}
94
95
static inline size_t
96
vn_cs_encoder_get_len(const struct vn_cs_encoder *enc)
97
{
98
if (unlikely(!enc->buffer_count))
99
return 0;
100
101
size_t len = enc->total_committed_size;
102
const struct vn_cs_encoder_buffer *cur_buf =
103
&enc->buffers[enc->buffer_count - 1];
104
if (!cur_buf->committed_size)
105
len += enc->cur - cur_buf->base;
106
return len;
107
}
108
109
bool
110
vn_cs_encoder_reserve_internal(struct vn_cs_encoder *enc, size_t size);
111
112
/**
113
* Reserve space for commands.
114
*/
115
static inline bool
116
vn_cs_encoder_reserve(struct vn_cs_encoder *enc, size_t size)
117
{
118
if (unlikely(size > enc->end - enc->cur)) {
119
if (!vn_cs_encoder_reserve_internal(enc, size)) {
120
vn_cs_encoder_set_fatal(enc);
121
return false;
122
}
123
assert(size <= enc->end - enc->cur);
124
}
125
126
return true;
127
}
128
129
static inline void
130
vn_cs_encoder_write(struct vn_cs_encoder *enc,
131
size_t size,
132
const void *val,
133
size_t val_size)
134
{
135
assert(val_size <= size);
136
assert(size <= enc->end - enc->cur);
137
138
/* we should not rely on the compiler to optimize away memcpy... */
139
memcpy(enc->cur, val, val_size);
140
enc->cur += size;
141
}
142
143
void
144
vn_cs_encoder_commit(struct vn_cs_encoder *enc);
145
146
static inline void
147
vn_cs_decoder_init(struct vn_cs_decoder *dec, const void *data, size_t size)
148
{
149
*dec = VN_CS_DECODER_INITIALIZER(data, size);
150
}
151
152
static inline void
153
vn_cs_decoder_set_fatal(const struct vn_cs_decoder *dec)
154
{
155
abort();
156
}
157
158
static inline bool
159
vn_cs_decoder_peek_internal(const struct vn_cs_decoder *dec,
160
size_t size,
161
void *val,
162
size_t val_size)
163
{
164
assert(val_size <= size);
165
166
if (unlikely(size > dec->end - dec->cur)) {
167
vn_cs_decoder_set_fatal(dec);
168
memset(val, 0, val_size);
169
return false;
170
}
171
172
/* we should not rely on the compiler to optimize away memcpy... */
173
memcpy(val, dec->cur, val_size);
174
return true;
175
}
176
177
static inline void
178
vn_cs_decoder_read(struct vn_cs_decoder *dec,
179
size_t size,
180
void *val,
181
size_t val_size)
182
{
183
if (vn_cs_decoder_peek_internal(dec, size, val, val_size))
184
dec->cur += size;
185
}
186
187
static inline void
188
vn_cs_decoder_peek(const struct vn_cs_decoder *dec,
189
size_t size,
190
void *val,
191
size_t val_size)
192
{
193
vn_cs_decoder_peek_internal(dec, size, val, val_size);
194
}
195
196
static inline vn_object_id
197
vn_cs_handle_load_id(const void **handle, VkObjectType type)
198
{
199
return *handle ? vn_object_get_id(*handle, type) : 0;
200
}
201
202
static inline void
203
vn_cs_handle_store_id(void **handle, vn_object_id id, VkObjectType type)
204
{
205
vn_object_set_id(*handle, id, type);
206
}
207
208
#endif /* VN_CS_H */
209
210