2
* Copyright 2011-2013 Maarten Lankhorst
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:
11
* The above copyright notice and this permission notice shall be included in
12
* all copies or substantial portions of the Software.
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.
28
#include "nouveau_screen.h"
29
#include "nouveau_context.h"
30
#include "nouveau_vp3_video.h"
32
#include "util/u_video.h"
33
#include "util/u_format.h"
34
#include "util/u_sampler.h"
36
static struct pipe_sampler_view **
37
nouveau_vp3_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer)
39
struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
40
return buf->sampler_view_planes;
43
static struct pipe_sampler_view **
44
nouveau_vp3_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
46
struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
47
return buf->sampler_view_components;
50
static struct pipe_surface **
51
nouveau_vp3_video_buffer_surfaces(struct pipe_video_buffer *buffer)
53
struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
58
nouveau_vp3_video_buffer_destroy(struct pipe_video_buffer *buffer)
60
struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer;
65
for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
66
pipe_resource_reference(&buf->resources[i], NULL);
67
pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL);
68
pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL);
69
pipe_surface_reference(&buf->surfaces[i * 2], NULL);
70
pipe_surface_reference(&buf->surfaces[i * 2 + 1], NULL);
75
struct pipe_video_buffer *
76
nouveau_vp3_video_buffer_create(struct pipe_context *pipe,
77
const struct pipe_video_buffer *templat,
80
struct nouveau_vp3_video_buffer *buffer;
81
struct pipe_resource templ;
82
unsigned i, j, component;
83
struct pipe_sampler_view sv_templ;
84
struct pipe_surface surf_templ;
86
assert(templat->interlaced);
87
if (getenv("XVMC_VL") || templat->buffer_format != PIPE_FORMAT_NV12)
88
return vl_video_buffer_create(pipe, templat);
90
assert(templat->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
92
buffer = CALLOC_STRUCT(nouveau_vp3_video_buffer);
96
buffer->base.buffer_format = templat->buffer_format;
97
buffer->base.context = pipe;
98
buffer->base.destroy = nouveau_vp3_video_buffer_destroy;
99
buffer->base.chroma_format = templat->chroma_format;
100
buffer->base.width = templat->width;
101
buffer->base.height = templat->height;
102
buffer->base.get_sampler_view_planes = nouveau_vp3_video_buffer_sampler_view_planes;
103
buffer->base.get_sampler_view_components = nouveau_vp3_video_buffer_sampler_view_components;
104
buffer->base.get_surfaces = nouveau_vp3_video_buffer_surfaces;
105
buffer->base.interlaced = true;
107
memset(&templ, 0, sizeof(templ));
108
templ.target = PIPE_TEXTURE_2D_ARRAY;
110
templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
111
templ.format = PIPE_FORMAT_R8_UNORM;
112
templ.width0 = buffer->base.width;
113
templ.height0 = (buffer->base.height + 1)/2;
115
templ.array_size = 2;
117
buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ);
118
if (!buffer->resources[0])
121
templ.format = PIPE_FORMAT_R8G8_UNORM;
122
buffer->num_planes = 2;
123
templ.width0 = (templ.width0 + 1) / 2;
124
templ.height0 = (templ.height0 + 1) / 2;
125
for (i = 1; i < buffer->num_planes; ++i) {
126
buffer->resources[i] = pipe->screen->resource_create(pipe->screen, &templ);
127
if (!buffer->resources[i])
131
memset(&sv_templ, 0, sizeof(sv_templ));
132
for (component = 0, i = 0; i < buffer->num_planes; ++i ) {
133
struct pipe_resource *res = buffer->resources[i];
134
unsigned nr_components = util_format_get_nr_components(res->format);
136
u_sampler_view_default_template(&sv_templ, res, res->format);
137
buffer->sampler_view_planes[i] = pipe->create_sampler_view(pipe, res, &sv_templ);
138
if (!buffer->sampler_view_planes[i])
141
for (j = 0; j < nr_components; ++j, ++component) {
142
sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j;
143
sv_templ.swizzle_a = PIPE_SWIZZLE_ONE;
145
buffer->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ);
146
if (!buffer->sampler_view_components[component])
151
memset(&surf_templ, 0, sizeof(surf_templ));
152
for (j = 0; j < buffer->num_planes; ++j) {
153
surf_templ.format = buffer->resources[j]->format;
154
surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 0;
155
buffer->surfaces[j * 2] = pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
156
if (!buffer->surfaces[j * 2])
159
surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 1;
160
buffer->surfaces[j * 2 + 1] = pipe->create_surface(pipe, buffer->resources[j], &surf_templ);
161
if (!buffer->surfaces[j * 2 + 1])
165
return &buffer->base;
168
nouveau_vp3_video_buffer_destroy(&buffer->base);
173
nouveau_vp3_decoder_flush(struct pipe_video_codec *decoder)
178
nouveau_vp3_decoder_begin_frame(struct pipe_video_codec *decoder,
179
struct pipe_video_buffer *target,
180
struct pipe_picture_desc *picture)
185
nouveau_vp3_decoder_end_frame(struct pipe_video_codec *decoder,
186
struct pipe_video_buffer *target,
187
struct pipe_picture_desc *picture)
192
nouveau_vp3_decoder_destroy(struct pipe_video_codec *decoder)
194
struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder;
197
nouveau_bo_ref(NULL, &dec->ref_bo);
198
nouveau_bo_ref(NULL, &dec->bitplane_bo);
199
nouveau_bo_ref(NULL, &dec->inter_bo[0]);
200
nouveau_bo_ref(NULL, &dec->inter_bo[1]);
201
#if NOUVEAU_VP3_DEBUG_FENCE
202
nouveau_bo_ref(NULL, &dec->fence_bo);
204
nouveau_bo_ref(NULL, &dec->fw_bo);
206
for (i = 0; i < NOUVEAU_VP3_VIDEO_QDEPTH; ++i)
207
nouveau_bo_ref(NULL, &dec->bsp_bo[i]);
209
nouveau_object_del(&dec->bsp);
210
nouveau_object_del(&dec->vp);
211
nouveau_object_del(&dec->ppp);
213
if (dec->channel[0] != dec->channel[1]) {
214
for (i = 0; i < 3; ++i) {
215
nouveau_pushbuf_del(&dec->pushbuf[i]);
216
nouveau_object_del(&dec->channel[i]);
219
nouveau_pushbuf_del(dec->pushbuf);
220
nouveau_object_del(dec->channel);
227
nouveau_vp3_decoder_init_common(struct pipe_video_codec *dec)
229
dec->destroy = nouveau_vp3_decoder_destroy;
230
dec->flush = nouveau_vp3_decoder_flush;
231
dec->begin_frame = nouveau_vp3_decoder_begin_frame;
232
dec->end_frame = nouveau_vp3_decoder_end_frame;
235
static void vp3_getpath(enum pipe_video_profile profile, char *path)
237
switch (u_reduce_video_profile(profile)) {
238
case PIPE_VIDEO_FORMAT_MPEG12: {
239
sprintf(path, "/lib/firmware/nouveau/vuc-vp3-mpeg12-0");
242
case PIPE_VIDEO_FORMAT_VC1: {
243
sprintf(path, "/lib/firmware/nouveau/vuc-vp3-vc1-0");
246
case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
247
sprintf(path, "/lib/firmware/nouveau/vuc-vp3-h264-0");
254
static void vp4_getpath(enum pipe_video_profile profile, char *path)
256
switch (u_reduce_video_profile(profile)) {
257
case PIPE_VIDEO_FORMAT_MPEG12: {
258
sprintf(path, "/lib/firmware/nouveau/vuc-mpeg12-0");
261
case PIPE_VIDEO_FORMAT_MPEG4: {
262
sprintf(path, "/lib/firmware/nouveau/vuc-mpeg4-0");
265
case PIPE_VIDEO_FORMAT_VC1: {
266
sprintf(path, "/lib/firmware/nouveau/vuc-vc1-0");
269
case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
270
sprintf(path, "/lib/firmware/nouveau/vuc-h264-0");
278
nouveau_vp3_load_firmware(struct nouveau_vp3_decoder *dec,
279
enum pipe_video_profile profile,
285
uint32_t *end, endval;
287
if (chipset >= 0xa3 && chipset != 0xaa && chipset != 0xac)
288
vp4_getpath(profile, path);
290
vp3_getpath(profile, path);
292
if (nouveau_bo_map(dec->fw_bo, NOUVEAU_BO_WR, dec->client))
295
fd = open(path, O_RDONLY | O_CLOEXEC);
297
fprintf(stderr, "opening firmware file %s failed: %m\n", path);
300
r = read(fd, dec->fw_bo->map, 0x4000);
304
fprintf(stderr, "reading firmware file %s failed: %m\n", path);
309
fprintf(stderr, "firmware file %s too large!\n", path);
314
fprintf(stderr, "firmware file %s wrong size!\n", path);
318
end = dec->fw_bo->map + r - 4;
320
while (endval == *end)
323
r = (intptr_t)end - (intptr_t)dec->fw_bo->map + 4;
325
switch (u_reduce_video_profile(profile)) {
326
case PIPE_VIDEO_FORMAT_MPEG12: {
327
assert((r & 0xff) == 0xe0);
328
dec->fw_sizes = (0x2e0<<16) | (r - 0x2e0);
331
case PIPE_VIDEO_FORMAT_MPEG4: {
332
assert((r & 0xff) == 0xe0);
333
dec->fw_sizes = (0x2e0<<16) | (r - 0x2e0);
336
case PIPE_VIDEO_FORMAT_VC1: {
337
assert((r & 0xff) == 0xac);
338
dec->fw_sizes = (0x3ac<<16) | (r - 0x3ac);
341
case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
342
assert((r & 0xff) == 0x70);
343
dec->fw_sizes = (0x370<<16) | (r - 0x370);
349
munmap(dec->fw_bo->map, dec->fw_bo->size);
350
dec->fw_bo->map = NULL;
355
firmware_present(struct pipe_screen *pscreen, enum pipe_video_profile profile)
357
struct nouveau_screen *screen = nouveau_screen(pscreen);
358
int chipset = screen->device->chipset;
359
int vp3 = chipset < 0xa3 || chipset == 0xaa || chipset == 0xac;
360
int vp5 = chipset >= 0xd0;
363
/* For all chipsets, try to create a BSP objects. Assume that if firmware
364
* is present for it, firmware is also present for VP/PPP */
365
if (!(screen->firmware_info.profiles_checked & 1)) {
366
struct nouveau_object *channel = NULL, *bsp = NULL;
367
struct nv04_fifo nv04_data = {.vram = 0xbeef0201, .gart = 0xbeef0202};
368
struct nvc0_fifo nvc0_args = {};
369
struct nve0_fifo nve0_args = {.engine = NVE0_FIFO_ENGINE_BSP};
374
else if (chipset < 0xe0)
379
if (chipset < 0xc0) {
381
size = sizeof(nv04_data);
382
} else if (chipset < 0xe0) {
384
size = sizeof(nvc0_args);
387
size = sizeof(nve0_args);
390
/* kepler must have its own channel, so just do this for everyone */
391
nouveau_object_new(&screen->device->object, 0,
392
NOUVEAU_FIFO_CHANNEL_CLASS,
393
data, size, &channel);
396
nouveau_object_new(channel, 0, oclass, NULL, 0, &bsp);
398
screen->firmware_info.profiles_present |= 1;
399
nouveau_object_del(&bsp);
400
nouveau_object_del(&channel);
402
screen->firmware_info.profiles_checked |= 1;
405
if (!(screen->firmware_info.profiles_present & 1))
408
/* For vp3/vp4 chipsets, make sure that the relevant firmware is present */
409
if (!vp5 && !(screen->firmware_info.profiles_checked & (1 << profile))) {
413
vp3_getpath(profile, path);
415
vp4_getpath(profile, path);
416
ret = stat(path, &s);
417
if (!ret && s.st_size > 1000)
418
screen->firmware_info.profiles_present |= (1 << profile);
419
screen->firmware_info.profiles_checked |= (1 << profile);
422
return vp5 || (screen->firmware_info.profiles_present & (1 << profile));
426
nouveau_vp3_screen_get_video_param(struct pipe_screen *pscreen,
427
enum pipe_video_profile profile,
428
enum pipe_video_entrypoint entrypoint,
429
enum pipe_video_cap param)
431
int chipset = nouveau_screen(pscreen)->device->chipset;
432
int vp3 = chipset < 0xa3 || chipset == 0xaa || chipset == 0xac;
433
int vp5 = chipset >= 0xd0;
434
enum pipe_video_format codec = u_reduce_video_profile(profile);
436
case PIPE_VIDEO_CAP_SUPPORTED:
437
/* VP3 does not support MPEG4, VP4+ do. */
438
return entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM &&
439
profile >= PIPE_VIDEO_PROFILE_MPEG1 &&
440
(!vp3 || codec != PIPE_VIDEO_FORMAT_MPEG4) &&
441
firmware_present(pscreen, profile);
442
case PIPE_VIDEO_CAP_NPOT_TEXTURES:
444
case PIPE_VIDEO_CAP_MAX_WIDTH:
445
case PIPE_VIDEO_CAP_MAX_HEIGHT:
446
return vp5 ? 4096 : 2048;
447
case PIPE_VIDEO_CAP_PREFERED_FORMAT:
448
return PIPE_FORMAT_NV12;
449
case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
450
case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
452
case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
454
case PIPE_VIDEO_CAP_MAX_LEVEL:
456
case PIPE_VIDEO_PROFILE_MPEG1:
458
case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
459
case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
461
case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE:
463
case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE:
465
case PIPE_VIDEO_PROFILE_VC1_SIMPLE:
467
case PIPE_VIDEO_PROFILE_VC1_MAIN:
469
case PIPE_VIDEO_PROFILE_VC1_ADVANCED:
471
case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
472
case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
473
case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
476
debug_printf("unknown video profile: %d\n", profile);
480
debug_printf("unknown video param: %d\n", param);
486
nouveau_vp3_screen_video_supported(struct pipe_screen *screen,
487
enum pipe_format format,
488
enum pipe_video_profile profile,
489
enum pipe_video_entrypoint entrypoint)
491
if (profile != PIPE_VIDEO_PROFILE_UNKNOWN)
492
return format == PIPE_FORMAT_NV12;
494
return vl_video_buffer_is_format_supported(screen, format, profile, entrypoint);