diff mbox

drm: add FOURCC formats for compute dma_buf interop.

Message ID 1394819961-21537-1-git-send-email-gwenole.beauchesne@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gwenole Beauchesne March 14, 2014, 5:59 p.m. UTC
This is a follow-up to:
http://lists.freedesktop.org/archives/mesa-dev/2014-March/055742.html

Add formats meant to convey a "compute" dimension when a DRM fourcc
format is needed for dma_buf interop (EGL, OpenCL).

Intended FOURCC format: ('T',<num_elements>,<type>,<size_element>).
- <num_elements>: number of elements in the tuple. Range: [0..3].
- <type>: type of each element. Values: {'_','I','U','F'},
  respectively for normalized to [0..1] range, signed integers,
  unsigned integers, floating-point.
- <size_element>: size of the element. Values: {1, 2, 4, 8}.

All entities are represented in native-endian byte-order in memory.
For example, 'T2F4' format would represent the (float, float) tuple
where elements are stored in little-endian byte-order on x86.

Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
---
 include/drm/drm_fourcc.h |   78 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

Comments

Daniel Vetter March 14, 2014, 9:52 p.m. UTC | #1
On Fri, Mar 14, 2014 at 06:59:21PM +0100, Gwenole Beauchesne wrote:
> This is a follow-up to:
> http://lists.freedesktop.org/archives/mesa-dev/2014-March/055742.html
> 
> Add formats meant to convey a "compute" dimension when a DRM fourcc
> format is needed for dma_buf interop (EGL, OpenCL).
> 
> Intended FOURCC format: ('T',<num_elements>,<type>,<size_element>).
> - <num_elements>: number of elements in the tuple. Range: [0..3].
> - <type>: type of each element. Values: {'_','I','U','F'},
>   respectively for normalized to [0..1] range, signed integers,
>   unsigned integers, floating-point.
> - <size_element>: size of the element. Values: {1, 2, 4, 8}.
> 
> All entities are represented in native-endian byte-order in memory.
> For example, 'T2F4' format would represent the (float, float) tuple
> where elements are stored in little-endian byte-order on x86.
> 
> Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>

So this fourcc stuff started out as pixel formats for the ADDFB2 ioctl,
i.e. stuff that can be displayed. Hence my first question: How can we
display these bastards here?

Next up: dma-buf has absolutely no intrinsic concept of the contents of a
buffer. It's a raw pile of bytes with a fixed length.

So given all this: Why do we need this in the kernel's header? It sounds
like purely a userspace business with no need at all the enshrine this
into kernel ABI headers. Note that e.g. the mesa import/export interface
have their own fourcc #defines for exactly this reason.
-Daniel

> ---
>  include/drm/drm_fourcc.h |   78 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 78 insertions(+)
> 
> diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
> index 85facb0..26a2ca8 100644
> --- a/include/drm/drm_fourcc.h
> +++ b/include/drm/drm_fourcc.h
> @@ -127,4 +127,82 @@
>  #define DRM_FORMAT_YUV444	fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
>  #define DRM_FORMAT_YVU444	fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
>  
> +/**
> + * \defgroup api_drm_tuples Compute formats (tuples)
> + *
> + * The following formats are not meant for display. Rather, they are
> + * meant to convey a "compute" dimension when a DRM fourcc format is
> + * needed for dma_buf interop (EGL, OpenCL).
> + *
> + * Intended FOURCC format: ('T',<num_elements>,<type>,<size_element>).
> + * - <num_elements>: number of elements in the tuple. Range: [0..3].
> + * - <type>: type of each element. Values: {'_','I','U','F'},
> + *   respectively for normalized to [0..1] range, signed integers,
> + *   unsigned integers, floating-point.
> + * - <size_element>: size of the element. Values: {1, 2, 4, 8}.
> + *
> + * All entities are represented in native-endian byte-order in memory.
> + * For example, 'T2F4' format would represent the (float, float) tuple
> + * where elements are stored in little-endian byte-order on x86.
> + *
> + * @{
> + */
> +
> +/** Type of a tuple element */
> +enum {
> +    DRM_FORMAT_TUPLE_TYPE_UNORM	= '_', /**< Unsigned integer value normalized to [0..1] range */
> +    DRM_FORMAT_TUPLE_TYPE_SINT	= 'I', /**< Signed integer value */
> +    DRM_FORMAT_TUPLE_TYPE_UINT	= 'U', /**< Unsigned integer value */
> +    DRM_FORMAT_TUPLE_TYPE_FLOAT	= 'F', /**< Floating-point value */
> +};
> +
> +/** Generates a FOURCC value for a tuple */
> +#define DRM_FORMAT_TUPLE(num_elements, type, size) \
> +    fourcc_code('T', '0'+(num_elements), DRM_FORMAT_TUPLE_TYPE_##type, '0'+(size))
> +
> +/** @name Unsigned integers normalized to [0..1] range */
> +/**@{*/
> +#define DRM_FORMAT_T1_1		DRM_FORMAT_TUPLE(1, UNORM, 1) /** (X), 8-bit integers normalized to [0..1] range */
> +#define DRM_FORMAT_T2_1		DRM_FORMAT_TUPLE(2, UNORM, 1) /** (X, Y), 8-bit integers normalized to [0..1] range */
> +#define DRM_FORMAT_T4_1		DRM_FORMAT_TUPLE(4, UNORM, 1) /** (X, Y, Z, W), 8-bit integers normalized to [0..1] range */
> +#define DRM_FORMAT_T1_2		DRM_FORMAT_TUPLE(1, UNORM, 2) /** (X), 16-bit integers normalized to [0..1] range */
> +#define DRM_FORMAT_T2_2		DRM_FORMAT_TUPLE(2, UNORM, 2) /** (X, Y), 16-bit integers normalized to [0..1] range */
> +#define DRM_FORMAT_T4_2		DRM_FORMAT_TUPLE(4, UNORM, 2) /** (X, Y, Z, W), 16-bit integers normalized to [0..1] range */
> +/**@}*/
> +
> +/** @name Signed integer values */
> +/**@{*/
> +#define DRM_FORMAT_T1I1		DRM_FORMAT_TUPLE(1, SINT, 1) /** (X), 8-bit signed integer */
> +#define DRM_FORMAT_T2I1		DRM_FORMAT_TUPLE(2, SINT, 1) /** (X, Y), 8-bit signed integer */
> +#define DRM_FORMAT_T4I1		DRM_FORMAT_TUPLE(4, SINT, 1) /** (X, Y, Z, W), 8-bit signed integer */
> +#define DRM_FORMAT_T1I2		DRM_FORMAT_TUPLE(1, SINT, 2) /** (X), 16-bit signed integer */
> +#define DRM_FORMAT_T2I2		DRM_FORMAT_TUPLE(2, SINT, 2) /** (X, Y), 16-bit signed integer */
> +#define DRM_FORMAT_T4I2		DRM_FORMAT_TUPLE(4, SINT, 2) /** (X, Y, Z, W), 16-bit signed integer */
> +#define DRM_FORMAT_T1I4		DRM_FORMAT_TUPLE(1, SINT, 4) /** (X), 32-bit signed integer */
> +#define DRM_FORMAT_T2I4		DRM_FORMAT_TUPLE(2, SINT, 4) /** (X, Y), 32-bit signed integer */
> +#define DRM_FORMAT_T4I4		DRM_FORMAT_TUPLE(4, SINT, 4) /** (X, Y, Z, W), 32-bit signed integer */
> +/**@}*/
> +
> +/** @name Unsigned integer values */
> +/**@{*/
> +#define DRM_FORMAT_T1U1		DRM_FORMAT_TUPLE(1, UINT, 1) /** (X), 8-bit unsigned integer */
> +#define DRM_FORMAT_T2U1		DRM_FORMAT_TUPLE(2, UINT, 1) /** (X, Y), 8-bit unsigned integer */
> +#define DRM_FORMAT_T4U1		DRM_FORMAT_TUPLE(4, UINT, 1) /** (X, Y, Z, W), 8-bit unsigned integer */
> +#define DRM_FORMAT_T1U2		DRM_FORMAT_TUPLE(1, UINT, 2) /** (X), 16-bit unsigned integer */
> +#define DRM_FORMAT_T2U2		DRM_FORMAT_TUPLE(2, UINT, 2) /** (X, Y), 16-bit unsigned integer */
> +#define DRM_FORMAT_T4U2		DRM_FORMAT_TUPLE(4, UINT, 2) /** (X, Y, Z, W), 16-bit unsigned integer */
> +#define DRM_FORMAT_T1U4		DRM_FORMAT_TUPLE(1, UINT, 4) /** (X), 32-bit unsigned integer */
> +#define DRM_FORMAT_T2U4		DRM_FORMAT_TUPLE(2, UINT, 4) /** (X, Y), 32-bit unsigned integer */
> +#define DRM_FORMAT_T4U4		DRM_FORMAT_TUPLE(4, UINT, 4) /** (X, Y, Z, W), 32-bit unsigned integer */
> +/**@}*/
> +
> +/** @name Floating-point values */
> +/**@{*/
> +#define DRM_FORMAT_T1F4		DRM_FORMAT_TUPLE(1, FLOAT, 4) /** (X), 32-bit floating-point */
> +#define DRM_FORMAT_T2F4		DRM_FORMAT_TUPLE(2, FLOAT, 4) /** (X, Y), 32-bit floating-point */
> +#define DRM_FORMAT_T4F4		DRM_FORMAT_TUPLE(4, FLOAT, 4) /** (X, Y, Z, W), 32-bit floating-point */
> +/**@}*/
> +
> +/**@}*/
> +
>  #endif /* DRM_FOURCC_H */
> -- 
> 1.7.9.5
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
Gwenole Beauchesne March 15, 2014, 4:41 a.m. UTC | #2
Hi,

2014-03-14 22:52 GMT+01:00 Daniel Vetter <daniel@ffwll.ch>:
> On Fri, Mar 14, 2014 at 06:59:21PM +0100, Gwenole Beauchesne wrote:
>> This is a follow-up to:
>> http://lists.freedesktop.org/archives/mesa-dev/2014-March/055742.html
>>
>> Add formats meant to convey a "compute" dimension when a DRM fourcc
>> format is needed for dma_buf interop (EGL, OpenCL).
>>
>> Intended FOURCC format: ('T',<num_elements>,<type>,<size_element>).
>> - <num_elements>: number of elements in the tuple. Range: [0..3].
>> - <type>: type of each element. Values: {'_','I','U','F'},
>>   respectively for normalized to [0..1] range, signed integers,
>>   unsigned integers, floating-point.
>> - <size_element>: size of the element. Values: {1, 2, 4, 8}.
>>
>> All entities are represented in native-endian byte-order in memory.
>> For example, 'T2F4' format would represent the (float, float) tuple
>> where elements are stored in little-endian byte-order on x86.
>>
>> Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
>
> So this fourcc stuff started out as pixel formats for the ADDFB2 ioctl,
> i.e. stuff that can be displayed. Hence my first question: How can we
> display these bastards here?

It's not meant to be displayed. The idea was maybe we could detect the
fourcc (e.g. (fourcc & 0xff) == 'T') and reject the buffer accordingly
when submitted to one of the display ioctl?

> So given all this: Why do we need this in the kernel's header? It sounds
> like purely a userspace business with no need at all the enshrine this
> into kernel ABI headers. Note that e.g. the mesa import/export interface
> have their own fourcc #defines for exactly this reason.

I could have stuffed everything in gbm.h for instance, or another new
header, but the EXT_dma_buf_import extension actually mentions
drm_fourcc.h. So, that's why I finally moved the definitions to there.
:)

What would be the better place? Can we make the userspace libdrm
version of the file live totally unsynchronized from the kernel
headers then?

Thanks,
Gwenole.

>>  include/drm/drm_fourcc.h |   78 ++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 78 insertions(+)
>>
>> diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
>> index 85facb0..26a2ca8 100644
>> --- a/include/drm/drm_fourcc.h
>> +++ b/include/drm/drm_fourcc.h
>> @@ -127,4 +127,82 @@
>>  #define DRM_FORMAT_YUV444    fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
>>  #define DRM_FORMAT_YVU444    fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
>>
>> +/**
>> + * \defgroup api_drm_tuples Compute formats (tuples)
>> + *
>> + * The following formats are not meant for display. Rather, they are
>> + * meant to convey a "compute" dimension when a DRM fourcc format is
>> + * needed for dma_buf interop (EGL, OpenCL).
>> + *
>> + * Intended FOURCC format: ('T',<num_elements>,<type>,<size_element>).
>> + * - <num_elements>: number of elements in the tuple. Range: [0..3].
>> + * - <type>: type of each element. Values: {'_','I','U','F'},
>> + *   respectively for normalized to [0..1] range, signed integers,
>> + *   unsigned integers, floating-point.
>> + * - <size_element>: size of the element. Values: {1, 2, 4, 8}.
>> + *
>> + * All entities are represented in native-endian byte-order in memory.
>> + * For example, 'T2F4' format would represent the (float, float) tuple
>> + * where elements are stored in little-endian byte-order on x86.
>> + *
>> + * @{
>> + */
>> +
>> +/** Type of a tuple element */
>> +enum {
>> +    DRM_FORMAT_TUPLE_TYPE_UNORM      = '_', /**< Unsigned integer value normalized to [0..1] range */
>> +    DRM_FORMAT_TUPLE_TYPE_SINT       = 'I', /**< Signed integer value */
>> +    DRM_FORMAT_TUPLE_TYPE_UINT       = 'U', /**< Unsigned integer value */
>> +    DRM_FORMAT_TUPLE_TYPE_FLOAT      = 'F', /**< Floating-point value */
>> +};
>> +
>> +/** Generates a FOURCC value for a tuple */
>> +#define DRM_FORMAT_TUPLE(num_elements, type, size) \
>> +    fourcc_code('T', '0'+(num_elements), DRM_FORMAT_TUPLE_TYPE_##type, '0'+(size))
>> +
>> +/** @name Unsigned integers normalized to [0..1] range */
>> +/**@{*/
>> +#define DRM_FORMAT_T1_1              DRM_FORMAT_TUPLE(1, UNORM, 1) /** (X), 8-bit integers normalized to [0..1] range */
>> +#define DRM_FORMAT_T2_1              DRM_FORMAT_TUPLE(2, UNORM, 1) /** (X, Y), 8-bit integers normalized to [0..1] range */
>> +#define DRM_FORMAT_T4_1              DRM_FORMAT_TUPLE(4, UNORM, 1) /** (X, Y, Z, W), 8-bit integers normalized to [0..1] range */
>> +#define DRM_FORMAT_T1_2              DRM_FORMAT_TUPLE(1, UNORM, 2) /** (X), 16-bit integers normalized to [0..1] range */
>> +#define DRM_FORMAT_T2_2              DRM_FORMAT_TUPLE(2, UNORM, 2) /** (X, Y), 16-bit integers normalized to [0..1] range */
>> +#define DRM_FORMAT_T4_2              DRM_FORMAT_TUPLE(4, UNORM, 2) /** (X, Y, Z, W), 16-bit integers normalized to [0..1] range */
>> +/**@}*/
>> +
>> +/** @name Signed integer values */
>> +/**@{*/
>> +#define DRM_FORMAT_T1I1              DRM_FORMAT_TUPLE(1, SINT, 1) /** (X), 8-bit signed integer */
>> +#define DRM_FORMAT_T2I1              DRM_FORMAT_TUPLE(2, SINT, 1) /** (X, Y), 8-bit signed integer */
>> +#define DRM_FORMAT_T4I1              DRM_FORMAT_TUPLE(4, SINT, 1) /** (X, Y, Z, W), 8-bit signed integer */
>> +#define DRM_FORMAT_T1I2              DRM_FORMAT_TUPLE(1, SINT, 2) /** (X), 16-bit signed integer */
>> +#define DRM_FORMAT_T2I2              DRM_FORMAT_TUPLE(2, SINT, 2) /** (X, Y), 16-bit signed integer */
>> +#define DRM_FORMAT_T4I2              DRM_FORMAT_TUPLE(4, SINT, 2) /** (X, Y, Z, W), 16-bit signed integer */
>> +#define DRM_FORMAT_T1I4              DRM_FORMAT_TUPLE(1, SINT, 4) /** (X), 32-bit signed integer */
>> +#define DRM_FORMAT_T2I4              DRM_FORMAT_TUPLE(2, SINT, 4) /** (X, Y), 32-bit signed integer */
>> +#define DRM_FORMAT_T4I4              DRM_FORMAT_TUPLE(4, SINT, 4) /** (X, Y, Z, W), 32-bit signed integer */
>> +/**@}*/
>> +
>> +/** @name Unsigned integer values */
>> +/**@{*/
>> +#define DRM_FORMAT_T1U1              DRM_FORMAT_TUPLE(1, UINT, 1) /** (X), 8-bit unsigned integer */
>> +#define DRM_FORMAT_T2U1              DRM_FORMAT_TUPLE(2, UINT, 1) /** (X, Y), 8-bit unsigned integer */
>> +#define DRM_FORMAT_T4U1              DRM_FORMAT_TUPLE(4, UINT, 1) /** (X, Y, Z, W), 8-bit unsigned integer */
>> +#define DRM_FORMAT_T1U2              DRM_FORMAT_TUPLE(1, UINT, 2) /** (X), 16-bit unsigned integer */
>> +#define DRM_FORMAT_T2U2              DRM_FORMAT_TUPLE(2, UINT, 2) /** (X, Y), 16-bit unsigned integer */
>> +#define DRM_FORMAT_T4U2              DRM_FORMAT_TUPLE(4, UINT, 2) /** (X, Y, Z, W), 16-bit unsigned integer */
>> +#define DRM_FORMAT_T1U4              DRM_FORMAT_TUPLE(1, UINT, 4) /** (X), 32-bit unsigned integer */
>> +#define DRM_FORMAT_T2U4              DRM_FORMAT_TUPLE(2, UINT, 4) /** (X, Y), 32-bit unsigned integer */
>> +#define DRM_FORMAT_T4U4              DRM_FORMAT_TUPLE(4, UINT, 4) /** (X, Y, Z, W), 32-bit unsigned integer */
>> +/**@}*/
>> +
>> +/** @name Floating-point values */
>> +/**@{*/
>> +#define DRM_FORMAT_T1F4              DRM_FORMAT_TUPLE(1, FLOAT, 4) /** (X), 32-bit floating-point */
>> +#define DRM_FORMAT_T2F4              DRM_FORMAT_TUPLE(2, FLOAT, 4) /** (X, Y), 32-bit floating-point */
>> +#define DRM_FORMAT_T4F4              DRM_FORMAT_TUPLE(4, FLOAT, 4) /** (X, Y, Z, W), 32-bit floating-point */
>> +/**@}*/
>> +
>> +/**@}*/
>> +
>>  #endif /* DRM_FOURCC_H */
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
Daniel Vetter March 15, 2014, 11:28 a.m. UTC | #3
On Sat, Mar 15, 2014 at 05:41:05AM +0100, Gwenole Beauchesne wrote:
> Hi,
> 
> 2014-03-14 22:52 GMT+01:00 Daniel Vetter <daniel@ffwll.ch>:
> > On Fri, Mar 14, 2014 at 06:59:21PM +0100, Gwenole Beauchesne wrote:
> >> This is a follow-up to:
> >> http://lists.freedesktop.org/archives/mesa-dev/2014-March/055742.html
> >>
> >> Add formats meant to convey a "compute" dimension when a DRM fourcc
> >> format is needed for dma_buf interop (EGL, OpenCL).
> >>
> >> Intended FOURCC format: ('T',<num_elements>,<type>,<size_element>).
> >> - <num_elements>: number of elements in the tuple. Range: [0..3].
> >> - <type>: type of each element. Values: {'_','I','U','F'},
> >>   respectively for normalized to [0..1] range, signed integers,
> >>   unsigned integers, floating-point.
> >> - <size_element>: size of the element. Values: {1, 2, 4, 8}.
> >>
> >> All entities are represented in native-endian byte-order in memory.
> >> For example, 'T2F4' format would represent the (float, float) tuple
> >> where elements are stored in little-endian byte-order on x86.
> >>
> >> Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
> >
> > So this fourcc stuff started out as pixel formats for the ADDFB2 ioctl,
> > i.e. stuff that can be displayed. Hence my first question: How can we
> > display these bastards here?
> 
> It's not meant to be displayed. The idea was maybe we could detect the
> fourcc (e.g. (fourcc & 0xff) == 'T') and reject the buffer accordingly
> when submitted to one of the display ioctl?

Well we already have explicit lists for all that, so no need to add a pile
of formats just to be able to reject them ;-)

> > So given all this: Why do we need this in the kernel's header? It sounds
> > like purely a userspace business with no need at all the enshrine this
> > into kernel ABI headers. Note that e.g. the mesa import/export interface
> > have their own fourcc #defines for exactly this reason.
> 
> I could have stuffed everything in gbm.h for instance, or another new
> header, but the EXT_dma_buf_import extension actually mentions
> drm_fourcc.h. So, that's why I finally moved the definitions to there.
> :)

That's a bit unfortunate ... But the spec also clearly states "as used by
the drm_mode_fb_cmd2 ioctl". And imo we can't make a case that this is
true.

> What would be the better place? Can we make the userspace libdrm
> version of the file live totally unsynchronized from the kernel
> headers then?

I think the right approach would be to ref the specification and also
allow other fourcc codes for non-display related buffer layaouts, maybe in
a different namespace. This entire fourcc stuff was only done since it was
a somewhat ill-defined "standard" for all kinds of YUV buffers. We've
already had to massivel pimp it to make it work properly with RGB.

Pimping this even further to support all kinds of random compute/gl
buffers sounds ill-advised. I think we need to steal a new namespace from
some existing standard for all this, maybe ogl or ocl has something? Ofc
that means creating a new dma_buf_import atttribute for eglCreateImageKHR
which could be used instead of DRM_FOURCC_EXT.

Cheers, Daniel
Gwenole Beauchesne March 19, 2014, 6:30 a.m. UTC | #4
Hi,

2014-03-15 12:28 GMT+01:00 Daniel Vetter <daniel@ffwll.ch>:
> On Sat, Mar 15, 2014 at 05:41:05AM +0100, Gwenole Beauchesne wrote:
>> Hi,
>>
>> 2014-03-14 22:52 GMT+01:00 Daniel Vetter <daniel@ffwll.ch>:
>> > On Fri, Mar 14, 2014 at 06:59:21PM +0100, Gwenole Beauchesne wrote:
>> >> This is a follow-up to:
>> >> http://lists.freedesktop.org/archives/mesa-dev/2014-March/055742.html
>> >>
>> >> Add formats meant to convey a "compute" dimension when a DRM fourcc
>> >> format is needed for dma_buf interop (EGL, OpenCL).
>> >>
>> >> Intended FOURCC format: ('T',<num_elements>,<type>,<size_element>).
>> >> - <num_elements>: number of elements in the tuple. Range: [0..3].
>> >> - <type>: type of each element. Values: {'_','I','U','F'},
>> >>   respectively for normalized to [0..1] range, signed integers,
>> >>   unsigned integers, floating-point.
>> >> - <size_element>: size of the element. Values: {1, 2, 4, 8}.
>> >>
>> >> All entities are represented in native-endian byte-order in memory.
>> >> For example, 'T2F4' format would represent the (float, float) tuple
>> >> where elements are stored in little-endian byte-order on x86.
>> >>
>> >> Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
>> >
>> > So this fourcc stuff started out as pixel formats for the ADDFB2 ioctl,
>> > i.e. stuff that can be displayed. Hence my first question: How can we
>> > display these bastards here?
>>
>> It's not meant to be displayed. The idea was maybe we could detect the
>> fourcc (e.g. (fourcc & 0xff) == 'T') and reject the buffer accordingly
>> when submitted to one of the display ioctl?
>
> Well we already have explicit lists for all that, so no need to add a pile
> of formats just to be able to reject them ;-)
>
>> > So given all this: Why do we need this in the kernel's header? It sounds
>> > like purely a userspace business with no need at all the enshrine this
>> > into kernel ABI headers. Note that e.g. the mesa import/export interface
>> > have their own fourcc #defines for exactly this reason.
>>
>> I could have stuffed everything in gbm.h for instance, or another new
>> header, but the EXT_dma_buf_import extension actually mentions
>> drm_fourcc.h. So, that's why I finally moved the definitions to there.
>> :)
>
> That's a bit unfortunate ... But the spec also clearly states "as used by
> the drm_mode_fb_cmd2 ioctl". And imo we can't make a case that this is
> true.
>
>> What would be the better place? Can we make the userspace libdrm
>> version of the file live totally unsynchronized from the kernel
>> headers then?
>
> I think the right approach would be to ref the specification and also
> allow other fourcc codes for non-display related buffer layaouts, maybe in
> a different namespace. This entire fourcc stuff was only done since it was
> a somewhat ill-defined "standard" for all kinds of YUV buffers. We've
> already had to massivel pimp it to make it work properly with RGB.
>
> Pimping this even further to support all kinds of random compute/gl
> buffers sounds ill-advised. I think we need to steal a new namespace from
> some existing standard for all this, maybe ogl or ocl has something? Ofc
> that means creating a new dma_buf_import atttribute for eglCreateImageKHR
> which could be used instead of DRM_FOURCC_EXT.

Thinking further about it, the patch is totally useless. It should be
enough to amend the EXT_image_dma_buf_import spec to allow for using
the GL format/type enums instead... Now, what are the chances to have
the required changes to appear in a new revision of the spec? :)

I'd suggest the following formalism:
- If EGL_LINUX_DRM_FOURCC_EXT attribute is 0 (zero), then a GL
format/type pair needs to be supplied to the <attrib_list>
- Accepted as an attribute to <attrib_list> would be EGL_GL_FORMAT_EXT
/ EGL_GL_TYPE_EXT, where EGL_GL_FORMAT_EXT attribute value would be
GL_{RED,RG,RGB,RGBA} as usual, and EGL_GL_TYPE_EXT value would be
GL_{{UNSIGNED_,}{BYTE,SHORT,INT},{HALF_,}FLOAT}.

Alternative would be to provide a unique "internal format", but this
would complicate implementations, for sanity checks (too large switch
cases).

WDYT?
Daniel Vetter March 19, 2014, 10:31 a.m. UTC | #5
On Wed, Mar 19, 2014 at 7:30 AM, Gwenole Beauchesne <gb.devel@gmail.com> wrote:
> 2014-03-15 12:28 GMT+01:00 Daniel Vetter <daniel@ffwll.ch>:
>> On Sat, Mar 15, 2014 at 05:41:05AM +0100, Gwenole Beauchesne wrote:
>>> Hi,
>>>
>>> 2014-03-14 22:52 GMT+01:00 Daniel Vetter <daniel@ffwll.ch>:
>>> > On Fri, Mar 14, 2014 at 06:59:21PM +0100, Gwenole Beauchesne wrote:
>>> >> This is a follow-up to:
>>> >> http://lists.freedesktop.org/archives/mesa-dev/2014-March/055742.html
>>> >>
>>> >> Add formats meant to convey a "compute" dimension when a DRM fourcc
>>> >> format is needed for dma_buf interop (EGL, OpenCL).
>>> >>
>>> >> Intended FOURCC format: ('T',<num_elements>,<type>,<size_element>).
>>> >> - <num_elements>: number of elements in the tuple. Range: [0..3].
>>> >> - <type>: type of each element. Values: {'_','I','U','F'},
>>> >>   respectively for normalized to [0..1] range, signed integers,
>>> >>   unsigned integers, floating-point.
>>> >> - <size_element>: size of the element. Values: {1, 2, 4, 8}.
>>> >>
>>> >> All entities are represented in native-endian byte-order in memory.
>>> >> For example, 'T2F4' format would represent the (float, float) tuple
>>> >> where elements are stored in little-endian byte-order on x86.
>>> >>
>>> >> Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
>>> >
>>> > So this fourcc stuff started out as pixel formats for the ADDFB2 ioctl,
>>> > i.e. stuff that can be displayed. Hence my first question: How can we
>>> > display these bastards here?
>>>
>>> It's not meant to be displayed. The idea was maybe we could detect the
>>> fourcc (e.g. (fourcc & 0xff) == 'T') and reject the buffer accordingly
>>> when submitted to one of the display ioctl?
>>
>> Well we already have explicit lists for all that, so no need to add a pile
>> of formats just to be able to reject them ;-)
>>
>>> > So given all this: Why do we need this in the kernel's header? It sounds
>>> > like purely a userspace business with no need at all the enshrine this
>>> > into kernel ABI headers. Note that e.g. the mesa import/export interface
>>> > have their own fourcc #defines for exactly this reason.
>>>
>>> I could have stuffed everything in gbm.h for instance, or another new
>>> header, but the EXT_dma_buf_import extension actually mentions
>>> drm_fourcc.h. So, that's why I finally moved the definitions to there.
>>> :)
>>
>> That's a bit unfortunate ... But the spec also clearly states "as used by
>> the drm_mode_fb_cmd2 ioctl". And imo we can't make a case that this is
>> true.
>>
>>> What would be the better place? Can we make the userspace libdrm
>>> version of the file live totally unsynchronized from the kernel
>>> headers then?
>>
>> I think the right approach would be to ref the specification and also
>> allow other fourcc codes for non-display related buffer layaouts, maybe in
>> a different namespace. This entire fourcc stuff was only done since it was
>> a somewhat ill-defined "standard" for all kinds of YUV buffers. We've
>> already had to massivel pimp it to make it work properly with RGB.
>>
>> Pimping this even further to support all kinds of random compute/gl
>> buffers sounds ill-advised. I think we need to steal a new namespace from
>> some existing standard for all this, maybe ogl or ocl has something? Ofc
>> that means creating a new dma_buf_import atttribute for eglCreateImageKHR
>> which could be used instead of DRM_FOURCC_EXT.
>
> Thinking further about it, the patch is totally useless. It should be
> enough to amend the EXT_image_dma_buf_import spec to allow for using
> the GL format/type enums instead... Now, what are the chances to have
> the required changes to appear in a new revision of the spec? :)
>
> I'd suggest the following formalism:
> - If EGL_LINUX_DRM_FOURCC_EXT attribute is 0 (zero), then a GL
> format/type pair needs to be supplied to the <attrib_list>
> - Accepted as an attribute to <attrib_list> would be EGL_GL_FORMAT_EXT
> / EGL_GL_TYPE_EXT, where EGL_GL_FORMAT_EXT attribute value would be
> GL_{RED,RG,RGB,RGBA} as usual, and EGL_GL_TYPE_EXT value would be
> GL_{{UNSIGNED_,}{BYTE,SHORT,INT},{HALF_,}FLOAT}.
>
> Alternative would be to provide a unique "internal format", but this
> would complicate implementations, for sanity checks (too large switch
> cases).
>
> WDYT?

Sounds imo sane, but my useful knowledge sharply drops off a steep
cliff as soon as we leave the kernel. Pulling in the original authors
of the spec. Maybe we can just add this as a revision/clarification
... Iirc Jesse Barker isn't at linaro any more, but I don't have his
latest mail.
-Daniel
diff mbox

Patch

diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 85facb0..26a2ca8 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -127,4 +127,82 @@ 
 #define DRM_FORMAT_YUV444	fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
 #define DRM_FORMAT_YVU444	fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
 
+/**
+ * \defgroup api_drm_tuples Compute formats (tuples)
+ *
+ * The following formats are not meant for display. Rather, they are
+ * meant to convey a "compute" dimension when a DRM fourcc format is
+ * needed for dma_buf interop (EGL, OpenCL).
+ *
+ * Intended FOURCC format: ('T',<num_elements>,<type>,<size_element>).
+ * - <num_elements>: number of elements in the tuple. Range: [0..3].
+ * - <type>: type of each element. Values: {'_','I','U','F'},
+ *   respectively for normalized to [0..1] range, signed integers,
+ *   unsigned integers, floating-point.
+ * - <size_element>: size of the element. Values: {1, 2, 4, 8}.
+ *
+ * All entities are represented in native-endian byte-order in memory.
+ * For example, 'T2F4' format would represent the (float, float) tuple
+ * where elements are stored in little-endian byte-order on x86.
+ *
+ * @{
+ */
+
+/** Type of a tuple element */
+enum {
+    DRM_FORMAT_TUPLE_TYPE_UNORM	= '_', /**< Unsigned integer value normalized to [0..1] range */
+    DRM_FORMAT_TUPLE_TYPE_SINT	= 'I', /**< Signed integer value */
+    DRM_FORMAT_TUPLE_TYPE_UINT	= 'U', /**< Unsigned integer value */
+    DRM_FORMAT_TUPLE_TYPE_FLOAT	= 'F', /**< Floating-point value */
+};
+
+/** Generates a FOURCC value for a tuple */
+#define DRM_FORMAT_TUPLE(num_elements, type, size) \
+    fourcc_code('T', '0'+(num_elements), DRM_FORMAT_TUPLE_TYPE_##type, '0'+(size))
+
+/** @name Unsigned integers normalized to [0..1] range */
+/**@{*/
+#define DRM_FORMAT_T1_1		DRM_FORMAT_TUPLE(1, UNORM, 1) /** (X), 8-bit integers normalized to [0..1] range */
+#define DRM_FORMAT_T2_1		DRM_FORMAT_TUPLE(2, UNORM, 1) /** (X, Y), 8-bit integers normalized to [0..1] range */
+#define DRM_FORMAT_T4_1		DRM_FORMAT_TUPLE(4, UNORM, 1) /** (X, Y, Z, W), 8-bit integers normalized to [0..1] range */
+#define DRM_FORMAT_T1_2		DRM_FORMAT_TUPLE(1, UNORM, 2) /** (X), 16-bit integers normalized to [0..1] range */
+#define DRM_FORMAT_T2_2		DRM_FORMAT_TUPLE(2, UNORM, 2) /** (X, Y), 16-bit integers normalized to [0..1] range */
+#define DRM_FORMAT_T4_2		DRM_FORMAT_TUPLE(4, UNORM, 2) /** (X, Y, Z, W), 16-bit integers normalized to [0..1] range */
+/**@}*/
+
+/** @name Signed integer values */
+/**@{*/
+#define DRM_FORMAT_T1I1		DRM_FORMAT_TUPLE(1, SINT, 1) /** (X), 8-bit signed integer */
+#define DRM_FORMAT_T2I1		DRM_FORMAT_TUPLE(2, SINT, 1) /** (X, Y), 8-bit signed integer */
+#define DRM_FORMAT_T4I1		DRM_FORMAT_TUPLE(4, SINT, 1) /** (X, Y, Z, W), 8-bit signed integer */
+#define DRM_FORMAT_T1I2		DRM_FORMAT_TUPLE(1, SINT, 2) /** (X), 16-bit signed integer */
+#define DRM_FORMAT_T2I2		DRM_FORMAT_TUPLE(2, SINT, 2) /** (X, Y), 16-bit signed integer */
+#define DRM_FORMAT_T4I2		DRM_FORMAT_TUPLE(4, SINT, 2) /** (X, Y, Z, W), 16-bit signed integer */
+#define DRM_FORMAT_T1I4		DRM_FORMAT_TUPLE(1, SINT, 4) /** (X), 32-bit signed integer */
+#define DRM_FORMAT_T2I4		DRM_FORMAT_TUPLE(2, SINT, 4) /** (X, Y), 32-bit signed integer */
+#define DRM_FORMAT_T4I4		DRM_FORMAT_TUPLE(4, SINT, 4) /** (X, Y, Z, W), 32-bit signed integer */
+/**@}*/
+
+/** @name Unsigned integer values */
+/**@{*/
+#define DRM_FORMAT_T1U1		DRM_FORMAT_TUPLE(1, UINT, 1) /** (X), 8-bit unsigned integer */
+#define DRM_FORMAT_T2U1		DRM_FORMAT_TUPLE(2, UINT, 1) /** (X, Y), 8-bit unsigned integer */
+#define DRM_FORMAT_T4U1		DRM_FORMAT_TUPLE(4, UINT, 1) /** (X, Y, Z, W), 8-bit unsigned integer */
+#define DRM_FORMAT_T1U2		DRM_FORMAT_TUPLE(1, UINT, 2) /** (X), 16-bit unsigned integer */
+#define DRM_FORMAT_T2U2		DRM_FORMAT_TUPLE(2, UINT, 2) /** (X, Y), 16-bit unsigned integer */
+#define DRM_FORMAT_T4U2		DRM_FORMAT_TUPLE(4, UINT, 2) /** (X, Y, Z, W), 16-bit unsigned integer */
+#define DRM_FORMAT_T1U4		DRM_FORMAT_TUPLE(1, UINT, 4) /** (X), 32-bit unsigned integer */
+#define DRM_FORMAT_T2U4		DRM_FORMAT_TUPLE(2, UINT, 4) /** (X, Y), 32-bit unsigned integer */
+#define DRM_FORMAT_T4U4		DRM_FORMAT_TUPLE(4, UINT, 4) /** (X, Y, Z, W), 32-bit unsigned integer */
+/**@}*/
+
+/** @name Floating-point values */
+/**@{*/
+#define DRM_FORMAT_T1F4		DRM_FORMAT_TUPLE(1, FLOAT, 4) /** (X), 32-bit floating-point */
+#define DRM_FORMAT_T2F4		DRM_FORMAT_TUPLE(2, FLOAT, 4) /** (X, Y), 32-bit floating-point */
+#define DRM_FORMAT_T4F4		DRM_FORMAT_TUPLE(4, FLOAT, 4) /** (X, Y, Z, W), 32-bit floating-point */
+/**@}*/
+
+/**@}*/
+
 #endif /* DRM_FOURCC_H */