mirror of
https://github.com/mpv-player/mpv
synced 2025-04-09 19:22:05 +00:00
vo_opengl: support float pixel formats
Like AV_PIX_FMT_GBRPF32LE.
This commit is contained in:
parent
817bb2bbbe
commit
63b1031ca2
@ -128,6 +128,8 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
|
|||||||
if (!pd || pd->nb_components > 4 || fmt == AV_PIX_FMT_NONE ||
|
if (!pd || pd->nb_components > 4 || fmt == AV_PIX_FMT_NONE ||
|
||||||
fmt == AV_PIX_FMT_UYYVYY411)
|
fmt == AV_PIX_FMT_UYYVYY411)
|
||||||
return mp_only_imgfmt_desc(mpfmt);
|
return mp_only_imgfmt_desc(mpfmt);
|
||||||
|
enum mp_component_type is_uint =
|
||||||
|
mp_imgfmt_get_component_type(fmt) == MP_COMPONENT_TYPE_UINT;
|
||||||
|
|
||||||
struct mp_imgfmt_desc desc = {
|
struct mp_imgfmt_desc desc = {
|
||||||
.id = mpfmt,
|
.id = mpfmt,
|
||||||
@ -229,7 +231,7 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
|
|||||||
&& (desc.flags & MP_IMGFLAG_BYTE_ALIGNED)
|
&& (desc.flags & MP_IMGFLAG_BYTE_ALIGNED)
|
||||||
&& !(pd->flags & AV_PIX_FMT_FLAG_PAL)
|
&& !(pd->flags & AV_PIX_FMT_FLAG_PAL)
|
||||||
&& !component_byte_overlap
|
&& !component_byte_overlap
|
||||||
&& shift >= 0)
|
&& shift >= 0 && is_uint)
|
||||||
{
|
{
|
||||||
bool same_depth = true;
|
bool same_depth = true;
|
||||||
for (int p = 0; p < desc.num_planes; p++) {
|
for (int p = 0; p < desc.num_planes; p++) {
|
||||||
@ -332,6 +334,22 @@ enum mp_csp mp_imgfmt_get_forced_csp(int imgfmt)
|
|||||||
return MP_CSP_AUTO;
|
return MP_CSP_AUTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum mp_component_type mp_imgfmt_get_component_type(int imgfmt)
|
||||||
|
{
|
||||||
|
const AVPixFmtDescriptor *pixdesc =
|
||||||
|
av_pix_fmt_desc_get(imgfmt2pixfmt(imgfmt));
|
||||||
|
|
||||||
|
if (!pixdesc)
|
||||||
|
return MP_COMPONENT_TYPE_UNKNOWN;
|
||||||
|
|
||||||
|
#ifdef AV_PIX_FMT_FLAG_FLOAT
|
||||||
|
if (pixdesc->flags & AV_PIX_FMT_FLAG_FLOAT)
|
||||||
|
return MP_COMPONENT_TYPE_FLOAT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return MP_COMPONENT_TYPE_UINT;
|
||||||
|
}
|
||||||
|
|
||||||
static bool is_native_endian(const AVPixFmtDescriptor *pixdesc)
|
static bool is_native_endian(const AVPixFmtDescriptor *pixdesc)
|
||||||
{
|
{
|
||||||
enum AVPixelFormat pixfmt = av_pix_fmt_desc_get_id(pixdesc);
|
enum AVPixelFormat pixfmt = av_pix_fmt_desc_get_id(pixdesc);
|
||||||
@ -357,6 +375,10 @@ bool mp_get_regular_imgfmt(struct mp_regular_imgfmt *dst, int imgfmt)
|
|||||||
!is_native_endian(pixdesc))
|
!is_native_endian(pixdesc))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
res.component_type = mp_imgfmt_get_component_type(imgfmt);
|
||||||
|
if (!res.component_type)
|
||||||
|
return false;
|
||||||
|
|
||||||
const AVComponentDescriptor *comp0 = &pixdesc->comp[0];
|
const AVComponentDescriptor *comp0 = &pixdesc->comp[0];
|
||||||
|
|
||||||
int depth = comp0->depth + comp0->shift;
|
int depth = comp0->depth + comp0->shift;
|
||||||
@ -497,6 +519,7 @@ int main(int argc, char **argv)
|
|||||||
int fcsp = mp_imgfmt_get_forced_csp(mpfmt);
|
int fcsp = mp_imgfmt_get_forced_csp(mpfmt);
|
||||||
if (fcsp)
|
if (fcsp)
|
||||||
printf(" fcsp=%d", fcsp);
|
printf(" fcsp=%d", fcsp);
|
||||||
|
printf(" ctype=%d", mp_imgfmt_get_component_type(mpfmt));
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(" planes=%d, chroma=%d:%d align=%d:%d bits=%d cbits=%d\n",
|
printf(" planes=%d, chroma=%d:%d align=%d:%d bits=%d cbits=%d\n",
|
||||||
d.num_planes, d.chroma_xs, d.chroma_ys, d.align_x, d.align_y,
|
d.num_planes, d.chroma_xs, d.chroma_ys, d.align_x, d.align_y,
|
||||||
|
@ -101,6 +101,14 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int imgfmt);
|
|||||||
// (Because IMGFMT/AV_PIX_FMT conflate format and csp for RGB and XYZ.)
|
// (Because IMGFMT/AV_PIX_FMT conflate format and csp for RGB and XYZ.)
|
||||||
enum mp_csp mp_imgfmt_get_forced_csp(int imgfmt);
|
enum mp_csp mp_imgfmt_get_forced_csp(int imgfmt);
|
||||||
|
|
||||||
|
enum mp_component_type {
|
||||||
|
MP_COMPONENT_TYPE_UNKNOWN = 0,
|
||||||
|
MP_COMPONENT_TYPE_UINT,
|
||||||
|
MP_COMPONENT_TYPE_FLOAT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum mp_component_type mp_imgfmt_get_component_type(int imgfmt);
|
||||||
|
|
||||||
#define MP_NUM_COMPONENTS 4
|
#define MP_NUM_COMPONENTS 4
|
||||||
|
|
||||||
struct mp_regular_imgfmt_plane {
|
struct mp_regular_imgfmt_plane {
|
||||||
@ -113,6 +121,9 @@ struct mp_regular_imgfmt_plane {
|
|||||||
// This describes pixel formats that are byte aligned, have byte aligned
|
// This describes pixel formats that are byte aligned, have byte aligned
|
||||||
// components, native endian, etc.
|
// components, native endian, etc.
|
||||||
struct mp_regular_imgfmt {
|
struct mp_regular_imgfmt {
|
||||||
|
// Type of each component.
|
||||||
|
enum mp_component_type component_type;
|
||||||
|
|
||||||
// Size of each component in bytes.
|
// Size of each component in bytes.
|
||||||
uint8_t component_size;
|
uint8_t component_size;
|
||||||
|
|
||||||
|
@ -130,6 +130,23 @@ const struct ra_format *ra_find_uint_format(struct ra *ra,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find a float format of any precision that matches the C type of the same
|
||||||
|
// size for upload.
|
||||||
|
static const struct ra_format *ra_find_float_format(struct ra *ra,
|
||||||
|
int bytes_per_component,
|
||||||
|
int n_components)
|
||||||
|
{
|
||||||
|
// Assumes ra_format are ordered by quality.
|
||||||
|
for (int n = 0; n < ra->num_formats; n++) {
|
||||||
|
const struct ra_format *fmt = ra->formats[n];
|
||||||
|
if (fmt->ctype == RA_CTYPE_FLOAT && fmt->num_components == n_components &&
|
||||||
|
fmt->pixel_size == bytes_per_component * n_components &&
|
||||||
|
fmt->linear_filter && ra_format_is_regular(fmt))
|
||||||
|
return fmt;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Return a filterable regular format that uses float16 internally, but does 32 bit
|
// Return a filterable regular format that uses float16 internally, but does 32 bit
|
||||||
// transfer. (This is just so we don't need 32->16 bit conversion on CPU,
|
// transfer. (This is just so we don't need 32->16 bit conversion on CPU,
|
||||||
// which would be ok but messy.)
|
// which would be ok but messy.)
|
||||||
@ -159,12 +176,20 @@ const struct ra_format *ra_find_named_format(struct ra *ra, const char *name)
|
|||||||
// Like ra_find_unorm_format(), but if no fixed point format is available,
|
// Like ra_find_unorm_format(), but if no fixed point format is available,
|
||||||
// return an unsigned integer format.
|
// return an unsigned integer format.
|
||||||
static const struct ra_format *find_plane_format(struct ra *ra, int bytes,
|
static const struct ra_format *find_plane_format(struct ra *ra, int bytes,
|
||||||
int n_channels)
|
int n_channels,
|
||||||
|
enum mp_component_type ctype)
|
||||||
{
|
{
|
||||||
|
switch (ctype) {
|
||||||
|
case MP_COMPONENT_TYPE_UINT: {
|
||||||
const struct ra_format *f = ra_find_unorm_format(ra, bytes, n_channels);
|
const struct ra_format *f = ra_find_unorm_format(ra, bytes, n_channels);
|
||||||
if (f)
|
if (f)
|
||||||
return f;
|
return f;
|
||||||
return ra_find_uint_format(ra, bytes, n_channels);
|
return ra_find_uint_format(ra, bytes, n_channels);
|
||||||
|
}
|
||||||
|
case MP_COMPONENT_TYPE_FLOAT:
|
||||||
|
return ra_find_float_format(ra, bytes, n_channels);
|
||||||
|
default: return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put a mapping of imgfmt to texture formats into *out. Basically it selects
|
// Put a mapping of imgfmt to texture formats into *out. Basically it selects
|
||||||
@ -188,7 +213,8 @@ bool ra_get_imgfmt_desc(struct ra *ra, int imgfmt, struct ra_imgfmt_desc *out)
|
|||||||
for (int n = 0; n < regfmt.num_planes; n++) {
|
for (int n = 0; n < regfmt.num_planes; n++) {
|
||||||
struct mp_regular_imgfmt_plane *plane = ®fmt.planes[n];
|
struct mp_regular_imgfmt_plane *plane = ®fmt.planes[n];
|
||||||
res.planes[n] = find_plane_format(ra, regfmt.component_size,
|
res.planes[n] = find_plane_format(ra, regfmt.component_size,
|
||||||
plane->num_components);
|
plane->num_components,
|
||||||
|
regfmt.component_type);
|
||||||
if (!res.planes[n])
|
if (!res.planes[n])
|
||||||
return false;
|
return false;
|
||||||
for (int i = 0; i < plane->num_components; i++)
|
for (int i = 0; i < plane->num_components; i++)
|
||||||
|
Loading…
Reference in New Issue
Block a user