Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/r600/r600_uvd.c
4570 views
1
/**************************************************************************
2
*
3
* Copyright 2011 Advanced Micro Devices, 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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
/*
29
* Authors:
30
* Christian König <[email protected]>
31
*
32
*/
33
34
#include <sys/types.h>
35
#include <assert.h>
36
#include <errno.h>
37
#include <unistd.h>
38
39
#include "pipe/p_video_codec.h"
40
41
#include "util/u_memory.h"
42
#include "util/u_video.h"
43
44
#include "vl/vl_defines.h"
45
#include "vl/vl_mpeg12_decoder.h"
46
47
#include "r600_pipe.h"
48
#include "radeon_video.h"
49
#include "radeon_uvd.h"
50
#include "radeon_vce.h"
51
#include "r600d.h"
52
53
#define R600_UVD_ENABLE_TILING 0
54
55
/**
56
* creates an video buffer with an UVD compatible memory layout
57
*/
58
struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
59
const struct pipe_video_buffer *tmpl)
60
{
61
struct r600_context *ctx = (struct r600_context *)pipe;
62
struct r600_texture *resources[VL_NUM_COMPONENTS] = {};
63
struct radeon_surf* surfaces[VL_NUM_COMPONENTS] = {};
64
struct pb_buffer **pbs[VL_NUM_COMPONENTS] = {};
65
enum pipe_format resource_formats[3];
66
struct pipe_video_buffer template;
67
struct pipe_resource templ;
68
unsigned i, array_size;
69
enum pipe_video_chroma_format chroma_format =
70
pipe_format_to_chroma_format(tmpl->buffer_format);
71
72
assert(pipe);
73
74
/* first create the needed resources as "normal" textures */
75
vl_get_video_buffer_formats(pipe->screen, tmpl->buffer_format, resource_formats);
76
77
array_size = tmpl->interlaced ? 2 : 1;
78
template = *tmpl;
79
template.width = align(tmpl->width, VL_MACROBLOCK_WIDTH);
80
template.height = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT);
81
82
vl_video_buffer_template(&templ, &template, resource_formats[0], 1, array_size,
83
PIPE_USAGE_DEFAULT, 0, chroma_format);
84
if (ctx->b.chip_class < EVERGREEN || tmpl->interlaced || !R600_UVD_ENABLE_TILING)
85
templ.bind = PIPE_BIND_LINEAR;
86
resources[0] = (struct r600_texture *)
87
pipe->screen->resource_create(pipe->screen, &templ);
88
if (!resources[0])
89
goto error;
90
91
if (resource_formats[1] != PIPE_FORMAT_NONE) {
92
vl_video_buffer_template(&templ, &template, resource_formats[1], 1, array_size,
93
PIPE_USAGE_DEFAULT, 1, chroma_format);
94
if (ctx->b.chip_class < EVERGREEN || tmpl->interlaced || !R600_UVD_ENABLE_TILING)
95
templ.bind = PIPE_BIND_LINEAR;
96
resources[1] = (struct r600_texture *)
97
pipe->screen->resource_create(pipe->screen, &templ);
98
if (!resources[1])
99
goto error;
100
}
101
102
if (resource_formats[2] != PIPE_FORMAT_NONE) {
103
vl_video_buffer_template(&templ, &template, resource_formats[2], 1, array_size,
104
PIPE_USAGE_DEFAULT, 2, chroma_format);
105
if (ctx->b.chip_class < EVERGREEN || tmpl->interlaced || !R600_UVD_ENABLE_TILING)
106
templ.bind = PIPE_BIND_LINEAR;
107
resources[2] = (struct r600_texture *)
108
pipe->screen->resource_create(pipe->screen, &templ);
109
if (!resources[2])
110
goto error;
111
}
112
113
for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
114
if (!resources[i])
115
continue;
116
117
pbs[i] = &resources[i]->resource.buf;
118
surfaces[i] = &resources[i]->surface;
119
}
120
121
rvid_join_surfaces(&ctx->b, pbs, surfaces);
122
123
for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
124
if (!resources[i])
125
continue;
126
127
/* reset the address */
128
resources[i]->resource.gpu_address = ctx->b.ws->buffer_get_virtual_address(
129
resources[i]->resource.buf);
130
}
131
132
template.height *= array_size;
133
return vl_video_buffer_create_ex2(pipe, &template, (struct pipe_resource **)resources);
134
135
error:
136
for (i = 0; i < VL_NUM_COMPONENTS; ++i)
137
r600_texture_reference(&resources[i], NULL);
138
139
return NULL;
140
}
141
142
/* hw encode the number of memory banks */
143
static uint32_t eg_num_banks(uint32_t nbanks)
144
{
145
switch (nbanks) {
146
case 2:
147
return 0;
148
case 4:
149
return 1;
150
case 8:
151
default:
152
return 2;
153
case 16:
154
return 3;
155
}
156
}
157
158
/* set the decoding target buffer offsets */
159
static struct pb_buffer* r600_uvd_set_dtb(struct ruvd_msg *msg, struct vl_video_buffer *buf)
160
{
161
struct r600_screen *rscreen = (struct r600_screen*)buf->base.context->screen;
162
struct r600_texture *luma = (struct r600_texture *)buf->resources[0];
163
struct r600_texture *chroma = (struct r600_texture *)buf->resources[1];
164
165
msg->body.decode.dt_field_mode = buf->base.interlaced;
166
msg->body.decode.dt_surf_tile_config |= RUVD_NUM_BANKS(eg_num_banks(rscreen->b.info.r600_num_banks));
167
168
ruvd_set_dt_surfaces(msg, &luma->surface, &chroma->surface);
169
170
return luma->resource.buf;
171
}
172
173
/* get the radeon resources for VCE */
174
static void r600_vce_get_buffer(struct pipe_resource *resource,
175
struct pb_buffer **handle,
176
struct radeon_surf **surface)
177
{
178
struct r600_texture *res = (struct r600_texture *)resource;
179
180
if (handle)
181
*handle = res->resource.buf;
182
183
if (surface)
184
*surface = &res->surface;
185
}
186
187
/* create decoder */
188
struct pipe_video_codec *r600_uvd_create_decoder(struct pipe_context *context,
189
const struct pipe_video_codec *templat)
190
{
191
struct r600_context *ctx = (struct r600_context *)context;
192
193
if (templat->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE)
194
return rvce_create_encoder(context, templat, ctx->b.ws, r600_vce_get_buffer);
195
196
return ruvd_create_decoder(context, templat, r600_uvd_set_dtb);
197
}
198
199