#include "vl/vl_defines.h"
#include "vl/vl_video_buffer.h"
-#include "../../winsys/radeon/drm/radeon_winsys.h"
#include "r600_pipe_common.h"
#include "radeon_video.h"
#include "radeon_vce.h"
}
/* create a buffer in the winsys */
-bool rvid_create_buffer(struct radeon_winsys *ws, struct rvid_buffer *buffer,
- unsigned size, enum radeon_bo_domain domain)
+bool rvid_create_buffer(struct pipe_screen *screen, struct rvid_buffer *buffer,
+ unsigned size, unsigned usage)
{
- buffer->domain = domain;
+ memset(buffer, 0, sizeof(*buffer));
+ buffer->usage = usage;
+ buffer->res = (struct r600_resource *)
+ pipe_buffer_create(screen, PIPE_BIND_CUSTOM, usage, size);
- buffer->buf = ws->buffer_create(ws, size, 4096, false, domain);
- if (!buffer->buf)
- return false;
-
- buffer->cs_handle = ws->buffer_get_cs_handle(buffer->buf);
- if (!buffer->cs_handle)
- return false;
-
- return true;
+ return buffer->res != NULL;
}
/* destroy a buffer */
void rvid_destroy_buffer(struct rvid_buffer *buffer)
{
- pb_reference(&buffer->buf, NULL);
- buffer->cs_handle = NULL;
+ pipe_resource_reference((struct pipe_resource **)&buffer->res, NULL);
}
/* reallocate a buffer, preserving its content */
-bool rvid_resize_buffer(struct radeon_winsys *ws, struct radeon_winsys_cs *cs,
+bool rvid_resize_buffer(struct pipe_screen *screen, struct radeon_winsys_cs *cs,
struct rvid_buffer *new_buf, unsigned new_size)
{
- unsigned bytes = MIN2(new_buf->buf->size, new_size);
+ struct r600_common_screen *rscreen = (struct r600_common_screen *)screen;
+ struct radeon_winsys* ws = rscreen->ws;
+ unsigned bytes = MIN2(new_buf->res->buf->size, new_size);
struct rvid_buffer old_buf = *new_buf;
void *src = NULL, *dst = NULL;
- if (!rvid_create_buffer(ws, new_buf, new_size, new_buf->domain))
+ if (!rvid_create_buffer(screen, new_buf, new_size, new_buf->usage))
goto error;
- src = ws->buffer_map(old_buf.cs_handle, cs, PIPE_TRANSFER_READ);
+ src = ws->buffer_map(old_buf.res->buf, cs, PIPE_TRANSFER_READ);
if (!src)
goto error;
- dst = ws->buffer_map(new_buf->cs_handle, cs, PIPE_TRANSFER_WRITE);
+ dst = ws->buffer_map(new_buf->res->buf, cs, PIPE_TRANSFER_WRITE);
if (!dst)
goto error;
dst += bytes;
memset(dst, 0, new_size);
}
- ws->buffer_unmap(new_buf->cs_handle);
- ws->buffer_unmap(old_buf.cs_handle);
+ ws->buffer_unmap(new_buf->res->buf);
+ ws->buffer_unmap(old_buf.res->buf);
rvid_destroy_buffer(&old_buf);
return true;
error:
if (src)
- ws->buffer_unmap(old_buf.cs_handle);
+ ws->buffer_unmap(old_buf.res->buf);
rvid_destroy_buffer(new_buf);
*new_buf = old_buf;
return false;
}
/* clear the buffer with zeros */
-void rvid_clear_buffer(struct radeon_winsys *ws, struct radeon_winsys_cs *cs, struct rvid_buffer* buffer)
+void rvid_clear_buffer(struct pipe_context *context, struct rvid_buffer* buffer)
{
- void *ptr = ws->buffer_map(buffer->cs_handle, cs, PIPE_TRANSFER_WRITE);
- if (!ptr)
- return;
+ struct r600_common_context *rctx = (struct r600_common_context*)context;
- memset(ptr, 0, buffer->buf->size);
- ws->buffer_unmap(buffer->cs_handle);
+ rctx->clear_buffer(context, &buffer->res->b.b, 0, buffer->res->buf->size,
+ 0, R600_COHERENCY_NONE);
+ context->flush(context, NULL, 0);
}
/**
* join surfaces into the same buffer with identical tiling params
* sumup their sizes and replace the backend buffers with a single bo
*/
-void rvid_join_surfaces(struct radeon_winsys* ws, unsigned bind,
+void rvid_join_surfaces(struct radeon_winsys* ws,
struct pb_buffer** buffers[VL_NUM_COMPONENTS],
- struct radeon_surface *surfaces[VL_NUM_COMPONENTS])
+ struct radeon_surf *surfaces[VL_NUM_COMPONENTS])
{
unsigned best_tiling, best_wh, off;
unsigned size, alignment;
/* adjust the texture layer offsets */
off = align(off, surfaces[i]->bo_alignment);
- for (j = 0; j < Elements(surfaces[i]->level); ++j)
+ for (j = 0; j < ARRAY_SIZE(surfaces[i]->level); ++j)
surfaces[i]->level[j].offset += off;
off += surfaces[i]->bo_size;
}
/* TODO: 2D tiling workaround */
alignment *= 2;
- pb = ws->buffer_create(ws, size, alignment, bind, RADEON_DOMAIN_VRAM);
+ pb = ws->buffer_create(ws, size, alignment, RADEON_DOMAIN_VRAM, 0);
if (!pb)
return;
enum pipe_video_cap param)
{
struct r600_common_screen *rscreen = (struct r600_common_screen *)screen;
+ enum pipe_video_format codec = u_reduce_video_profile(profile);
if (entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
switch (param) {
case PIPE_VIDEO_CAP_SUPPORTED:
- return u_reduce_video_profile(profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC &&
+ return codec == PIPE_VIDEO_FORMAT_MPEG4_AVC &&
rvce_is_fw_version_supported(rscreen);
case PIPE_VIDEO_CAP_NPOT_TEXTURES:
return 1;
case PIPE_VIDEO_CAP_MAX_WIDTH:
- return 2048;
+ return (rscreen->family < CHIP_TONGA) ? 2048 : 4096;
case PIPE_VIDEO_CAP_MAX_HEIGHT:
- return 1152;
+ return (rscreen->family < CHIP_TONGA) ? 1152 : 2304;
case PIPE_VIDEO_CAP_PREFERED_FORMAT:
return PIPE_FORMAT_NV12;
case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
return false;
case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
return true;
+ case PIPE_VIDEO_CAP_STACKED_FRAMES:
+ return (rscreen->family < CHIP_TONGA) ? 1 : 2;
default:
return 0;
}
}
- /* UVD 2.x limits */
- if (rscreen->family < CHIP_PALM) {
- enum pipe_video_format codec = u_reduce_video_profile(profile);
- switch (param) {
- case PIPE_VIDEO_CAP_SUPPORTED:
- /* no support for MPEG4 */
- return codec != PIPE_VIDEO_FORMAT_MPEG4 &&
- /* FIXME: VC-1 simple/main profile is broken */
- profile != PIPE_VIDEO_PROFILE_VC1_SIMPLE &&
- profile != PIPE_VIDEO_PROFILE_VC1_MAIN;
- case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
- case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
- /* and MPEG2 only with shaders */
- return codec != PIPE_VIDEO_FORMAT_MPEG12;
- default:
- break;
- }
- }
-
switch (param) {
case PIPE_VIDEO_CAP_SUPPORTED:
- switch (u_reduce_video_profile(profile)) {
+ switch (codec) {
case PIPE_VIDEO_FORMAT_MPEG12:
+ return profile != PIPE_VIDEO_PROFILE_MPEG1;
case PIPE_VIDEO_FORMAT_MPEG4:
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
- return entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE;
+ if (rscreen->family < CHIP_PALM)
+ /* no support for MPEG4 */
+ return codec != PIPE_VIDEO_FORMAT_MPEG4;
+ return true;
case PIPE_VIDEO_FORMAT_VC1:
- /* FIXME: VC-1 simple/main profile is broken */
- return profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED &&
- entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE;
+ return true;
+ case PIPE_VIDEO_FORMAT_HEVC:
+ /* Carrizo only supports HEVC Main */
+ if (rscreen->family >= CHIP_STONEY)
+ return (profile == PIPE_VIDEO_PROFILE_HEVC_MAIN ||
+ profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10);
+ else if (rscreen->family >= CHIP_CARRIZO)
+ return profile == PIPE_VIDEO_PROFILE_HEVC_MAIN;
default:
return false;
}
case PIPE_VIDEO_CAP_NPOT_TEXTURES:
return 1;
case PIPE_VIDEO_CAP_MAX_WIDTH:
- return 2048;
+ return (rscreen->family < CHIP_TONGA) ? 2048 : 4096;
case PIPE_VIDEO_CAP_MAX_HEIGHT:
- return 1152;
+ return (rscreen->family < CHIP_TONGA) ? 1152 : 4096;
case PIPE_VIDEO_CAP_PREFERED_FORMAT:
return PIPE_FORMAT_NV12;
case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
- return true;
case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
- return true;
+ if (rscreen->family < CHIP_PALM) {
+ /* MPEG2 only with shaders and no support for
+ interlacing on R6xx style UVD */
+ return codec != PIPE_VIDEO_FORMAT_MPEG12 &&
+ rscreen->family > CHIP_RV770;
+ } else {
+ if (u_reduce_video_profile(profile) == PIPE_VIDEO_FORMAT_HEVC)
+ return false; //The firmware doesn't support interlaced HEVC.
+ return true;
+ }
case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
return true;
case PIPE_VIDEO_CAP_MAX_LEVEL:
case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
- return 41;
+ return (rscreen->family < CHIP_TONGA) ? 41 : 52;
+ case PIPE_VIDEO_PROFILE_HEVC_MAIN:
+ case PIPE_VIDEO_PROFILE_HEVC_MAIN_10:
+ return 186;
default:
return 0;
}