Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/nouveau/nouveau_vp3_video.h
4570 views
1
/*
2
* Copyright 2011-2013 Maarten Lankhorst
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
23
#include <nouveau.h>
24
25
#include "pipe/p_defines.h"
26
#include "vl/vl_video_buffer.h"
27
#include "util/u_video.h"
28
29
struct nouveau_vp3_video_buffer {
30
struct pipe_video_buffer base;
31
unsigned num_planes, valid_ref;
32
struct pipe_resource *resources[VL_NUM_COMPONENTS];
33
struct pipe_sampler_view *sampler_view_planes[VL_NUM_COMPONENTS];
34
struct pipe_sampler_view *sampler_view_components[VL_NUM_COMPONENTS];
35
struct pipe_surface *surfaces[VL_NUM_COMPONENTS * 2];
36
};
37
38
#define SLICE_SIZE 0x200
39
#define VP_OFFSET 0x200
40
#define COMM_OFFSET 0x500
41
42
#define NOUVEAU_VP3_BSP_RESERVED_SIZE 0x700
43
44
#define NOUVEAU_VP3_DEBUG_FENCE 0
45
46
#if NOUVEAU_VP3_DEBUG_FENCE
47
# define NOUVEAU_VP3_VIDEO_QDEPTH 1
48
#else
49
# define NOUVEAU_VP3_VIDEO_QDEPTH 2
50
#endif
51
52
#define SUBC_BSP(m) dec->bsp_idx, (m)
53
#define SUBC_VP(m) dec->vp_idx, (m)
54
#define SUBC_PPP(m) dec->ppp_idx, (m)
55
56
union pipe_desc {
57
struct pipe_picture_desc *base;
58
struct pipe_mpeg12_picture_desc *mpeg12;
59
struct pipe_mpeg4_picture_desc *mpeg4;
60
struct pipe_vc1_picture_desc *vc1;
61
struct pipe_h264_picture_desc *h264;
62
};
63
64
struct nouveau_vp3_decoder {
65
struct pipe_video_codec base;
66
struct nouveau_client *client;
67
struct nouveau_object *channel[3], *bsp, *vp, *ppp;
68
struct nouveau_pushbuf *pushbuf[3];
69
70
#if NOUVEAU_VP3_DEBUG_FENCE
71
/* dump fence and comm, as needed.. */
72
unsigned *fence_map;
73
struct comm *comm;
74
75
struct nouveau_bo *fence_bo;
76
#endif
77
78
struct nouveau_bo *fw_bo, *bitplane_bo;
79
80
// array size max_references + 2, contains unpostprocessed images
81
// added at the end of ref_bo is a tmp array
82
// tmp is an array for h264, with each member being used for a ref frame or current
83
// target.. size = (((mb(w)*((mb(h)+1)&~1))+3)>>2)<<8 * (max_references+1)
84
// for other codecs, it simply seems that size = w*h is enough
85
// unsure what it's supposed to contain..
86
struct nouveau_bo *ref_bo;
87
88
struct nouveau_bo *inter_bo[2];
89
90
struct nouveau_bo *bsp_bo[NOUVEAU_VP3_VIDEO_QDEPTH];
91
92
// bo's used by each cycle:
93
94
// bsp_bo: contains raw bitstream data and parameters for BSP and VP.
95
// inter_bo: contains data shared between BSP and VP
96
// ref_bo: reference image data, used by PPP and VP
97
// bitplane_bo: contain bitplane data (similar to ref_bo), used by BSP only
98
// fw_bo: used by VP only.
99
100
// Needed amount of copies in optimal case:
101
// 2 copies of inter_bo, VP would process the last inter_bo, while BSP is
102
// writing out a new set.
103
// NOUVEAU_VP3_VIDEO_QDEPTH copies of bsp_bo. We don't want to block the
104
// pipeline ever, and give shaders a chance to run as well.
105
106
struct {
107
struct nouveau_vp3_video_buffer *vidbuf;
108
unsigned last_used;
109
unsigned field_pic_flag : 1;
110
unsigned decoded_top : 1;
111
unsigned decoded_bottom : 1;
112
unsigned decoded_first : 1;
113
} refs[17];
114
unsigned fence_seq, fw_sizes, last_frame_num, tmp_stride, ref_stride;
115
116
unsigned bsp_idx, vp_idx, ppp_idx;
117
118
/* End of the bsp bo where new data should be appended between one begin/end
119
* frame.
120
*/
121
char *bsp_ptr;
122
};
123
124
struct comm {
125
uint32_t bsp_cur_index; // 000
126
uint32_t byte_ofs; // 004
127
uint32_t status[0x10]; // 008
128
uint32_t pos[0x10]; // 048
129
uint8_t pad[0x100 - 0x88]; // 0a0 bool comm_encrypted
130
131
uint32_t pvp_cur_index; // 100
132
uint32_t acked_byte_ofs; // 104
133
uint32_t status_vp[0x10]; // 108
134
uint16_t mb_y[0x10]; //148
135
uint32_t pvp_stage; // 168 0xeeXX
136
uint16_t parse_endpos_index; // 16c
137
uint16_t irq_index; // 16e
138
uint8_t irq_470[0x10]; // 170
139
uint32_t irq_pos[0x10]; // 180
140
uint32_t parse_endpos[0x10]; // 1c0
141
};
142
143
static inline uint32_t nouveau_vp3_video_align(uint32_t h)
144
{
145
return ((h+0x3f)&~0x3f);
146
};
147
148
static inline uint32_t mb(uint32_t coord)
149
{
150
return (coord + 0xf)>>4;
151
}
152
153
static inline uint32_t mb_half(uint32_t coord)
154
{
155
return (coord + 0x1f)>>5;
156
}
157
158
static inline uint64_t
159
nouveau_vp3_video_addr(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *target)
160
{
161
uint64_t ret;
162
if (target)
163
ret = dec->ref_stride * target->valid_ref;
164
else
165
ret = dec->ref_stride * (dec->base.max_references+1);
166
return dec->ref_bo->offset + ret;
167
}
168
169
static inline void
170
nouveau_vp3_ycbcr_offsets(struct nouveau_vp3_decoder *dec, uint32_t *y2,
171
uint32_t *cbcr, uint32_t *cbcr2)
172
{
173
uint32_t w = mb(dec->base.width), size;
174
*y2 = mb_half(dec->base.height)*w;
175
*cbcr = *y2 * 2;
176
*cbcr2 = *cbcr + w * (nouveau_vp3_video_align(dec->base.height)>>6);
177
178
/* The check here should never fail because it means a bug
179
* in the code rather than a bug in hardware..
180
*/
181
size = (2 * (*cbcr2 - *cbcr) + *cbcr) << 8;
182
if (size > dec->ref_stride) {
183
debug_printf("Overshot ref_stride (%u) with size %u and ofs (%u,%u,%u)\n",
184
dec->ref_stride, size, *y2<<8, *cbcr<<8, *cbcr2<<8);
185
*y2 = *cbcr = *cbcr2 = 0;
186
assert(size <= dec->ref_stride);
187
}
188
}
189
190
static inline void
191
nouveau_vp3_inter_sizes(struct nouveau_vp3_decoder *dec, uint32_t slice_count,
192
uint32_t *slice_size, uint32_t *bucket_size,
193
uint32_t *ring_size)
194
{
195
*slice_size = (SLICE_SIZE * slice_count)>>8;
196
if (u_reduce_video_profile(dec->base.profile) == PIPE_VIDEO_FORMAT_MPEG12)
197
*bucket_size = 0;
198
else
199
*bucket_size = mb(dec->base.width) * 3;
200
*ring_size = (dec->inter_bo[0]->size >> 8) - *bucket_size - *slice_size;
201
}
202
203
struct pipe_video_buffer *
204
nouveau_vp3_video_buffer_create(struct pipe_context *pipe,
205
const struct pipe_video_buffer *templat,
206
int flags);
207
208
void
209
nouveau_vp3_decoder_init_common(struct pipe_video_codec *decoder);
210
211
int
212
nouveau_vp3_load_firmware(struct nouveau_vp3_decoder *dec,
213
enum pipe_video_profile profile,
214
unsigned chipset);
215
216
void
217
nouveau_vp3_bsp_begin(struct nouveau_vp3_decoder *dec);
218
219
void
220
nouveau_vp3_bsp_next(struct nouveau_vp3_decoder *dec, unsigned num_buffers,
221
const void *const *data, const unsigned *num_bytes);
222
223
uint32_t
224
nouveau_vp3_bsp_end(struct nouveau_vp3_decoder *dec, union pipe_desc desc);
225
226
void
227
nouveau_vp3_vp_caps(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
228
struct nouveau_vp3_video_buffer *target, unsigned comm_seq,
229
unsigned *caps, unsigned *is_ref,
230
struct nouveau_vp3_video_buffer *refs[16]);
231
232
int
233
nouveau_vp3_screen_get_video_param(struct pipe_screen *pscreen,
234
enum pipe_video_profile profile,
235
enum pipe_video_entrypoint entrypoint,
236
enum pipe_video_cap param);
237
238
bool
239
nouveau_vp3_screen_video_supported(struct pipe_screen *screen,
240
enum pipe_format format,
241
enum pipe_video_profile profile,
242
enum pipe_video_entrypoint entrypoint);
243
244