Update for v1.0alpha2

This commit is contained in:
James Deng 2024-03-01 19:54:36 +08:00
parent b8e6af96a8
commit b5fd683534
149 changed files with 15373 additions and 1404 deletions

View file

@ -118,6 +118,7 @@ BACKGROUND_PIDS="$! $BACKGROUND_PIDS"
if [ -n "$HWCI_START_XORG" ]; then
echo "touch /xorg-started; sleep 100000" > /xorg-script
env \
VK_ICD_FILENAMES=/install/share/vulkan/icd.d/${VK_DRIVER}_icd.`uname -m`.json \
xinit /bin/sh /xorg-script -- /usr/bin/Xorg -noreset -s 0 -dpms -logfile /Xorg.0.log &
BACKGROUND_PIDS="$! $BACKGROUND_PIDS"
@ -131,6 +132,17 @@ if [ -n "$HWCI_START_XORG" ]; then
export DISPLAY=:0
fi
if [ -n "$HWCI_START_WESTON" ]; then
export XDG_RUNTIME_DIR=/run/user
mkdir -p $XDG_RUNTIME_DIR
env \
VK_ICD_FILENAMES=/install/share/vulkan/icd.d/${VK_DRIVER}_icd.`uname -m`.json \
weston -Bheadless-backend.so --use-gl -Swayland-0 &
export WAYLAND_DISPLAY=wayland-0
sleep 1
fi
RESULT=fail
set +e
sh -c "$HWCI_TEST_SCRIPT"

View file

@ -117,7 +117,6 @@ supported, although some of these might not actually get verified:
* ``VkPhysicalDeviceFeatures``:
* ``occlusionQueryPrecise``
* ``dualSrcBlend``
* Device extensions:
@ -240,26 +239,12 @@ are required to be supported
* ``VkPhysicalDeviceFeatures``:
* ``samplerAnisotropy``
* ``pipelineStatisticsQuery``
* ``depthBiasClamp``
* Device extensions:
* `VK_KHR_draw_indirect_count`_
Performance
-----------
If you notice poor performance and high CPU usage while running an application,
changing the descriptor manager may improve performance:
.. envvar:: ZINK_DESCRIPTORS <mode> ("auto")
``auto``
Automatically detect best mode. This is the default.
``lazy``
Attempt to use the least amount of CPU by binding descriptors opportunistically.
Debugging
---------

View file

@ -699,6 +699,11 @@ the box region, not the beginning of the resource. If transfer_map fails,
the returned pointer to the buffer memory is NULL, and the pointer
to the transfer object remains unchanged (i.e. it can be non-NULL).
When mapping an MSAA surface, the samples are implicitly resolved to
single-sampled for reads (returning the first sample for depth/stencil/integer,
averaged for others). See u_transfer_helper's U_TRANSFER_HELPER_MSAA_MAP for a
way to get that behavior using a resolve blit.
``transfer_unmap`` remove the memory mapping for and destroy
the transfer object. The pointer into the resource should be considered
invalid and discarded.

View file

@ -49,6 +49,11 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG
#define EGL_DRM_BUFFER_FORMAT_RGB565_MESA 0x3292
#endif /* EGL_MESA_drm_image_formats */
#ifndef EGL_IMG_cl_image
#define EGL_IMG_cl_image 1
#define EGL_CL_IMAGE_IMG 0x6010
#endif /* Experimental eglCreateImageKHR target */
#ifdef __cplusplus
}
#endif

View file

@ -730,7 +730,13 @@ struct __DRIuseInvalidateExtensionRec {
#define __DRI_ATTRIB_GREEN_SHIFT 51
#define __DRI_ATTRIB_BLUE_SHIFT 52
#define __DRI_ATTRIB_ALPHA_SHIFT 53
#define __DRI_ATTRIB_MAX 54
#define __DRI_ATTRIB_YUV_ORDER 54
#define __DRI_ATTRIB_YUV_NUMBER_OF_PLANES 55
#define __DRI_ATTRIB_YUV_SUBSAMPLE 56
#define __DRI_ATTRIB_YUV_DEPTH_RANGE 57
#define __DRI_ATTRIB_YUV_CSC_STANDARD 58
#define __DRI_ATTRIB_YUV_PLANE_BPP 59
#define __DRI_ATTRIB_MAX 60
/* __DRI_ATTRIB_RENDER_TYPE */
#define __DRI_ATTRIB_RGBA_BIT 0x01
@ -738,6 +744,7 @@ struct __DRIuseInvalidateExtensionRec {
#define __DRI_ATTRIB_LUMINANCE_BIT 0x04
#define __DRI_ATTRIB_FLOAT_BIT 0x08
#define __DRI_ATTRIB_UNSIGNED_FLOAT_BIT 0x10
#define __DRI_ATTRIB_YUV_BIT 0x20
/* __DRI_ATTRIB_CONFIG_CAVEAT */
#define __DRI_ATTRIB_SLOW_BIT 0x01
@ -764,6 +771,39 @@ struct __DRIuseInvalidateExtensionRec {
#define __DRI_ATTRIB_SWAP_COPY 0x8062
#define __DRI_ATTRIB_SWAP_UNDEFINED 0x8063
/* __DRI_ATTRIB_YUV_ORDER */
#define __DRI_ATTRIB_YUV_ORDER_NONE 0x0
#define __DRI_ATTRIB_YUV_ORDER_YUV_BIT 0x1
#define __DRI_ATTRIB_YUV_ORDER_YVU_BIT 0x2
#define __DRI_ATTRIB_YUV_ORDER_YUYV_BIT 0x4
#define __DRI_ATTRIB_YUV_ORDER_UYVY_BIT 0x8
#define __DRI_ATTRIB_YUV_ORDER_YVYU_BIT 0x10
#define __DRI_ATTRIB_YUV_ORDER_VYUY_BIT 0x20
#define __DRI_ATTRIB_YUV_ORDER_AYUV_BIT 0x40
/* __DRI_ATTRIB_YUV_SUBSAMPLE */
#define __DRI_ATTRIB_YUV_SUBSAMPLE_NONE 0x0
#define __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT 0x1
#define __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT 0x2
#define __DRI_ATTRIB_YUV_SUBSAMPLE_4_4_4_BIT 0x4
/* __DRI_ATTRIB_YUV_DEPTH_RANGE */
#define __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE 0x0
#define __DRI_ATTRIB_YUV_DEPTH_RANGE_LIMITED_BIT 0x1
#define __DRI_ATTRIB_YUV_DEPTH_RANGE_FULL_BIT 0x2
/* __DRI_ATTRIB_YUV_CSC_STANDARD */
#define __DRI_ATTRIB_YUV_CSC_STANDARD_NONE 0x0
#define __DRI_ATTRIB_YUV_CSC_STANDARD_601_BIT 0x1
#define __DRI_ATTRIB_YUV_CSC_STANDARD_709_BIT 0x2
#define __DRI_ATTRIB_YUV_CSC_STANDARD_2020_BIT 0x4
/* __DRI_ATTRIB_YUV_PLANE_BPP */
#define __DRI_ATTRIB_YUV_PLANE_BPP_NONE 0x0
#define __DRI_ATTRIB_YUV_PLANE_BPP_0_BIT 0x1
#define __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT 0x2
#define __DRI_ATTRIB_YUV_PLANE_BPP_10_BIT 0x4
/**
* This extension defines the core DRI functionality.
*
@ -975,7 +1015,7 @@ struct __DRIbufferRec {
};
#define __DRI_DRI2_LOADER "DRI_DRI2Loader"
#define __DRI_DRI2_LOADER_VERSION 5
#define __DRI_DRI2_LOADER_VERSION 6
enum dri_loader_cap {
/* Whether the loader handles RGBA channel ordering correctly. If not,
@ -983,6 +1023,7 @@ enum dri_loader_cap {
*/
DRI_LOADER_CAP_RGBA_ORDERING,
DRI_LOADER_CAP_FP16,
DRI_LOADER_CAP_YUV_SURFACE_IMG = 0x7001,
};
struct __DRIdri2LoaderExtensionRec {
@ -1055,6 +1096,17 @@ struct __DRIdri2LoaderExtensionRec {
* \since 5
*/
void (*destroyLoaderImageState)(void *loaderPrivate);
/**
* Get the display FD
*
* Get the FD of the display device.
*
* \param loaderPrivate The last parameter of createNewScreen or
* createNewScreen2.
* \since 6
*/
int (*getDisplayFD)(void *loaderPrivate);
};
/**
@ -1229,6 +1281,16 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_FORMAT_SXRGB8 0x1016
#define __DRI_IMAGE_FORMAT_ABGR16161616 0x1017
#define __DRI_IMAGE_FORMAT_XBGR16161616 0x1018
#define __DRI_IMAGE_FORMAT_ARGB4444 0x1019
#define __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG 0x101a
#define __DRI_IMAGE_FORMAT_BGR888 0x101b
#define __DRI_IMAGE_FORMAT_NV12 0x101c
#define __DRI_IMAGE_FORMAT_NV21 0x101d
#define __DRI_IMAGE_FORMAT_YU12 0x101e
#define __DRI_IMAGE_FORMAT_YV12 0x101f
#define __DRI_IMAGE_FORMAT_YVYU 0x1020
#define __DRI_IMAGE_FORMAT_VYUY 0x1021
#define __DRI_IMAGE_FORMAT_AXBXGXRX106106106106 0x1022
#define __DRI_IMAGE_USE_SHARE 0x0001
#define __DRI_IMAGE_USE_SCANOUT 0x0002
@ -1260,6 +1322,8 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_FOURCC_SARGB8888 0x83324258
#define __DRI_IMAGE_FOURCC_SABGR8888 0x84324258
#define __DRI_IMAGE_FOURCC_SXRGB8888 0x85324258
#define __DRI_IMAGE_FOURCC_RGBA16161616 0x38344152 /* fourcc_code('R', 'A', '4', '8' ) */
#define __DRI_IMAGE_FOURCC_SBGR888 0xff324742
/**
* Queryable on images created by createImageFromNames.
@ -1279,11 +1343,12 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_COMPONENTS_Y_U_V 0x3003
#define __DRI_IMAGE_COMPONENTS_Y_UV 0x3004
#define __DRI_IMAGE_COMPONENTS_Y_XUXV 0x3005
#define __DRI_IMAGE_COMPONENTS_R 0x3006
#define __DRI_IMAGE_COMPONENTS_RG 0x3007
#define __DRI_IMAGE_COMPONENTS_Y_UXVX 0x3008
#define __DRI_IMAGE_COMPONENTS_AYUV 0x3009
#define __DRI_IMAGE_COMPONENTS_XYUV 0x300A
#define __DRI_IMAGE_COMPONENTS_R 0x3006
#define __DRI_IMAGE_COMPONENTS_RG 0x3007
#define __DRI_IMAGE_COMPONENTS_EXTERNAL 0x300B
/**
@ -1352,6 +1417,8 @@ enum __DRIChromaSiting {
*/
/*@{*/
#define __DRI_IMAGE_CAP_GLOBAL_NAMES 1
#define __DRI_IMAGE_CAP_PRIME_IMPORT 0x2000
#define __DRI_IMAGE_CAP_PRIME_EXPORT 0x4000
/*@}*/
/**
@ -1718,6 +1785,19 @@ struct __DRIimageExtensionRec {
* \since 21
*/
void (*setInFenceFd)(__DRIimage *image, int fd);
/**
* Support for experimental EGL_CL_IMAGE_IMG.
* Like createImageFromTexture, but from a buffer, the contents
* of which depend on the target.
*
* \since 8
*/
__DRIimage *(*createImageFromBuffer)(__DRIcontext *context,
int target,
void *buffer,
unsigned *error,
void *loaderPrivate);
};
@ -1913,6 +1993,8 @@ typedef struct __DRIDriverVtableExtensionRec {
#define __DRI2_RENDERER_HAS_PROTECTED_CONTEXT 0x0020
#define __DRI2_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG 0x7001
typedef struct __DRI2rendererQueryExtensionRec __DRI2rendererQueryExtension;
struct __DRI2rendererQueryExtensionRec {
__DRIextension base;
@ -1976,16 +2058,20 @@ enum __DRIimageBufferMask {
* OpenGL ES API and little change to the SurfaceFlinger API.
*/
__DRI_IMAGE_BUFFER_SHARED = (1 << 2),
#define DRI_IMAGE_HAS_BUFFER_PREV
__DRI_IMAGE_BUFFER_PREV = (1 << 31),
};
struct __DRIimageList {
uint32_t image_mask;
__DRIimage *back;
__DRIimage *front;
__DRIimage *prev;
};
#define __DRI_IMAGE_LOADER "DRI_IMAGE_LOADER"
#define __DRI_IMAGE_LOADER_VERSION 4
#define __DRI_IMAGE_LOADER_VERSION 5
struct __DRIimageLoaderExtensionRec {
__DRIextension base;
@ -2053,6 +2139,17 @@ struct __DRIimageLoaderExtensionRec {
* \since 4
*/
void (*destroyLoaderImageState)(void *loaderPrivate);
/**
* Get the display FD
*
* Get the FD of the display device.
*
* \param loaderPrivate The last parameter of createNewScreen or
* createNewScreen2.
* \since 5
*/
int (*getDisplayFD)(void *loaderPrivate);
};
/**

View file

@ -383,6 +383,7 @@ extern "C" {
#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 */
#define DRM_FORMAT_YVU444_PACK10_IMG fourcc_code('I', 'M', 'G', '2')
/*
* Format Modifiers:

View file

@ -41,6 +41,12 @@ endif
cc = meson.get_compiler('c')
cpp = meson.get_compiler('cpp')
if not cpp.compiles('thread_local int x = 0;', name : 'thread_local')
if cpp.has_argument('-std=c++11')
add_project_arguments('-std=c++11', language : 'cpp')
endif
endif
null_dep = dependency('', required : false)
if get_option('layout') != 'mirror'
@ -192,16 +198,16 @@ if gallium_drivers.contains('auto')
if ['x86', 'x86_64'].contains(host_machine.cpu_family())
gallium_drivers = [
'r300', 'r600', 'radeonsi', 'nouveau', 'virgl', 'svga', 'swrast',
'iris', 'crocus', 'i915'
'iris', 'crocus', 'i915', 'pvr'
]
elif ['arm', 'aarch64'].contains(host_machine.cpu_family())
gallium_drivers = [
'v3d', 'vc4', 'freedreno', 'etnaviv', 'nouveau', 'svga',
'tegra', 'virgl', 'lima', 'panfrost', 'swrast'
'v3d', 'vc4', 'freedreno', 'etnaviv', 'nouveau',
'tegra', 'virgl', 'lima', 'panfrost', 'swrast', 'pvr'
]
elif ['mips', 'mips64', 'riscv32', 'riscv64'].contains(host_machine.cpu_family())
gallium_drivers = [
'r300', 'r600', 'radeonsi', 'nouveau', 'virgl', 'swrast'
'r300', 'r600', 'radeonsi', 'nouveau', 'virgl', 'swrast', 'pvr'
]
else
error('Unknown architecture @0@. Please pass -Dgallium-drivers to set driver options. Patches gladly accepted to fix this.'.format(
@ -234,6 +240,7 @@ with_gallium_lima = gallium_drivers.contains('lima')
with_gallium_zink = gallium_drivers.contains('zink')
with_gallium_d3d12 = gallium_drivers.contains('d3d12')
with_gallium_asahi = gallium_drivers.contains('asahi')
with_gallium_pvr = gallium_drivers.contains('pvr')
foreach gallium_driver : gallium_drivers
pre_args += '-DHAVE_@0@'.format(gallium_driver.to_upper())
endforeach
@ -245,6 +252,17 @@ if not system_has_kms_drm
with_gallium_kmsro = false
endif
if with_gallium_pvr
gallium_pvr_alias = get_option('gallium-pvr-alias')
if gallium_pvr_alias == 'pvr'
gallium_pvr_alias = ''
endif
with_gallium_pvr_alias = gallium_pvr_alias != ''
else
gallium_pvr_alias = ''
with_gallium_pvr_alias = false
endif
with_dri = false
if with_gallium and system_has_kms_drm
_glx = get_option('glx')
@ -288,6 +306,7 @@ with_broadcom_vk = _vulkan_drivers.contains('broadcom')
with_imagination_vk = _vulkan_drivers.contains('imagination-experimental')
with_imagination_srv = get_option('imagination-srv')
with_microsoft_vk = _vulkan_drivers.contains('microsoft-experimental')
with_pvr_vk = _vulkan_drivers.contains('pvr')
with_any_vk = _vulkan_drivers.length() != 0
with_any_broadcom = with_gallium_vc4 or with_gallium_v3d or with_broadcom_vk
@ -342,7 +361,7 @@ endforeach
_platforms = get_option('platforms')
if _platforms.contains('auto')
if system_has_kms_drm
_platforms = ['x11', 'wayland']
_platforms = ['x11', 'wayland', 'null']
elif ['darwin', 'cygwin'].contains(host_machine.system())
_platforms = ['x11']
elif ['haiku'].contains(host_machine.system())
@ -360,6 +379,11 @@ with_platform_x11 = _platforms.contains('x11')
with_platform_wayland = _platforms.contains('wayland')
with_platform_haiku = _platforms.contains('haiku')
with_platform_windows = _platforms.contains('windows')
with_platform_null = _platforms.contains('null')
if with_platform_null
null_dri_driver_name = get_option('null-dri-driver-name')
endif
with_glx = get_option('glx')
if with_glx == 'auto'
@ -484,7 +508,7 @@ elif _egl == 'enabled'
error('EGL requires dri, haiku, or windows')
elif not with_shared_glapi
error('EGL requires shared-glapi')
elif not ['disabled', 'dri'].contains(with_glx)
elif not ['disabled', 'dri', 'null'].contains(with_glx)
error('EGL requires dri, but a GLX is being built without dri')
elif host_machine.system() == 'darwin'
error('EGL is not available on MacOS')
@ -510,6 +534,10 @@ if with_egl and not _platforms.contains(egl_native_platform)
error('-Degl-native-platform does not specify an enabled platform')
endif
if with_egl and with_opengl and with_glx != 'disabled'
pre_args += '-DEGL_WITH_OPENGL'
endif
if 'x11' in _platforms
_platforms += 'xcb'
endif
@ -538,7 +566,7 @@ endforeach
if not have_mtls_dialect
# need .run to check libc support. meson aborts when calling .run when
# cross-compiling, but because this is just an optimization we can skip it
if meson.is_cross_build() and not meson.has_exe_wrapper()
if meson.is_cross_build()
warning('cannot auto-detect -mtls-dialect when cross-compiling, using compiler default')
else
# -fpic to force dynamic tls, otherwise TLS relaxation defeats check
@ -561,7 +589,7 @@ if not have_mtls_dialect
endif
endif
if with_glx != 'disabled'
if with_glx != 'disabled' and with_glx != 'null'
if not (with_platform_x11 and with_any_opengl)
error('Cannot build GLX support without X11 platform support and at least one OpenGL API')
elif with_glx == 'xlib'
@ -619,7 +647,7 @@ if with_any_vk and (with_platform_x11 and not with_dri3)
error('Vulkan drivers require dri3 for X11 support')
endif
if with_dri
if with_glx == 'disabled' and not with_egl and not with_gbm
if (with_glx == 'disabled' or with_glx == 'null') and not with_egl and not with_gbm
error('building dri drivers require at least one windowing system')
endif
endif
@ -991,6 +1019,10 @@ if with_platform_android
]
endif
if with_platform_null
pre_args += '-DHAVE_NULL_PLATFORM'
endif
prog_python = import('python').find_installation('python3')
has_mako = run_command(
prog_python, '-c',
@ -1710,7 +1742,8 @@ with_gallium_drisw_kms = false
dep_libdrm = dependency(
'libdrm', version : '>=' + _drm_ver,
# GNU/Hurd includes egl_dri2, without drm.
required : (with_dri2 and host_machine.system() != 'gnu') or with_dri3
required : (with_dri2 and host_machine.system() != 'gnu') or with_dri3 or
with_platform_null
)
if dep_libdrm.found()
pre_args += '-DHAVE_LIBDRM'

View file

@ -23,7 +23,7 @@ option(
type : 'array',
value : ['auto'],
choices : [
'auto', 'x11', 'wayland', 'haiku', 'android', 'windows',
'auto', 'x11', 'wayland', 'haiku', 'android', 'windows', 'null',
],
description : 'window systems to support. If this is set to `auto`, all platforms applicable will be enabled.'
)
@ -37,6 +37,12 @@ option(
],
description : 'the window system EGL assumes for EGL_DEFAULT_DISPLAY',
)
option(
'null-dri-driver-name',
type : 'string',
value : '',
description : 'For the null platform, ignore all dri drivers apart from this one. By default, no dri drivers are ignored.'
)
option(
'android-stub',
type : 'boolean',
@ -75,10 +81,16 @@ option(
choices : [
'auto', 'kmsro', 'radeonsi', 'r300', 'r600', 'nouveau', 'freedreno',
'swrast', 'v3d', 'vc4', 'etnaviv', 'tegra', 'i915', 'svga', 'virgl',
'panfrost', 'iris', 'lima', 'zink', 'd3d12', 'asahi', 'crocus'
'panfrost', 'iris', 'lima', 'zink', 'd3d12', 'asahi', 'crocus', 'pvr'
],
description : 'List of gallium drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built'
)
option(
'gallium-pvr-alias',
type : 'string',
value : '',
description : 'Gallium PVR alias. This must match the name of the kernel display driver.'
)
option(
'gallium-extra-hud',
type : 'boolean',
@ -185,7 +197,7 @@ option(
'vulkan-drivers',
type : 'array',
value : ['auto'],
choices : ['auto', 'amd', 'broadcom', 'freedreno', 'imagination-experimental', 'intel', 'intel_hasvk', 'microsoft-experimental', 'panfrost', 'swrast', 'virtio-experimental'],
choices : ['auto', 'amd', 'broadcom', 'freedreno', 'imagination-experimental', 'intel', 'intel_hasvk', 'microsoft-experimental', 'panfrost', 'pvr', 'swrast', 'virtio-experimental'],
description : 'List of vulkan drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built'
)
option(
@ -293,7 +305,7 @@ option(
'glx',
type : 'combo',
value : 'auto',
choices : ['auto', 'disabled', 'dri', 'xlib'],
choices : ['auto', 'disabled', 'dri', 'xlib', 'null'],
description : 'Build support for GLX platform'
)
option(

View file

@ -262,6 +262,7 @@ files_libnir = files(
'nir_opt_undef.c',
'nir_opt_uniform_atomics.c',
'nir_opt_vectorize.c',
'nir_passthrough_gs.c',
'nir_passthrough_tcs.c',
'nir_phi_builder.c',
'nir_phi_builder.h',

View file

@ -4925,6 +4925,10 @@ nir_shader * nir_create_passthrough_tcs_impl(const nir_shader_compiler_options *
uint8_t patch_vertices);
nir_shader * nir_create_passthrough_tcs(const nir_shader_compiler_options *options,
const nir_shader *vs, uint8_t patch_vertices);
nir_shader * nir_create_passthrough_gs(const nir_shader_compiler_options *options,
const nir_shader *prev_stage,
enum shader_prim primitive_type,
unsigned vertices);
bool nir_lower_fragcolor(nir_shader *shader, unsigned max_cbufs);
bool nir_lower_fragcoord_wtrans(nir_shader *shader);

View file

@ -0,0 +1,108 @@
/*
* Copyright © 2022 Collabora Ltc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "nir.h"
#include "nir_builder.h"
/*
* A helper to create a passthrough GS shader for drivers that needs to lower
* some rendering tasks to the GS.
*/
nir_shader *
nir_create_passthrough_gs(const nir_shader_compiler_options *options,
const nir_shader *prev_stage,
enum shader_prim primitive_type,
unsigned vertices)
{
nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_GEOMETRY,
options,
"gs passthrough");
nir_shader *nir = b.shader;
nir->info.gs.input_primitive = primitive_type;
nir->info.gs.output_primitive = primitive_type;
nir->info.gs.vertices_in = vertices;
nir->info.gs.vertices_out = vertices;
nir->info.gs.invocations = 1;
nir->info.gs.active_stream_mask = 1;
nir_variable *in_vars[VARYING_SLOT_MAX];
nir_variable *out_vars[VARYING_SLOT_MAX];
unsigned num_vars = 0;
/* Create input/output variables. */
nir_foreach_shader_out_variable(var, prev_stage) {
assert(!var->data.patch);
char name[100];
if (var->name)
snprintf(name, sizeof(name), "in_%s", var->name);
else
snprintf(name, sizeof(name), "in_%d", var->data.driver_location);
nir_variable *in = nir_variable_create(nir, nir_var_shader_in,
glsl_array_type(var->type,
vertices,
false),
name);
in->data.location = var->data.location;
in->data.location_frac = var->data.location_frac;
in->data.driver_location = var->data.driver_location;
in->data.interpolation = var->data.interpolation;
in->data.compact = var->data.compact;
if (var->name)
snprintf(name, sizeof(name), "out_%s", var->name);
else
snprintf(name, sizeof(name), "out_%d", var->data.driver_location);
nir_variable *out = nir_variable_create(nir, nir_var_shader_out,
var->type, name);
out->data.location = var->data.location;
out->data.location_frac = var->data.location_frac;
out->data.driver_location = var->data.driver_location;
out->data.interpolation = var->data.interpolation;
out->data.compact = var->data.compact;
in_vars[num_vars] = in;
out_vars[num_vars++] = out;
}
for (unsigned i = 0; i < vertices; ++i) {
/* Copy inputs to outputs. */
for (unsigned j = 0; j < num_vars; ++j) {
/* no need to use copy_var to save a lower pass */
nir_ssa_def *value = nir_load_array_var_imm(&b, in_vars[j], i);
nir_store_var(&b, out_vars[j], value,
(1u << value->num_components) - 1);
}
nir_emit_vertex(&b, 0);
}
nir_end_primitive(&b, 0);
nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
nir_validate_shader(nir, "in nir_create_passthrough_gs");
return nir;
}

View file

@ -316,6 +316,7 @@ static const EGLint dri2_to_egl_attribute_map[__DRI_ATTRIB_MAX] = {
[__DRI_ATTRIB_MAX_SWAP_INTERVAL] = EGL_MAX_SWAP_INTERVAL,
[__DRI_ATTRIB_MIN_SWAP_INTERVAL] = EGL_MIN_SWAP_INTERVAL,
[__DRI_ATTRIB_YINVERTED] = EGL_Y_INVERTED_NOK,
[__DRI_ATTRIB_YUV_NUMBER_OF_PLANES] = EGL_YUV_NUMBER_OF_PLANES_EXT,
};
const __DRIconfig *
@ -416,6 +417,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
_EGLConfig base;
unsigned int attrib, value, double_buffer;
unsigned int pbuffer_width = 0, pbuffer_height = 0, pbuffer_pixels = 0;
bool srgb = false;
EGLint key, bind_to_texture_rgb, bind_to_texture_rgba;
int dri_shifts[4] = { -1, -1, -1, -1 };
@ -442,6 +444,8 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
value = EGL_RGB_BUFFER;
else if (value & __DRI_ATTRIB_LUMINANCE_BIT)
value = EGL_LUMINANCE_BUFFER;
else if (value & __DRI_ATTRIB_YUV_BIT)
value = EGL_YUV_BUFFER_EXT;
else
return NULL;
base.ColorBufferType = value;
@ -537,15 +541,88 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
break;
case __DRI_ATTRIB_MAX_PBUFFER_WIDTH:
base.MaxPbufferWidth = _EGL_MAX_PBUFFER_WIDTH;
pbuffer_width = (value != 0) ? value : _EGL_MAX_PBUFFER_WIDTH;
break;
case __DRI_ATTRIB_MAX_PBUFFER_HEIGHT:
base.MaxPbufferHeight = _EGL_MAX_PBUFFER_HEIGHT;
pbuffer_height = (value != 0) ? value : _EGL_MAX_PBUFFER_HEIGHT;
break;
case __DRI_ATTRIB_MAX_PBUFFER_PIXELS:
pbuffer_pixels = value;
break;
case __DRI_ATTRIB_MUTABLE_RENDER_BUFFER:
if (disp->Extensions.KHR_mutable_render_buffer)
surface_type |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR;
break;
case __DRI_ATTRIB_YUV_ORDER:
if (value & __DRI_ATTRIB_YUV_ORDER_YUV_BIT)
value = EGL_YUV_ORDER_YUV_EXT;
else if (value & __DRI_ATTRIB_YUV_ORDER_YVU_BIT)
value = EGL_YUV_ORDER_YVU_EXT;
else if (value & __DRI_ATTRIB_YUV_ORDER_YUYV_BIT)
value = EGL_YUV_ORDER_YUYV_EXT;
else if (value & __DRI_ATTRIB_YUV_ORDER_UYVY_BIT)
value = EGL_YUV_ORDER_UYVY_EXT;
else if (value & __DRI_ATTRIB_YUV_ORDER_YVYU_BIT)
value = EGL_YUV_ORDER_YVYU_EXT;
else if (value & __DRI_ATTRIB_YUV_ORDER_VYUY_BIT)
value = EGL_YUV_ORDER_VYUY_EXT;
else if (value & __DRI_ATTRIB_YUV_ORDER_AYUV_BIT)
value = EGL_YUV_ORDER_AYUV_EXT;
else
value = EGL_NONE;
_eglSetConfigKey(&base, EGL_YUV_ORDER_EXT, value);
break;
case __DRI_ATTRIB_YUV_SUBSAMPLE:
if (value & __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT)
value = EGL_YUV_SUBSAMPLE_4_2_0_EXT;
else if (value & __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT)
value = EGL_YUV_SUBSAMPLE_4_2_2_EXT;
else if (value & __DRI_ATTRIB_YUV_SUBSAMPLE_4_4_4_BIT)
value = EGL_YUV_SUBSAMPLE_4_4_4_EXT;
else
value = EGL_NONE;
_eglSetConfigKey(&base, EGL_YUV_SUBSAMPLE_EXT, value);
break;
case __DRI_ATTRIB_YUV_DEPTH_RANGE:
if (value & __DRI_ATTRIB_YUV_DEPTH_RANGE_LIMITED_BIT)
value = EGL_YUV_DEPTH_RANGE_LIMITED_EXT;
else if (value & __DRI_ATTRIB_YUV_DEPTH_RANGE_FULL_BIT)
value = EGL_YUV_DEPTH_RANGE_FULL_EXT;
else
value = EGL_NONE;
_eglSetConfigKey(&base, EGL_YUV_DEPTH_RANGE_EXT, value);
break;
case __DRI_ATTRIB_YUV_CSC_STANDARD:
if (value & __DRI_ATTRIB_YUV_CSC_STANDARD_601_BIT)
value = EGL_YUV_CSC_STANDARD_601_EXT;
else if (value & __DRI_ATTRIB_YUV_CSC_STANDARD_709_BIT)
value = EGL_YUV_CSC_STANDARD_709_EXT;
else if (value & __DRI_ATTRIB_YUV_CSC_STANDARD_2020_BIT)
value = EGL_YUV_CSC_STANDARD_2020_EXT;
else
value = EGL_NONE;
_eglSetConfigKey(&base, EGL_YUV_CSC_STANDARD_EXT, value);
break;
case __DRI_ATTRIB_YUV_PLANE_BPP:
if (value & __DRI_ATTRIB_YUV_PLANE_BPP_0_BIT)
value = EGL_YUV_PLANE_BPP_0_EXT;
else if (value & __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT)
value = EGL_YUV_PLANE_BPP_8_EXT;
else if (value & __DRI_ATTRIB_YUV_PLANE_BPP_10_BIT)
value = EGL_YUV_PLANE_BPP_10_EXT;
else
value = EGL_NONE;
_eglSetConfigKey(&base, EGL_YUV_PLANE_BPP_EXT, value);
break;
default:
key = dri2_to_egl_attribute_map[attrib];
if (key != 0)
@ -554,6 +631,15 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
}
}
if (surface_type & EGL_PBUFFER_BIT) {
if (pbuffer_pixels == 0)
pbuffer_pixels = pbuffer_width * pbuffer_height;
base.MaxPbufferWidth = pbuffer_width;
base.MaxPbufferHeight = pbuffer_height;
base.MaxPbufferPixels = pbuffer_pixels;
}
if (attr_list)
for (int i = 0; attr_list[i] != EGL_NONE; i += 2)
_eglSetConfigKey(&base, attr_list[i], attr_list[i+1]);
@ -584,6 +670,17 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
base.RenderableType = disp->ClientAPIs;
base.Conformant = disp->ClientAPIs;
/*
* We assume that if dri_config is YUV then GL_EXT_YUV_target must be
* supported, which requires OpenGL ES 3.0.
*/
if (base.ColorBufferType == EGL_YUV_BUFFER_EXT) {
base.RenderableType &= EGL_OPENGL_ES3_BIT;
base.Conformant &= EGL_OPENGL_ES3_BIT;
}
if (!base.RenderableType)
return NULL;
base.MinSwapInterval = dri2_dpy->min_swap_interval;
base.MaxSwapInterval = dri2_dpy->max_swap_interval;
@ -1024,6 +1121,13 @@ dri2_setup_screen(_EGLDisplay *disp)
disp->Extensions.EXT_image_dma_buf_import_modifiers = EGL_TRUE;
}
#endif
if (dri2_dpy->image->base.version >= 8 &&
dri2_dpy->image->createImageFromBuffer) {
disp->Extensions.IMG_cl_image = EGL_TRUE;
}
if (disp->Extensions.KHR_gl_colorspace)
disp->Extensions.EXT_image_gl_colorspace = EGL_TRUE;
}
if (dri2_dpy->flush_control)
@ -1038,6 +1142,8 @@ dri2_setup_screen(_EGLDisplay *disp)
disp->Extensions.EXT_protected_content =
dri2_renderer_query_integer(dri2_dpy,
__DRI2_RENDERER_HAS_PROTECTED_CONTEXT);
disp->Extensions.EXT_yuv_surface = EGL_TRUE;
}
void
@ -1194,6 +1300,9 @@ dri2_initialize(_EGLDisplay *disp)
case _EGL_PLATFORM_DEVICE:
ret = dri2_initialize_device(disp);
break;
case _EGL_PLATFORM_NULL:
ret = dri2_initialize_null(disp);
break;
case _EGL_PLATFORM_X11:
case _EGL_PLATFORM_XCB:
ret = dri2_initialize_x11(disp);
@ -1255,8 +1364,6 @@ dri2_display_destroy(_EGLDisplay *disp)
dri2_dpy->vtbl->close_screen_notify(disp);
dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
}
if (dri2_dpy->fd >= 0)
close(dri2_dpy->fd);
/* Don't dlclose the driver when building with the address sanitizer, so you
* get good symbols from the leak reports.
@ -1282,11 +1389,29 @@ dri2_display_destroy(_EGLDisplay *disp)
case _EGL_PLATFORM_WAYLAND:
dri2_teardown_wayland(dri2_dpy);
break;
case _EGL_PLATFORM_NULL:
dri2_teardown_null(dri2_dpy);
break;
default:
/* TODO: add teardown for other platforms */
break;
}
switch (disp->Platform) {
case _EGL_PLATFORM_DRM:
case _EGL_PLATFORM_NULL:
case _EGL_PLATFORM_WAYLAND:
case _EGL_PLATFORM_X11:
if (dri2_dpy->fd_dpy >= 0 && dri2_dpy->fd_dpy != dri2_dpy->fd)
close(dri2_dpy->fd_dpy);
break;
default:
break;
}
if (dri2_dpy->fd >= 0)
close(dri2_dpy->fd);
/* The drm platform does not create the screen/driver_configs but reuses
* the ones from the gbm device. As such the gbm itself is responsible
* for the cleanup.
@ -1937,6 +2062,26 @@ dri2_make_current(_EGLDisplay *disp, _EGLSurface *dsurf,
return EGL_TRUE;
}
static EGLint
dri2_query_context_client_version(_EGLDisplay *disp, _EGLContext *ctx)
{
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
switch (dri2_ctx->base.ClientAPI) {
case EGL_OPENGL_ES_API:
switch (dri2_ctx->base.ClientMajorVersion) {
case 2:
return dri2_renderer_query_integer(dri2_dpy,
__DRI2_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG);
default:
return 0;
}
default:
return 0;
}
}
__DRIdrawable *
dri2_surface_get_dri_drawable(_EGLSurface *surf)
{
@ -2399,6 +2544,7 @@ static const struct wl_drm_components_descriptor {
{ __DRI_IMAGE_COMPONENTS_Y_U_V, EGL_TEXTURE_Y_U_V_WL, 3 },
{ __DRI_IMAGE_COMPONENTS_Y_UV, EGL_TEXTURE_Y_UV_WL, 2 },
{ __DRI_IMAGE_COMPONENTS_Y_XUXV, EGL_TEXTURE_Y_XUXV_WL, 2 },
{ __DRI_IMAGE_COMPONENTS_EXTERNAL, EGL_TEXTURE_EXTERNAL_WL, 1 },
};
static _EGLImage *
@ -2421,6 +2567,11 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
if (!_eglParseImageAttribList(&attrs, disp, attr_list))
return NULL;
if (attrs.GLColorspace != EGL_GL_COLORSPACE_DEFAULT_EXT) {
_eglError(EGL_BAD_MATCH, "unsupported colorspace");
return NULL;
}
plane = attrs.PlaneWL;
f = buffer->driver_format;
if (plane < 0 || plane >= f->nplanes) {
@ -2465,17 +2616,13 @@ dri2_get_msc_rate_angle(_EGLDisplay *disp, _EGLSurface *surf,
return dri2_dpy->vtbl->get_msc_rate(disp, surf, numerator, denominator);
}
/**
* Set the error code after a call to
* dri2_egl_image::dri_image::createImageFromTexture.
*/
static void
dri2_create_image_khr_texture_error(int dri_error)
dri2_create_image_khr_error(int dri_error)
{
EGLint egl_error = egl_error_from_dri_image_error(dri_error);
if (egl_error != EGL_SUCCESS)
_eglError(egl_error, "dri2_create_image_khr_texture");
_eglError(egl_error, "dri2_create_image_khr");
}
static _EGLImage *
@ -2501,6 +2648,11 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
if (!_eglParseImageAttribList(&attrs, disp, attr_list))
return EGL_NO_IMAGE_KHR;
if (attrs.GLColorspace != EGL_GL_COLORSPACE_DEFAULT_EXT) {
_eglError(EGL_BAD_MATCH, "unsupported colorspace");
return EGL_NO_IMAGE_KHR;
}
switch (target) {
case EGL_GL_TEXTURE_2D_KHR:
if (!disp->Extensions.KHR_gl_texture_2D_image) {
@ -2554,7 +2706,49 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
attrs.GLTextureLevel,
&error,
NULL);
dri2_create_image_khr_texture_error(error);
dri2_create_image_khr_error(error);
if (!dri2_img->dri_image) {
free(dri2_img);
return EGL_NO_IMAGE_KHR;
}
return &dri2_img->base;
}
static _EGLImage *
dri2_create_image_img_buffer(_EGLDisplay *disp, _EGLContext *ctx,
EGLenum target,
EGLClientBuffer buffer,
const EGLint *attr_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
struct dri2_egl_image *dri2_img;
unsigned error;
switch (target) {
case EGL_CL_IMAGE_IMG:
break;
default:
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
return EGL_NO_IMAGE_KHR;
}
dri2_img = malloc(sizeof *dri2_img);
if (!dri2_img) {
_eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
return EGL_NO_IMAGE_KHR;
}
_eglInitImage(&dri2_img->base, disp);
dri2_img->dri_image =
dri2_dpy->image->createImageFromBuffer(dri2_ctx->dri_context,
target,
buffer,
&error,
NULL);
dri2_create_image_khr_error(error);
if (!dri2_img->dri_image) {
free(dri2_img);
@ -2615,6 +2809,11 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
return NULL;
}
if (attrs.GLColorspace != EGL_GL_COLORSPACE_DEFAULT_EXT) {
_eglError(EGL_BAD_MATCH, "unsupported colorspace");
return NULL;
}
switch (attrs.DRMBufferFormatMESA) {
case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
format = __DRI_IMAGE_FORMAT_ARGB8888;
@ -2758,6 +2957,7 @@ dri2_num_fourcc_format_planes(EGLint format)
case DRM_FORMAT_XBGR16161616:
case DRM_FORMAT_XBGR16161616F:
case DRM_FORMAT_ABGR16161616F:
case DRM_FORMAT_AXBXGXRX106106106106:
case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY:
@ -2770,6 +2970,7 @@ dri2_num_fourcc_format_planes(EGLint format)
case DRM_FORMAT_Y410:
case DRM_FORMAT_Y412:
case DRM_FORMAT_Y416:
case DRM_FORMAT_YVU444_PACK10_IMG:
return 1;
case DRM_FORMAT_NV12:
@ -2798,6 +2999,23 @@ dri2_num_fourcc_format_planes(EGLint format)
}
}
static int
dri2_get_srgb_fourcc(int drm_fourcc)
{
switch (drm_fourcc) {
case DRM_FORMAT_ARGB8888:
return __DRI_IMAGE_FOURCC_SARGB8888;
case DRM_FORMAT_ABGR8888:
return __DRI_IMAGE_FOURCC_SABGR8888;
case DRM_FORMAT_BGR888:
return __DRI_IMAGE_FOURCC_SBGR888;
default:
_eglLog(_EGL_DEBUG, "%s: no matching sRGB FourCC for %#x",
__func__, drm_fourcc);
return 0;
}
}
/* Returns the total number of file descriptors. Zero indicates an error. */
static unsigned
dri2_check_dma_buf_format(const _EGLImageAttribs *attrs)
@ -2955,6 +3173,7 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
int fds[DMA_BUF_MAX_PLANES];
int pitches[DMA_BUF_MAX_PLANES];
int offsets[DMA_BUF_MAX_PLANES];
int fourcc;
uint64_t modifier;
bool has_modifier = false;
unsigned error;
@ -2981,6 +3200,18 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
if (!num_fds)
return NULL;
if (attrs.GLColorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
fourcc = dri2_get_srgb_fourcc(attrs.DMABufFourCC.Value);
if (fourcc == 0) {
_eglError(EGL_BAD_MATCH, "unsupported colorspace");
return NULL;
}
} else {
assert(attrs.GLColorspace == EGL_GL_COLORSPACE_LINEAR_KHR ||
attrs.GLColorspace == EGL_GL_COLORSPACE_DEFAULT_EXT);
fourcc = attrs.DMABufFourCC.Value;
}
for (unsigned i = 0; i < num_fds; ++i) {
fds[i] = attrs.DMABufPlaneFds[i].Value;
pitches[i] = attrs.DMABufPlanePitches[i].Value;
@ -3025,7 +3256,7 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
}
dri_image =
dri2_dpy->image->createImageFromDmaBufs2(dri2_dpy->dri_screen,
attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
attrs.Width, attrs.Height, fourcc,
modifier, fds, num_fds, pitches, offsets,
attrs.DMABufYuvColorSpaceHint.Value,
attrs.DMABufSampleRangeHint.Value,
@ -3037,7 +3268,7 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
else {
dri_image =
dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
attrs.Width, attrs.Height, fourcc,
fds, num_fds, pitches, offsets,
attrs.DMABufYuvColorSpaceHint.Value,
attrs.DMABufSampleRangeHint.Value,
@ -3299,6 +3530,8 @@ dri2_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target,
case EGL_WAYLAND_BUFFER_WL:
return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list);
#endif
case EGL_CL_IMAGE_IMG:
return dri2_create_image_img_buffer(disp, ctx, target, buffer, attr_list);
default:
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
return EGL_NO_IMAGE_KHR;
@ -3391,7 +3624,7 @@ dri2_bind_wayland_display_wl(_EGLDisplay *disp, struct wl_display *wl_dpy)
if (dri2_dpy->wl_server_drm)
goto fail;
device_name = drmGetRenderDeviceNameFromFd(dri2_dpy->fd);
device_name = drmGetRenderDeviceNameFromFd(dri2_dpy->fd_dpy);
if (!device_name)
device_name = strdup(dri2_dpy->device_name);
if (!device_name)
@ -3402,6 +3635,15 @@ dri2_bind_wayland_display_wl(_EGLDisplay *disp, struct wl_display *wl_dpy)
dri2_dpy->image->base.version >= 7 &&
dri2_dpy->image->createImageFromFds != NULL)
flags |= WAYLAND_DRM_PRIME;
else if (dri2_dpy->image->base.version >= 10 &&
dri2_dpy->image->getCapabilities != NULL) {
int capabilities;
capabilities = dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen);
if ((capabilities & __DRI_IMAGE_CAP_PRIME_IMPORT) != 0 &&
(capabilities & __DRI_IMAGE_CAP_PRIME_EXPORT) != 0)
flags |= WAYLAND_DRM_PRIME;
}
dri2_dpy->wl_server_drm =
wayland_drm_init(wl_dpy, device_name,
@ -3848,6 +4090,7 @@ const _EGLDriver _eglDriver = {
.CreateContext = dri2_create_context,
.DestroyContext = dri2_destroy_context,
.MakeCurrent = dri2_make_current,
.QueryContextClientVersion = dri2_query_context_client_version,
.CreateWindowSurface = dri2_create_window_surface,
.CreatePixmapSurface = dri2_create_pixmap_surface,
.CreatePbufferSurface = dri2_create_pbuffer_surface,

View file

@ -78,6 +78,10 @@ struct zwp_linux_dmabuf_feedback_v1;
#endif /* HAVE_ANDROID_PLATFORM */
#ifdef HAVE_NULL_PLATFORM
#include <xf86drmMode.h>
#endif
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldevice.h"
@ -95,6 +99,25 @@ struct zwp_linux_dmabuf_feedback_v1;
struct wl_buffer;
#ifdef HAVE_NULL_PLATFORM
struct display_output {
bool in_use;
bool in_fence_supported;
uint32_t connector_id;
drmModePropertyRes **connector_prop_res;
uint32_t crtc_id;
drmModePropertyRes **crtc_prop_res;
uint32_t plane_id;
drmModePropertyRes **plane_prop_res;
drmModeModeInfo mode;
uint32_t mode_blob_id;
unsigned formats;
drmModeAtomicReq *atomic_state;
uint32_t in_formats_id;
struct u_vector modifiers;
};
#endif
struct dri2_egl_display_vtbl {
/* mandatory on Wayland, unused otherwise */
int (*authenticate)(_EGLDisplay *disp, uint32_t id);
@ -244,6 +267,7 @@ struct dri2_egl_display
const __DRIconfigOptionsExtension *configOptions;
const __DRImutableRenderBufferDriverExtension *mutable_render_buffer;
int fd;
int fd_dpy;
/* dri2_initialize/dri2_terminate increment/decrement this count, so does
* dri2_make_current (tracks if there are active contexts/surfaces). */
@ -296,6 +320,13 @@ struct dri2_egl_display
char *device_name;
#endif
#ifdef HAVE_NULL_PLATFORM
bool atomic_enabled;
bool in_formats_enabled;
bool async_flip_enabled;
struct display_output output;
#endif
#ifdef HAVE_ANDROID_PLATFORM
const gralloc_module_t *gralloc;
/* gralloc vendor usage bit for front rendering */
@ -312,6 +343,26 @@ struct dri2_egl_context
__DRIcontext *dri_context;
};
#define DRI2_SURFACE_NUM_COLOR_BUFFERS 4
#ifdef HAVE_NULL_PLATFORM
struct swap_queue_elem
{
uint32_t swap_interval;
uint32_t back_id;
uint32_t fb_id;
int kms_in_fence_fd;
};
enum {
SWAP_IDLE,
SWAP_FLIP,
SWAP_VBLANK,
SWAP_POLL,
SWAP_ERROR,
};
#endif
struct dri2_egl_surface
{
_EGLSurface base;
@ -340,24 +391,43 @@ struct dri2_egl_surface
struct zwp_linux_dmabuf_feedback_v1 *wl_dmabuf_feedback;
struct dmabuf_feedback dmabuf_feedback, pending_dmabuf_feedback;
bool compositor_using_another_device;
int format;
bool resized;
bool received_dmabuf_feedback;
#endif
#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_NULL_PLATFORM)
int format;
#endif
#ifdef HAVE_DRM_PLATFORM
struct gbm_dri_surface *gbm_surf;
#endif
#if defined(HAVE_NULL_PLATFORM)
/*
* Protects swap_queue_idx_head, swap_queue_idx_tail and
* color_buffers.locked.
*/
pthread_mutex_t mutex;
pthread_cond_t swap_queue_cond;
pthread_cond_t swap_unlock_buffer_cond;
int swap_queue_idx_head;
int swap_queue_idx_tail;
pthread_t swap_queue_processor;
#endif
/* EGL-owned buffers */
__DRIbuffer *local_buffers[__DRI_BUFFER_COUNT];
#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM)
#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM) || \
defined(HAVE_NULL_PLATFORM)
struct {
#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_NULL_PLATFORM)
__DRIimage *dri_image;
#endif
#ifdef HAVE_WAYLAND_PLATFORM
struct wl_buffer *wl_buffer;
bool wl_release;
__DRIimage *dri_image;
/* for is_different_gpu case. NULL else */
__DRIimage *linear_copy;
/* for swrast */
@ -366,10 +436,17 @@ struct dri2_egl_surface
#endif
#ifdef HAVE_DRM_PLATFORM
struct gbm_bo *bo;
#endif
#ifdef HAVE_NULL_PLATFORM
uint32_t fb_id;
#endif
bool locked;
int age;
} color_buffers[4], *back, *current;
#ifdef HAVE_NULL_PLATFORM
} color_buffers[DRI2_SURFACE_NUM_COLOR_BUFFERS], *back, *current, front_buffer;
#else
} color_buffers[DRI2_SURFACE_NUM_COLOR_BUFFERS], *back, *current;
#endif
#endif
#ifdef HAVE_ANDROID_PLATFORM
@ -397,6 +474,24 @@ struct dri2_egl_surface
/* surfaceless and device */
__DRIimage *front;
unsigned int visual;
#ifdef HAVE_DRM_PLATFORM
struct gbm_bo *front_bo;
#endif
#ifdef HAVE_WAYLAND_PLATFORM
void *swrast_front;
#endif
#ifdef HAVE_NULL_PLATFORM
struct swap_queue_elem swap_queue[DRI2_SURFACE_NUM_COLOR_BUFFERS];
struct swap_queue_elem *swap_data;
int swap_state;
bool mutex_init;
bool cond_init;
bool front_render_enabled;
bool front_render_init;
bool cond_init_unlock_buffer;
#endif
int out_fence_fd;
EGLBoolean enable_out_fence;
@ -588,6 +683,21 @@ dri2_initialize_android(_EGLDisplay *disp)
EGLBoolean
dri2_initialize_surfaceless(_EGLDisplay *disp);
#ifdef HAVE_NULL_PLATFORM
EGLBoolean
dri2_initialize_null(_EGLDisplay *disp);
void
dri2_teardown_null(struct dri2_egl_display *dri2_dpy);
#else
static inline EGLBoolean
dri2_initialize_null(_EGLDisplay *disp)
{
return _eglError(EGL_NOT_INITIALIZED, "Null platform not built");
}
static inline void
dri2_teardown_null(struct dri2_egl_display *dri2_dpy) {}
#endif
EGLBoolean
dri2_initialize_device(_EGLDisplay *disp);
static inline void

View file

@ -41,6 +41,38 @@
#include "egl_dri2.h"
#include "loader.h"
static bool
dri2_drm_alloc_front_image(struct dri2_egl_surface *dri2_surf)
{
if (!dri2_surf->front_bo) {
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
dri2_surf->front_bo = gbm_bo_create(&dri2_dpy->gbm_dri->base,
surf->base.v0.width,
surf->base.v0.height,
surf->base.v0.format,
surf->base.v0.flags);
if (!dri2_surf->front_bo) {
_eglError(EGL_BAD_ALLOC, "failed to allocate front buffer");
return false;
}
}
return true;
}
static void
dri2_drm_free_front_image(struct dri2_egl_surface *dri2_surf)
{
if (dri2_surf->front_bo) {
gbm_bo_destroy(dri2_surf->front_bo);
dri2_surf->front_bo = NULL;
}
}
static struct gbm_bo *
lock_front_buffer(struct gbm_surface *_surf)
{
@ -138,8 +170,8 @@ dri2_drm_config_is_compatible(struct dri2_egl_display *dri2_dpy,
}
static _EGLSurface *
dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
void *native_surface, const EGLint *attrib_list)
dri2_drm_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
void *native_surface, const EGLint *attrib_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
@ -154,11 +186,25 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf,
if (!dri2_init_surface(&dri2_surf->base, disp, type, conf,
attrib_list, false, native_surface))
goto cleanup_surf;
config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
if (type == EGL_PBUFFER_BIT) {
struct gbm_device *gbm = disp->PlatformDisplay;
_EGLSurface *surf = &dri2_surf->base;
assert(!surface);
surface = gbm_surface_create(gbm, surf->Width, surf->Height,
conf->NativeVisualID, GBM_BO_USE_RENDERING);
if (!surface) {
_eglError(EGL_BAD_ALLOC, "Failed to allocate pbuffer GBM surface");
goto cleanup_surf;
}
}
config = dri2_get_dri_config(dri2_conf, type,
dri2_surf->base.GLColorspace);
if (!config) {
@ -183,11 +229,22 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
return &dri2_surf->base;
cleanup_surf:
if (type == EGL_PBUFFER_BIT && surface != NULL)
gbm_surface_destroy(surface);
free(dri2_surf);
return NULL;
}
static _EGLSurface *
dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
void *native_surface, const EGLint *attrib_list)
{
return dri2_drm_create_surface(disp, EGL_WINDOW_BIT, conf,
native_surface, attrib_list);
}
static _EGLSurface *
dri2_drm_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
void *native_window, const EGLint *attrib_list)
@ -202,6 +259,14 @@ dri2_drm_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
static _EGLSurface *
dri2_drm_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf,
const EGLint *attrib_list)
{
return dri2_drm_create_surface(disp, EGL_PBUFFER_BIT, conf,
NULL, attrib_list);
}
static EGLBoolean
dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
{
@ -217,6 +282,11 @@ dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
dri2_egl_surface_free_local_buffers(dri2_surf);
dri2_drm_free_front_image(dri2_surf);
if (surf->Type == EGL_PBUFFER_BIT)
gbm_surface_destroy(&dri2_surf->gbm_surf->base);
dri2_fini_surface(surf);
free(surf);
@ -402,12 +472,27 @@ dri2_drm_image_get_buffers(__DRIdrawable *driDrawable,
struct dri2_egl_surface *dri2_surf = loaderPrivate;
struct gbm_dri_bo *bo;
if (get_back_bo(dri2_surf) < 0)
return 0;
buffers->image_mask = 0;
buffers->front = NULL;
buffers->back = NULL;
bo = gbm_dri_bo(dri2_surf->back->bo);
buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
buffers->back = bo->image;
if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
if (!dri2_drm_alloc_front_image(dri2_surf))
return 0;
bo = gbm_dri_bo(dri2_surf->front_bo);
buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
buffers->front = bo->image;
}
if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
if (get_back_bo(dri2_surf) < 0)
return 0;
bo = gbm_dri_bo(dri2_surf->back->bo);
buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
buffers->back = bo->image;
}
return 1;
}
@ -425,6 +510,9 @@ dri2_drm_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
if (dri2_surf->base.Type != EGL_WINDOW_BIT)
return EGL_TRUE;
if (!dri2_dpy->flush) {
dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
return EGL_TRUE;
@ -507,7 +595,7 @@ dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
return drmAuthMagic(dri2_dpy->fd, id);
return drmAuthMagic(dri2_dpy->fd_dpy, id);
}
static void
@ -648,7 +736,8 @@ drm_add_configs_for_visuals(_EGLDisplay *disp)
};
dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
config_count + 1, EGL_WINDOW_BIT, attr_list, NULL, NULL);
config_count + 1, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
attr_list, NULL, NULL);
if (dri2_conf) {
if (dri2_conf->base.ConfigID == config_count + 1)
config_count++;
@ -672,6 +761,7 @@ static const struct dri2_egl_display_vtbl dri2_drm_display_vtbl = {
.authenticate = dri2_drm_authenticate,
.create_window_surface = dri2_drm_create_window_surface,
.create_pixmap_surface = dri2_drm_create_pixmap_surface,
.create_pbuffer_surface = dri2_drm_create_pbuffer_surface,
.destroy_surface = dri2_drm_destroy_surface,
.create_image = dri2_drm_create_image_khr,
.swap_buffers = dri2_drm_swap_buffers,
@ -692,6 +782,7 @@ dri2_initialize_drm(_EGLDisplay *disp)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
dri2_dpy->fd = -1;
dri2_dpy->fd_dpy = -1;
disp->DriverData = (void *) dri2_dpy;
gbm = disp->PlatformDisplay;
@ -699,16 +790,16 @@ dri2_initialize_drm(_EGLDisplay *disp)
char buf[64];
int n = snprintf(buf, sizeof(buf), DRM_DEV_NAME, DRM_DIR_NAME, 0);
if (n != -1 && n < sizeof(buf))
dri2_dpy->fd = loader_open_device(buf);
gbm = gbm_create_device(dri2_dpy->fd);
dri2_dpy->fd_dpy = loader_open_device(buf);
gbm = gbm_create_device(dri2_dpy->fd_dpy);
if (gbm == NULL) {
err = "DRI2: failed to create gbm device";
goto cleanup;
}
dri2_dpy->own_device = true;
} else {
dri2_dpy->fd = os_dupfd_cloexec(gbm_device_get_fd(gbm));
if (dri2_dpy->fd < 0) {
dri2_dpy->fd_dpy = os_dupfd_cloexec(gbm_device_get_fd(gbm));
if (dri2_dpy->fd_dpy < 0) {
err = "DRI2: failed to fcntl() existing gbm device";
goto cleanup;
}
@ -720,6 +811,12 @@ dri2_initialize_drm(_EGLDisplay *disp)
goto cleanup;
}
if (gbm_dri_device_get_fd(dri2_dpy->gbm_dri) ==
gbm_device_get_fd(gbm))
dri2_dpy->fd = dri2_dpy->fd_dpy;
else
dri2_dpy->fd = os_dupfd_cloexec(gbm_dri_device_get_fd(dri2_dpy->gbm_dri));
dev = _eglAddDevice(dri2_dpy->fd, dri2_dpy->gbm_dri->software);
if (!dev) {
err = "DRI2: failed to find EGLDevice";
@ -785,7 +882,7 @@ dri2_initialize_drm(_EGLDisplay *disp)
disp->Extensions.EXT_buffer_age = EGL_TRUE;
#ifdef HAVE_WAYLAND_PLATFORM
dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd);
dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd_dpy);
#endif
dri2_set_WL_bind_wayland_display(disp);

File diff suppressed because it is too large Load diff

View file

@ -44,6 +44,7 @@
#include "loader.h"
#include "util/u_vector.h"
#include "util/anon_file.h"
#include "util/os_file.h"
#include "eglglobals.h"
#include "kopper_interface.h"
@ -151,6 +152,13 @@ static const struct dri2_wl_visual {
{ 11, 5, 0, -1 },
{ 5, 6, 5, 0 },
},
{
"YUYV",
WL_DRM_FORMAT_YUYV, WL_SHM_FORMAT_YUYV,
__DRI_IMAGE_FORMAT_YUYV, __DRI_IMAGE_FORMAT_NONE, 32,
{ -1, -1, -1, -1 },
{ 0, 0, 0, 0 },
},
};
static int
@ -385,6 +393,9 @@ resize_callback(struct wl_egl_window *wl_win, void *data)
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
dri2_surf->dx = wl_win->dx;
dri2_surf->dy = wl_win->dy;
if (dri2_surf->base.Width == wl_win->width &&
dri2_surf->base.Height == wl_win->height)
return;
@ -787,6 +798,99 @@ dri2_wl_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
static _EGLSurface *
dri2_wl_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf,
const EGLint *attrib_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
struct dri2_egl_surface *dri2_surf;
int visual_idx;
const __DRIconfig *config;
dri2_surf = calloc(1, sizeof *dri2_surf);
if (!dri2_surf) {
_eglError(EGL_BAD_ALLOC, "dri2_create_surface");
return NULL;
}
if (!dri2_init_surface(&dri2_surf->base, disp, EGL_PBUFFER_BIT, conf,
attrib_list, false, NULL))
goto cleanup_surf;
config = dri2_get_dri_config(dri2_conf, EGL_PBUFFER_BIT,
dri2_surf->base.GLColorspace);
if (!config) {
_eglError(EGL_BAD_MATCH, "Unsupported surfacetype/colorspace configuration");
goto cleanup_surf;
}
visual_idx = dri2_wl_visual_idx_from_config(dri2_dpy, config, false);
assert(visual_idx != -1);
if (dri2_dpy->wl_dmabuf || dri2_dpy->wl_drm) {
dri2_surf->format = dri2_wl_visuals[visual_idx].wl_drm_format;
} else {
assert(dri2_dpy->wl_shm);
dri2_surf->format = dri2_wl_visuals[visual_idx].wl_shm_format;
}
if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf))
goto cleanup_surf;
return &dri2_surf->base;
cleanup_surf:
free(dri2_surf);
return NULL;
}
static int
allocate_front_buffer(struct dri2_egl_display *dri2_dpy,
struct dri2_egl_surface *dri2_surf,
EGLBoolean need_name)
{
int use_flags = need_name ? __DRI_IMAGE_USE_SHARE : 0;
int visual_idx;
unsigned int dri_image_format;
visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
assert(visual_idx != -1);
dri_image_format = dri2_wl_visuals[visual_idx].dri_image_format;
if (!dri2_surf->front)
dri2_surf->front = dri2_dpy->image->createImage(dri2_dpy->dri_screen,
dri2_surf->base.Width,
dri2_surf->base.Height,
dri_image_format,
use_flags,
NULL);
if (!dri2_surf->front) {
_eglError(EGL_BAD_ALLOC, "failed to allocate front buffer");
return -1;
}
return 0;
}
static void
free_front_buffer(struct dri2_egl_display *dri2_dpy,
struct dri2_egl_surface *dri2_surf)
{
if (dri2_surf->front) {
dri2_dpy->image->destroyImage(dri2_surf->front);
dri2_surf->front = NULL;
}
}
static void
swrast_free_front_buffer(struct dri2_egl_surface *dri2_surf)
{
free(dri2_surf->swrast_front);
dri2_surf->swrast_front = NULL;
}
/**
* Called via eglDestroySurface(), drv->DestroySurface().
*/
@ -813,6 +917,9 @@ dri2_wl_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
if (dri2_dpy->dri2)
dri2_egl_surface_free_local_buffers(dri2_surf);
free_front_buffer(dri2_dpy, dri2_surf);
swrast_free_front_buffer(dri2_surf);
if (dri2_surf->throttle_callback)
wl_callback_destroy(dri2_surf->throttle_callback);
@ -822,8 +929,10 @@ dri2_wl_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
dri2_surf->wl_win->destroy_window_callback = NULL;
}
wl_proxy_wrapper_destroy(dri2_surf->wl_surface_wrapper);
wl_proxy_wrapper_destroy(dri2_surf->wl_dpy_wrapper);
if (dri2_surf->wl_surface_wrapper)
wl_proxy_wrapper_destroy(dri2_surf->wl_surface_wrapper);
if (dri2_surf->wl_dpy_wrapper)
wl_proxy_wrapper_destroy(dri2_surf->wl_dpy_wrapper);
if (dri2_surf->wl_drm_wrapper)
wl_proxy_wrapper_destroy(dri2_surf->wl_drm_wrapper);
if (dri2_surf->wl_dmabuf_feedback) {
@ -831,7 +940,8 @@ dri2_wl_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
dmabuf_feedback_fini(&dri2_surf->dmabuf_feedback);
dmabuf_feedback_fini(&dri2_surf->pending_dmabuf_feedback);
}
wl_event_queue_destroy(dri2_surf->wl_queue);
if (dri2_surf->wl_queue)
wl_event_queue_destroy(dri2_surf->wl_queue);
dri2_fini_surface(surf);
free(surf);
@ -852,12 +962,22 @@ dri2_wl_swap_interval(_EGLDisplay *disp, _EGLSurface *surf, EGLint interval)
}
static void
dri2_wl_release_buffers(struct dri2_egl_surface *dri2_surf)
dri2_wl_release_buffers(struct dri2_egl_surface *dri2_surf,
bool release_non_current,
bool release_current)
{
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
if (dri2_surf->current == &dri2_surf->color_buffers[i]) {
if (!release_current)
continue;
} else {
if (!release_non_current)
continue;
}
if (dri2_surf->color_buffers[i].wl_buffer) {
if (dri2_surf->color_buffers[i].locked) {
dri2_surf->color_buffers[i].wl_release = true;
@ -882,6 +1002,9 @@ dri2_wl_release_buffers(struct dri2_egl_surface *dri2_surf)
if (dri2_dpy->dri2)
dri2_egl_surface_free_local_buffers(dri2_surf);
if (release_current)
dri2_surf->current = NULL;
}
static void
@ -904,7 +1027,7 @@ create_dri_image_diff_gpu(struct dri2_egl_surface *dri2_surf,
&linear_mod, 1, NULL);
}
static void
static bool
create_dri_image_from_dmabuf_feedback(struct dri2_egl_surface *dri2_surf,
unsigned int dri_image_format, uint32_t use_flags)
{
@ -917,7 +1040,7 @@ create_dri_image_from_dmabuf_feedback(struct dri2_egl_surface *dri2_surf,
/* We don't have valid dma-buf feedback, so return */
if (dri2_surf->dmabuf_feedback.main_device == 0)
return;
return false;
visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
assert(visual_idx != -1);
@ -961,11 +1084,13 @@ create_dri_image_from_dmabuf_feedback(struct dri2_egl_surface *dri2_surf,
modifiers, num_modifiers, NULL);
if (dri2_surf->back->dri_image)
return;
return num_modifiers != 0;
}
return false;
}
static void
static bool
create_dri_image(struct dri2_egl_surface *dri2_surf,
unsigned int dri_image_format, uint32_t use_flags)
{
@ -997,10 +1122,13 @@ create_dri_image(struct dri2_egl_surface *dri2_surf,
dri_image_format,
dri2_dpy->is_different_gpu ? 0 : use_flags,
modifiers, num_modifiers, NULL);
return num_modifiers != 0;
}
static int
get_back_bo(struct dri2_egl_surface *dri2_surf)
get_back_bo(struct dri2_egl_surface *dri2_surf, bool allow_preserve,
bool preserve_current)
{
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
@ -1008,6 +1136,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
int visual_idx;
unsigned int dri_image_format;
unsigned int linear_dri_image_format;
bool have_modifiers = false;
visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
assert(visual_idx != -1);
@ -1067,23 +1196,46 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
use_flags |= __DRI_IMAGE_USE_PROTECTED;
}
if (dri2_dpy->is_different_gpu && dri2_surf->back->linear_copy == NULL) {
create_dri_image_diff_gpu(dri2_surf, linear_dri_image_format, use_flags);
if (dri2_surf->back->linear_copy == NULL)
return -1;
}
if (dri2_surf->back->dri_image == NULL) {
if (dri2_surf->wl_dmabuf_feedback)
create_dri_image_from_dmabuf_feedback(dri2_surf, dri_image_format, use_flags);
have_modifiers = create_dri_image_from_dmabuf_feedback(dri2_surf, dri_image_format, use_flags);
if (dri2_surf->back->dri_image == NULL)
create_dri_image(dri2_surf, dri_image_format, use_flags);
have_modifiers = create_dri_image(dri2_surf, dri_image_format, use_flags);
dri2_surf->back->age = 0;
}
if (dri2_surf->back->dri_image == NULL)
return -1;
if (dri2_dpy->is_different_gpu && !have_modifiers &&
dri2_surf->back->linear_copy == NULL) {
create_dri_image_diff_gpu(dri2_surf, linear_dri_image_format, use_flags);
if (dri2_surf->back->linear_copy == NULL)
return -1;
}
if ((allow_preserve || preserve_current) &&
dri2_surf->base.SwapBehavior == EGL_BUFFER_PRESERVED &&
dri2_surf->current && dri2_surf->back->age != 1) {
_EGLContext *ctx = _eglGetCurrentContext();
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
if (dri2_ctx) {
dri2_dpy->image->blitImage(dri2_ctx->dri_context,
dri2_surf->back->dri_image,
dri2_surf->current->dri_image,
0, 0, dri2_surf->base.Width,
dri2_surf->base.Height,
0, 0, dri2_surf->base.Width,
dri2_surf->base.Height,
__BLIT_FLAG_FLUSH);
dri2_surf->back->age = 1;
if (!preserve_current)
dri2_surf->current = NULL;
}
}
dri2_surf->back->locked = true;
return 0;
@ -1091,23 +1243,28 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
static void
back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
bo_to_dri_buffer(struct dri2_egl_display *dri2_dpy, unsigned int attachment,
__DRIimage *image, __DRIbuffer *buffer)
{
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
__DRIimage *image;
int name, pitch;
image = dri2_surf->back->dri_image;
int name, pitch, format;
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NAME, &name);
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format);
buffer->attachment = __DRI_BUFFER_BACK_LEFT;
buffer->attachment = attachment;
buffer->name = name;
buffer->pitch = pitch;
buffer->cpp = 4;
buffer->flags = 0;
switch (format) {
case __DRI_IMAGE_FORMAT_RGB565:
buffer->cpp = 2;
break;
default:
buffer->cpp = 4;
break;
}
}
/* Value chosen empirically as a compromise between avoiding frequent
@ -1116,11 +1273,31 @@ back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
*/
#define BUFFER_TRIM_AGE_HYSTERESIS 20
static int
update_buffers(struct dri2_egl_surface *dri2_surf)
static void
back_bo_to_dri_buffer(struct dri2_egl_display *dri2_dpy,
struct dri2_egl_surface *dri2_surf,
__DRIbuffer *buffer)
{
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
bo_to_dri_buffer(dri2_dpy, __DRI_BUFFER_BACK_LEFT,
dri2_surf->back->dri_image, buffer);
}
static void
front_bo_to_dri_buffer(struct dri2_egl_display *dri2_dpy,
struct dri2_egl_surface *dri2_surf,
__DRIbuffer *buffer)
{
bo_to_dri_buffer(dri2_dpy, __DRI_BUFFER_FRONT_LEFT,
dri2_surf->front, buffer);
}
static int
update_buffers(struct dri2_egl_display *dri2_dpy,
struct dri2_egl_surface *dri2_surf,
bool allow_preserve)
{
bool preserve_current = false;
int res;
if (dri2_surf->wl_win &&
(dri2_surf->base.Width != dri2_surf->wl_win->width ||
@ -1128,17 +1305,23 @@ update_buffers(struct dri2_egl_surface *dri2_surf)
dri2_surf->base.Width = dri2_surf->wl_win->width;
dri2_surf->base.Height = dri2_surf->wl_win->height;
dri2_surf->dx = dri2_surf->wl_win->dx;
dri2_surf->dy = dri2_surf->wl_win->dy;
}
if (dri2_surf->resized || dri2_surf->received_dmabuf_feedback) {
dri2_wl_release_buffers(dri2_surf);
preserve_current = !dri2_surf->resized &&
dri2_surf->base.SwapBehavior == EGL_BUFFER_PRESERVED;
dri2_wl_release_buffers(dri2_surf, true, !preserve_current);
dri2_surf->resized = false;
dri2_surf->received_dmabuf_feedback = false;
}
if (get_back_bo(dri2_surf) < 0) {
res = get_back_bo(dri2_surf, allow_preserve, preserve_current);
if (preserve_current)
dri2_wl_release_buffers(dri2_surf, false, true);
if (res < 0) {
_eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
return -1;
}
@ -1154,7 +1337,7 @@ update_buffers(struct dri2_egl_surface *dri2_surf)
dri2_surf->color_buffers[i].age > BUFFER_TRIM_AGE_HYSTERESIS) {
wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
if (dri2_dpy->is_different_gpu)
if (dri2_surf->color_buffers[i].linear_copy)
dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].linear_copy);
dri2_surf->color_buffers[i].wl_buffer = NULL;
dri2_surf->color_buffers[i].dri_image = NULL;
@ -1167,12 +1350,14 @@ update_buffers(struct dri2_egl_surface *dri2_surf)
}
static int
update_buffers_if_needed(struct dri2_egl_surface *dri2_surf)
update_buffers_if_needed(struct dri2_egl_display *dri2_dpy,
struct dri2_egl_surface *dri2_surf,
bool allow_preserve)
{
if (dri2_surf->back != NULL)
return 0;
return update_buffers(dri2_surf);
return update_buffers(dri2_dpy, dri2_surf, allow_preserve);
}
static __DRIbuffer *
@ -1182,17 +1367,25 @@ dri2_wl_get_buffers_with_format(__DRIdrawable * driDrawable,
int *out_count, void *loaderPrivate)
{
struct dri2_egl_surface *dri2_surf = loaderPrivate;
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
int i, j;
if (update_buffers_if_needed(dri2_surf) < 0)
return NULL;
for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
__DRIbuffer *local;
switch (attachments[i]) {
case __DRI_BUFFER_BACK_LEFT:
back_bo_to_dri_buffer(dri2_surf, &dri2_surf->buffers[j]);
if (update_buffers_if_needed(dri2_dpy, dri2_surf, true) < 0)
return NULL;
back_bo_to_dri_buffer(dri2_dpy, dri2_surf, &dri2_surf->buffers[j]);
break;
case __DRI_BUFFER_FRONT_LEFT:
if (allocate_front_buffer(dri2_dpy, dri2_surf, EGL_TRUE) < 0)
return NULL;
front_bo_to_dri_buffer(dri2_dpy, dri2_surf, &dri2_surf->buffers[j]);
break;
default:
local = dri2_egl_surface_alloc_local_buffer(dri2_surf, attachments[i],
@ -1262,12 +1455,41 @@ image_get_buffers(__DRIdrawable *driDrawable,
struct __DRIimageList *buffers)
{
struct dri2_egl_surface *dri2_surf = loaderPrivate;
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
if (update_buffers_if_needed(dri2_surf) < 0)
return 0;
buffers->image_mask = 0;
buffers->front = NULL;
buffers->back = NULL;
buffers->prev = NULL;
buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
buffers->back = dri2_surf->back->dri_image;
if (buffer_mask & __DRI_IMAGE_BUFFER_BACK)
{
bool buffer_prev = buffer_mask & __DRI_IMAGE_BUFFER_PREV;
if (update_buffers_if_needed(dri2_dpy, dri2_surf, !buffer_prev) < 0)
return 0;
buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
buffers->back = dri2_surf->back->dri_image;
if (buffer_prev && dri2_surf->current &&
dri2_surf->base.SwapBehavior == EGL_BUFFER_PRESERVED)
{
buffers->image_mask |= __DRI_IMAGE_BUFFER_PREV;
buffers->prev = dri2_surf->current->dri_image;
dri2_surf->back->age = 1;
}
}
if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT)
{
if (allocate_front_buffer(dri2_dpy, dri2_surf, EGL_FALSE) < 0)
return 0;
buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
buffers->front = dri2_surf->front;
}
return 1;
}
@ -1284,6 +1506,7 @@ dri2_wl_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
{
switch (cap) {
case DRI_LOADER_CAP_FP16:
case DRI_LOADER_CAP_YUV_SURFACE_IMG:
return 1;
case DRI_LOADER_CAP_RGBA_ORDERING:
return 1;
@ -1292,21 +1515,32 @@ dri2_wl_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
}
}
static int
dri2_wl_get_display_fd(void *loaderPrivate)
{
_EGLDisplay *disp = loaderPrivate;
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
return dri2_dpy->fd_dpy;
}
static const __DRIdri2LoaderExtension dri2_loader_extension = {
.base = { __DRI_DRI2_LOADER, 4 },
.base = { __DRI_DRI2_LOADER, 6 },
.getBuffers = dri2_wl_get_buffers,
.flushFrontBuffer = dri2_wl_flush_front_buffer,
.getBuffersWithFormat = dri2_wl_get_buffers_with_format,
.getCapability = dri2_wl_get_capability,
.getDisplayFD = dri2_wl_get_display_fd,
};
static const __DRIimageLoaderExtension image_loader_extension = {
.base = { __DRI_IMAGE_LOADER, 2 },
.base = { __DRI_IMAGE_LOADER, 5 },
.getBuffers = image_get_buffers,
.flushFrontBuffer = dri2_wl_flush_front_buffer,
.getCapability = dri2_wl_get_capability,
.getDisplayFD = dri2_wl_get_display_fd,
};
static void
@ -1515,6 +1749,9 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
if (draw->Type != EGL_WINDOW_BIT)
return EGL_TRUE;
if (!dri2_surf->wl_win)
return _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_swap_buffers");
@ -1540,7 +1777,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
/* Make sure we have a back buffer in case we're swapping without ever
* rendering. */
if (update_buffers_if_needed(dri2_surf) < 0)
if (update_buffers_if_needed(dri2_dpy, dri2_surf, true) < 0)
return _eglError(EGL_BAD_ALLOC, "dri2_swap_buffers");
if (draw->SwapInterval > 0) {
@ -1557,7 +1794,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
if (!dri2_surf->current->wl_buffer) {
__DRIimage *image;
if (dri2_dpy->is_different_gpu)
if (dri2_surf->current->linear_copy)
image = dri2_surf->current->linear_copy;
else
image = dri2_surf->current->dri_image;
@ -1584,11 +1821,12 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
/* If the compositor doesn't support damage_buffer, we deliberately
* ignore the damage region and post maximum damage, due to
* https://bugs.freedesktop.org/78190 */
if (!n_rects || !try_damage_buffer(dri2_surf, rects, n_rects))
if (dri2_dpy->is_different_gpu ||
!n_rects || !try_damage_buffer(dri2_surf, rects, n_rects))
wl_surface_damage(dri2_surf->wl_surface_wrapper,
0, 0, INT32_MAX, INT32_MAX);
if (dri2_dpy->is_different_gpu) {
if (dri2_surf->current->linear_copy) {
_EGLContext *ctx = _eglGetCurrentContext();
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
dri2_dpy->image->blitImage(dri2_ctx->dri_context,
@ -1597,7 +1835,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
0, 0, dri2_surf->base.Width,
dri2_surf->base.Height,
0, 0, dri2_surf->base.Width,
dri2_surf->base.Height, 0);
dri2_surf->base.Height, __BLIT_FLAG_FLUSH);
}
wl_surface_commit(dri2_surf->wl_surface_wrapper);
@ -1620,9 +1858,13 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
static EGLint
dri2_wl_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
if (update_buffers_if_needed(dri2_surf) < 0) {
if (surface->Type != EGL_WINDOW_BIT)
return 0;
if (update_buffers_if_needed(dri2_dpy, dri2_surf, true) < 0) {
_eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
return -1;
}
@ -1977,6 +2219,7 @@ static const struct dri2_egl_display_vtbl dri2_wl_display_vtbl = {
.authenticate = dri2_wl_authenticate,
.create_window_surface = dri2_wl_create_window_surface,
.create_pixmap_surface = dri2_wl_create_pixmap_surface,
.create_pbuffer_surface = dri2_wl_create_pbuffer_surface,
.destroy_surface = dri2_wl_destroy_surface,
.swap_interval = dri2_wl_swap_interval,
.create_image = dri2_create_image_khr,
@ -2003,11 +2246,12 @@ static const __DRIextension *image_loader_extensions[] = {
};
static EGLBoolean
dri2_wl_add_configs_for_visuals(_EGLDisplay *disp)
dri2_wl_add_configs_for_visuals(_EGLDisplay *disp, bool allow_preserve)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
unsigned int format_count[ARRAY_SIZE(dri2_wl_visuals)] = { 0 };
unsigned int count = 0;
EGLint surface_type;
bool assigned;
for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) {
@ -2019,8 +2263,16 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp)
if (!BITSET_TEST(dri2_dpy->formats.formats_bitmap, j))
continue;
surface_type = EGL_WINDOW_BIT;
if (dri2_wl_visuals[j].wl_drm_format != WL_DRM_FORMAT_YUYV)
surface_type |= EGL_PBUFFER_BIT;
if (allow_preserve &&
dri2_dpy->image->base.version >= 9 && dri2_dpy->image->blitImage)
surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
count + 1, EGL_WINDOW_BIT, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes);
count + 1, surface_type, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes);
if (dri2_conf) {
if (dri2_conf->base.ConfigID == count + 1)
count++;
@ -2083,12 +2335,14 @@ dri2_initialize_wayland_drm(_EGLDisplay *disp)
{
_EGLDevice *dev;
struct dri2_egl_display *dri2_dpy;
int fd_old;
dri2_dpy = calloc(1, sizeof *dri2_dpy);
if (!dri2_dpy)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
dri2_dpy->fd = -1;
dri2_dpy->fd_dpy = -1;
disp->DriverData = (void *) dri2_dpy;
if (dri2_wl_formats_init(&dri2_dpy->formats) < 0)
@ -2160,8 +2414,20 @@ dri2_initialize_wayland_drm(_EGLDisplay *disp)
goto cleanup;
}
fd_old = dri2_dpy->fd;
dri2_dpy->fd_dpy = os_dupfd_cloexec(dri2_dpy->fd);
dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd,
&dri2_dpy->is_different_gpu);
if (dri2_dpy->fd == fd_old) {
if (dri2_dpy->fd_dpy != -1)
close(dri2_dpy->fd_dpy);
dri2_dpy->fd_dpy = dri2_dpy->fd;
} else if (dri2_dpy->fd_dpy == -1) {
_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to dup display FD");
goto cleanup;
}
dev = _eglAddDevice(dri2_dpy->fd, false);
if (!dev) {
_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice");
@ -2241,7 +2507,7 @@ dri2_initialize_wayland_drm(_EGLDisplay *disp)
goto cleanup;
}
if (!dri2_wl_add_configs_for_visuals(disp)) {
if (!dri2_wl_add_configs_for_visuals(disp, true)) {
_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to add configs");
goto cleanup;
}
@ -2282,6 +2548,23 @@ dri2_wl_swrast_get_stride_for_format(int format, int w)
return w * (dri2_wl_visuals[visual_idx].bpp / 8);
}
static EGLBoolean
swrast_allocate_local_buffer(int format, int w, int h, void **data)
{
int stride, size_map;
void *data_map;
stride = dri2_wl_swrast_get_stride_for_format(format, w);
size_map = h * stride;
data_map = malloc(size_map);
if (!data_map)
return EGL_FALSE;
*data = data_map;
return EGL_TRUE;
}
static EGLBoolean
dri2_wl_swrast_allocate_buffer(struct dri2_egl_surface *dri2_surf,
int format, int w, int h,
@ -2336,7 +2619,7 @@ swrast_update_buffers(struct dri2_egl_surface *dri2_surf)
dri2_surf->base.Height != dri2_surf->wl_win->height)) {
if (!zink)
dri2_wl_release_buffers(dri2_surf);
dri2_wl_release_buffers(dri2_surf, true, true);
dri2_surf->base.Width = dri2_surf->wl_win->width;
dri2_surf->base.Height = dri2_surf->wl_win->height;
@ -2413,8 +2696,24 @@ swrast_update_buffers(struct dri2_egl_surface *dri2_surf)
return 0;
}
static int
swrast_allocate_front_buffer(struct dri2_egl_surface *dri2_surf)
{
if (!dri2_surf->swrast_front) {
if (!swrast_allocate_local_buffer(dri2_surf->format,
dri2_surf->base.Width,
dri2_surf->base.Height,
&dri2_surf->swrast_front)) {
_eglError(EGL_BAD_ALLOC, "failed to allocate front buffer");
return -1;
}
}
return 0;
}
static void*
dri2_wl_swrast_get_frontbuffer_data(struct dri2_egl_surface *dri2_surf)
dri2_wl_swrast_get_currentbuffer_data(struct dri2_egl_surface *dri2_surf)
{
/* if there has been a resize: */
if (!dri2_surf->current)
@ -2484,7 +2783,9 @@ dri2_wl_swrast_get_drawable_info(__DRIdrawable * draw,
{
struct dri2_egl_surface *dri2_surf = loaderPrivate;
(void) swrast_update_buffers(dri2_surf);
if (dri2_surf->base.Type == EGL_WINDOW_BIT)
(void) swrast_update_buffers(dri2_surf);
*x = 0;
*y = 0;
*w = dri2_surf->base.Width;
@ -2503,7 +2804,11 @@ dri2_wl_swrast_get_image(__DRIdrawable * read,
int dst_stride = copy_width;
char *src, *dst;
src = dri2_wl_swrast_get_frontbuffer_data(dri2_surf);
if (dri2_surf->base.Type == EGL_WINDOW_BIT)
src = dri2_wl_swrast_get_currentbuffer_data(dri2_surf);
else
src = dri2_surf->swrast_front;
if (!src) {
memset(data, 0, copy_width * h);
return;
@ -2541,14 +2846,20 @@ dri2_wl_swrast_put_image2(__DRIdrawable * draw, int op,
assert(copy_width <= stride);
(void) swrast_update_buffers(dri2_surf);
dst = dri2_wl_swrast_get_backbuffer_data(dri2_surf);
if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
(void) swrast_update_buffers(dri2_surf);
dst = dri2_wl_swrast_get_backbuffer_data(dri2_surf);
/* partial copy, copy old content */
if (copy_width < dst_stride)
dri2_wl_swrast_get_image(draw, 0, 0,
dri2_surf->base.Width, dri2_surf->base.Height,
dst, loaderPrivate);
/* partial copy, copy old content */
if (copy_width < dst_stride)
dri2_wl_swrast_get_image(draw, 0, 0,
dri2_surf->base.Width, dri2_surf->base.Height,
dst, loaderPrivate);
} else {
(void) swrast_allocate_front_buffer(dri2_surf);
dst = dri2_surf->swrast_front;
assert(dst);
}
dst += x_offset;
dst += y * dst_stride;
@ -2566,7 +2877,9 @@ dri2_wl_swrast_put_image2(__DRIdrawable * draw, int op,
src += stride;
dst += dst_stride;
}
dri2_wl_swrast_commit_backbuffer(dri2_surf);
if (dri2_surf->base.Type == EGL_WINDOW_BIT)
dri2_wl_swrast_commit_backbuffer(dri2_surf);
}
static void
@ -2638,6 +2951,7 @@ static const struct dri2_egl_display_vtbl dri2_wl_swrast_display_vtbl = {
.authenticate = NULL,
.create_window_surface = dri2_wl_create_window_surface,
.create_pixmap_surface = dri2_wl_create_pixmap_surface,
.create_pbuffer_surface = dri2_wl_create_pbuffer_surface,
.destroy_surface = dri2_wl_destroy_surface,
.create_image = dri2_create_image_khr,
.swap_buffers = dri2_wl_swrast_swap_buffers,
@ -2690,6 +3004,7 @@ dri2_initialize_wayland_swrast(_EGLDisplay *disp)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
dri2_dpy->fd = -1;
dri2_dpy->fd_dpy = -1;
disp->DriverData = (void *) dri2_dpy;
if (dri2_wl_formats_init(&dri2_dpy->formats) < 0)
@ -2751,7 +3066,7 @@ dri2_initialize_wayland_swrast(_EGLDisplay *disp)
dri2_wl_setup_swap_interval(disp);
if (!dri2_wl_add_configs_for_visuals(disp)) {
if (!dri2_wl_add_configs_for_visuals(disp, false)) {
_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to add configs");
goto cleanup;
}

View file

@ -1507,6 +1507,7 @@ dri2_initialize_x11_swrast(_EGLDisplay *disp)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
dri2_dpy->fd = -1;
dri2_dpy->fd_dpy = -1;
if (!dri2_get_xcb_connection(disp, dri2_dpy))
goto cleanup;
@ -1596,6 +1597,7 @@ dri2_initialize_x11_dri3(_EGLDisplay *disp)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
dri2_dpy->fd = -1;
dri2_dpy->fd_dpy = -1;
if (!dri2_get_xcb_connection(disp, dri2_dpy))
goto cleanup;
@ -1708,6 +1710,7 @@ dri2_initialize_x11_dri2(_EGLDisplay *disp)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
dri2_dpy->fd = -1;
dri2_dpy->fd_dpy = -1;
if (!dri2_get_xcb_connection(disp, dri2_dpy))
goto cleanup;

View file

@ -32,6 +32,7 @@
#include <xf86drm.h>
#include "util/macros.h"
#include "util/os_file.h"
#include "egl_dri2.h"
#include "platform_x11_dri3.h"
@ -157,6 +158,7 @@ dri3_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
struct dri3_egl_surface *dri3_surf;
const __DRIconfig *dri_config;
xcb_drawable_t drawable;
bool is_incompat_gpu;
dri3_surf = calloc(1, sizeof *dri3_surf);
if (!dri3_surf) {
@ -164,6 +166,10 @@ dri3_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
return NULL;
}
is_incompat_gpu = dri2_dpy->is_different_gpu &&
!loader_dri3_has_modifiers(dri2_dpy->multibuffers_available,
dri2_dpy->image);
if (!dri2_init_surface(&dri3_surf->surf.base, disp, type, conf,
attrib_list, false, native_surface))
goto cleanup_surf;
@ -189,7 +195,7 @@ dri3_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
if (loader_dri3_drawable_init(dri2_dpy->conn, drawable,
egl_to_loader_dri3_drawable_type(type),
dri2_dpy->dri_screen,
dri2_dpy->is_different_gpu,
is_incompat_gpu,
dri2_dpy->multibuffers_available,
true,
dri_config,
@ -431,11 +437,21 @@ dri3_flush_front_buffer(__DRIdrawable *driDrawable, void *loaderPrivate)
_eglLog(_EGL_WARNING, "FIXME: egl/x11 doesn't support front buffer rendering.");
}
static int
dri3_get_display_fd(void *loaderPrivate)
{
_EGLDisplay *disp = loaderPrivate;
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
return dri2_dpy->fd_dpy;
}
const __DRIimageLoaderExtension dri3_image_loader_extension = {
.base = { __DRI_IMAGE_LOADER, 1 },
.base = { __DRI_IMAGE_LOADER, 5 },
.getBuffers = loader_dri3_get_buffers,
.flushFrontBuffer = dri3_flush_front_buffer,
.getDisplayFD = dri3_get_display_fd,
};
static EGLBoolean
@ -555,6 +571,7 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy)
xcb_xfixes_query_version_cookie_t xfixes_query_cookie;
xcb_generic_error_t *error;
const xcb_query_extension_reply_t *extension;
int fd_old;
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri3_id);
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_present_id);
@ -634,12 +651,25 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy)
return EGL_FALSE;
}
fd_old = dri2_dpy->fd;
dri2_dpy->fd_dpy = os_dupfd_cloexec(dri2_dpy->fd);
dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd, &dri2_dpy->is_different_gpu);
if (dri2_dpy->fd == fd_old) {
if (dri2_dpy->fd_dpy != -1)
close(dri2_dpy->fd_dpy);
dri2_dpy->fd_dpy = dri2_dpy->fd;
} else if (dri2_dpy->fd_dpy == -1) {
_eglLog(_EGL_WARNING, "DRI3: failed to dup display FD");
close(dri2_dpy->fd);
return EGL_FALSE;
}
dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
if (!dri2_dpy->driver_name) {
_eglLog(_EGL_WARNING, "DRI3: No driver found");
close(dri2_dpy->fd);
close(dri2_dpy->fd_dpy);
return EGL_FALSE;
}

View file

@ -297,6 +297,14 @@ haiku_make_current(_EGLDisplay *disp, _EGLSurface *dsurf,
}
extern "C"
EGLint
haiku_dri2_query_context_client_version(_EGLDisplay *disp, _EGLContext *ctx)
{
// Tell caller to use the default value.
return 0;
}
extern "C"
EGLBoolean
haiku_swap_buffers(_EGLDisplay *disp, _EGLSurface *surf)
@ -316,6 +324,7 @@ const _EGLDriver _eglDriver = {
.CreateContext = haiku_create_context,
.DestroyContext = haiku_destroy_context,
.MakeCurrent = haiku_make_current,
.QueryContextClientVersion = haiku_dri2_query_context_client_version,
.CreateWindowSurface = haiku_create_window_surface,
.CreatePixmapSurface = haiku_create_pixmap_surface,
.CreatePbufferSurface = haiku_create_pbuffer_surface,

View file

@ -564,11 +564,13 @@ _eglCreateExtensionsString(_EGLDisplay *disp)
_EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
_EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
_EGL_CHECK_EXTENSION(EXT_protected_content);
_EGL_CHECK_EXTENSION(EXT_image_gl_colorspace);
_EGL_CHECK_EXTENSION(EXT_protected_surface);
_EGL_CHECK_EXTENSION(EXT_present_opaque);
_EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata);
_EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata);
_EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
_EGL_CHECK_EXTENSION(EXT_yuv_surface);
_EGL_CHECK_EXTENSION(IMG_context_priority);
@ -613,6 +615,7 @@ _eglCreateExtensionsString(_EGLDisplay *disp)
_EGL_CHECK_EXTENSION(WL_bind_wayland_display);
_EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
_EGL_CHECK_EXTENSION(IMG_cl_image);
#undef _EGL_CHECK_EXTENSION
}
@ -934,6 +937,7 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
EGLContext ctx)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLContext *current_context = _eglGetCurrentContext();
_EGLContext *context = _eglLookupContext(ctx, disp);
_EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
_EGLSurface *read_surf = _eglLookupSurface(read, disp);
@ -987,8 +991,17 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
draw_surf && !draw_surf->ProtectedContent)
RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);
egl_relax (disp, &draw_surf->Resource, &read_surf->Resource, &context->Resource) {
ret = disp->Driver->MakeCurrent(disp, draw_surf, read_surf, context);
/* As an optimisation don't do anything unless something has changed */
if (context != current_context ||
(current_context &&
(draw_surf != current_context->DrawSurface ||
read_surf != current_context->ReadSurface)) ||
(!current_context && (draw_surf || read_surf))) {
egl_relax (disp, &draw_surf->Resource, &read_surf->Resource, &context->Resource) {
ret = disp->Driver->MakeCurrent(disp, draw_surf, read_surf, context);
}
} else {
ret = EGL_TRUE;
}
RETURN_EGL_EVAL(disp, ret);
@ -1051,7 +1064,10 @@ _eglCreateWindowSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
if (native_window == NULL)
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
#ifdef HAVE_NULL_PLATFORM
if (disp && disp->Platform != _EGL_PLATFORM_NULL)
#endif
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
if (disp && (disp->Platform == _EGL_PLATFORM_SURFACELESS ||
disp->Platform == _EGL_PLATFORM_DEVICE)) {

View file

@ -258,6 +258,24 @@ static const struct {
{ EGL_COLOR_COMPONENT_TYPE_EXT, ATTRIB_TYPE_ENUM,
ATTRIB_CRITERION_EXACT,
EGL_COLOR_COMPONENT_TYPE_FIXED_EXT },
{ EGL_YUV_ORDER_EXT, ATTRIB_TYPE_ENUM,
ATTRIB_CRITERION_EXACT,
EGL_DONT_CARE },
{ EGL_YUV_NUMBER_OF_PLANES_EXT, ATTRIB_TYPE_INTEGER,
ATTRIB_CRITERION_ATLEAST,
0 },
{ EGL_YUV_SUBSAMPLE_EXT, ATTRIB_TYPE_ENUM,
ATTRIB_CRITERION_EXACT,
EGL_DONT_CARE },
{ EGL_YUV_DEPTH_RANGE_EXT, ATTRIB_TYPE_ENUM,
ATTRIB_CRITERION_EXACT,
EGL_DONT_CARE },
{ EGL_YUV_CSC_STANDARD_EXT, ATTRIB_TYPE_ENUM,
ATTRIB_CRITERION_EXACT,
EGL_DONT_CARE },
{ EGL_YUV_PLANE_BPP_EXT, ATTRIB_TYPE_ENUM,
ATTRIB_CRITERION_EXACT,
EGL_DONT_CARE },
};
@ -296,6 +314,28 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
if (val > 1 || val < 0)
valid = EGL_FALSE;
break;
case EGL_YUV_NUMBER_OF_PLANES_EXT:
/* From the EGL_EXT_yuv_surface spec (v9):
*
* The allowed values for EGL_YUV_NUMBER_OF_PLANES_EXT must
* be greater than zero and not more than three.
*
* However, it also says:
*
* Attribute Default Selection Sort Sort
* Criteria Order Priority
* ---------------------------- ------- --------- ----- --------
* EGL_YUV_NUMBER_OF_PLANES_EXT 0 At least None
*
* This means that we need to allow the value 0 when doing config
* matching (where it's essentially treated as EGL_DONT_CARE).
* Furthermore, this attribute isn't applicable to non-YUV EGL
* color buffer types. Allow 0 through here and then do further
* validation later on.
*/
if (val < 0 || val > 3)
valid = EGL_FALSE;
break;
default:
if (val < 0)
valid = EGL_FALSE;
@ -318,7 +358,43 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
valid = EGL_FALSE;
break;
case EGL_COLOR_BUFFER_TYPE:
if (val != EGL_RGB_BUFFER && val != EGL_LUMINANCE_BUFFER)
if (val != EGL_RGB_BUFFER && val != EGL_LUMINANCE_BUFFER &&
val != EGL_YUV_BUFFER_EXT)
valid = EGL_FALSE;
break;
case EGL_YUV_ORDER_EXT:
if (val != EGL_NONE &&
val != EGL_YUV_ORDER_YUV_EXT && val != EGL_YUV_ORDER_YVU_EXT &&
val != EGL_YUV_ORDER_YUYV_EXT && val != EGL_YUV_ORDER_UYVY_EXT &&
val != EGL_YUV_ORDER_YVYU_EXT && val != EGL_YUV_ORDER_VYUY_EXT &&
val != EGL_YUV_ORDER_AYUV_EXT)
valid = EGL_FALSE;
break;
case EGL_YUV_SUBSAMPLE_EXT:
if (val != EGL_NONE &&
val != EGL_YUV_SUBSAMPLE_4_2_0_EXT &&
val != EGL_YUV_SUBSAMPLE_4_2_2_EXT &&
val != EGL_YUV_SUBSAMPLE_4_4_4_EXT)
valid = EGL_FALSE;
break;
case EGL_YUV_DEPTH_RANGE_EXT:
if (val != EGL_NONE &&
val != EGL_YUV_DEPTH_RANGE_LIMITED_EXT &&
val != EGL_YUV_DEPTH_RANGE_FULL_EXT)
valid = EGL_FALSE;
break;
case EGL_YUV_CSC_STANDARD_EXT:
if (val != EGL_NONE &&
val != EGL_YUV_CSC_STANDARD_601_EXT &&
val != EGL_YUV_CSC_STANDARD_709_EXT &&
val != EGL_YUV_CSC_STANDARD_2020_EXT)
valid = EGL_FALSE;
break;
case EGL_YUV_PLANE_BPP_EXT:
if (val != EGL_NONE &&
val != EGL_YUV_PLANE_BPP_0_EXT &&
val != EGL_YUV_PLANE_BPP_8_EXT &&
val != EGL_YUV_PLANE_BPP_10_EXT)
valid = EGL_FALSE;
break;
case EGL_COLOR_COMPONENT_TYPE_EXT:
@ -404,6 +480,11 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
if (conf->LuminanceSize + conf->AlphaSize != conf->BufferSize)
valid = EGL_FALSE;
break;
case EGL_YUV_BUFFER_EXT:
if (conf->RedSize || conf->GreenSize || conf->BlueSize ||
conf->AlphaSize || conf->LuminanceSize)
valid = EGL_FALSE;
break;
}
if (!valid) {
_eglLog(_EGL_DEBUG, "conflicting color buffer type and channel sizes");
@ -430,6 +511,88 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
return EGL_FALSE;
}
/* From the EGL_EXT_yuv_surface spec (v9):
*
* SUBSAMPLE_EXT NUMBER_OF_PLANES_EXT ORDER_EXT PLANE_BPP_EXT
* ------------------- -------------------- ----------------- ------------------
* SUBSAMPLE_4_2_0_EXT 2 or 3 ORDER_YUV_EXT or PLANE_BPP_8_EXT or
* ORDER_YVU_EXT PLANE_BPP_10_EXT
*/
if (conf->YUVSubsampleEXT == EGL_YUV_SUBSAMPLE_4_2_0_EXT) {
if ((!for_matching || conf->YUVNumberOfPlanesEXT != 0) &&
conf->YUVNumberOfPlanesEXT != 2 &&
conf->YUVNumberOfPlanesEXT != 3)
valid = EGL_FALSE;
if (conf->YUVOrderEXT != EGL_DONT_CARE &&
conf->YUVOrderEXT != EGL_YUV_ORDER_YUV_EXT &&
conf->YUVOrderEXT != EGL_YUV_ORDER_YVU_EXT)
valid = EGL_FALSE;
if (conf->YUVPlaneBPPEXT != EGL_DONT_CARE &&
conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_8_EXT &&
conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_10_EXT)
valid = EGL_FALSE;
}
/* From the EGL_EXT_yuv_surface spec (v9):
*
* SUBSAMPLE_EXT NUMBER_OF_PLANES_EXT ORDER_EXT PLANE_BPP_EXT
* ------------------- -------------------- ----------------- ------------------
* SUBSAMPLE_4_2_2_EXT 1 ORDER_YUYV_EXT or PLANE_BPP_8_EXT or
* ORDER_YVYU_EXT or PLANE_BPP_10_EXT
* ORDER_UYVY_EXT or
* ORDER_VYUY_EXT
*
* SUBSAMPLE_4_2_2_EXT 2 or 3 ORDER_YUV_EXT or PLANE_BPP_8_EXT or
* ORDER_YVU_EXT PLANE_BPP_10_EXT
*/
else if (conf->YUVSubsampleEXT == EGL_YUV_SUBSAMPLE_4_2_2_EXT) {
if ((!for_matching || conf->YUVNumberOfPlanesEXT != 0) &&
conf->YUVNumberOfPlanesEXT != 1 &&
conf->YUVNumberOfPlanesEXT != 2 &&
conf->YUVNumberOfPlanesEXT != 3)
valid = EGL_FALSE;
if (conf->YUVNumberOfPlanesEXT == 1) {
if (conf->YUVOrderEXT != EGL_DONT_CARE &&
conf->YUVOrderEXT != EGL_YUV_ORDER_YUYV_EXT &&
conf->YUVOrderEXT != EGL_YUV_ORDER_YVYU_EXT &&
conf->YUVOrderEXT != EGL_YUV_ORDER_UYVY_EXT &&
conf->YUVOrderEXT != EGL_YUV_ORDER_VYUY_EXT)
valid = EGL_FALSE;
} else if (conf->YUVNumberOfPlanesEXT == 2 ||
conf->YUVNumberOfPlanesEXT == 3) {
if (conf->YUVOrderEXT != EGL_DONT_CARE &&
conf->YUVOrderEXT != EGL_YUV_ORDER_YUV_EXT &&
conf->YUVOrderEXT != EGL_YUV_ORDER_YVU_EXT)
valid = EGL_FALSE;
}
if (conf->YUVPlaneBPPEXT != EGL_DONT_CARE &&
conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_8_EXT &&
conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_10_EXT)
valid = EGL_FALSE;
}
/* From the EGL_EXT_yuv_surface spec (v9):
*
* SUBSAMPLE_EXT NUMBER_OF_PLANES_EXT ORDER_EXT PLANE_BPP_EXT
* ------------------- -------------------- ----------------- ------------------
* SUBSAMPLE_4_4_4_EXT 1 ORDER_AYUV_EXT PLANE_BPP_8_EXT or
* PLANE_BPP_10_EXT
*/
else if (conf->YUVSubsampleEXT == EGL_YUV_SUBSAMPLE_4_4_4_EXT) {
if ((!for_matching || conf->YUVNumberOfPlanesEXT != 0) &&
conf->YUVNumberOfPlanesEXT != 1)
valid = EGL_FALSE;
if (conf->YUVOrderEXT != EGL_DONT_CARE &&
conf->YUVOrderEXT != EGL_YUV_ORDER_AYUV_EXT)
valid = EGL_FALSE;
if (conf->YUVPlaneBPPEXT != EGL_DONT_CARE &&
conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_8_EXT &&
conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_10_EXT)
valid = EGL_FALSE;
}
if (!valid) {
_eglLog(_EGL_DEBUG, "invalid YUV subsample/num planes/order/bpp combination");
return EGL_FALSE;
}
return valid;
}
@ -509,6 +672,28 @@ _eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
return conf->Display->Extensions.ANDROID_framebuffer_target;
case EGL_RECORDABLE_ANDROID:
return conf->Display->Extensions.ANDROID_recordable;
case EGL_YUV_ORDER_EXT:
case EGL_YUV_NUMBER_OF_PLANES_EXT:
case EGL_YUV_SUBSAMPLE_EXT:
case EGL_YUV_DEPTH_RANGE_EXT:
case EGL_YUV_CSC_STANDARD_EXT:
case EGL_YUV_PLANE_BPP_EXT:
return conf->Display->Extensions.EXT_yuv_surface;
default:
break;
}
return EGL_TRUE;
}
static inline EGLBoolean
_eglIsConfigAttribValueValid(_EGLConfig *conf, EGLint attr, EGLint val)
{
switch (attr) {
case EGL_COLOR_BUFFER_TYPE:
if (!conf->Display->Extensions.EXT_yuv_surface && val == EGL_YUV_BUFFER_EXT)
return EGL_FALSE;
break;
default:
break;
}
@ -543,6 +728,9 @@ _eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *disp,
if (!_eglIsConfigAttribValid(conf, attr))
return EGL_FALSE;
if (!_eglIsConfigAttribValueValid(conf, attr, val))
return EGL_FALSE;
_eglSetConfigKey(conf, attr, val);
}
@ -617,6 +805,7 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
/* the enum values have the desired ordering */
STATIC_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
STATIC_ASSERT(EGL_LUMINANCE_BUFFER < EGL_YUV_BUFFER_EXT);
val1 = conf1->ColorBufferType - conf2->ColorBufferType;
if (val1)
return val1;
@ -636,16 +825,42 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
val1 += conf1->BlueSize;
val2 += conf2->BlueSize;
}
if (criteria->AlphaSize > 0) {
val1 += conf1->AlphaSize;
val2 += conf2->AlphaSize;
}
}
else {
else if (conf1->ColorBufferType == EGL_LUMINANCE_BUFFER) {
if (criteria->LuminanceSize > 0) {
val1 += conf1->LuminanceSize;
val2 += conf2->LuminanceSize;
}
if (criteria->AlphaSize > 0) {
val1 += conf1->AlphaSize;
val2 += conf2->AlphaSize;
}
}
if (criteria->AlphaSize > 0) {
val1 += conf1->AlphaSize;
val2 += conf2->AlphaSize;
else {
/* From the EGL_EXT_yuv_surface spec (v9):
*
* Special: by larger total number of color bits
* ...
* for YUV color buffers, this returns the integer value with
* respect to the enumeration provided for EGL_YUV_PLANE_BPP_EXT
*
* and:
*
* EGL_BUFFER_SIZE gives the total of the color component bits of
* the color buffer for EGL_RGB_BUFFER or for EGL_LUMINANCE_BUFFER.
* ...
* When EGL_COLOR_BUFFER_TYPE is of type EGL_YUV_BUFFER_EXT,
* this will reflect the enumeration provided as an integer)
* for EGL_YUV_PLANE_BPP_EXT, giving a value of 0, 8 or 10
*/
if (criteria->BufferSize > 0) {
val1 = conf1->BufferSize;
val2 = conf2->BufferSize;
}
}
}
else {
@ -664,6 +879,36 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
return (val1 - val2);
}
if (conf1->YUVOrderEXT != conf2->YUVOrderEXT)
{
const EGLint yuv_order[] = {
EGL_NONE,
EGL_YUV_ORDER_YUV_EXT,
EGL_YUV_ORDER_YVU_EXT,
EGL_YUV_ORDER_YUYV_EXT,
EGL_YUV_ORDER_YVYU_EXT,
EGL_YUV_ORDER_UYVY_EXT,
EGL_YUV_ORDER_VYUY_EXT,
EGL_YUV_ORDER_AYUV_EXT,
};
val1 = val2 = 0;
for (i = 0; i < ARRAY_SIZE(yuv_order); i++) {
if (yuv_order[i] == conf1->YUVOrderEXT) {
val1 = i;
break;
}
}
for (i = 0; i < ARRAY_SIZE(yuv_order); i++) {
if (yuv_order[i] == conf2->YUVOrderEXT) {
val2 = i;
break;
}
}
if (val1 != val2)
return val1 - val2;
}
/* EGL_NATIVE_VISUAL_TYPE cannot be compared here */
return (compare_id) ? (conf1->ConfigID - conf2->ConfigID) : 0;

View file

@ -88,6 +88,12 @@ struct _egl_config
EGLint FramebufferTargetAndroid;
EGLint RecordableAndroid;
EGLint ComponentType;
EGLint YUVOrderEXT;
EGLint YUVNumberOfPlanesEXT;
EGLint YUVSubsampleEXT;
EGLint YUVDepthRangeEXT;
EGLint YUVCSCStandardEXT;
EGLint YUVPlaneBPPEXT;
};
@ -138,6 +144,12 @@ _eglOffsetOfConfig(EGLint attr)
ATTRIB_MAP(EGL_FRAMEBUFFER_TARGET_ANDROID, FramebufferTargetAndroid);
ATTRIB_MAP(EGL_RECORDABLE_ANDROID, RecordableAndroid);
ATTRIB_MAP(EGL_COLOR_COMPONENT_TYPE_EXT, ComponentType);
ATTRIB_MAP(EGL_YUV_ORDER_EXT, YUVOrderEXT);
ATTRIB_MAP(EGL_YUV_NUMBER_OF_PLANES_EXT, YUVNumberOfPlanesEXT);
ATTRIB_MAP(EGL_YUV_SUBSAMPLE_EXT, YUVSubsampleEXT);
ATTRIB_MAP(EGL_YUV_DEPTH_RANGE_EXT, YUVDepthRangeEXT);
ATTRIB_MAP(EGL_YUV_CSC_STANDARD_EXT, YUVCSCStandardEXT);
ATTRIB_MAP(EGL_YUV_PLANE_BPP_EXT, YUVPlaneBPPEXT);
#undef ATTRIB_MAP
default:
return -1;

View file

@ -35,6 +35,7 @@
#include "eglcontext.h"
#include "egldisplay.h"
#include "eglcurrent.h"
#include "egldriver.h"
#include "eglsurface.h"
#include "egllog.h"
#include "util/macros.h"
@ -678,6 +679,17 @@ _eglQueryContextRenderBuffer(_EGLContext *ctx)
}
static EGLint
_eglQueryContextClientVersion(_EGLContext *ctx)
{
_EGLDisplay *disp = ctx->Resource.Display;
EGLint version;
version = disp->Driver->QueryContextClientVersion(disp, ctx);
return (version) ? version : ctx->ClientMajorVersion;
}
EGLBoolean
_eglQueryContext(_EGLContext *c, EGLint attribute, EGLint *value)
{
@ -698,7 +710,7 @@ _eglQueryContext(_EGLContext *c, EGLint attribute, EGLint *value)
*value = c->Config ? c->Config->ConfigID : 0;
break;
case EGL_CONTEXT_CLIENT_VERSION:
*value = c->ClientMajorVersion;
*value = _eglQueryContextClientVersion(c);
break;
case EGL_CONTEXT_CLIENT_TYPE:
*value = c->ClientAPI;

View file

@ -72,11 +72,10 @@ struct _egl_thread_info
static inline EGLBoolean
_eglIsApiValid(EGLenum api)
{
#ifdef ANDROID
/* OpenGL is not a valid/supported API on Android */
return api == EGL_OPENGL_ES_API;
#else
#ifdef EGL_WITH_OPENGL
return (api == EGL_OPENGL_ES_API || api == EGL_OPENGL_API);
#else
return api == EGL_OPENGL_ES_API;
#endif
}

View file

@ -85,6 +85,7 @@ static const struct {
{ _EGL_PLATFORM_SURFACELESS, "surfaceless" },
{ _EGL_PLATFORM_DEVICE, "device" },
{ _EGL_PLATFORM_WINDOWS, "windows" },
{ _EGL_PLATFORM_NULL, "null" },
};

View file

@ -56,6 +56,7 @@ enum _egl_platform_type {
_EGL_PLATFORM_SURFACELESS,
_EGL_PLATFORM_DEVICE,
_EGL_PLATFORM_WINDOWS,
_EGL_PLATFORM_NULL,
_EGL_NUM_PLATFORMS,
_EGL_INVALID_PLATFORM = -1
@ -111,6 +112,7 @@ struct _egl_extensions
EGLBoolean EXT_create_context_robustness;
EGLBoolean EXT_image_dma_buf_import;
EGLBoolean EXT_image_dma_buf_import_modifiers;
EGLBoolean EXT_image_gl_colorspace;
EGLBoolean EXT_pixel_format_float;
EGLBoolean EXT_protected_content;
EGLBoolean EXT_protected_surface;
@ -118,6 +120,7 @@ struct _egl_extensions
EGLBoolean EXT_surface_CTA861_3_metadata;
EGLBoolean EXT_surface_SMPTE2086_metadata;
EGLBoolean EXT_swap_buffers_with_damage;
EGLBoolean EXT_yuv_surface;
unsigned int IMG_context_priority;
#define __EGL_CONTEXT_PRIORITY_LOW_BIT 0
@ -157,6 +160,8 @@ struct _egl_extensions
EGLBoolean WL_bind_wayland_display;
EGLBoolean WL_create_wayland_buffer_from_image;
EGLBoolean IMG_cl_image;
};
struct _egl_display

View file

@ -96,6 +96,7 @@ struct _egl_driver
EGLBoolean (*MakeCurrent)(_EGLDisplay *disp,
_EGLSurface *draw, _EGLSurface *read,
_EGLContext *ctx);
EGLint (*QueryContextClientVersion)(_EGLDisplay *disp, _EGLContext *ctx);
/* surface funcs */
_EGLSurface *(*CreateWindowSurface)(_EGLDisplay *disp, _EGLConfig *config,

View file

@ -46,6 +46,18 @@ _eglParseKHRImageAttribs(_EGLImageAttribs *attrs, _EGLDisplay *disp,
attrs->ImagePreserved = val;
break;
case EGL_GL_COLORSPACE_KHR:
if (!disp->Extensions.EXT_image_gl_colorspace)
return EGL_BAD_PARAMETER;
if (val != EGL_GL_COLORSPACE_SRGB_KHR &&
val != EGL_GL_COLORSPACE_LINEAR_KHR &&
val != EGL_GL_COLORSPACE_DEFAULT_EXT)
return EGL_BAD_PARAMETER;
attrs->GLColorspace = val;
break;
case EGL_GL_TEXTURE_LEVEL_KHR:
if (!disp->Extensions.KHR_gl_texture_2D_image)
return EGL_BAD_PARAMETER;
@ -286,6 +298,8 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *disp,
memset(attrs, 0, sizeof(*attrs));
attrs->GLColorspace = EGL_GL_COLORSPACE_DEFAULT_EXT;
if (!attrib_list)
return EGL_TRUE;

View file

@ -80,6 +80,9 @@ struct _egl_image_attribs
/* EGL_EXT_protected_content || EGL_EXT_protected_surface */
EGLBoolean ProtectedContent;
/* EGL_EXT_image_gl_colorspace */
EGLint GLColorspace;
};
/**

View file

@ -152,6 +152,16 @@ elif with_platform_windows
incs_for_egl += [inc_wgl, inc_gallium, inc_gallium_aux]
link_for_egl += libgallium_wgl
endif
if with_platform_null
if null_dri_driver_name != ''
c_args_for_egl += [
'-DNULL_DRI_DRIVER_NAME="@0@"'.format(null_dri_driver_name),
]
endif
files_egl += files('drivers/dri2/platform_null.c')
incs_for_egl += [inc_loader]
deps_for_egl += dep_libdrm
endif
if cc.has_function('mincore')
c_args_for_egl += '-DHAVE_MINCORE'

View file

@ -49,6 +49,21 @@ libwayland_drm = static_library(
build_by_default : false,
)
install_data('wayland-drm.xml')
pkg.generate(
filebase : 'wayland-drm',
name : 'Mesa Wayland Protocols',
description : 'Mesa Wayland protocol files',
version : meson.project_version(),
variables : [
'datarootdir=${prefix}/' + get_option('datadir'),
'pkgdatadir=${pc_sysrootdir}${datarootdir}/' + meson.project_name(),
],
install_dir : '@0@/@1@/pkgconfig'.format(get_option('prefix'),
get_option('datadir')),
)
# linux-dmabuf isn't part of wayland-drm, but this happens to be the only
# place which is a) guaranteed to be built when building either or both
# of EGL and Vulkan WSI, and b) guaranteed to be included before both,

View file

@ -0,0 +1,7 @@
prefix=@prefix@
datarootdir=@datarootdir@
pkgdatadir=${pc_sysrootdir}@datadir@/@PACKAGE@
Name: @PACKAGE_NAME@ Wayland Protocols
Description: @PACKAGE_NAME@ Wayland protocol files
Version: @PACKAGE_VERSION@

View file

@ -107,6 +107,7 @@ struct aa_transform_context {
uint64_t tempsUsed; /**< bitmask */
int colorOutput; /**< which output is the primary color */
int maxInput, maxGeneric; /**< max input index found */
int numImm; /**< number of immediate regsters */
int colorTemp, aaTemp; /**< temp registers */
};
@ -147,6 +148,18 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
ctx->emit_declaration(ctx, decl);
}
/**
* TGSI immediate declaration transform callback.
*/
static void
aa_immediate(struct tgsi_transform_context *ctx,
struct tgsi_full_immediate *imm)
{
struct aa_transform_context *aactx = (struct aa_transform_context *)ctx;
ctx->emit_immediate(ctx, imm);
aactx->numImm++;
}
/**
* Find the lowest zero bit, or -1 if bitfield is all ones.
@ -182,6 +195,9 @@ aa_transform_prolog(struct tgsi_transform_context *ctx)
/* declare new temp regs */
tgsi_transform_temp_decl(ctx, aactx->aaTemp);
tgsi_transform_temp_decl(ctx, aactx->colorTemp);
/* declare new immediate reg */
tgsi_transform_immediate_decl(ctx, 2.0, -1.0, 0.0, 0.25);
}
@ -215,6 +231,26 @@ aa_transform_epilog(struct tgsi_transform_context *ctx)
inst.Src[1].Register.Negate = true;
ctx->emit_instruction(ctx, &inst);
/* linelength * 2 - 1 */
tgsi_transform_op3_swz_inst(ctx, TGSI_OPCODE_MAD,
TGSI_FILE_TEMPORARY, aactx->aaTemp,
TGSI_WRITEMASK_Y,
TGSI_FILE_INPUT, aactx->maxInput + 1,
TGSI_SWIZZLE_W, false,
TGSI_FILE_IMMEDIATE, aactx->numImm,
TGSI_SWIZZLE_X,
TGSI_FILE_IMMEDIATE, aactx->numImm,
TGSI_SWIZZLE_Y);
/* MIN height alpha */
tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_MIN,
TGSI_FILE_TEMPORARY, aactx->aaTemp,
TGSI_WRITEMASK_Z,
TGSI_FILE_TEMPORARY, aactx->aaTemp,
TGSI_SWIZZLE_Z,
TGSI_FILE_TEMPORARY, aactx->aaTemp,
TGSI_SWIZZLE_Y, false);
/* MUL width / height alpha */
tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_MUL,
TGSI_FILE_TEMPORARY, aactx->aaTemp,
@ -292,6 +328,7 @@ generate_aaline_fs(struct aaline_stage *aaline)
transform.base.epilog = aa_transform_epilog;
transform.base.transform_instruction = aa_transform_inst;
transform.base.transform_declaration = aa_transform_decl;
transform.base.transform_immediate = aa_immediate;
aaline_fs.tokens = tgsi_transform_shader(orig_fs->tokens, newLen, &transform.base);
if (!aaline_fs.tokens)
@ -324,7 +361,7 @@ generate_aaline_fs_nir(struct aaline_stage *aaline)
if (!aaline_fs.ir.nir)
return FALSE;
nir_lower_aaline_fs(aaline_fs.ir.nir, &aaline->fs->generic_attrib);
nir_lower_aaline_fs(aaline_fs.ir.nir, &aaline->fs->generic_attrib, NULL, NULL);
aaline->fs->aaline_fs = aaline->driver_create_fs_state(pipe, &aaline_fs);
if (aaline->fs->aaline_fs == NULL)
return FALSE;
@ -383,36 +420,13 @@ aaline_line(struct draw_stage *stage, struct prim_header *header)
float *pos, *tex;
float dx = header->v[1]->data[posPos][0] - header->v[0]->data[posPos][0];
float dy = header->v[1]->data[posPos][1] - header->v[0]->data[posPos][1];
float a = atan2f(dy, dx);
float c_a = cosf(a), s_a = sinf(a);
float half_length;
float length = sqrtf(dx * dx + dy * dy);
float c_a = dx / length, s_a = dy / length;
float half_length = 0.5 * length;
float t_l, t_w;
uint i;
half_length = 0.5f * sqrtf(dx * dx + dy * dy);
if (half_length < 0.5f) {
/*
* The logic we use for "normal" sized segments is incorrect
* for very short segments (basically because we only have
* one value to interpolate, not a distance to each endpoint).
* Therefore, we calculate half_length differently, so that for
* original line length (near) 0, we get alpha 0 - otherwise
* max alpha would still be 0.5. This also prevents us from
* artifacts due to degenerated lines (the endpoints being
* identical, which would still receive anywhere from alpha
* 0-0.5 otherwise) (at least the pstipple stage may generate
* such lines due to float inaccuracies if line length is very
* close to a integer).
* Might not be fully accurate neither (because the "strength" of
* the line is going to be determined by how close to the pixel
* center those 1 or 2 fragments are) but it's probably the best
* we can do.
*/
half_length = 2.0f * half_length;
} else {
half_length = half_length + 0.5f;
}
half_length = half_length + 0.5f;
t_w = half_width;
t_l = 0.5f;

View file

@ -147,71 +147,94 @@ nir_lower_pstipple_fs(struct nir_shader *shader,
}
typedef struct {
nir_builder b;
nir_shader *shader;
nir_variable *line_width_input;
nir_variable *stipple_counter;
nir_variable *stipple_pattern;
} lower_aaline;
static void
nir_lower_aaline_block(nir_block *block,
lower_aaline *state)
static bool
lower_aaline_instr(nir_builder *b, nir_instr *instr, void *data)
{
nir_builder *b = &state->b;
nir_foreach_instr(instr, block) {
if (instr->type != nir_instr_type_intrinsic)
continue;
lower_aaline *state = data;
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
if (intrin->intrinsic != nir_intrinsic_store_deref)
continue;
if (instr->type != nir_instr_type_intrinsic)
return false;
nir_variable *var = nir_intrinsic_get_var(intrin, 0);
if (var->data.mode != nir_var_shader_out)
continue;
if (var->data.location < FRAG_RESULT_DATA0 && var->data.location != FRAG_RESULT_COLOR)
continue;
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
if (intrin->intrinsic != nir_intrinsic_store_deref)
return false;
nir_ssa_def *out_input = intrin->src[1].ssa;
b->cursor = nir_before_instr(instr);
nir_ssa_def *lw = nir_load_var(b, state->line_width_input);
nir_ssa_def *tmp = nir_fsat(b, nir_fadd(b, nir_channel(b, lw, 1),
nir_fneg(b, nir_fabs(b, nir_channel(b, lw, 0)))));
nir_ssa_def *tmp1 = nir_fsat(b, nir_fadd(b, nir_channel(b, lw, 3),
nir_fneg(b, nir_fabs(b, nir_channel(b, lw, 2)))));
nir_variable *var = nir_intrinsic_get_var(intrin, 0);
if (var->data.mode != nir_var_shader_out)
return false;
if (var->data.location < FRAG_RESULT_DATA0 && var->data.location != FRAG_RESULT_COLOR)
return false;
tmp = nir_fmul(b, tmp, tmp1);
tmp = nir_fmul(b, nir_channel(b, out_input, 3), tmp);
nir_ssa_def *out_input = intrin->src[1].ssa;
b->cursor = nir_before_instr(instr);
nir_ssa_def *lw = nir_load_var(b, state->line_width_input);
nir_ssa_def *len = nir_channel(b, lw, 3);
len = nir_fadd_imm(b, nir_fmul_imm(b, len, 2.0), -1.0);
nir_ssa_def *tmp = nir_fsat(b, nir_fadd(b, nir_channels(b, lw, 0xa),
nir_fneg(b, nir_fabs(b, nir_channels(b, lw, 0x5)))));
nir_ssa_def *out = nir_vec4(b, nir_channel(b, out_input, 0),
nir_channel(b, out_input, 1),
nir_channel(b, out_input, 2),
tmp);
nir_instr_rewrite_src(instr, &intrin->src[1], nir_src_for_ssa(out));
nir_ssa_def *max = len;
if (state->stipple_counter) {
assert(state->stipple_pattern);
nir_ssa_def *counter = nir_load_var(b, state->stipple_counter);
nir_ssa_def *pattern = nir_load_var(b, state->stipple_pattern);
nir_ssa_def *factor = nir_i2f32(b, nir_ishr_imm(b, pattern, 16));
pattern = nir_iand_imm(b, pattern, 0xffff);
nir_ssa_def *stipple_pos = nir_vec2(b, nir_fadd_imm(b, counter, -0.5),
nir_fadd_imm(b, counter, 0.5));
stipple_pos = nir_frem(b, nir_fdiv(b, stipple_pos, factor),
nir_imm_float(b, 16.0));
nir_ssa_def *p = nir_f2i32(b, stipple_pos);
nir_ssa_def *one = nir_imm_float(b, 1.0);
// float t = 1.0 - min((1.0 - fract(stipple_pos.x)) * factor, 1.0);
nir_ssa_def *t = nir_ffract(b, nir_channel(b, stipple_pos, 0));
t = nir_fsub(b, one,
nir_fmin(b, nir_fmul(b, factor,
nir_fsub(b, one, t)), one));
// vec2 a = vec2((uvec2(pattern) >> p) & uvec2(1u));
nir_ssa_def *a = nir_i2f32(b,
nir_iand(b, nir_ishr(b, nir_vec2(b, pattern, pattern), p),
nir_imm_ivec2(b, 1, 1)));
// float cov = mix(a.x, a.y, t);
nir_ssa_def *cov = nir_flrp(b, nir_channel(b, a, 0), nir_channel(b, a, 1), t);
max = nir_fmin(b, len, cov);
}
}
tmp = nir_fmul(b, nir_channel(b, tmp, 0),
nir_fmin(b, nir_channel(b, tmp, 1), max));
tmp = nir_fmul(b, nir_channel(b, out_input, 3), tmp);
static void
nir_lower_aaline_impl(nir_function_impl *impl,
lower_aaline *state)
{
nir_builder *b = &state->b;
nir_builder_init(b, impl);
nir_foreach_block(block, impl) {
nir_lower_aaline_block(block, state);
}
nir_ssa_def *out = nir_vec4(b, nir_channel(b, out_input, 0),
nir_channel(b, out_input, 1),
nir_channel(b, out_input, 2),
tmp);
nir_instr_rewrite_src(instr, &intrin->src[1], nir_src_for_ssa(out));
return true;
}
void
nir_lower_aaline_fs(struct nir_shader *shader, int *varying)
nir_lower_aaline_fs(struct nir_shader *shader, int *varying,
nir_variable *stipple_counter,
nir_variable *stipple_pattern)
{
lower_aaline state = {
.shader = shader,
.stipple_counter = stipple_counter,
.stipple_pattern = stipple_pattern,
};
if (shader->info.stage != MESA_SHADER_FRAGMENT)
return;
assert(shader->info.stage == MESA_SHADER_FRAGMENT);
int highest_location = -1, highest_drv_location = -1;
nir_foreach_shader_in_variable(var, shader) {
@ -234,11 +257,8 @@ nir_lower_aaline_fs(struct nir_shader *shader, int *varying)
*varying = tgsi_get_generic_gl_varying_index(line_width->data.location, true);
state.line_width_input = line_width;
nir_foreach_function(function, shader) {
if (function->impl) {
nir_lower_aaline_impl(function->impl, &state);
}
}
nir_shader_instructions_pass(shader, lower_aaline_instr,
nir_metadata_dominance, &state);
}
typedef struct {

View file

@ -38,7 +38,9 @@ nir_lower_pstipple_fs(struct nir_shader *shader,
bool fs_pos_is_sysval);
void
nir_lower_aaline_fs(struct nir_shader *shader, int *varying);
nir_lower_aaline_fs(struct nir_shader *shader, int *varying,
nir_variable *stipple_counter,
nir_variable *stipple_pattern);
void
nir_lower_aapoint_fs(struct nir_shader *shader, int *varying);

View file

@ -39,8 +39,13 @@ struct u_transfer_helper {
bool interleave_in_place;
};
static inline bool need_interleave_path(struct u_transfer_helper *helper,
enum pipe_format format)
/* If we need to take the path for PIPE_MAP_DEPTH/STENCIL_ONLY on the parent
* depth/stencil resource an interleaving those to/from a staging buffer. The
* other path for z/s interleave is when separate z and s resources are
* created at resource create time.
*/
static inline bool needs_in_place_zs_interleave(struct u_transfer_helper *helper,
enum pipe_format format)
{
if (!helper->interleave_in_place)
return false;
@ -68,6 +73,9 @@ static inline bool handle_transfer(struct pipe_resource *prsc)
if (helper->msaa_map && (prsc->nr_samples > 1))
return true;
if (needs_in_place_zs_interleave(helper, prsc->format))
return true;
return false;
}
@ -263,10 +271,9 @@ u_transfer_helper_transfer_map(struct pipe_context *pctx,
enum pipe_format format = prsc->format;
unsigned width = box->width;
unsigned height = box->height;
bool in_place_zs_interleave = needs_in_place_zs_interleave(helper, format);
if (need_interleave_path(helper, format))
return u_transfer_helper_deinterleave_transfer_map(pctx, prsc, level, usage, box, pptrans);
else if (!handle_transfer(prsc))
if (!handle_transfer(prsc))
return helper->vtbl->transfer_map(pctx, prsc, level, usage, box, pptrans);
if (helper->msaa_map && (prsc->nr_samples > 1))
@ -290,15 +297,22 @@ u_transfer_helper_transfer_map(struct pipe_context *pctx,
if (!trans->staging)
goto fail;
trans->ptr = helper->vtbl->transfer_map(pctx, prsc, level, usage, box,
&trans->trans);
trans->ptr = helper->vtbl->transfer_map(pctx, prsc, level,
usage | (in_place_zs_interleave ? PIPE_MAP_DEPTH_ONLY : 0),
box, &trans->trans);
if (!trans->ptr)
goto fail;
if (util_format_is_depth_and_stencil(prsc->format)) {
struct pipe_resource *stencil = helper->vtbl->get_stencil(prsc);
struct pipe_resource *stencil;
if (in_place_zs_interleave)
stencil = prsc;
else
stencil = helper->vtbl->get_stencil(prsc);
trans->ptr2 = helper->vtbl->transfer_map(pctx, stencil, level,
usage, box, &trans->trans2);
usage | (in_place_zs_interleave ? PIPE_MAP_STENCIL_ONLY : 0),
box, &trans->trans2);
if (needs_pack(usage)) {
switch (prsc->format) {
@ -315,27 +329,53 @@ u_transfer_helper_transfer_map(struct pipe_context *pctx,
width, height);
break;
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
if (helper->z24_in_z32f) {
util_format_z24_unorm_s8_uint_pack_z_float(trans->staging,
ptrans->stride,
trans->ptr,
trans->trans->stride,
width, height);
util_format_z24_unorm_s8_uint_pack_s_8uint(trans->staging,
ptrans->stride,
trans->ptr2,
trans->trans2->stride,
width, height);
if (in_place_zs_interleave) {
if (helper->z24_in_z32f) {
util_format_z24_unorm_s8_uint_pack_separate_z32(trans->staging,
ptrans->stride,
trans->ptr,
trans->trans->stride,
trans->ptr2,
trans->trans2->stride,
width, height);
} else {
util_format_z24_unorm_s8_uint_pack_separate(trans->staging,
ptrans->stride,
trans->ptr,
trans->trans->stride,
trans->ptr2,
trans->trans2->stride,
width, height);
}
} else {
util_format_z24_unorm_s8_uint_pack_separate(trans->staging,
ptrans->stride,
trans->ptr,
trans->trans->stride,
trans->ptr2,
trans->trans2->stride,
width, height);
if (helper->z24_in_z32f) {
util_format_z24_unorm_s8_uint_pack_z_float(trans->staging,
ptrans->stride,
trans->ptr,
trans->trans->stride,
width, height);
util_format_z24_unorm_s8_uint_pack_s_8uint(trans->staging,
ptrans->stride,
trans->ptr2,
trans->trans2->stride,
width, height);
} else {
util_format_z24_unorm_s8_uint_pack_separate(trans->staging,
ptrans->stride,
trans->ptr,
trans->trans->stride,
trans->ptr2,
trans->trans2->stride,
width, height);
}
}
break;
case PIPE_FORMAT_Z24X8_UNORM:
assert(helper->z24_in_z32f);
util_format_z24x8_unorm_pack_z_float(trans->staging, ptrans->stride,
trans->ptr, trans->trans->stride,
width, height);
break;
default:
unreachable("Unexpected format");
}
@ -495,21 +535,12 @@ u_transfer_helper_transfer_flush_region(struct pipe_context *pctx,
}
}
static void
u_transfer_helper_deinterleave_transfer_unmap(struct pipe_context *pctx,
struct pipe_transfer *ptrans);
void
u_transfer_helper_transfer_unmap(struct pipe_context *pctx,
struct pipe_transfer *ptrans)
{
struct u_transfer_helper *helper = pctx->screen->transfer_helper;
if (need_interleave_path(helper, ptrans->resource->format)) {
u_transfer_helper_deinterleave_transfer_unmap(pctx, ptrans);
return;
}
if (handle_transfer(ptrans->resource)) {
struct u_transfer *trans = u_transfer(ptrans);
@ -563,144 +594,3 @@ u_transfer_helper_destroy(struct u_transfer_helper *helper)
{
free(helper);
}
/* these two functions 'deinterleave' are meant to be used without the corresponding
* resource_create/destroy hooks, as they perform the interleaving on-the-fly
*
* drivers should expect to be passed the same buffer repeatedly with the format changed
* to indicate which component is being mapped
*/
static void *
u_transfer_helper_deinterleave_transfer_map(struct pipe_context *pctx,
struct pipe_resource *prsc,
unsigned level, unsigned usage,
const struct pipe_box *box,
struct pipe_transfer **pptrans)
{
struct u_transfer_helper *helper = pctx->screen->transfer_helper;
struct u_transfer *trans;
struct pipe_transfer *ptrans;
enum pipe_format format = prsc->format;
unsigned width = box->width;
unsigned height = box->height;
if (!need_interleave_path(helper, format))
return helper->vtbl->transfer_map(pctx, prsc, level, usage, box, pptrans);
assert(box->depth == 1);
trans = calloc(1, sizeof(*trans));
if (!trans)
return NULL;
ptrans = &trans->base;
pipe_resource_reference(&ptrans->resource, prsc);
ptrans->level = level;
ptrans->usage = usage;
ptrans->box = *box;
ptrans->stride = util_format_get_stride(format, box->width);
ptrans->layer_stride = ptrans->stride * box->height;
bool has_stencil = util_format_is_depth_and_stencil(format);
trans->staging = malloc(ptrans->layer_stride);
if (!trans->staging)
goto fail;
trans->ptr = helper->vtbl->transfer_map(pctx, prsc, level, usage | PIPE_MAP_DEPTH_ONLY, box,
&trans->trans);
if (!trans->ptr)
goto fail;
trans->ptr2 = NULL;
if (has_stencil)
trans->ptr2 = helper->vtbl->transfer_map(pctx, prsc, level,
usage | PIPE_MAP_STENCIL_ONLY, box, &trans->trans2);
if (needs_pack(usage)) {
switch (prsc->format) {
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
util_format_z32_float_s8x24_uint_pack_z_float(trans->staging,
ptrans->stride,
trans->ptr,
trans->trans->stride,
width, height);
util_format_z32_float_s8x24_uint_pack_s_8uint(trans->staging,
ptrans->stride,
trans->ptr2,
trans->trans2->stride,
width, height);
break;
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
if (helper->z24_in_z32f) {
util_format_z24_unorm_s8_uint_pack_separate_z32(trans->staging,
ptrans->stride,
trans->ptr,
trans->trans->stride,
trans->ptr2,
trans->trans2->stride,
width, height);
} else {
util_format_z24_unorm_s8_uint_pack_separate(trans->staging,
ptrans->stride,
trans->ptr,
trans->trans->stride,
trans->ptr2,
trans->trans2->stride,
width, height);
}
break;
case PIPE_FORMAT_Z24X8_UNORM:
assert(helper->z24_in_z32f);
util_format_z24x8_unorm_pack_z_float(trans->staging, ptrans->stride,
trans->ptr, trans->trans->stride,
width, height);
break;
default:
unreachable("Unexpected format");
}
}
*pptrans = ptrans;
return trans->staging;
fail:
if (trans->trans)
helper->vtbl->transfer_unmap(pctx, trans->trans);
if (trans->trans2)
helper->vtbl->transfer_unmap(pctx, trans->trans2);
pipe_resource_reference(&ptrans->resource, NULL);
free(trans->staging);
free(trans);
return NULL;
}
static void
u_transfer_helper_deinterleave_transfer_unmap(struct pipe_context *pctx,
struct pipe_transfer *ptrans)
{
struct u_transfer_helper *helper = pctx->screen->transfer_helper;
enum pipe_format format = ptrans->resource->format;
if (!need_interleave_path(helper, format)) {
helper->vtbl->transfer_unmap(pctx, ptrans);
return;
}
struct u_transfer *trans = (struct u_transfer *)ptrans;
if (!(ptrans->usage & PIPE_MAP_FLUSH_EXPLICIT)) {
struct pipe_box box;
u_box_2d(0, 0, ptrans->box.width, ptrans->box.height, &box);
flush_region(pctx, ptrans, &box);
}
helper->vtbl->transfer_unmap(pctx, trans->trans);
if (trans->trans2)
helper->vtbl->transfer_unmap(pctx, trans->trans2);
pipe_resource_reference(&ptrans->resource, NULL);
free(trans->staging);
free(trans);
}

View file

@ -72,7 +72,7 @@ traces:
checksum: de5452f4cbc0100d8ecb51459e47cd99
bgfx/29-debugdraw.rdc:
gl-vmware-llvmpipe:
checksum: 164e5226af26b6552506542a45bc6bf5
checksum: 015201fe000d6a323b0f7d3f218d3e47
bgfx/31-rsm.rdc:
gl-vmware-llvmpipe:
checksum: b59d323511488d5c098ebfa9b434c2dc
@ -126,7 +126,7 @@ traces:
checksum: a55dd3d87a86b3b47121ff67861028c3
jvgs/jvgs-d27fb67-v2.trace:
gl-vmware-llvmpipe:
checksum: b8c21bf76e667735d1640b215f456531
checksum: 43b89627364b4cabbab84931aef4ce5e
pathfinder/demo-v2.trace:
gl-vmware-llvmpipe:
checksum: a053c56658bc830249bc94317a3b3ea8

View file

@ -0,0 +1,23 @@
# Copyright (c) Imagination Technologies Ltd.
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
driver_pvr = declare_dependency(
compile_args : '-DGALLIUM_PVR'
)

View file

@ -0,0 +1,23 @@
# Copyright (c) Imagination Technologies Ltd.
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
driver_pvr_alias = declare_dependency(
compile_args: '-DGALLIUM_PVR_ALIAS=@0@'.format(gallium_pvr_alias)
)

View file

@ -33,12 +33,6 @@
},
"VkPhysicalDeviceLineRasterizationFeaturesEXT": {
"rectangularLines": true,
"bresenhamLines": true
}
},
"properties": {
"VkPhysicalDeviceProperties": {
}
}
},
@ -59,6 +53,22 @@
}
}
},
"gl21_baseline_line_bresenham": {
"features": {
"VkPhysicalDeviceLineRasterizationFeaturesEXT": {
"bresenhamLines": true
}
}
},
"gl21_baseline_line_non_strict": {
"properties": {
"VkPhysicalDeviceProperties": {
"limits": {
"strictLines": false
}
}
}
},
"gl21_optional": {
"extensions": {
"VK_KHR_external_memory": 1
@ -105,7 +115,6 @@
},
"features": {
"VkPhysicalDeviceFeatures": {
"occlusionQueryPrecise": true,
"dualSrcBlend": true
}
}
@ -190,6 +199,33 @@
}
}
},
"gl43_baseline_rb2": {
"extensions": {
"VK_EXT_robustness2": 1
},
"features": {
"VkPhysicalDeviceRobustness2FeaturesEXT": {
"robustImageAccess2": true
}
}
},
"gl43_baseline_rb_image_vk13": {
"features": {
"VkPhysicalDeviceVulkan13Features": {
"robustImageAccess": true
}
}
},
"gl43_baseline_rb_image_ext": {
"extensions": {
"VK_EXT_image_robustness": 1
},
"features": {
"VkPhysicalDeviceImageRobustnessFeaturesEXT": {
"robustImageAccess": true
}
}
},
"gl43_baseline": {
"features": {
"VkPhysicalDeviceFeatures": {
@ -298,7 +334,6 @@
"features": {
"VkPhysicalDeviceFeatures": {
"samplerAnisotropy": true,
"pipelineStatisticsQuery": true,
"depthBiasClamp": true
}
}
@ -551,7 +586,8 @@
"capabilities": [
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ]
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ]
]
},
"VP_ZINK_gl30_baseline": {
@ -563,6 +599,7 @@
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ],
"gl30_baseline"
]
},
@ -575,6 +612,7 @@
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ],
"gl30_baseline",
"gl31_baseline"
]
@ -588,6 +626,7 @@
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ],
"gl30_baseline",
"gl31_baseline",
"gl32_baseline"
@ -602,6 +641,7 @@
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ],
"gl30_baseline",
"gl31_baseline",
"gl32_baseline",
@ -617,6 +657,7 @@
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ],
"gl30_baseline",
"gl31_baseline",
"gl32_baseline",
@ -633,6 +674,7 @@
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ],
"gl30_baseline",
"gl31_baseline",
"gl32_baseline",
@ -650,6 +692,7 @@
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ],
"gl30_baseline",
"gl31_baseline",
"gl32_baseline",
@ -669,6 +712,7 @@
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ],
"gl30_baseline",
"gl31_baseline",
"gl32_baseline",
@ -677,7 +721,8 @@
"gl41_baseline",
"gl42_baseline",
[ "gl42_baseline_vk10", "gl42_baseline_vk12" ],
"gl43_baseline"
"gl43_baseline",
[ "gl43_baseline_rb2", "gl43_baseline_rb_image_vk13", "gl43_baseline_rb_image_ext" ]
]
},
"VP_ZINK_gl44_baseline": {
@ -689,6 +734,7 @@
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ],
"gl30_baseline",
"gl31_baseline",
"gl32_baseline",
@ -698,6 +744,7 @@
"gl42_baseline",
[ "gl42_baseline_vk10", "gl42_baseline_vk12" ],
"gl43_baseline",
[ "gl43_baseline_rb2", "gl43_baseline_rb_image_vk13", "gl43_baseline_rb_image_ext" ],
"gl44_baseline"
]
},
@ -710,6 +757,7 @@
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ],
"gl30_baseline",
"gl31_baseline",
"gl32_baseline",
@ -719,6 +767,7 @@
"gl42_baseline",
[ "gl42_baseline_vk10", "gl42_baseline_vk12" ],
"gl43_baseline",
[ "gl43_baseline_rb2", "gl43_baseline_rb_image_vk13", "gl43_baseline_rb_image_ext" ],
"gl44_baseline",
"gl45_baseline"
]
@ -732,6 +781,7 @@
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ],
"gl30_baseline",
"gl31_baseline",
"gl32_baseline",
@ -741,6 +791,7 @@
"gl42_baseline",
[ "gl42_baseline_vk10", "gl42_baseline_vk12" ],
"gl43_baseline",
[ "gl43_baseline_rb2", "gl43_baseline_rb_image_vk13", "gl43_baseline_rb_image_ext" ],
"gl44_baseline",
"gl45_baseline",
"gl46_baseline"
@ -755,6 +806,7 @@
"vulkan10requirements",
"gl21_baseline",
[ "gl21_baseline_vk10", "gl21_baseline_vk12" ],
[ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ],
"gl30_baseline",
"gl31_baseline",
"gl32_baseline",
@ -764,6 +816,7 @@
"gl42_baseline",
[ "gl42_baseline_vk10", "gl42_baseline_vk12" ],
"gl43_baseline",
[ "gl43_baseline_rb2", "gl43_baseline_rb_image_vk13", "gl43_baseline_rb_image_ext" ],
"gl44_baseline",
"gl45_baseline",
"gl46_baseline",

View file

@ -0,0 +1,813 @@
dEQP-GLES31.functional.layout_binding.ubo.fragment_binding_array,Fail
dEQP-GLES31.functional.layout_binding.ubo.fragment_binding_max_array,Fail
dEQP-GLES31.functional.layout_binding.ubo.fragment_binding_multiple,Fail
dEQP-GLES31.functional.layout_binding.ubo.vertex_binding_array,Fail
dEQP-GLES31.functional.layout_binding.ubo.vertex_binding_max_array,Fail
dEQP-GLES31.functional.layout_binding.ubo.vertex_binding_multiple,Fail
# CTS bug: https://gitlab.khronos.org/Tracker/vk-gl-cts/-/issues/4200
KHR-GLES31.core.compute_shader.max,Fail
# "Invalid result. Region (0x0). Expected: 0 got 1"
KHR-GLES31.core.viewport_array.dynamic_viewport_index,Fail
# "Fail, buffer content is not well preserved when age > 0 (Fail)"
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_clear_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_clear_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_render_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_clear_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_render_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_clear_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.no_resize.odd_render_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_clear_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_clear_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_render_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_clear_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_render_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_clear_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_after_swap.odd_render_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_clear_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_clear_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_render_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_clear_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_clear_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_render_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_clear_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_even_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_render_even_clear_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_render_even_clear,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_render_even_none,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_render_even_render_render,Fail
dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_render_even_render,Fail
dEQP-EGL.functional.query_context.get_current_context.rgba8888_window,Crash
# Around the time of running these tests there are some warnings from the kernel in dma_resv.c, and at least
# some failures look like not waiting for rendering to complete.
wayland-dEQP-EGL.functional.color_clears.multi_context.gles1_gles2_gles3.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles1_gles2_gles3.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles1_gles2_gles3.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles1_gles2.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles1_gles2.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles1_gles2.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles1.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles1.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles1.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles2.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles2.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles2.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles3.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles3.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_context.gles3.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles1_gles2_gles3.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles1_gles2_gles3.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles1_gles2_gles3.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles1_gles2.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles1_gles2.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles1_gles2.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles1.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles1.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles1.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles2.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles2.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles2.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles3.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles3.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.multi_thread.gles3.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.single_context.gles1.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.single_context.gles1.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.single_context.gles1.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.single_context.gles2.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.single_context.gles2.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.single_context.gles2.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.single_context.gles3.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.single_context.gles3.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.color_clears.single_context.gles3.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.negative_api.create_pixmap_surface,Fail
wayland-dEQP-EGL.functional.render.multi_context.gles2_gles3.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_context.gles2_gles3.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_context.gles2_gles3.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_context.gles2.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_context.gles2.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_context.gles2.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_context.gles3.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_context.gles3.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_context.gles3.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_thread.gles2_gles3.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_thread.gles2_gles3.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_thread.gles2_gles3.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_thread.gles2.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_thread.gles2.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_thread.gles2.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_thread.gles3.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_thread.gles3.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.multi_thread.gles3.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.single_context.gles2.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.render.single_context.gles2.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.single_context.gles2.rgba8888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.single_context.gles3.rgb565_pbuffer,Fail
wayland-dEQP-EGL.functional.render.single_context.gles3.rgb888_pbuffer,Fail
wayland-dEQP-EGL.functional.render.single_context.gles3.rgba8888_pbuffer,Fail
565-nozs-dEQP-GLES3.functional.color_clear.complex_rgb,Fail
spec@egl_chromium_sync_control@conformance@eglGetSyncValuesCHROMIUM_ust_test,Fail
spec@egl_chromium_sync_control@conformance@eglGetSyncValuesCHROMIUM_msc_and_sbc_test,Fail
spec@egl_chromium_sync_control@conformance,Fail
# "GLX_MESA_copy_sub_buffer found in both client and server extension strings, but missing from unified string."
glx@extension string sanity,Fail
glx@glx_arb_create_context_es2_profile@invalid opengl es version,Fail
glx@glx_arb_create_context_no_error@no error,Fail
glx@glx_arb_create_context_robustness@invalid reset notification strategy,Fail
# "Could not create initial indirect-rendering context."
glx@glx_ext_import_context@free context,Fail
glx@glx_ext_import_context@get context id,Fail
glx@glx_ext_import_context@get current display,Fail
glx@glx_ext_import_context@import context- multi process,Fail
glx@glx_ext_import_context@import context- single process,Fail
glx@glx_ext_import_context@imported context has same context id,Fail
glx@glx_ext_import_context@make current- multi process,Fail
glx@glx_ext_import_context@make current- single process,Fail
glx@glx_ext_import_context@query context info,Fail
# See also the EGL buffer age failures
glx@glx-buffer-age,Fail
glx@glx-buffer-age vblank_mode=0,Fail
glx@glx-make-current,Crash
glx@glx-multi-window-single-context,Crash
glx@glx-swap-copy,Fail
glx@glx-swap-pixmap-bad,Fail
glx@glx-tfp,Crash
# errors like:
# X Error of failed request: BadWindow (invalid Window parameter)
# ../src/gallium/drivers/zink/zink_resource.c:1215: resource_create: Assertion `res->obj->dt' failed.
glx@glx-visuals-depth,Crash
# ../src/gallium/drivers/zink/zink_kopper.c:859: zink_kopper_update: Assertion `pres->bind & PIPE_BIND_DISPLAY_TARGET' failed.
glx@glx-visuals-depth -pixmap,Crash
glx@glx-visuals-stencil -pixmap,Crash
glx@glx-visuals-stencil,Crash
shaders@glsl-fs-pointcoord,Fail
shaders@point-vertex-id divisor,Fail
shaders@point-vertex-id gl_instanceid divisor,Fail
shaders@point-vertex-id gl_instanceid,Fail
shaders@point-vertex-id gl_vertexid divisor,Fail
shaders@point-vertex-id gl_vertexid gl_instanceid divisor,Fail
shaders@point-vertex-id gl_vertexid gl_instanceid,Fail
shaders@point-vertex-id gl_vertexid,Fail
spec@!opengl 1.0@gl-1.0-edgeflag-quads,Fail
spec@!opengl 1.0@gl-1.0-edgeflag,Fail
spec@!opengl 1.0@gl-1.0-no-op-paths,Fail
spec@!opengl 1.0@gl-1.0-spot-light,Fail
spec@!opengl 1.0@gl-1.0-swapbuffers-behavior,Fail
spec@!opengl 1.1@depthstencil-default_fb-blit samples=16,Fail
spec@!opengl 1.1@depthstencil-default_fb-blit samples=2,Fail
spec@!opengl 1.1@depthstencil-default_fb-blit samples=6,Fail
spec@!opengl 1.1@depthstencil-default_fb-blit samples=8,Fail
spec@!opengl 1.1@line-aa-width,Fail
spec@!opengl 1.1@line-flat-clip-color,Fail
spec@!opengl 1.1@polygon-mode-facing,Fail
spec@!opengl 1.1@polygon-mode-offset,Fail
spec@!opengl 1.1@polygon-mode-offset@config 0: Expected blue pixel in center,Fail
spec@!opengl 1.1@polygon-mode-offset@config 1: Expected blue pixel in center,Fail
spec@!opengl 1.1@polygon-mode-offset@config 2: Expected blue pixel in center,Fail
spec@!opengl 1.1@polygon-mode-offset@config 2: Expected white pixel on right edge,Fail
spec@!opengl 1.1@polygon-mode-offset@config 2: Expected white pixel on top edge,Fail
spec@!opengl 1.1@polygon-mode-offset@config 5: Expected blue pixel in center,Fail
spec@!opengl 1.1@polygon-mode-offset@config 6: Expected blue pixel in center,Fail
spec@!opengl 1.1@polygon-mode-offset@config 6: Expected white pixel on right edge,Fail
spec@!opengl 1.1@polygon-mode-offset@config 6: Expected white pixel on top edge,Fail
# Frontend issue across multiple drivers.
spec@!opengl 1.0@rasterpos,Fail
spec@!opengl 1.0@rasterpos@glsl_vs_gs_linked,Fail
spec@!opengl 1.0@rasterpos@glsl_vs_tes_linked,Fail
spec@!opengl 1.1@linestipple@Line strip,Fail
spec@!opengl 1.1@linestipple@Line loop,Fail
spec@!opengl 1.1@linestipple@Factor 2x,Fail
spec@!opengl 1.1@linestipple@Factor 3x,Fail
spec@!opengl 1.1@linestipple,Fail
# polygon-mode: glPolygonMode(front=GL_LINE, back=GL_FILL), glCullMode(GL_NONE/GL_FALSE/GL_NO_ERROR) failed
# At position 0, found prim GL_FILL instead of GL_LINE
# polygon-mode: glPolygonMode(front=GL_POINT, back=GL_FILL), glCullMode(GL_NONE/GL_FALSE/GL_NO_ERROR) failed
# At position 1, found prim GL_POINT instead of GL_FILL
# (and more)
spec@!opengl 1.1@polygon-mode,Fail
spec@!opengl 2.0@gl-2.0-edgeflag-immediate,Fail
spec@!opengl 2.0@gl-2.0-edgeflag,Fail
spec@!opengl 2.0@vs-point_size-zero,Fail
spec@!opengl 2.1@pbo,Fail
spec@!opengl 2.1@pbo@test_polygon_stip,Fail
spec@!opengl 2.1@polygon-stipple-fs,Fail
spec@!opengl 3.0@clearbuffer-depth-cs-probe,Fail
spec@!opengl 3.2@gl-3.2-adj-prims cull-back pv-first,Fail
spec@!opengl 3.2@gl-3.2-adj-prims cull-front pv-first,Fail
spec@!opengl 3.2@gl-3.2-adj-prims line cull-back pv-first,Fail
spec@!opengl 3.2@gl-3.2-adj-prims line cull-front pv-first,Fail
spec@!opengl 3.2@gl-3.2-adj-prims pv-first,Fail
spec@!opengl es 2.0@glsl-fs-pointcoord,Fail
spec@arb_arrays_of_arrays@execution@image_store@basic-imagestore-mixed-const-non-const-uniform-index,Fail
spec@arb_arrays_of_arrays@execution@image_store@basic-imagestore-mixed-const-non-const-uniform-index2,Fail
spec@arb_arrays_of_arrays@execution@image_store@basic-imagestore-non-const-uniform-index,Fail
spec@arb_framebuffer_object@fbo-blit-scaled-linear,Fail
spec@arb_framebuffer_object@fbo-gl_pointcoord,Fail
spec@arb_gl_spirv@execution@xfb@vs_block_array,Fail
spec@arb_gpu_shader_fp64@execution@arb_gpu_shader_fp64-tf-separate,Fail
spec@arb_gpu_shader_fp64@execution@glsl-fs-loop-unroll-mul-fp64,Fail
spec@arb_gpu_shader_fp64@uniform_buffers@fs-ubo-load.indirect.3,Fail
spec@arb_point_sprite@arb_point_sprite-checkerboard,Fail
spec@arb_point_sprite@arb_point_sprite-mipmap,Fail
spec@arb_program_interface_query@arb_program_interface_query-getprogramresourceindex,Fail
spec@arb_program_interface_query@arb_program_interface_query-getprogramresourceindex@'vs_input2[1][0]' on GL_PROGRAM_INPUT,Fail
spec@arb_sample_locations@test,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 0- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 1- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 2- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 1- X: 3- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 0- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 1- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 2- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 16- X: 3- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 0- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 1- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 2- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 2- X: 3- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 0- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 1- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 2- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 4- X: 3- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 0- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 1- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 2- Y: 6- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 0- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 0- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 1- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 1- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 2- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 2- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 3- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 3- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 4- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 4- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 5- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 5- Grid: true,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 6- Grid: false,Fail
spec@arb_sample_locations@test@MSAA: 8- X: 3- Y: 6- Grid: true,Fail
spec@arb_sample_shading@samplemask 16 all,Fail
spec@arb_sample_shading@samplemask 16 all@0.062500 mask_in_one,Fail
spec@arb_sample_shading@samplemask 16 all@0.125000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 16 all@0.250000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 16 all@0.500000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 16 all@1.000000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 16 all@noms mask_in_one,Fail
spec@arb_sample_shading@samplemask 16 all@noms partition,Fail
spec@arb_sample_shading@samplemask 16 all@sample mask_in_one,Fail
spec@arb_sample_shading@samplemask 16,Fail
spec@arb_sample_shading@samplemask 16@0.062500 mask_in_one,Fail
spec@arb_sample_shading@samplemask 16@0.125000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 16@0.250000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 16@0.500000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 16@1.000000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 16@noms mask_in_one,Fail
spec@arb_sample_shading@samplemask 16@noms partition,Fail
spec@arb_sample_shading@samplemask 16@sample mask_in_one,Fail
spec@arb_sample_shading@samplemask 2 all,Fail
spec@arb_sample_shading@samplemask 2 all@0.500000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 2 all@1.000000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 2 all@noms mask_in_one,Fail
spec@arb_sample_shading@samplemask 2 all@noms partition,Fail
spec@arb_sample_shading@samplemask 2 all@sample mask_in_one,Fail
spec@arb_sample_shading@samplemask 2,Fail
spec@arb_sample_shading@samplemask 2@0.500000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 2@1.000000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 2@noms mask_in_one,Fail
spec@arb_sample_shading@samplemask 2@noms partition,Fail
spec@arb_sample_shading@samplemask 2@sample mask_in_one,Fail
spec@arb_sample_shading@samplemask 4 all,Fail
spec@arb_sample_shading@samplemask 4 all@0.250000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 4 all@0.500000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 4 all@1.000000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 4 all@noms mask_in_one,Fail
spec@arb_sample_shading@samplemask 4 all@noms partition,Fail
spec@arb_sample_shading@samplemask 4 all@sample mask_in_one,Fail
spec@arb_sample_shading@samplemask 4,Fail
spec@arb_sample_shading@samplemask 4@0.250000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 4@0.500000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 4@1.000000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 4@noms mask_in_one,Fail
spec@arb_sample_shading@samplemask 4@noms partition,Fail
spec@arb_sample_shading@samplemask 4@sample mask_in_one,Fail
spec@arb_sample_shading@samplemask 6 all,Fail
spec@arb_sample_shading@samplemask 6 all@0.125000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 6 all@0.250000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 6 all@0.500000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 6 all@1.000000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 6 all@noms mask_in_one,Fail
spec@arb_sample_shading@samplemask 6 all@noms partition,Fail
spec@arb_sample_shading@samplemask 6 all@sample mask_in_one,Fail
spec@arb_sample_shading@samplemask 6,Fail
spec@arb_sample_shading@samplemask 6@0.125000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 6@0.250000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 6@0.500000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 6@1.000000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 6@noms mask_in_one,Fail
spec@arb_sample_shading@samplemask 6@noms partition,Fail
spec@arb_sample_shading@samplemask 6@sample mask_in_one,Fail
spec@arb_sample_shading@samplemask 8 all,Fail
spec@arb_sample_shading@samplemask 8 all@0.125000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 8 all@0.250000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 8 all@0.500000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 8 all@1.000000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 8 all@noms mask_in_one,Fail
spec@arb_sample_shading@samplemask 8 all@noms partition,Fail
spec@arb_sample_shading@samplemask 8 all@sample mask_in_one,Fail
spec@arb_sample_shading@samplemask 8,Fail
spec@arb_sample_shading@samplemask 8@0.125000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 8@0.250000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 8@0.500000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 8@1.000000 mask_in_one,Fail
spec@arb_sample_shading@samplemask 8@noms mask_in_one,Fail
spec@arb_sample_shading@samplemask 8@noms partition,Fail
spec@arb_sample_shading@samplemask 8@sample mask_in_one,Fail
spec@arb_shader_image_load_store@early-z,Fail
spec@arb_shader_image_load_store@early-z@occlusion query test/early-z pass,Fail
spec@arb_shader_image_load_store@host-mem-barrier,Fail
spec@arb_shader_image_load_store@host-mem-barrier@Transform feedback/WaW/one bit barrier test/16x16,Fail
spec@arb_shader_image_load_store@host-mem-barrier@Transform feedback/WaW/one bit barrier test/4x4,Fail
spec@arb_shader_image_load_store@host-mem-barrier@Transform feedback/WaW/one bit barrier test/64x64,Fail
spec@arb_tessellation_shader@execution@variable-indexing@tcs-patch-vec4-swiz-index-wr,Fail
# "../src/gallium/drivers/zink/zink_compiler.c:2071: assign_producer_var_io: Assertion `*reserved < MAX_VARYING' failed."
spec@arb_tessellation_shader@execution@variable-indexing@tes-both-input-array-float-index-rd,Crash
spec@arb_tessellation_shader@execution@variable-indexing@tes-both-input-array-vec2-index-rd,Crash
spec@arb_tessellation_shader@execution@variable-indexing@tes-both-input-array-vec3-index-rd,Crash
spec@arb_tessellation_shader@execution@variable-indexing@tes-both-input-array-vec4-index-rd,Crash
# "arb_texture_buffer_object-formats: ../src/gallium/drivers/zink/zink_context.c:807: create_bvci: Assertion `bvci.format' failed."
spec@arb_texture_buffer_object@formats (vs- arb),Crash
spec@arb_texture_buffer_object@formats (fs- arb),Crash
spec@arb_texture_buffer_object@formats (fs- arb)@GL_ALPHA16,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_ALPHA16F_ARB,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_ALPHA16I_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_ALPHA16UI_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_ALPHA32F_ARB,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_ALPHA32I_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_ALPHA32UI_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_ALPHA8,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_ALPHA8I_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_ALPHA8UI_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE_ALPHA16F_ARB,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE_ALPHA16I_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE_ALPHA16UI_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE_ALPHA32F_ARB,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE_ALPHA32I_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE_ALPHA32UI_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE_ALPHA8I_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE_ALPHA8UI_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE16_ALPHA16,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE16,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE16F_ARB,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE16I_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE16UI_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE32F_ARB,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE32I_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE32UI_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE8_ALPHA8,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE8,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE8I_EXT,Fail
spec@arb_texture_buffer_object@formats (fs- arb)@GL_LUMINANCE8UI_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_ALPHA16,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_ALPHA16F_ARB,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_ALPHA16I_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_ALPHA16UI_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_ALPHA32F_ARB,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_ALPHA32I_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_ALPHA32UI_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_ALPHA8,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_ALPHA8I_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_ALPHA8UI_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE_ALPHA16F_ARB,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE_ALPHA16I_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE_ALPHA16UI_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE_ALPHA32F_ARB,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE_ALPHA32I_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE_ALPHA32UI_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE_ALPHA8I_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE_ALPHA8UI_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE16_ALPHA16,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE16,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE16F_ARB,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE16I_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE16UI_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE32F_ARB,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE32I_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE32UI_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE8_ALPHA8,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE8,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE8I_EXT,Fail
spec@arb_texture_buffer_object@formats (vs- arb)@GL_LUMINANCE8UI_EXT,Fail
spec@arb_texture_cube_map@copyteximage cube samples=16,Fail
spec@arb_texture_cube_map@copyteximage cube samples=2,Fail
spec@arb_texture_cube_map@copyteximage cube samples=4,Fail
spec@arb_texture_cube_map@copyteximage cube samples=6,Fail
spec@arb_texture_cube_map@copyteximage cube samples=8,Fail
spec@egl 1.4@eglterminate then unbind context,Fail
spec@egl_khr_gl_image@egl_khr_gl_renderbuffer_image-clear-shared-image gl_depth_component24,Fail
spec@egl_khr_surfaceless_context@viewport,Fail
spec@egl_mesa_configless_context@basic,Fail
# Fails across most drivers, but it's a silly test.
spec@ext_framebuffer_blit@fbo-blit-check-limits,Fail
spec@ext_framebuffer_multisample@blit-mismatched-formats,Fail
spec@ext_framebuffer_multisample@clip-and-scissor-blit 16 msaa,Fail
spec@ext_framebuffer_multisample@enable-flag,Fail
spec@ext_framebuffer_multisample@interpolation 16 centroid-deriv-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 16 centroid-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 16 non-centroid-deriv-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 16 non-centroid-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 2 centroid-deriv-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 2 centroid-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 2 non-centroid-deriv-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 2 non-centroid-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 4 centroid-deriv-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 4 centroid-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 4 non-centroid-deriv-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 4 non-centroid-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 6 centroid-deriv-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 6 centroid-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 6 non-centroid-deriv-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 6 non-centroid-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 8 centroid-deriv-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 8 centroid-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 8 non-centroid-deriv-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 8 non-centroid-disabled,Fail
spec@ext_packed_float@query-rgba-signed-components,Fail
spec@ext_texture_array@copyteximage 1d_array samples=16,Fail
spec@ext_texture_array@copyteximage 1d_array samples=2,Fail
spec@ext_texture_array@copyteximage 1d_array samples=4,Fail
spec@ext_texture_array@copyteximage 1d_array samples=6,Fail
spec@ext_texture_array@copyteximage 1d_array samples=8,Fail
spec@ext_texture_array@copyteximage 2d_array samples=16,Fail
spec@ext_texture_array@copyteximage 2d_array samples=2,Fail
spec@ext_texture_array@copyteximage 2d_array samples=4,Fail
spec@ext_texture_array@copyteximage 2d_array samples=6,Fail
spec@ext_texture_array@copyteximage 2d_array samples=8,Fail
spec@ext_transform_feedback@tessellation triangle_fan flat_first,Fail
spec@glsl-1.50@execution@primitive-id-no-gs-quad-strip,Fail
spec@glsl-1.50@execution@primitive-id-no-gs-quads,Fail
spec@khr_texture_compression_astc@miptree-gl srgb-fp,Fail
spec@khr_texture_compression_astc@miptree-gl srgb-fp@sRGB decode full precision,Fail
spec@khr_texture_compression_astc@miptree-gles srgb-fp,Fail
spec@khr_texture_compression_astc@miptree-gles srgb-fp@sRGB decode full precision,Fail
spec@khr_texture_compression_astc@sliced-3d-miptree-gl srgb-fp,Fail
spec@khr_texture_compression_astc@sliced-3d-miptree-gl srgb-fp@sRGB decode full precision,Fail
spec@khr_texture_compression_astc@sliced-3d-miptree-gles srgb-fp,Fail
spec@khr_texture_compression_astc@sliced-3d-miptree-gles srgb-fp@sRGB decode full precision,Fail

View file

@ -85,13 +85,11 @@ spec@!opengl 1.1@polygon-mode-offset@config 6: Expected blue pixel in center,Fai
spec@!opengl 1.1@polygon-mode-offset@config 6: Expected white pixel on right edge,Fail
spec@!opengl 1.1@polygon-mode-offset@config 6: Expected white pixel on top edge,Fail
spec@!opengl 1.2@copyteximage 3d,Fail
spec@!opengl 2.0@depth-tex-modes-glsl,Fail
spec@!opengl 2.0@gl-2.0-edgeflag,Fail
spec@!opengl 2.0@gl-2.0-edgeflag-immediate,Fail
spec@!opengl 2.1@pbo,Fail
spec@!opengl 2.1@pbo@test_polygon_stip,Fail
spec@!opengl 2.1@polygon-stipple-fs,Fail
spec@arb_depth_texture@depth-tex-modes,Fail
spec@arb_gpu_shader_fp64@execution@arb_gpu_shader_fp64-tf-separate,Fail
spec@arb_pipeline_statistics_query@arb_pipeline_statistics_query-frag,Fail
spec@arb_point_sprite@arb_point_sprite-checkerboard,Fail
@ -154,7 +152,6 @@ spec@ext_framebuffer_multisample@interpolation 4 centroid-edges,Fail
spec@ext_framebuffer_multisample@interpolation 4 non-centroid-deriv-disabled,Fail
spec@ext_framebuffer_multisample@interpolation 4 non-centroid-disabled,Fail
spec@ext_packed_float@query-rgba-signed-components,Fail
spec@ext_texture_swizzle@depth_texture_mode_and_swizzle,Fail
spec@intel_performance_query@intel_performance_query-issue_2235,Fail
spec@khr_texture_compression_astc@miptree-gl srgb-fp,Fail
@ -185,12 +182,6 @@ spec@!opengl 1.0@rasterpos@glsl_vs_tes_linked,Fail
spec@arb_arrays_of_arrays@execution@image_store@basic-imagestore-mixed-const-non-const-uniform-index,Fail
spec@arb_arrays_of_arrays@execution@image_store@basic-imagestore-mixed-const-non-const-uniform-index2,Fail
spec@arb_arrays_of_arrays@execution@image_store@basic-imagestore-non-const-uniform-index,Fail
spec@arb_fragment_program_shadow@tex-shadow1d,Fail
spec@arb_fragment_program_shadow@tex-shadow2d,Fail
spec@arb_fragment_program_shadow@tex-shadow2drect,Fail
spec@arb_fragment_program_shadow@txp-shadow1d,Fail
spec@arb_fragment_program_shadow@txp-shadow2d,Fail
spec@arb_fragment_program_shadow@txp-shadow2drect,Fail
spec@arb_gl_spirv@execution@xfb@vs_block_array,Fail
spec@arb_gpu_shader_fp64@execution@conversion@frag-conversion-explicit-dmat2-mat2,Fail
spec@arb_gpu_shader_fp64@execution@conversion@frag-conversion-explicit-dmat2x3-mat2x3,Fail
@ -232,48 +223,7 @@ spec@arb_gpu_shader_fp64@execution@conversion@vert-conversion-explicit-dvec2-vec
spec@arb_gpu_shader_fp64@execution@conversion@vert-conversion-explicit-dvec3-vec3,Fail
spec@arb_gpu_shader_fp64@execution@conversion@vert-conversion-explicit-dvec4-vec4,Fail
spec@arb_shader_storage_buffer_object@execution@ssbo-atomiccompswap-int,Fail
spec@arb_shader_texture_lod@execution@glsl-fs-shadow2dgradarb-01,Fail
spec@arb_shader_texture_lod@execution@glsl-fs-shadow2dgradarb-03,Fail
spec@arb_shader_texture_lod@execution@glsl-fs-shadow2dgradarb-07,Fail
spec@arb_shader_texture_lod@execution@glsl-fs-shadow2dgradarb-08,Fail
spec@arb_shader_texture_lod@execution@glsl-fs-shadow2dgradarb-cumulative,Fail
spec@arb_tessellation_shader@execution@gs-primitiveid-instanced,Fail
spec@arb_texture_rectangle@glsl-fs-shadow2drect,Fail
spec@arb_texture_rectangle@glsl-fs-shadow2drect-01,Fail
spec@arb_texture_rectangle@glsl-fs-shadow2drect-03,Fail
spec@arb_texture_rectangle@glsl-fs-shadow2drect-07,Fail
spec@arb_texture_rectangle@glsl-fs-shadow2drect-08,Fail
spec@arb_texture_rectangle@glsl-fs-shadow2drectproj,Fail
spec@arb_texture_rg@execution@fs-shadow2d-red-01,Fail
spec@arb_texture_rg@execution@fs-shadow2d-red-02,Fail
spec@arb_texture_rg@execution@fs-shadow2d-red-03,Fail
spec@ext_texture_array@glsl-fs-shadow1darray,Fail
spec@ext_texture_array@glsl-fs-shadow1darray-01,Fail
spec@ext_texture_array@glsl-fs-shadow1darray-03,Fail
spec@ext_texture_array@glsl-fs-shadow1darray-07,Fail
spec@ext_texture_array@glsl-fs-shadow1darray-08,Fail
spec@ext_texture_array@glsl-fs-shadow1darray-bias,Fail
spec@ext_texture_array@glsl-fs-shadow2darray,Fail
spec@ext_texture_array@glsl-fs-shadow2darray-01,Fail
spec@ext_texture_array@glsl-fs-shadow2darray-03,Fail
spec@ext_texture_array@glsl-fs-shadow2darray-07,Fail
spec@ext_texture_array@glsl-fs-shadow2darray-08,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow1d,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow1d-01,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow1d-03,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow1d-07,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow1d-08,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow1d-bias,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow1dproj,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow1dproj-bias,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow2d,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow2d-01,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow2d-03,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow2d-07,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow2d-08,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow2d-bias,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow2dproj,Fail
spec@glsl-1.10@execution@samplers@glsl-fs-shadow2dproj-bias,Fail
spec@glsl-1.50@execution@primitive-id-no-gs-quad-strip,Fail
spec@glsl-1.50@execution@primitive-id-no-gs-quads,Fail
spec@glsl-4.00@execution@conversion@frag-conversion-explicit-dmat2-mat2,Fail

View file

@ -779,6 +779,25 @@ emit_output(struct ntv_context *ctx, struct nir_variable *var)
ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
}
static void
emit_shader_temp(struct ntv_context *ctx, struct nir_variable *var)
{
SpvId var_type = get_glsl_type(ctx, var->type);
SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
SpvStorageClassPrivate,
var_type);
SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
SpvStorageClassPrivate);
if (var->name)
spirv_builder_emit_name(&ctx->builder, var_id, var->name);
_mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
}
static void
emit_temp(struct ntv_context *ctx, struct nir_variable *var)
{
@ -3286,7 +3305,7 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
emit_load_uint_input(ctx, intr, &ctx->sample_mask_in_var, "gl_SampleMaskIn", SpvBuiltInSampleMask);
break;
case nir_intrinsic_emit_vertex_with_counter:
case nir_intrinsic_emit_vertex:
/* geometry shader emits copied xfb outputs just prior to EmitVertex(),
* since that's the end of the shader
*/
@ -3297,11 +3316,7 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
ctx->nir->info.stage == MESA_SHADER_GEOMETRY && util_bitcount(ctx->nir->info.gs.active_stream_mask) > 1);
break;
case nir_intrinsic_set_vertex_and_primitive_count:
/* do nothing */
break;
case nir_intrinsic_end_primitive_with_counter:
case nir_intrinsic_end_primitive:
spirv_builder_end_primitive(&ctx->builder, nir_intrinsic_stream_id(intr),
ctx->nir->info.stage == MESA_SHADER_GEOMETRY && util_bitcount(ctx->nir->info.gs.active_stream_mask) > 1);
break;
@ -3831,26 +3846,22 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
return;
}
SpvId actual_dest_type;
if (dref && tex->op != nir_texop_tg4)
actual_dest_type = spirv_builder_type_float(&ctx->builder, 32);
else {
unsigned num_components = nir_dest_num_components(tex->dest);
switch (nir_alu_type_get_base_type(tex->dest_type)) {
case nir_type_int:
actual_dest_type = get_ivec_type(ctx, 32, num_components);
break;
unsigned num_components = nir_dest_num_components(tex->dest);
switch (nir_alu_type_get_base_type(tex->dest_type)) {
case nir_type_int:
actual_dest_type = get_ivec_type(ctx, 32, num_components);
break;
case nir_type_uint:
actual_dest_type = get_uvec_type(ctx, 32, num_components);
break;
case nir_type_uint:
actual_dest_type = get_uvec_type(ctx, 32, num_components);
break;
case nir_type_float:
actual_dest_type = get_fvec_type(ctx, 32, num_components);
break;
case nir_type_float:
actual_dest_type = get_fvec_type(ctx, 32, num_components);
break;
default:
unreachable("unexpected nir_alu_type");
}
default:
unreachable("unexpected nir_alu_type");
}
SpvId result;
@ -4741,6 +4752,9 @@ nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, uint32_
ctx.regs[reg->index] = var;
}
nir_foreach_variable_with_modes(var, s, nir_var_shader_temp)
emit_shader_temp(&ctx, var);
nir_foreach_function_temp_variable(var, entry)
emit_temp(&ctx, var);

View file

@ -29,8 +29,8 @@ reset_obj(struct zink_screen *screen, struct zink_batch_state *bs, struct zink_r
/* if no batch usage exists after removing the usage from 'bs', this resource is considered fully idle */
if (!zink_resource_object_usage_unset(obj, bs)) {
/* the resource is idle, so reset all access/reordering info */
obj->unordered_read = false;
obj->unordered_write = false;
obj->unordered_read = true;
obj->unordered_write = true;
obj->access = 0;
obj->access_stage = 0;
/* also prune dead view objects */
@ -139,14 +139,15 @@ zink_reset_batch_state(struct zink_context *ctx, struct zink_batch_state *bs)
util_dynarray_clear(&bs->wait_semaphore_stages);
bs->present = VK_NULL_HANDLE;
/* semaphores are not destroyed here;
* destroying semaphores triggers ioctls, so defer deletion to the submit thread to avoid blocking
*/
memcpy(&bs->unref_semaphores, &bs->acquires, sizeof(struct util_dynarray));
util_dynarray_init(&bs->acquires, NULL);
while (util_dynarray_contains(&bs->wait_semaphores, VkSemaphore))
util_dynarray_append(&bs->unref_semaphores, VkSemaphore, util_dynarray_pop(&bs->wait_semaphores, VkSemaphore));
util_dynarray_init(&bs->wait_semaphores, NULL);
/* check the arrays first to avoid locking unnecessarily */
if (util_dynarray_contains(&bs->acquires, VkSemaphore) || util_dynarray_contains(&bs->wait_semaphores, VkSemaphore)) {
simple_mtx_lock(&screen->semaphores_lock);
util_dynarray_append_dynarray(&screen->semaphores, &bs->acquires);
util_dynarray_clear(&bs->acquires);
util_dynarray_append_dynarray(&screen->semaphores, &bs->wait_semaphores);
util_dynarray_clear(&bs->wait_semaphores);
simple_mtx_unlock(&screen->semaphores_lock);
}
bs->swapchain = NULL;
/* only reset submitted here so that tc fence desync can pick up the 'completed' flag
@ -198,8 +199,6 @@ unref_resources(struct zink_screen *screen, struct zink_batch_state *bs)
/* this is typically where resource objects get destroyed */
zink_resource_object_reference(screen, &obj, NULL);
}
while (util_dynarray_contains(&bs->unref_semaphores, VkSemaphore))
VKSCR(DestroySemaphore)(screen->dev, util_dynarray_pop(&bs->unref_semaphores, VkSemaphore), NULL);
}
/* utility for resetting a batch state; called on context destruction */
@ -269,7 +268,6 @@ zink_batch_state_destroy(struct zink_screen *screen, struct zink_batch_state *bs
util_dynarray_fini(&bs->bindless_releases[0]);
util_dynarray_fini(&bs->bindless_releases[1]);
util_dynarray_fini(&bs->acquires);
util_dynarray_fini(&bs->unref_semaphores);
util_dynarray_fini(&bs->acquire_flags);
zink_batch_descriptor_deinit(screen, bs);
ralloc_free(bs);
@ -326,7 +324,6 @@ create_batch_state(struct zink_context *ctx)
util_dynarray_init(&bs->persistent_resources, NULL);
util_dynarray_init(&bs->unref_resources, NULL);
util_dynarray_init(&bs->acquires, NULL);
util_dynarray_init(&bs->unref_semaphores, NULL);
util_dynarray_init(&bs->acquire_flags, NULL);
util_dynarray_init(&bs->bindless_releases[0], NULL);
util_dynarray_init(&bs->bindless_releases[1], NULL);

View file

@ -721,23 +721,10 @@ zink_bo_unmap(struct zink_screen *screen, struct zink_bo *bo)
}
}
static VkSemaphore
get_semaphore(struct zink_screen *screen)
{
VkSemaphoreCreateInfo sci = {
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
NULL,
0
};
VkSemaphore sem;
VkResult ret = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &sem);
return ret == VK_SUCCESS ? sem : VK_NULL_HANDLE;
}
static VkSemaphore
buffer_commit_single(struct zink_screen *screen, struct zink_resource *res, struct zink_bo *bo, uint32_t bo_offset, uint32_t offset, uint32_t size, bool commit, VkSemaphore wait)
{
VkSemaphore sem = get_semaphore(screen);
VkSemaphore sem = zink_create_semaphore(screen);
VkBindSparseInfo sparse = {0};
sparse.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
sparse.bufferBindCount = res->obj->storage_buffer ? 2 : 1;
@ -886,7 +873,7 @@ out:
static VkSemaphore
texture_commit_single(struct zink_screen *screen, struct zink_resource *res, VkSparseImageMemoryBind *ibind, unsigned num_binds, bool commit, VkSemaphore wait)
{
VkSemaphore sem = get_semaphore(screen);
VkSemaphore sem = zink_create_semaphore(screen);
VkBindSparseInfo sparse = {0};
sparse.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
sparse.imageBindCount = 1;
@ -911,7 +898,7 @@ texture_commit_single(struct zink_screen *screen, struct zink_resource *res, VkS
static VkSemaphore
texture_commit_miptail(struct zink_screen *screen, struct zink_resource *res, struct zink_bo *bo, uint32_t bo_offset, uint32_t offset, bool commit, VkSemaphore wait)
{
VkSemaphore sem = get_semaphore(screen);
VkSemaphore sem = zink_create_semaphore(screen);
VkBindSparseInfo sparse = {0};
sparse.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
sparse.imageOpaqueBindCount = 1;
@ -969,9 +956,9 @@ zink_bo_commit(struct zink_screen *screen, struct zink_resource *res, unsigned l
unsigned nheight = DIV_ROUND_UP(box->height, gheight);
unsigned ndepth = DIV_ROUND_UP(box->depth, gdepth);
VkExtent3D lastBlockExtent = {
(box->width % gwidth) ? box->width % gwidth : gwidth,
(box->height % gheight) ? box->height % gheight : gheight,
(box->depth % gdepth) ? box->depth % gdepth : gdepth
(box->width % gwidth) ? box->width % gwidth : gwidth,
(box->height % gheight) ? box->height % gheight : gheight,
(box->depth % gdepth) ? box->depth % gdepth : gdepth
};
#define NUM_BATCHED_BINDS 50
VkSparseImageMemoryBind ibind[NUM_BATCHED_BINDS];

File diff suppressed because it is too large Load diff

View file

@ -59,8 +59,9 @@ void
zink_screen_init_compiler(struct zink_screen *screen);
void
zink_compiler_assign_io(struct zink_screen *screen, nir_shader *producer, nir_shader *consumer);
/* pass very large shader key data with extra_data */
VkShaderModule
zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shader *nir, const struct zink_shader_key *key);
zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shader *nir, const struct zink_shader_key *key, const void *extra_data);
VkShaderModule
zink_shader_spirv_compile(struct zink_screen *screen, struct zink_shader *zs, struct spirv_shader *spirv);
struct zink_shader *

View file

@ -521,9 +521,15 @@ get_imageview_for_binding(struct zink_context *ctx, gl_shader_stage stage, enum
if (!sampler_view || !sampler_view->base.texture)
return NULL;
/* if this is a non-seamless cube sampler, return the cube array view */
return (ctx->di.emulate_nonseamless[stage] & ctx->di.cubes[stage] & BITFIELD_BIT(idx)) ?
sampler_view->cube_array :
sampler_view->image_view;
if (ctx->di.emulate_nonseamless[stage] & ctx->di.cubes[stage] & BITFIELD_BIT(idx))
return sampler_view->cube_array;
bool needs_zs_shader_swizzle = (ctx->di.zs_swizzle[stage].mask & BITFIELD_BIT(idx)) &&
zink_screen(ctx->base.screen)->driver_workarounds.needs_zs_shader_swizzle;
bool needs_shadow_shader_swizzle = (stage == MESA_SHADER_FRAGMENT) && ctx->gfx_stages[MESA_SHADER_FRAGMENT] &&
(ctx->di.zs_swizzle[MESA_SHADER_FRAGMENT].mask & ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & BITFIELD_BIT(idx));
if (sampler_view->zs_view && (needs_zs_shader_swizzle || needs_shadow_shader_swizzle))
return sampler_view->zs_view;
return sampler_view->image_view;
}
case ZINK_DESCRIPTOR_TYPE_IMAGE: {
struct zink_image_view *image_view = &ctx->image_views[stage][idx];
@ -644,6 +650,13 @@ update_descriptor_state_sampler(struct zink_context *ctx, gl_shader_stage shader
return res;
}
void
zink_update_shadow_samplerviews(struct zink_context *ctx, unsigned mask)
{
u_foreach_bit(slot, mask)
update_descriptor_state_sampler(ctx, MESA_SHADER_FRAGMENT, slot, ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW][MESA_SHADER_FRAGMENT][slot]);
}
ALWAYS_INLINE static struct zink_resource *
update_descriptor_state_image(struct zink_context *ctx, gl_shader_stage shader, unsigned slot, struct zink_resource *res)
{
@ -964,25 +977,27 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres,
ivci = create_ivci(screen, res, &templ, state->target);
ivci.subresourceRange.levelCount = state->u.tex.last_level - state->u.tex.first_level + 1;
ivci.subresourceRange.aspectMask = sampler_aspect_from_format(state->format);
bool shadow_needs_shader_swizzle = false;
/* samplers for stencil aspects of packed formats need to always use stencil swizzle */
if (ivci.subresourceRange.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
if (sampler_view->base.swizzle_r == PIPE_SWIZZLE_0 &&
sampler_view->base.swizzle_g == PIPE_SWIZZLE_0 &&
sampler_view->base.swizzle_b == PIPE_SWIZZLE_0 &&
sampler_view->base.swizzle_a == PIPE_SWIZZLE_X) {
/*
* When the state tracker asks for 000x swizzles, this is depth mode GL_ALPHA,
* however with the single dref fetch this will fail, so just spam all the channels.
*/
ivci.components.r = VK_COMPONENT_SWIZZLE_R;
ivci.components.g = VK_COMPONENT_SWIZZLE_R;
ivci.components.b = VK_COMPONENT_SWIZZLE_R;
ivci.components.a = VK_COMPONENT_SWIZZLE_R;
} else {
ivci.components.r = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_r));
ivci.components.g = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_g));
ivci.components.b = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_b));
ivci.components.a = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_a));
ivci.components.r = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_r));
ivci.components.g = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_g));
ivci.components.b = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_b));
ivci.components.a = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_a));
if (ivci.subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT ||
zink_screen(ctx->base.screen)->driver_workarounds.needs_zs_shader_swizzle) {
VkComponentSwizzle *swizzle = (VkComponentSwizzle*)&ivci.components;
for (unsigned i = 0; i < 4; i++) {
/* these require shader rewrites to correctly emulate */
if (swizzle[i] == VK_COMPONENT_SWIZZLE_ONE ||
(swizzle[i] == VK_COMPONENT_SWIZZLE_ZERO && ivci.subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT))
shadow_needs_shader_swizzle = true;
}
/* this is the data that will be used in shader rewrites */
sampler_view->swizzle.s[0] = clamp_zs_swizzle(sampler_view->base.swizzle_r);
sampler_view->swizzle.s[1] = clamp_zs_swizzle(sampler_view->base.swizzle_g);
sampler_view->swizzle.s[2] = clamp_zs_swizzle(sampler_view->base.swizzle_b);
sampler_view->swizzle.s[3] = clamp_zs_swizzle(sampler_view->base.swizzle_a);
}
} else {
enum pipe_swizzle swizzle[4] = {
@ -1039,6 +1054,15 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres,
if (!screen->info.have_EXT_non_seamless_cube_map && viewtype_is_cube(&sampler_view->image_view->ivci)) {
ivci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
sampler_view->cube_array = (struct zink_surface*)zink_get_surface(ctx, pres, &templ, &ivci);
} else if (shadow_needs_shader_swizzle) {
/* there is only one component, and real swizzling can't be done here,
* so ensure the shader gets the sampled data
*/
ivci.components.r = VK_COMPONENT_SWIZZLE_R;
ivci.components.g = VK_COMPONENT_SWIZZLE_R;
ivci.components.b = VK_COMPONENT_SWIZZLE_R;
ivci.components.a = VK_COMPONENT_SWIZZLE_R;
sampler_view->zs_view = (struct zink_surface*)zink_get_surface(ctx, pres, &templ, &ivci);
}
err = !sampler_view->image_view;
} else {
@ -1084,6 +1108,7 @@ zink_sampler_view_destroy(struct pipe_context *pctx,
else {
zink_surface_reference(zink_screen(pctx->screen), &view->image_view, NULL);
zink_surface_reference(zink_screen(pctx->screen), &view->cube_array, NULL);
zink_surface_reference(zink_screen(pctx->screen), &view->zs_view, NULL);
}
pipe_resource_reference(&pview->texture, NULL);
FREE_CL(view);
@ -1809,6 +1834,8 @@ unbind_samplerview(struct zink_context *ctx, gl_shader_stage stage, unsigned slo
unbind_descriptor_stage(res, stage);
unbind_descriptor_reads(res, stage);
}
assert(slot < 32);
ctx->di.zs_swizzle[stage].mask &= ~BITFIELD_BIT(slot);
}
static void
@ -1824,9 +1851,11 @@ zink_set_sampler_views(struct pipe_context *pctx,
unsigned i;
const uint32_t mask = BITFIELD_RANGE(start_slot, num_views);
uint32_t shadow_mask = ctx->di.zs_swizzle[shader_type].mask;
ctx->di.cubes[shader_type] &= ~mask;
bool update = false;
bool shadow_update = false;
for (i = 0; i < num_views; ++i) {
struct pipe_sampler_view *pview = views ? views[i] : NULL;
struct zink_sampler_view *a = zink_sampler_view(ctx->sampler_views[shader_type][start_slot + i]);
@ -1860,27 +1889,38 @@ zink_set_sampler_views(struct pipe_context *pctx,
res->gfx_barrier);
zink_batch_resource_usage_set(&ctx->batch, res, false, true);
} else if (!res->obj->is_buffer) {
if (res->base.b.format != b->image_view->base.format)
/* mutable not set by default */
zink_resource_object_init_mutable(ctx, res);
if (res->obj != b->image_view->obj) {
struct pipe_surface *psurf = &b->image_view->base;
VkImageView iv = b->image_view->image_view;
zink_rebind_surface(ctx, &psurf);
b->image_view = zink_surface(psurf);
update |= iv != b->image_view->image_view;
} else if (a != b)
update = true;
if (shader_type == MESA_SHADER_COMPUTE)
flush_pending_clears(ctx, res);
if (b->cube_array) {
ctx->di.cubes[shader_type] |= BITFIELD_BIT(start_slot + i);
}
check_for_layout_update(ctx, res, shader_type == MESA_SHADER_COMPUTE);
if (!a)
update = true;
zink_batch_resource_usage_set(&ctx->batch, res, false, false);
res->obj->unordered_write = false;
if (res->base.b.format != b->image_view->base.format)
/* mutable not set by default */
zink_resource_object_init_mutable(ctx, res);
if (res->obj != b->image_view->obj) {
struct pipe_surface *psurf = &b->image_view->base;
VkImageView iv = b->image_view->image_view;
zink_rebind_surface(ctx, &psurf);
b->image_view = zink_surface(psurf);
update |= iv != b->image_view->image_view;
} else if (a != b)
update = true;
if (shader_type == MESA_SHADER_COMPUTE)
flush_pending_clears(ctx, res);
if (b->cube_array) {
ctx->di.cubes[shader_type] |= BITFIELD_BIT(start_slot + i);
}
check_for_layout_update(ctx, res, shader_type == MESA_SHADER_COMPUTE);
if (!a)
update = true;
zink_batch_resource_usage_set(&ctx->batch, res, false, false);
res->obj->unordered_write = false;
if (b->zs_view) {
assert(start_slot + i < 32); //bitfield size
ctx->di.zs_swizzle[shader_type].mask |= BITFIELD_BIT(start_slot + i);
/* this is already gonna be slow, so don't bother trying to micro-optimize */
shadow_update |= memcmp(&ctx->di.zs_swizzle[shader_type].swizzle[start_slot + i],
&b->swizzle, sizeof(struct zink_zs_swizzle));
memcpy(&ctx->di.zs_swizzle[shader_type].swizzle[start_slot + i], &b->swizzle, sizeof(struct zink_zs_swizzle));
} else {
assert(start_slot + i < 32); //bitfield size
ctx->di.zs_swizzle[shader_type].mask &= ~BITFIELD_BIT(start_slot + i);
}
}
res->sampler_binds[shader_type] |= BITFIELD_BIT(start_slot + i);
res->obj->unordered_read = false;
@ -1910,6 +1950,8 @@ zink_set_sampler_views(struct pipe_context *pctx,
zink_context_invalidate_descriptor_state(ctx, shader_type, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot, num_views);
if (!screen->info.have_EXT_non_seamless_cube_map)
update_nonseamless_shader_key(ctx, shader_type);
shadow_update |= shadow_mask != ctx->di.zs_swizzle[shader_type].mask;
zink_set_zs_needs_shader_swizzle_key(ctx, shader_type, shadow_update);
}
}
@ -2243,8 +2285,8 @@ zink_update_fbfetch(struct zink_context *ctx)
ctx->di.fbfetch.imageView = zink_csurface(ctx->fb_state.cbufs[0])->image_view;
bool fbfetch_ms = ctx->fb_state.cbufs[0]->texture->nr_samples > 1;
if (zink_get_fs_key(ctx)->fbfetch_ms != fbfetch_ms)
zink_set_fs_key(ctx)->fbfetch_ms = fbfetch_ms;
if (zink_get_fs_base_key(ctx)->fbfetch_ms != fbfetch_ms)
zink_set_fs_base_key(ctx)->fbfetch_ms = fbfetch_ms;
}
ctx->di.fbfetch.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
if (changed) {
@ -2301,7 +2343,9 @@ begin_rendering(struct zink_context *ctx)
unsigned clear_buffers = 0;
ctx->gfx_pipeline_state.render_pass = NULL;
zink_update_vk_sample_locations(ctx);
zink_render_update_swapchain(ctx);
bool has_swapchain = zink_render_update_swapchain(ctx);
if (has_swapchain)
zink_render_fixup_swapchain(ctx);
bool has_depth = false;
bool has_stencil = false;
bool changed_layout = false;
@ -2450,6 +2494,14 @@ begin_rendering(struct zink_context *ctx)
return 0;
ctx->dynamic_fb.attachments[i].imageView = iv;
}
if (has_swapchain) {
struct zink_resource *res = zink_resource(ctx->fb_state.cbufs[0]->texture);
zink_render_fixup_swapchain(ctx);
assert(ctx->dynamic_fb.info.renderArea.extent.width <= res->base.b.width0);
assert(ctx->dynamic_fb.info.renderArea.extent.height <= res->base.b.height0);
assert(ctx->fb_state.width <= res->base.b.width0);
assert(ctx->fb_state.height <= res->base.b.height0);
}
if (ctx->fb_state.zsbuf && zsbuf_used) {
struct zink_surface *surf = zink_csurface(ctx->fb_state.zsbuf);
VkImageView iv = zink_prep_fb_attachment(ctx, surf, ctx->fb_state.nr_cbufs);
@ -2458,6 +2510,8 @@ begin_rendering(struct zink_context *ctx)
ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageView = iv;
ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageLayout = zink_resource(surf->base.texture)->layout;
}
assert(ctx->fb_state.width >= ctx->dynamic_fb.info.renderArea.extent.width);
assert(ctx->fb_state.height >= ctx->dynamic_fb.info.renderArea.extent.height);
ctx->gfx_pipeline_state.dirty |= rp_changed;
ctx->gfx_pipeline_state.rp_state = rp_state;
@ -2918,6 +2972,22 @@ zink_set_color_write_enables(struct zink_context *ctx)
}
}
static void
check_framebuffer_surface_mutable(struct pipe_context *pctx, struct pipe_surface *psurf)
{
struct zink_context *ctx = zink_context(pctx);
struct zink_ctx_surface *csurf = (struct zink_ctx_surface *)psurf;
if (!csurf->needs_mutable)
return;
zink_resource_object_init_mutable(ctx, zink_resource(psurf->texture));
struct pipe_surface *psurf2 = pctx->create_surface(pctx, psurf->texture, psurf);
pipe_resource_reference(&psurf2->texture, NULL);
struct zink_ctx_surface *csurf2 = (struct zink_ctx_surface *)psurf2;
zink_surface_reference(zink_screen(pctx->screen), &csurf->surf, csurf2->surf);
pctx->surface_destroy(pctx, psurf2);
csurf->needs_mutable = false;
}
static void
zink_set_framebuffer_state(struct pipe_context *pctx,
const struct pipe_framebuffer_state *state)
@ -2941,7 +3011,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
struct zink_surface *b = zink_csurface(state->cbufs[i]);
if (a == b)
continue;
if (memcmp(&a->base.u.tex, &b->base.u.tex, sizeof(b->base.u.tex)) ||
if (!a || !b || memcmp(&a->base.u.tex, &b->base.u.tex, sizeof(b->base.u.tex)) ||
a->base.texture != b->base.texture)
flush_clears = true;
else if (a->base.format != b->base.format)
@ -3004,6 +3074,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
if (!samples)
samples = MAX3(transient ? transient->base.nr_samples : 1, psurf->texture->nr_samples, 1);
struct zink_resource *res = zink_resource(psurf->texture);
check_framebuffer_surface_mutable(pctx, psurf);
if (zink_csurface(psurf)->info.layerCount > layers)
ctx->fb_layer_mismatch |= BITFIELD_BIT(i);
if (res->modifiers) {
@ -3033,6 +3104,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
if (ctx->fb_state.zsbuf) {
struct pipe_surface *psurf = ctx->fb_state.zsbuf;
struct zink_surface *transient = zink_transient_surface(psurf);
check_framebuffer_surface_mutable(pctx, psurf);
if (transient)
ctx->transient_attachments |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS);
if (!samples)
@ -4356,7 +4428,8 @@ zink_copy_image_buffer(struct zink_context *ctx, struct zink_resource *dst, stru
int aspect = 1 << u_bit_scan(&aspects);
region.imageSubresource.aspectMask = aspect;
/* this may or may not work with multisampled depth/stencil buffers depending on the driver implementation:
/* MSAA transfers should have already been handled by U_TRANSFER_HELPER_MSAA_MAP, since
* there's no way to resolve using this interface:
*
* srcImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT
* - vkCmdCopyImageToBuffer spec
@ -4364,6 +4437,7 @@ zink_copy_image_buffer(struct zink_context *ctx, struct zink_resource *dst, stru
* dstImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT
* - vkCmdCopyBufferToImage spec
*/
assert(img->base.b.nr_samples <= 1);
if (buf2img)
VKCTX(CmdCopyBufferToImage)(cmdbuf, buf->obj->buffer, img->obj->image, img->layout, 1, &region);
else
@ -4509,32 +4583,33 @@ zink_resource_commit(struct pipe_context *pctx, struct pipe_resource *pres, unsi
static void
rebind_image(struct zink_context *ctx, struct zink_resource *res)
{
zink_rebind_framebuffer(ctx, res);
if (!zink_resource_has_binds(res))
return;
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
if (res->sampler_binds[i]) {
for (unsigned j = 0; j < ctx->di.num_sampler_views[i]; j++) {
struct zink_sampler_view *sv = zink_sampler_view(ctx->sampler_views[i][j]);
if (sv && sv->base.texture == &res->base.b) {
struct pipe_surface *psurf = &sv->image_view->base;
zink_rebind_surface(ctx, &psurf);
sv->image_view = zink_surface(psurf);
zink_context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, j, 1);
update_descriptor_state_sampler(ctx, i, j, res);
}
}
}
if (!res->image_bind_count[i == MESA_SHADER_COMPUTE])
continue;
for (unsigned j = 0; j < ctx->di.num_images[i]; j++) {
if (zink_resource(ctx->image_views[i][j].base.resource) == res) {
zink_context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_IMAGE, j, 1);
update_descriptor_state_image(ctx, i, j, res);
_mesa_set_add(ctx->need_barriers[i == MESA_SHADER_COMPUTE], res);
}
}
}
if (res->fb_binds)
zink_rebind_framebuffer(ctx, res);
if (!zink_resource_has_binds(res))
return;
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
if (res->sampler_binds[i]) {
for (unsigned j = 0; j < ctx->di.num_sampler_views[i]; j++) {
struct zink_sampler_view *sv = zink_sampler_view(ctx->sampler_views[i][j]);
if (sv && sv->base.texture == &res->base.b) {
struct pipe_surface *psurf = &sv->image_view->base;
zink_rebind_surface(ctx, &psurf);
sv->image_view = zink_surface(psurf);
zink_context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, j, 1);
update_descriptor_state_sampler(ctx, i, j, res);
}
}
}
if (!res->image_bind_count[i == MESA_SHADER_COMPUTE])
continue;
for (unsigned j = 0; j < ctx->di.num_images[i]; j++) {
if (zink_resource(ctx->image_views[i][j].base.resource) == res) {
zink_context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_IMAGE, j, 1);
update_descriptor_state_image(ctx, i, j, res);
_mesa_set_add(ctx->need_barriers[i == MESA_SHADER_COMPUTE], res);
}
}
}
}
bool
@ -4728,6 +4803,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
struct zink_context *ctx = rzalloc(NULL, struct zink_context);
bool is_copy_only = (flags & ZINK_CONTEXT_COPY_ONLY) > 0;
bool is_compute_only = (flags & PIPE_CONTEXT_COMPUTE_ONLY) > 0;
bool is_robust = (flags & PIPE_CONTEXT_ROBUST_BUFFER_ACCESS) > 0;
if (!ctx)
goto fail;
@ -4843,8 +4919,19 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_VERTEX].size = sizeof(struct zink_vs_key_base);
ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_EVAL].size = sizeof(struct zink_vs_key_base);
ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_CTRL].size = sizeof(struct zink_tcs_key);
ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_GEOMETRY].size = sizeof(struct zink_vs_key_base);
ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_GEOMETRY].size = sizeof(struct zink_gs_key);
ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].size = sizeof(struct zink_fs_key);
/* this condition must be updated if new fields are added to zink_cs_key */
if (screen->driver_workarounds.lower_robustImageAccess2)
ctx->compute_pipeline_state.key.size = sizeof(struct zink_cs_key);
if (is_robust && screen->driver_workarounds.lower_robustImageAccess2) {
ctx->compute_pipeline_state.key.key.cs.robust_access = true;
for (gl_shader_stage pstage = MESA_SHADER_VERTEX; pstage < MESA_SHADER_FRAGMENT; pstage++)
ctx->gfx_pipeline_state.shader_keys.key[pstage].key.vs_base.robust_access = true;
ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs.robust_access = true;
}
}
_mesa_hash_table_init(&ctx->framebuffer_cache, ctx, hash_framebuffer_imageless, equals_framebuffer_imageless);
if (!zink_init_render_pass(ctx))

View file

@ -211,6 +211,9 @@ zink_component_mapping(enum pipe_swizzle swizzle)
}
}
void
zink_update_shadow_samplerviews(struct zink_context *ctx, unsigned mask);
enum pipe_swizzle
zink_clamp_void_swizzle(const struct util_format_description *desc, enum pipe_swizzle swizzle);

View file

@ -1042,15 +1042,9 @@ consolidate_pool_alloc(struct zink_screen *screen, struct zink_descriptor_pool_m
if (!mpool->overflowed_pools[mpool->overflow_idx].size)
return;
unsigned old_size = mpool->overflowed_pools[!mpool->overflow_idx].size;
if (util_dynarray_resize(&mpool->overflowed_pools[!mpool->overflow_idx], struct zink_descriptor_pool*, sizes[0] + sizes[1])) {
/* attempt to consolidate all the overflow into one array to maximize reuse */
uint8_t *src = mpool->overflowed_pools[mpool->overflow_idx].data;
uint8_t *dst = mpool->overflowed_pools[!mpool->overflow_idx].data;
dst += old_size;
memcpy(dst, src, mpool->overflowed_pools[mpool->overflow_idx].size);
util_dynarray_clear(&mpool->overflowed_pools[mpool->overflow_idx]);
}
/* attempt to consolidate all the overflow into one array to maximize reuse */
util_dynarray_append_dynarray(&mpool->overflowed_pools[!mpool->overflow_idx], &mpool->overflowed_pools[mpool->overflow_idx]);
util_dynarray_clear(&mpool->overflowed_pools[mpool->overflow_idx]);
}
/* called when a batch state is reset, i.e., just before a batch state becomes the current state */

View file

@ -60,39 +60,54 @@ import sys
# - guard: adds a #if defined(`extension_name`)/#endif guard around the code generated for this Extension.
EXTENSIONS = [
Extension("VK_KHR_maintenance1",
required=True),
required=True),
Extension("VK_KHR_maintenance2"),
Extension("VK_KHR_maintenance3"),
Extension("VK_KHR_maintenance4", alias="maint4", features=True),
Extension("VK_KHR_maintenance4",
alias="maint4",
features=True),
Extension("VK_KHR_external_memory"),
Extension("VK_KHR_external_memory_fd"),
Extension("VK_KHR_vulkan_memory_model"),
Extension("VK_KHR_pipeline_executable_properties", alias="pipestats", features=True),
Extension("VK_KHR_pipeline_executable_properties",
alias="pipestats",
features=True),
Extension("VK_KHR_external_semaphore_fd"),
Extension("VK_KHR_create_renderpass2", required=True),
Extension("VK_KHR_create_renderpass2",
required=True),
Extension("VK_KHR_synchronization2",
alias="sync2",
features=True),
Extension("VK_KHR_external_memory_win32"),
Extension("VK_KHR_external_semaphore_win32"),
Extension("VK_EXT_external_memory_dma_buf"),
Extension("VK_KHR_buffer_device_address", alias="bda", features=True),
Extension("VK_KHR_buffer_device_address",
alias="bda",
features=True),
Extension("VK_EXT_queue_family_foreign"),
Extension("VK_KHR_swapchain_mutable_format"),
Extension("VK_EXT_provoking_vertex",
alias="pv",
features=True,
properties=True,
conditions=["$feats.provokingVertexLast"]),
alias="pv",
features=True,
properties=True,
conditions=["$feats.provokingVertexLast"]),
Extension("VK_EXT_shader_viewport_index_layer"),
Extension("VK_KHR_get_memory_requirements2"),
Extension("VK_EXT_post_depth_coverage"),
Extension("VK_EXT_depth_clip_control", alias="clip_control", features=True),
Extension("VK_EXT_depth_clamp_zero_one", alias="clamp_01", features=True),
Extension("VK_EXT_depth_clip_control",
alias="clip_control",
features=True),
Extension("VK_EXT_depth_clamp_zero_one",
alias="clamp_01",
features=True),
Extension("VK_EXT_shader_subgroup_ballot"),
Extension("VK_EXT_shader_subgroup_vote"),
Extension("VK_EXT_shader_atomic_float", alias="atomic_float", features=True),
Extension("VK_KHR_shader_atomic_int64", alias="atomic_int", features=True),
Extension("VK_EXT_shader_atomic_float",
alias="atomic_float",
features=True),
Extension("VK_KHR_shader_atomic_int64",
alias="atomic_int",
features=True),
Extension("VK_KHR_8bit_storage",
alias="storage_8bit",
features=True,
@ -105,56 +120,59 @@ EXTENSIONS = [
alias="view2d",
features=True),
Extension("VK_KHR_driver_properties",
alias="driver",
properties=True),
alias="driver",
properties=True),
Extension("VK_EXT_memory_budget"),
Extension("VK_KHR_draw_indirect_count"),
Extension("VK_EXT_attachment_feedback_loop_layout",
alias="feedback_loop",
features=True),
Extension("VK_EXT_fragment_shader_interlock",
alias="interlock",
features=True,
conditions=["$feats.fragmentShaderSampleInterlock", "$feats.fragmentShaderPixelInterlock"]),
alias="interlock",
features=True,
conditions=["$feats.fragmentShaderSampleInterlock", "$feats.fragmentShaderPixelInterlock"]),
Extension("VK_EXT_sample_locations",
alias="sample_locations",
properties=True),
alias="sample_locations",
properties=True),
Extension("VK_EXT_conservative_rasterization",
alias="cons_raster",
properties=True,
conditions=["$props.fullyCoveredFragmentShaderInputVariable"]),
alias="cons_raster",
properties=True,
conditions=["$props.fullyCoveredFragmentShaderInputVariable"]),
Extension("VK_KHR_shader_draw_parameters"),
Extension("VK_KHR_sampler_mirror_clamp_to_edge"),
Extension("VK_EXT_conditional_rendering",
alias="cond_render",
features=True,
conditions=["$feats.conditionalRendering"]),
alias="cond_render",
features=True,
conditions=["$feats.conditionalRendering"]),
Extension("VK_EXT_transform_feedback",
alias="tf",
properties=True,
features=True,
conditions=["$feats.transformFeedback"]),
alias="tf",
properties=True,
features=True,
conditions=["$feats.transformFeedback"]),
Extension("VK_EXT_index_type_uint8",
alias="index_uint8",
features=True,
conditions=["$feats.indexTypeUint8"]),
alias="index_uint8",
features=True,
conditions=["$feats.indexTypeUint8"]),
Extension("VK_KHR_image_format_list"),
Extension("VK_KHR_sampler_ycbcr_conversion"),
Extension("VK_KHR_imageless_framebuffer",
alias="imgless",
features=True,
required=True),
alias="imgless",
features=True,
required=True),
Extension("VK_EXT_robustness2",
alias="rb2",
properties=True,
features=True,
conditions=["$feats.nullDescriptor"]),
alias="rb2",
properties=True,
features=True,
conditions=["$feats.nullDescriptor"]),
Extension("VK_EXT_image_robustness",
alias="rb_image",
features=True),
Extension("VK_EXT_image_drm_format_modifier"),
Extension("VK_EXT_vertex_attribute_divisor",
alias="vdiv",
properties=True,
features=True,
conditions=["$feats.vertexAttributeInstanceRateDivisor"]),
alias="vdiv",
properties=True,
features=True,
conditions=["$feats.vertexAttributeInstanceRateDivisor"]),
Extension("VK_EXT_calibrated_timestamps"),
Extension("VK_NV_linear_color_attachment",
alias="linear_color",
@ -163,60 +181,64 @@ EXTENSIONS = [
alias="dynamic_render",
features=True),
Extension("VK_KHR_shader_clock",
alias="shader_clock",
features=True,
conditions=["$feats.shaderSubgroupClock"]),
alias="shader_clock",
features=True,
conditions=["$feats.shaderSubgroupClock"]),
Extension("VK_EXT_sampler_filter_minmax",
alias="reduction",
properties=True,
conditions=["$props.filterMinmaxSingleComponentFormats"]),
alias="reduction",
properties=True,
conditions=["$props.filterMinmaxSingleComponentFormats"]),
Extension("VK_EXT_custom_border_color",
alias="border_color",
properties=True,
features=True,
conditions=["$feats.customBorderColors"]),
alias="border_color",
properties=True,
features=True,
conditions=["$feats.customBorderColors"]),
Extension("VK_EXT_non_seamless_cube_map",
alias="nonseamless",
features=True),
alias="nonseamless",
features=True),
Extension("VK_EXT_border_color_swizzle",
alias="border_swizzle",
features=True),
alias="border_swizzle",
features=True),
Extension("VK_EXT_blend_operation_advanced",
alias="blend",
properties=True,
# TODO: we can probably support non-premul here with some work?
conditions=["$props.advancedBlendNonPremultipliedSrcColor", "$props.advancedBlendNonPremultipliedDstColor"]),
alias="blend",
properties=True,
# TODO: we can probably support non-premul here with some work?
conditions=["$props.advancedBlendNonPremultipliedSrcColor", "$props.advancedBlendNonPremultipliedDstColor"]),
Extension("VK_EXT_extended_dynamic_state",
alias="dynamic_state",
features=True,
conditions=["$feats.extendedDynamicState"]),
alias="dynamic_state",
features=True,
conditions=["$feats.extendedDynamicState"]),
Extension("VK_EXT_extended_dynamic_state2",
alias="dynamic_state2",
features=True,
conditions=["$feats.extendedDynamicState2"]),
alias="dynamic_state2",
features=True,
conditions=["$feats.extendedDynamicState2"]),
Extension("VK_EXT_extended_dynamic_state3",
alias="dynamic_state3",
properties=True,
features=True),
alias="dynamic_state3",
properties=True,
features=True),
Extension("VK_EXT_pipeline_creation_cache_control",
alias="pipeline_cache_control",
features=True,
conditions=["$feats.pipelineCreationCacheControl"]),
alias="pipeline_cache_control",
features=True,
conditions=["$feats.pipelineCreationCacheControl"]),
Extension("VK_EXT_shader_stencil_export",
alias="stencil_export"),
alias="stencil_export"),
Extension("VK_KHR_portability_subset",
alias="portability_subset",
features=True,
guard=True),
Extension("VK_KHR_timeline_semaphore", alias="timeline", features=True),
Extension("VK_EXT_color_write_enable", alias="cwrite", features=True),
alias="portability_subset",
features=True,
guard=True),
Extension("VK_KHR_timeline_semaphore",
alias="timeline",
features=True),
Extension("VK_EXT_color_write_enable",
alias="cwrite",
features=True),
Extension("VK_EXT_4444_formats",
alias="format_4444",
features=True),
alias="format_4444",
features=True),
Extension("VK_EXT_scalar_block_layout",
alias="scalar_block_layout",
features=True,
conditions=["$feats.scalarBlockLayout"]),
alias="scalar_block_layout",
features=True,
conditions=["$feats.scalarBlockLayout"]),
Extension("VK_KHR_swapchain"),
Extension("VK_EXT_rasterization_order_attachment_access",
alias="rast_order_access",
@ -227,48 +249,48 @@ EXTENSIONS = [
features=True),
Extension("VK_EXT_multi_draw",
alias="multidraw",
features=True,
properties=True,
conditions=["$feats.multiDraw"]),
features=True,
properties=True,
conditions=["$feats.multiDraw"]),
Extension("VK_EXT_primitives_generated_query",
alias="primgen",
features=True),
features=True),
Extension("VK_KHR_pipeline_library"),
Extension("VK_EXT_graphics_pipeline_library",
alias="gpl",
features=True,
properties=True),
features=True,
properties=True),
Extension("VK_KHR_push_descriptor",
alias="push",
properties=True),
alias="push",
properties=True),
Extension("VK_KHR_descriptor_update_template",
alias="template", required=True),
alias="template", required=True),
Extension("VK_EXT_line_rasterization",
alias="line_rast",
properties=True,
features=True),
alias="line_rast",
properties=True,
features=True),
Extension("VK_EXT_vertex_input_dynamic_state",
alias="vertex_input",
features=True,
conditions=["$feats.vertexInputDynamicState"]),
alias="vertex_input",
features=True,
conditions=["$feats.vertexInputDynamicState"]),
Extension("VK_EXT_primitive_topology_list_restart",
alias="list_restart",
features=True,
conditions=["$feats.primitiveTopologyListRestart"]),
alias="list_restart",
features=True,
conditions=["$feats.primitiveTopologyListRestart"]),
Extension("VK_KHR_dedicated_allocation",
alias="dedicated"),
alias="dedicated"),
Extension("VK_EXT_descriptor_indexing",
alias="desc_indexing",
features=True,
properties=True,
conditions=["$feats.descriptorBindingPartiallyBound"]),
alias="desc_indexing",
features=True,
properties=True,
conditions=["$feats.descriptorBindingPartiallyBound"]),
Extension("VK_EXT_depth_clip_enable",
alias="depth_clip_enable",
features=True),
alias="depth_clip_enable",
features=True),
Extension("VK_EXT_shader_demote_to_helper_invocation",
alias="demote",
features=True,
conditions=["$feats.shaderDemoteToHelperInvocation"]),
alias="demote",
features=True,
conditions=["$feats.shaderDemoteToHelperInvocation"]),
]
# constructor: Versions(device_version(major, minor, patch), struct_version(major, minor))

View file

@ -525,6 +525,7 @@ zink_draw(struct pipe_context *pctx,
zink_set_last_vertex_key(ctx)->push_drawid = drawid_broken;
bool rast_prim_changed = false;
bool lines_changed = false;
bool rast_state_changed = ctx->rast_state_changed;
if (mode_changed || ctx->gfx_pipeline_state.modules_changed ||
rast_state_changed) {
@ -534,6 +535,10 @@ zink_draw(struct pipe_context *pctx,
(ctx->gfx_pipeline_state.rast_prim == PIPE_PRIM_POINTS) !=
(rast_prim == PIPE_PRIM_POINTS);
lines_changed =
(ctx->gfx_pipeline_state.rast_prim == PIPE_PRIM_LINES) !=
(rast_prim == PIPE_PRIM_LINES);
ctx->gfx_pipeline_state.rast_prim = rast_prim;
rast_prim_changed = true;
@ -543,6 +548,10 @@ zink_draw(struct pipe_context *pctx,
}
ctx->gfx_pipeline_state.gfx_prim_mode = mode;
if (!screen->optimal_keys &&
(lines_changed || rast_state_changed || ctx->gfx_pipeline_state.modules_changed))
zink_set_primitive_emulation_keys(ctx);
if (index_size) {
const VkIndexType index_type[3] = {
VK_INDEX_TYPE_UINT8_EXT,
@ -670,7 +679,7 @@ zink_draw(struct pipe_context *pctx,
VKCTX(CmdSetCullModeEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.dyn_state1.cull_mode);
}
if ((BATCH_CHANGED || rast_state_changed) &&
(DYNAMIC_STATE >= ZINK_DYNAMIC_STATE3 || (screen->info.have_EXT_line_rasterization && rast_state->base.line_stipple_enable)))
(DYNAMIC_STATE >= ZINK_DYNAMIC_STATE3 || (!screen->driver_workarounds.no_linestipple && rast_state->base.line_stipple_enable)))
VKCTX(CmdSetLineStippleEXT)(batch->state->cmdbuf, rast_state->base.line_stipple_factor, rast_state->base.line_stipple_pattern);
if ((BATCH_CHANGED || rast_state_changed) && DYNAMIC_STATE >= ZINK_DYNAMIC_STATE3) {
@ -695,9 +704,11 @@ zink_draw(struct pipe_context *pctx,
VKCTX(CmdSetAlphaToCoverageEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->alpha_to_coverage);
if (screen->info.feats.features.alphaToOne)
VKCTX(CmdSetAlphaToOneEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->alpha_to_one);
VKCTX(CmdSetColorBlendEnableEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.enables);
VKCTX(CmdSetColorWriteMaskEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.wrmask);
VKCTX(CmdSetColorBlendEquationEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.eq);
if (ctx->fb_state.nr_cbufs) {
VKCTX(CmdSetColorBlendEnableEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.enables);
VKCTX(CmdSetColorWriteMaskEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.wrmask);
VKCTX(CmdSetColorBlendEquationEXT)(batch->state->cmdbuf, 0, ctx->fb_state.nr_cbufs, ctx->gfx_pipeline_state.blend_state->ds3.eq);
}
VKCTX(CmdSetLogicOpEnableEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->logicop_enable);
VKCTX(CmdSetLogicOpEXT)(batch->state->cmdbuf, ctx->gfx_pipeline_state.blend_state->logicop_func);
}
@ -787,12 +798,52 @@ zink_draw(struct pipe_context *pctx,
&draw_mode_is_indexed);
}
if (ctx->curr_program->shaders[MESA_SHADER_TESS_CTRL] &&
ctx->curr_program->shaders[MESA_SHADER_TESS_CTRL]->tcs.is_generated) {
ctx->curr_program->shaders[MESA_SHADER_TESS_CTRL]->non_fs.is_generated) {
VKCTX(CmdPushConstants)(batch->state->cmdbuf, ctx->curr_program->base.layout, VK_SHADER_STAGE_ALL_GRAPHICS,
offsetof(struct zink_gfx_push_constant, default_inner_level), sizeof(float) * 6,
&ctx->tess_levels[0]);
}
if (!screen->optimal_keys) {
if (zink_get_fs_key(ctx)->lower_line_stipple ||
zink_get_gs_key(ctx)->lower_gl_point ||
zink_get_fs_key(ctx)->lower_line_smooth) {
assert(zink_get_gs_key(ctx)->lower_line_stipple ==
zink_get_fs_key(ctx)->lower_line_stipple);
assert(zink_get_gs_key(ctx)->lower_line_smooth ==
zink_get_fs_key(ctx)->lower_line_smooth);
float viewport_scale[2] = {
ctx->vp_state.viewport_states[0].scale[0],
ctx->vp_state.viewport_states[0].scale[1]
};
VKCTX(CmdPushConstants)(batch->state->cmdbuf,
ctx->curr_program->base.layout,
VK_SHADER_STAGE_ALL_GRAPHICS,
offsetof(struct zink_gfx_push_constant, viewport_scale),
sizeof(float) * 2, &viewport_scale);
uint32_t stipple = ctx->rast_state->base.line_stipple_pattern;
stipple |= ctx->rast_state->base.line_stipple_factor << 16;
VKCTX(CmdPushConstants)(batch->state->cmdbuf,
ctx->curr_program->base.layout,
VK_SHADER_STAGE_ALL_GRAPHICS,
offsetof(struct zink_gfx_push_constant, line_stipple_pattern),
sizeof(uint32_t), &stipple);
if (ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs.lower_line_smooth) {
float line_width = ctx->rast_state->base.line_width;
VKCTX(CmdPushConstants)(batch->state->cmdbuf,
ctx->curr_program->base.layout,
VK_SHADER_STAGE_ALL_GRAPHICS,
offsetof(struct zink_gfx_push_constant, line_width),
sizeof(uint32_t), &line_width);
}
}
}
if (have_streamout) {
for (unsigned i = 0; i < ctx->num_so_targets; i++) {
struct zink_so_target *t = zink_so_target(ctx->so_targets[i]);

View file

@ -493,17 +493,12 @@ kopper_acquire(struct zink_screen *screen, struct zink_resource *res, uint64_t t
p_atomic_read_relaxed(&cdt->swapchain->num_acquires) >= cdt->swapchain->max_acquires) {
util_queue_fence_wait(&cdt->present_fence);
}
VkSemaphoreCreateInfo sci = {
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
NULL,
0
};
VkResult ret;
if (!acquire) {
ret = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &acquire);
acquire = zink_create_semaphore(screen);
assert(acquire);
if (ret != VK_SUCCESS)
return ret;
if (!acquire)
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
ret = VKSCR(AcquireNextImageKHR)(screen->dev, cdt->swapchain->swapchain, timeout, acquire, VK_NULL_HANDLE, &res->obj->dt_idx);
if (ret != VK_SUCCESS && ret != VK_SUBOPTIMAL_KHR) {
@ -611,14 +606,9 @@ zink_kopper_present(struct zink_screen *screen, struct zink_resource *res)
{
assert(res->obj->dt);
assert(!res->obj->present);
VkSemaphoreCreateInfo sci = {
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
NULL,
0
};
assert(zink_kopper_acquired(res->obj->dt, res->obj->dt_idx));
VkResult ret = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &res->obj->present);
return zink_screen_handle_vkresult(screen, ret) ? res->obj->present : VK_NULL_HANDLE;
res->obj->present = zink_create_semaphore(screen);
return res->obj->present;
}
struct kopper_present_info {
@ -730,6 +720,11 @@ zink_kopper_present_queue(struct zink_screen *screen, struct zink_resource *res)
struct kopper_displaytarget *cdt = res->obj->dt;
assert(zink_kopper_acquired(res->obj->dt, res->obj->dt_idx));
assert(res->obj->present);
/* always try to prune if the current swapchain has seen presents */
if (cdt->swapchain->last_present != UINT32_MAX)
prune_old_swapchains(screen, cdt, false);
struct kopper_present_info *cpi = malloc(sizeof(struct kopper_present_info));
cpi->sem = res->obj->present;
cpi->res = res;

View file

@ -148,7 +148,7 @@ zink_create_gfx_pipeline(struct zink_screen *screen,
viewport_state.pViewports = NULL;
viewport_state.scissorCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
viewport_state.pScissors = NULL;
if (!screen->driver_workarounds.depth_clip_control_missing && !hw_rast_state->clip_halfz)
if (screen->info.have_EXT_depth_clip_control && !hw_rast_state->clip_halfz)
viewport_state.pNext = &clip;
VkPipelineRasterizationStateCreateInfo rast_state = {0};
@ -270,7 +270,8 @@ zink_create_gfx_pipeline(struct zink_screen *screen,
assert(state->rast_prim != PIPE_PRIM_MAX);
VkPipelineRasterizationLineStateCreateInfoEXT rast_line_state;
if (screen->info.have_EXT_line_rasterization) {
if (screen->info.have_EXT_line_rasterization &&
!state->shader_keys.key[MESA_SHADER_FRAGMENT].key.fs.lower_line_smooth) {
rast_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
rast_line_state.pNext = rast_state.pNext;
rast_line_state.stippledLineEnable = VK_FALSE;
@ -294,7 +295,18 @@ zink_create_gfx_pipeline(struct zink_screen *screen,
mode_idx += hw_rast_state->line_stipple_enable * 3;
if (*(feat + mode_idx))
rast_line_state.lineRasterizationMode = hw_rast_state->line_mode;
else
else if (hw_rast_state->line_stipple_enable &&
screen->driver_workarounds.no_linestipple) {
/* drop line stipple, we can emulate it */
mode_idx -= hw_rast_state->line_stipple_enable * 3;
if (*(feat + mode_idx))
rast_line_state.lineRasterizationMode = hw_rast_state->line_mode;
/* non-strictLine default lines are either parallelogram or bresenham which while not in GL spec,
* in practice end up being within the two-pixel exception in the GL spec.
*/
else if ((mode_idx != 1) || screen->info.props.limits.strictLines)
warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][0]);
} else if ((mode_idx != 1) || screen->info.props.limits.strictLines)
warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][hw_rast_state->line_stipple_enable]);
}
@ -681,7 +693,7 @@ zink_create_gfx_pipeline_library(struct zink_screen *screen, struct zink_gfx_pro
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT;
if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT;
if (screen->info.have_EXT_line_rasterization)
if (!screen->driver_workarounds.no_linestipple)
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
assert(state_count < ARRAY_SIZE(dynamicStateEnables));

View file

@ -38,6 +38,7 @@
#include "util/u_memory.h"
#include "util/u_prim.h"
#include "nir_serialize.h"
#include "nir/nir_draw_helpers.h"
/* for pipeline cache */
#define XXH_INLINE_ALL
@ -58,7 +59,8 @@ debug_describe_zink_compute_program(char *buf, const struct zink_compute_program
ALWAYS_INLINE static bool
shader_key_matches_tcs_nongenerated(const struct zink_shader_module *zm, const struct zink_shader_key *key, unsigned num_uniforms)
{
if (zm->num_uniforms != num_uniforms || zm->has_nonseamless != !!key->base.nonseamless_cube_mask)
if (zm->num_uniforms != num_uniforms || zm->has_nonseamless != !!key->base.nonseamless_cube_mask ||
zm->needs_zs_shader_swizzle != key->base.needs_zs_shader_swizzle)
return false;
const uint32_t nonseamless_size = zm->has_nonseamless ? sizeof(uint32_t) : 0;
return (!nonseamless_size || !memcmp(zm->key + zm->key_size, &key->base.nonseamless_cube_mask, nonseamless_size)) &&
@ -84,6 +86,8 @@ shader_key_matches(const struct zink_shader_module *zm,
(nonseamless_size && memcmp(zm->key + zm->key_size, &key->base.nonseamless_cube_mask, nonseamless_size)))
return false;
}
if (zm->needs_zs_shader_swizzle != key->base.needs_zs_shader_swizzle)
return false;
return !memcmp(zm->key, key, zm->key_size);
}
@ -129,17 +133,21 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr
struct zink_shader_module *zm;
const struct zink_shader_key *key = &state->shader_keys.key[stage];
/* non-generated tcs won't use the shader key */
const bool is_nongenerated_tcs = stage == MESA_SHADER_TESS_CTRL && !zs->tcs.is_generated;
zm = malloc(sizeof(struct zink_shader_module) + key->size + (!has_nonseamless ? nonseamless_size : 0) + inline_size * sizeof(uint32_t));
const bool is_nongenerated_tcs = stage == MESA_SHADER_TESS_CTRL && !zs->non_fs.is_generated;
const bool shadow_needs_shader_swizzle = key->base.needs_zs_shader_swizzle ||
(stage == MESA_SHADER_FRAGMENT && key->key.fs.base.shadow_needs_shader_swizzle);
zm = malloc(sizeof(struct zink_shader_module) + key->size +
(!has_nonseamless ? nonseamless_size : 0) + inline_size * sizeof(uint32_t) +
(shadow_needs_shader_swizzle ? sizeof(struct zink_zs_swizzle_key) : 0));
if (!zm) {
return NULL;
}
unsigned patch_vertices = state->shader_keys.key[MESA_SHADER_TESS_CTRL ].key.tcs.patch_vertices;
if (stage == MESA_SHADER_TESS_CTRL && zs->tcs.is_generated && zs->spirv) {
if (stage == MESA_SHADER_TESS_CTRL && zs->non_fs.is_generated && zs->spirv) {
assert(ctx); //TODO async
mod = zink_shader_tcs_compile(screen, zs, patch_vertices);
} else {
mod = zink_shader_compile(screen, zs, prog->nir[stage], key);
mod = zink_shader_compile(screen, zs, prog->nir[stage], key, &ctx->di.zs_swizzle[stage]);
}
if (!mod) {
FREE(zm);
@ -158,14 +166,19 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr
/* nonseamless mask gets added to base key if it exists */
memcpy(zm->key + key->size, &key->base.nonseamless_cube_mask, nonseamless_size);
}
zm->needs_zs_shader_swizzle = shadow_needs_shader_swizzle;
zm->has_nonseamless = has_nonseamless ? 0 : !!nonseamless_size;
if (inline_size)
memcpy(zm->key + key->size + nonseamless_size, key->base.inlined_uniform_values, inline_size * sizeof(uint32_t));
if (stage == MESA_SHADER_TESS_CTRL && zs->tcs.is_generated)
if (stage == MESA_SHADER_TESS_CTRL && zs->non_fs.is_generated)
zm->hash = patch_vertices;
else
zm->hash = shader_module_hash(zm);
zm->default_variant = !inline_size && !util_dynarray_contains(&prog->shader_cache[stage][0][0], void*);
if (unlikely(shadow_needs_shader_swizzle)) {
memcpy(zm->key + key->size + nonseamless_size + inline_size * sizeof(uint32_t), &ctx->di.zs_swizzle[stage], sizeof(struct zink_zs_swizzle_key));
zm->hash ^= _mesa_hash_data(&ctx->di.zs_swizzle[stage], sizeof(struct zink_zs_swizzle_key));
}
zm->default_variant = !shadow_needs_shader_swizzle && !inline_size && !util_dynarray_contains(&prog->shader_cache[stage][0][0], void*);
if (inline_size)
prog->inlined_variant_count[stage]++;
util_dynarray_append(&prog->shader_cache[stage][has_nonseamless ? 0 : !!nonseamless_size][!!inline_size], void*, zm);
@ -183,7 +196,9 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *screen
{
const struct zink_shader_key *key = &state->shader_keys.key[stage];
/* non-generated tcs won't use the shader key */
const bool is_nongenerated_tcs = stage == MESA_SHADER_TESS_CTRL && !zs->tcs.is_generated;
const bool is_nongenerated_tcs = stage == MESA_SHADER_TESS_CTRL && !zs->non_fs.is_generated;
const bool shadow_needs_shader_swizzle = unlikely(key->base.needs_zs_shader_swizzle) ||
(stage == MESA_SHADER_FRAGMENT && unlikely(key->key.fs.base.shadow_needs_shader_swizzle));
struct util_dynarray *shader_cache = &prog->shader_cache[stage][!has_nonseamless ? !!nonseamless_size : 0][has_inline ? !!inline_size : 0];
unsigned count = util_dynarray_num_elements(shader_cache, struct zink_shader_module *);
@ -198,6 +213,12 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *screen
continue;
if (!shader_key_matches(iter, key, inline_size, has_inline, has_nonseamless))
continue;
if (unlikely(shadow_needs_shader_swizzle)) {
/* shadow swizzle data needs a manual compare since it's so fat */
if (memcmp(iter->key + iter->key_size + nonseamless_size + iter->num_uniforms * sizeof(uint32_t),
&ctx->di.zs_swizzle[stage], sizeof(struct zink_zs_swizzle_key)))
continue;
}
}
if (i > 0) {
struct zink_shader_module *zero = pzm[0];
@ -220,26 +241,28 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr
struct zink_shader_module *zm;
uint16_t *key;
unsigned mask = stage == MESA_SHADER_FRAGMENT ? BITFIELD_MASK(16) : BITFIELD_MASK(8);
bool shadow_needs_shader_swizzle = false;
if (zs == prog->last_vertex_stage) {
key = (uint16_t*)&state->shader_keys_optimal.key.vs_base;
} else if (stage == MESA_SHADER_FRAGMENT) {
key = (uint16_t*)&state->shader_keys_optimal.key.fs;
} else if (stage == MESA_SHADER_TESS_CTRL && zs->tcs.is_generated) {
shadow_needs_shader_swizzle = ctx ? ctx->gfx_pipeline_state.shader_keys_optimal.key.fs.shadow_needs_shader_swizzle : false;
} else if (stage == MESA_SHADER_TESS_CTRL && zs->non_fs.is_generated) {
key = (uint16_t*)&state->shader_keys_optimal.key.tcs;
} else {
key = NULL;
}
size_t key_size = sizeof(uint16_t);
zm = calloc(1, sizeof(struct zink_shader_module) + (key ? key_size : 0));
zm = calloc(1, sizeof(struct zink_shader_module) + (key ? key_size : 0) + (unlikely(shadow_needs_shader_swizzle) ? sizeof(struct zink_zs_swizzle_key) : 0));
if (!zm) {
return NULL;
}
if (stage == MESA_SHADER_TESS_CTRL && zs->tcs.is_generated && zs->spirv) {
if (stage == MESA_SHADER_TESS_CTRL && zs->non_fs.is_generated && zs->spirv) {
assert(ctx); //TODO async
struct zink_tcs_key *tcs = (struct zink_tcs_key*)key;
mod = zink_shader_tcs_compile(screen, zs, tcs->patch_vertices);
} else {
mod = zink_shader_compile(screen, zs, prog->nir[stage], (struct zink_shader_key*)key);
mod = zink_shader_compile(screen, zs, prog->nir[stage], (struct zink_shader_key*)key, shadow_needs_shader_swizzle ? &ctx->di.zs_swizzle[stage] : NULL);
}
if (!mod) {
FREE(zm);
@ -247,12 +270,14 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr
}
zm->shader = mod;
/* non-generated tcs won't use the shader key */
const bool is_nongenerated_tcs = stage == MESA_SHADER_TESS_CTRL && !zs->tcs.is_generated;
const bool is_nongenerated_tcs = stage == MESA_SHADER_TESS_CTRL && !zs->non_fs.is_generated;
if (key && !is_nongenerated_tcs) {
zm->key_size = key_size;
uint16_t *data = (uint16_t*)zm->key;
/* sanitize actual key bits */
*data = (*key) & mask;
if (unlikely(shadow_needs_shader_swizzle))
memcpy(&data[1], &ctx->di.zs_swizzle[stage], sizeof(struct zink_zs_swizzle_key));
}
zm->default_variant = !util_dynarray_contains(&prog->shader_cache[stage][0][0], void*);
util_dynarray_append(&prog->shader_cache[stage][0][0], void*, zm);
@ -266,14 +291,16 @@ get_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_screen
struct zink_gfx_pipeline_state *state)
{
/* non-generated tcs won't use the shader key */
const bool is_nongenerated_tcs = stage == MESA_SHADER_TESS_CTRL && !zs->tcs.is_generated;
const bool is_nongenerated_tcs = stage == MESA_SHADER_TESS_CTRL && !zs->non_fs.is_generated;
bool shadow_needs_shader_swizzle = false;
uint16_t *key;
unsigned mask = stage == MESA_SHADER_FRAGMENT ? BITFIELD_MASK(16) : BITFIELD_MASK(8);
if (zs == prog->last_vertex_stage) {
key = (uint16_t*)&ctx->gfx_pipeline_state.shader_keys_optimal.key.vs_base;
} else if (stage == MESA_SHADER_FRAGMENT) {
key = (uint16_t*)&ctx->gfx_pipeline_state.shader_keys_optimal.key.fs;
} else if (stage == MESA_SHADER_TESS_CTRL && zs->tcs.is_generated) {
shadow_needs_shader_swizzle = ctx->gfx_pipeline_state.shader_keys_optimal.key.fs.shadow_needs_shader_swizzle;
} else if (stage == MESA_SHADER_TESS_CTRL && zs->non_fs.is_generated) {
key = (uint16_t*)&ctx->gfx_pipeline_state.shader_keys_optimal.key.tcs;
} else {
key = NULL;
@ -290,6 +317,11 @@ get_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_screen
/* no key is bigger than uint16_t */
if (memcmp(iter->key, &val, sizeof(uint16_t)))
continue;
if (unlikely(shadow_needs_shader_swizzle)) {
/* shadow swizzle data needs a manual compare since it's so fat */
if (memcmp(iter->key + sizeof(uint16_t), &ctx->di.zs_swizzle[stage], sizeof(struct zink_zs_swizzle_key)))
continue;
}
}
if (i > 0) {
struct zink_shader_module *zero = pzm[0];
@ -370,31 +402,6 @@ update_gfx_shader_modules(struct zink_context *ctx,
}
}
ALWAYS_INLINE static void
update_gfx_shader_modules_optimal(struct zink_context *ctx,
struct zink_screen *screen,
struct zink_gfx_program *prog, uint32_t mask,
struct zink_gfx_pipeline_state *state)
{
assert(prog->modules[MESA_SHADER_VERTEX]);
for (unsigned i = 0; i < MESA_SHADER_COMPUTE; i++) {
if (!(mask & BITFIELD_BIT(i)))
continue;
assert(prog->shaders[i]);
struct zink_shader_module *zm = get_shader_module_for_stage_optimal(ctx, screen, prog->shaders[i], prog, i, state);
if (!zm)
zm = create_shader_module_for_stage_optimal(ctx, screen, prog->shaders[i], prog, i, state);
if (prog->modules[i] == zm->shader)
continue;
state->modules_changed = true;
prog->modules[i] = zm->shader;
}
prog->last_variant_hash = state->shader_keys_optimal.key.val;
}
static void
generate_gfx_program_modules(struct zink_context *ctx, struct zink_screen *screen, struct zink_gfx_program *prog, struct zink_gfx_pipeline_state *state)
{
@ -453,7 +460,8 @@ generate_gfx_program_modules_optimal(struct zink_context *ctx, struct zink_scree
static uint32_t
hash_pipeline_lib_generated_tcs(const void *key)
{
return 1;
const struct zink_gfx_library_key *gkey = key;
return gkey->optimal_key;
}
@ -623,7 +631,7 @@ zink_gfx_program_update(struct zink_context *ctx)
ctx->dirty_gfx_stages = 0;
}
ALWAYS_INLINE static void
ALWAYS_INLINE static bool
update_gfx_shader_module_optimal(struct zink_context *ctx, struct zink_gfx_program *prog, gl_shader_stage pstage)
{
struct zink_screen *screen = zink_screen(ctx->base.screen);
@ -632,7 +640,10 @@ update_gfx_shader_module_optimal(struct zink_context *ctx, struct zink_gfx_progr
struct zink_shader_module *zm = get_shader_module_for_stage_optimal(ctx, screen, prog->shaders[pstage], prog, pstage, &ctx->gfx_pipeline_state);
if (!zm)
zm = create_shader_module_for_stage_optimal(ctx, screen, prog->shaders[pstage], prog, pstage, &ctx->gfx_pipeline_state);
bool changed = prog->modules[pstage] != zm->shader;
prog->modules[pstage] = zm->shader;
return changed;
}
static void
@ -640,17 +651,24 @@ update_gfx_program_optimal(struct zink_context *ctx, struct zink_gfx_program *pr
{
const union zink_shader_key_optimal *optimal_key = (union zink_shader_key_optimal*)&prog->last_variant_hash;
if (ctx->gfx_pipeline_state.shader_keys_optimal.key.vs_bits != optimal_key->vs_bits) {
update_gfx_shader_module_optimal(ctx, prog, ctx->last_vertex_stage->nir->info.stage);
ctx->gfx_pipeline_state.modules_changed = true;
bool changed = update_gfx_shader_module_optimal(ctx, prog, ctx->last_vertex_stage->nir->info.stage);
ctx->gfx_pipeline_state.modules_changed |= changed;
}
if (ctx->gfx_pipeline_state.shader_keys_optimal.key.fs_bits != optimal_key->fs_bits) {
update_gfx_shader_module_optimal(ctx, prog, MESA_SHADER_FRAGMENT);
ctx->gfx_pipeline_state.modules_changed = true;
const bool shadow_needs_shader_swizzle = optimal_key->fs.shadow_needs_shader_swizzle && (ctx->dirty_gfx_stages & BITFIELD_BIT(MESA_SHADER_FRAGMENT));
if (ctx->gfx_pipeline_state.shader_keys_optimal.key.fs_bits != optimal_key->fs_bits ||
/* always recheck shadow swizzles since they aren't directly part of the key */
unlikely(shadow_needs_shader_swizzle)) {
bool changed = update_gfx_shader_module_optimal(ctx, prog, MESA_SHADER_FRAGMENT);
ctx->gfx_pipeline_state.modules_changed |= changed;
if (unlikely(shadow_needs_shader_swizzle)) {
struct zink_shader_module **pzm = prog->shader_cache[MESA_SHADER_FRAGMENT][0][0].data;
ctx->gfx_pipeline_state.shadow = (struct zink_zs_swizzle_key*)pzm[0]->key + sizeof(uint16_t);
}
}
if (prog->shaders[MESA_SHADER_TESS_CTRL] && prog->shaders[MESA_SHADER_TESS_CTRL]->tcs.is_generated &&
if (prog->shaders[MESA_SHADER_TESS_CTRL] && prog->shaders[MESA_SHADER_TESS_CTRL]->non_fs.is_generated &&
ctx->gfx_pipeline_state.shader_keys_optimal.key.tcs_bits != optimal_key->tcs_bits) {
update_gfx_shader_module_optimal(ctx, prog, MESA_SHADER_TESS_CTRL);
ctx->gfx_pipeline_state.modules_changed = true;
bool changed = update_gfx_shader_module_optimal(ctx, prog, MESA_SHADER_TESS_CTRL);
ctx->gfx_pipeline_state.modules_changed |= changed;
}
prog->last_variant_hash = ctx->gfx_pipeline_state.shader_keys_optimal.key.val;
}
@ -725,8 +743,10 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c
struct zink_shader *zs = comp->shader;
VkShaderModule mod;
struct zink_shader_module *zm = NULL;
unsigned inline_size = 0, nonseamless_size = 0;
unsigned inline_size = 0, nonseamless_size = 0, zs_swizzle_size = 0;
struct zink_shader_key *key = &ctx->compute_pipeline_state.key;
ASSERTED bool check_robustness = screen->driver_workarounds.lower_robustImageAccess2 && (ctx->flags & PIPE_CONTEXT_ROBUST_BUFFER_ACCESS);
assert(zink_cs_key(key)->robust_access == check_robustness);
if (ctx && zs->nir->info.num_inlinable_uniforms &&
ctx->inlinable_uniforms_valid_mask & BITFIELD64_BIT(MESA_SHADER_COMPUTE)) {
@ -737,8 +757,10 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c
}
if (key->base.nonseamless_cube_mask)
nonseamless_size = sizeof(uint32_t);
if (key->base.needs_zs_shader_swizzle)
zs_swizzle_size = sizeof(struct zink_zs_swizzle_key);
if (inline_size || nonseamless_size) {
if (inline_size || nonseamless_size || zink_cs_key(key)->robust_access || zs_swizzle_size) {
struct util_dynarray *shader_cache = &comp->shader_cache[!!nonseamless_size];
unsigned count = util_dynarray_num_elements(shader_cache, struct zink_shader_module *);
struct zink_shader_module **pzm = shader_cache->data;
@ -748,6 +770,12 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c
screen->driconf.inline_uniforms,
screen->info.have_EXT_non_seamless_cube_map))
continue;
if (unlikely(zs_swizzle_size)) {
/* zs swizzle data needs a manual compare since it's so fat */
if (memcmp(iter->key + iter->key_size + nonseamless_size + inline_size * sizeof(uint32_t),
&ctx->di.zs_swizzle[MESA_SHADER_COMPUTE], zs_swizzle_size))
continue;
}
if (i > 0) {
struct zink_shader_module *zero = pzm[0];
pzm[0] = iter;
@ -760,31 +788,36 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c
}
if (!zm) {
zm = malloc(sizeof(struct zink_shader_module) + nonseamless_size + inline_size * sizeof(uint32_t));
zm = malloc(sizeof(struct zink_shader_module) + nonseamless_size + inline_size * sizeof(uint32_t) + zs_swizzle_size);
if (!zm) {
return;
}
mod = zink_shader_compile(screen, zs, comp->shader->nir, key);
mod = zink_shader_compile(screen, zs, comp->shader->nir, key, zs_swizzle_size ? &ctx->di.zs_swizzle[MESA_SHADER_COMPUTE] : NULL);
if (!mod) {
FREE(zm);
return;
}
zm->shader = mod;
zm->num_uniforms = inline_size;
zm->key_size = 0;
zm->key_size = key->size;
memcpy(zm->key, key, key->size);
zm->has_nonseamless = !!nonseamless_size;
assert(nonseamless_size || inline_size);
zm->needs_zs_shader_swizzle = !!zs_swizzle_size;
assert(nonseamless_size || inline_size || zink_cs_key(key)->robust_access || zs_swizzle_size);
if (nonseamless_size)
memcpy(zm->key, &key->base.nonseamless_cube_mask, nonseamless_size);
memcpy(zm->key + zm->key_size, &key->base.nonseamless_cube_mask, nonseamless_size);
if (inline_size)
memcpy(zm->key + nonseamless_size, key->base.inlined_uniform_values, inline_size * sizeof(uint32_t));
memcpy(zm->key + zm->key_size + nonseamless_size, key->base.inlined_uniform_values, inline_size * sizeof(uint32_t));
if (zs_swizzle_size)
memcpy(zm->key + zm->key_size + nonseamless_size + inline_size * sizeof(uint32_t), &ctx->di.zs_swizzle[MESA_SHADER_COMPUTE], zs_swizzle_size);
zm->hash = shader_module_hash(zm);
zm->default_variant = false;
if (inline_size)
comp->inlined_variant_count++;
/* this is otherwise the default variant, which is stored as comp->module */
if (zm->num_uniforms || nonseamless_size)
if (zm->num_uniforms || nonseamless_size || zink_cs_key(key)->robust_access || zs_swizzle_size)
util_dynarray_append(&comp->shader_cache[!!nonseamless_size], void*, zm);
}
if (comp->curr == zm)
@ -886,10 +919,10 @@ zink_create_gfx_program(struct zink_context *ctx,
prog->ctx = ctx;
for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) {
util_dynarray_init(&prog->shader_cache[i][0][0], NULL);
util_dynarray_init(&prog->shader_cache[i][0][1], NULL);
util_dynarray_init(&prog->shader_cache[i][1][0], NULL);
util_dynarray_init(&prog->shader_cache[i][1][1], NULL);
util_dynarray_init(&prog->shader_cache[i][0][0], prog);
util_dynarray_init(&prog->shader_cache[i][0][1], prog);
util_dynarray_init(&prog->shader_cache[i][1][0], prog);
util_dynarray_init(&prog->shader_cache[i][1][1], prog);
if (stages[i]) {
prog->shaders[i] = stages[i];
prog->stages_present |= BITFIELD_BIT(i);
@ -897,7 +930,7 @@ zink_create_gfx_program(struct zink_context *ctx,
}
bool generated_tcs = false;
if (stages[MESA_SHADER_TESS_EVAL] && !stages[MESA_SHADER_TESS_CTRL]) {
prog->shaders[MESA_SHADER_TESS_EVAL]->tes.generated =
prog->shaders[MESA_SHADER_TESS_EVAL]->non_fs.generated_tcs =
prog->shaders[MESA_SHADER_TESS_CTRL] =
zink_shader_tcs_create(screen, stages[MESA_SHADER_VERTEX], vertices_per_patch);
prog->stages_present |= BITFIELD_BIT(MESA_SHADER_TESS_CTRL);
@ -1009,10 +1042,10 @@ precompile_compute_job(void *data, void *gdata, int thread_index)
comp->shader = zink_shader_create(screen, comp->nir, NULL);
comp->curr = comp->module = CALLOC_STRUCT(zink_shader_module);
assert(comp->module);
comp->module->shader = zink_shader_compile(screen, comp->shader, comp->shader->nir, NULL);
comp->module->shader = zink_shader_compile(screen, comp->shader, comp->shader->nir, NULL, NULL);
assert(comp->module->shader);
util_dynarray_init(&comp->shader_cache[0], NULL);
util_dynarray_init(&comp->shader_cache[1], NULL);
util_dynarray_init(&comp->shader_cache[0], comp);
util_dynarray_init(&comp->shader_cache[1], comp);
struct blob blob = {0};
blob_init(&blob);
@ -1045,7 +1078,9 @@ create_compute_program(struct zink_context *ctx, nir_shader *nir)
comp->use_local_size = !(nir->info.workgroup_size[0] ||
nir->info.workgroup_size[1] ||
nir->info.workgroup_size[2]);
comp->base.can_precompile = !comp->use_local_size && (screen->info.have_EXT_non_seamless_cube_map || !zink_shader_has_cubes(nir));
comp->base.can_precompile = !comp->use_local_size &&
(screen->info.have_EXT_non_seamless_cube_map || !zink_shader_has_cubes(nir)) &&
(screen->info.rb2_feats.robustImageAccess2 || !(ctx->flags & PIPE_CONTEXT_ROBUST_BUFFER_ACCESS));
_mesa_hash_table_init(&comp->pipelines, comp, NULL, comp->use_local_size ?
equals_compute_pipeline_state_local_size :
equals_compute_pipeline_state);
@ -1226,8 +1261,13 @@ zink_destroy_compute_program(struct zink_screen *screen,
{
deinit_program(screen, &comp->base);
if (comp->shader)
_mesa_set_remove_key(comp->shader->programs, comp);
assert(comp->shader);
assert(!comp->shader->spirv);
_mesa_set_destroy(comp->shader->programs, NULL);
ralloc_free(comp->shader->nir);
ralloc_free(comp->shader);
destroy_shader_cache(screen, &comp->shader_cache[0]);
destroy_shader_cache(screen, &comp->shader_cache[1]);
@ -1306,7 +1346,7 @@ zink_get_compute_pipeline(struct zink_screen *screen,
return state->pipeline;
}
ALWAYS_INLINE static void
static void
bind_gfx_stage(struct zink_context *ctx, gl_shader_stage stage, struct zink_shader *shader)
{
if (shader && shader->nir->info.num_inlinable_uniforms)
@ -1314,8 +1354,18 @@ bind_gfx_stage(struct zink_context *ctx, gl_shader_stage stage, struct zink_shad
else
ctx->shader_has_inlinable_uniforms_mask &= ~(1 << stage);
if (ctx->gfx_stages[stage])
if (ctx->gfx_stages[stage]) {
ctx->gfx_hash ^= ctx->gfx_stages[stage]->hash;
/* unbind the generated GS */
if (stage != MESA_SHADER_FRAGMENT &&
ctx->gfx_stages[stage]->non_fs.generated_gs &&
ctx->gfx_stages[MESA_SHADER_GEOMETRY] ==
ctx->gfx_stages[stage]->non_fs.generated_gs) {
assert(stage != MESA_SHADER_GEOMETRY); /* let's not keep recursing! */
bind_gfx_stage(ctx, MESA_SHADER_GEOMETRY, NULL);
}
}
ctx->gfx_stages[stage] = shader;
ctx->gfx_dirty = ctx->gfx_stages[MESA_SHADER_FRAGMENT] && ctx->gfx_stages[MESA_SHADER_VERTEX];
ctx->gfx_pipeline_state.modules_changed = true;
@ -1460,9 +1510,9 @@ zink_update_fs_key_samples(struct zink_context *ctx)
return;
nir_shader *nir = ctx->gfx_stages[MESA_SHADER_FRAGMENT]->nir;
if (nir->info.outputs_written & (1 << FRAG_RESULT_SAMPLE_MASK)) {
bool samples = zink_get_fs_key(ctx)->samples;
bool samples = zink_get_fs_base_key(ctx)->samples;
if (samples != (ctx->fb_state.samples > 1))
zink_set_fs_key(ctx)->samples = ctx->fb_state.samples > 1;
zink_set_fs_base_key(ctx)->samples = ctx->fb_state.samples > 1;
}
}
@ -1473,6 +1523,7 @@ zink_bind_fs_state(struct pipe_context *pctx,
struct zink_context *ctx = zink_context(pctx);
if (!cso && !ctx->gfx_stages[MESA_SHADER_FRAGMENT])
return;
unsigned shadow_mask = ctx->gfx_stages[MESA_SHADER_FRAGMENT] ? ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask : 0;
bind_gfx_stage(ctx, MESA_SHADER_FRAGMENT, cso);
ctx->fbfetch_outputs = 0;
if (cso) {
@ -1489,6 +1540,10 @@ zink_bind_fs_state(struct pipe_context *pctx,
ctx->gfx_pipeline_state.dirty = true;
ctx->gfx_pipeline_state.rast_attachment_order = nir->info.fs.uses_fbfetch_output;
}
zink_set_zs_needs_shader_swizzle_key(ctx, MESA_SHADER_FRAGMENT, false);
if (shadow_mask != ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask &&
!zink_screen(pctx->screen)->driver_workarounds.needs_zs_shader_swizzle)
zink_update_shadow_samplerviews(ctx, shadow_mask | ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask);
}
zink_update_fbfetch(ctx);
}
@ -1521,7 +1576,7 @@ zink_bind_tes_state(struct pipe_context *pctx,
if (!!ctx->gfx_stages[MESA_SHADER_TESS_EVAL] != !!cso) {
if (!cso) {
/* if unsetting a TESS that uses a generated TCS, ensure the TCS is unset */
if (ctx->gfx_stages[MESA_SHADER_TESS_EVAL]->tes.generated)
if (ctx->gfx_stages[MESA_SHADER_TESS_EVAL]->non_fs.generated_tcs)
ctx->gfx_stages[MESA_SHADER_TESS_CTRL] = NULL;
}
}
@ -1851,3 +1906,59 @@ zink_driver_thread_add_job(struct pipe_screen *pscreen, void *data,
struct zink_screen *screen = zink_screen(pscreen);
util_queue_add_job(&screen->cache_get_thread, data, fence, execute, cleanup, job_size);
}
void
zink_set_primitive_emulation_keys(struct zink_context *ctx)
{
struct zink_screen *screen = zink_screen(ctx->base.screen);
bool lower_line_stipple = ctx->gfx_pipeline_state.rast_prim == PIPE_PRIM_LINES &&
screen->driver_workarounds.no_linestipple &&
ctx->rast_state->base.line_stipple_enable &&
!ctx->num_so_targets;
if (zink_get_fs_key(ctx)->lower_line_stipple != lower_line_stipple) {
assert(zink_get_gs_key(ctx)->lower_line_stipple ==
zink_get_fs_key(ctx)->lower_line_stipple);
zink_set_fs_key(ctx)->lower_line_stipple = lower_line_stipple;
zink_set_gs_key(ctx)->lower_line_stipple = lower_line_stipple;
}
bool lower_line_smooth = screen->driver_workarounds.no_linesmooth &&
ctx->rast_state->base.line_smooth &&
!ctx->num_so_targets;
if (zink_get_fs_key(ctx)->lower_line_smooth != lower_line_smooth) {
assert(zink_get_gs_key(ctx)->lower_line_smooth ==
zink_get_fs_key(ctx)->lower_line_smooth);
zink_set_fs_key(ctx)->lower_line_smooth = lower_line_smooth;
zink_set_gs_key(ctx)->lower_line_smooth = lower_line_smooth;
}
if (lower_line_stipple || lower_line_smooth ||
zink_get_gs_key(ctx)->lower_gl_point) {
enum pipe_shader_type prev_vertex_stage =
ctx->gfx_stages[MESA_SHADER_TESS_EVAL] ?
MESA_SHADER_TESS_EVAL : MESA_SHADER_VERTEX;
if (!ctx->gfx_stages[MESA_SHADER_GEOMETRY]) {
assert(!screen->optimal_keys);
if (!ctx->gfx_stages[prev_vertex_stage]->non_fs.generated_gs) {
nir_shader *nir = nir_create_passthrough_gs(
&screen->nir_options,
ctx->gfx_stages[prev_vertex_stage]->nir,
(lower_line_stipple || lower_line_smooth) ? SHADER_PRIM_LINE_STRIP : SHADER_PRIM_POINTS,
(lower_line_stipple || lower_line_smooth) ? 2 : 1);
struct zink_shader *shader = zink_shader_create(screen, nir, NULL);
ctx->gfx_stages[prev_vertex_stage]->non_fs.generated_gs = shader;
shader->non_fs.is_generated = true;
}
bind_gfx_stage(ctx, MESA_SHADER_GEOMETRY,
ctx->gfx_stages[prev_vertex_stage]->non_fs.generated_gs);
}
} else if (ctx->gfx_stages[MESA_SHADER_GEOMETRY] &&
ctx->gfx_stages[MESA_SHADER_GEOMETRY]->non_fs.is_generated)
bind_gfx_stage(ctx, MESA_SHADER_GEOMETRY, NULL);
}

View file

@ -240,21 +240,50 @@ zink_program_has_descriptors(const struct zink_program *pg)
return pg->num_dsl > 0;
}
static inline struct zink_fs_key *
zink_set_fs_key(struct zink_context *ctx)
static inline struct zink_fs_key_base *
zink_set_fs_base_key(struct zink_context *ctx)
{
ctx->dirty_gfx_stages |= BITFIELD_BIT(MESA_SHADER_FRAGMENT);
return zink_screen(ctx->base.screen)->optimal_keys ?
&ctx->gfx_pipeline_state.shader_keys_optimal.key.fs :
&ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs;
&ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs.base;
}
static inline const struct zink_fs_key_base *
zink_get_fs_base_key(struct zink_context *ctx)
{
return zink_screen(ctx->base.screen)->optimal_keys ?
&ctx->gfx_pipeline_state.shader_keys_optimal.key.fs :
&ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs.base;
}
static inline struct zink_fs_key *
zink_set_fs_key(struct zink_context *ctx)
{
assert(!zink_screen(ctx->base.screen)->optimal_keys);
ctx->dirty_gfx_stages |= BITFIELD_BIT(MESA_SHADER_FRAGMENT);
return &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs;
}
static inline const struct zink_fs_key *
zink_get_fs_key(struct zink_context *ctx)
{
return zink_screen(ctx->base.screen)->optimal_keys ?
&ctx->gfx_pipeline_state.shader_keys_optimal.key.fs :
&ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs;
assert(!zink_screen(ctx->base.screen)->optimal_keys);
return &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs;
}
static inline struct zink_gs_key *
zink_set_gs_key(struct zink_context *ctx)
{
ctx->dirty_gfx_stages |= BITFIELD_BIT(MESA_SHADER_GEOMETRY);
assert(!zink_screen(ctx->base.screen)->optimal_keys);
return &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_GEOMETRY].key.gs;
}
static inline const struct zink_gs_key *
zink_get_gs_key(struct zink_context *ctx)
{
return &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_GEOMETRY].key.gs;
}
static inline bool
@ -316,16 +345,19 @@ zink_get_last_vertex_key(struct zink_context *ctx)
static inline void
zink_set_fs_point_coord_key(struct zink_context *ctx)
{
const struct zink_fs_key *fs = zink_get_fs_key(ctx);
const struct zink_fs_key_base *fs = zink_get_fs_base_key(ctx);
bool disable = ctx->gfx_pipeline_state.rast_prim != PIPE_PRIM_POINTS;
uint8_t coord_replace_bits = disable ? 0 : ctx->rast_state->base.sprite_coord_enable;
bool point_coord_yinvert = disable ? false : !!ctx->rast_state->base.sprite_coord_mode;
if (fs->coord_replace_bits != coord_replace_bits || fs->point_coord_yinvert != point_coord_yinvert) {
zink_set_fs_key(ctx)->coord_replace_bits = coord_replace_bits;
zink_set_fs_key(ctx)->point_coord_yinvert = point_coord_yinvert;
zink_set_fs_base_key(ctx)->coord_replace_bits = coord_replace_bits;
zink_set_fs_base_key(ctx)->point_coord_yinvert = point_coord_yinvert;
}
}
void
zink_set_primitive_emulation_keys(struct zink_context *ctx);
static inline const struct zink_shader_key_base *
zink_get_shader_key_base(struct zink_context *ctx, gl_shader_stage pstage)
{
@ -341,6 +373,24 @@ zink_set_shader_key_base(struct zink_context *ctx, gl_shader_stage pstage)
return &ctx->gfx_pipeline_state.shader_keys.key[pstage].base;
}
static inline void
zink_set_zs_needs_shader_swizzle_key(struct zink_context *ctx, gl_shader_stage pstage, bool swizzle_update)
{
if (!zink_screen(ctx->base.screen)->driver_workarounds.needs_zs_shader_swizzle) {
if (pstage != MESA_SHADER_FRAGMENT)
return;
const struct zink_fs_key_base *fs = zink_get_fs_base_key(ctx);
bool enable = ctx->gfx_stages[MESA_SHADER_FRAGMENT] && (ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & ctx->di.zs_swizzle[pstage].mask) > 0;
if (enable != fs->shadow_needs_shader_swizzle || (enable && swizzle_update))
zink_set_fs_base_key(ctx)->shadow_needs_shader_swizzle = enable;
return;
}
bool enable = !!ctx->di.zs_swizzle[pstage].mask;
const struct zink_shader_key_base *key = zink_get_shader_key_base(ctx, pstage);
if (enable != key->needs_zs_shader_swizzle || (enable && swizzle_update))
zink_set_shader_key_base(ctx, pstage)->needs_zs_shader_swizzle = enable;
}
bool
zink_set_rasterizer_discard(struct zink_context *ctx, bool disable);
void

View file

@ -226,7 +226,10 @@ zink_get_gfx_pipeline(struct zink_context *ctx,
const int rp_idx = state->render_pass ? 1 : 0;
/* shortcut for reusing previous pipeline across program changes */
if (DYNAMIC_STATE == ZINK_DYNAMIC_VERTEX_INPUT || DYNAMIC_STATE == ZINK_DYNAMIC_VERTEX_INPUT2) {
if (prog->last_finalized_hash[rp_idx][idx] == state->final_hash && !prog->inline_variants && likely(prog->last_pipeline[rp_idx][idx])) {
if (prog->last_finalized_hash[rp_idx][idx] == state->final_hash &&
!prog->inline_variants && likely(prog->last_pipeline[rp_idx][idx]) &&
/* this data is too big to compare in the fast-path */
likely(!prog->shaders[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask)) {
state->pipeline = prog->last_pipeline[rp_idx][idx]->pipeline;
return state->pipeline;
}
@ -251,9 +254,11 @@ zink_get_gfx_pipeline(struct zink_context *ctx,
if (HAVE_LIB &&
/* TODO: if there's ever a dynamic render extension with input attachments */
!ctx->gfx_pipeline_state.render_pass &&
/* this is just terrible */
!zink_get_fs_base_key(ctx)->shadow_needs_shader_swizzle &&
/* TODO: is sample shading even possible to handle with GPL? */
!ctx->gfx_stages[MESA_SHADER_FRAGMENT]->nir->info.fs.uses_sample_shading &&
!zink_get_fs_key(ctx)->fbfetch_ms &&
!zink_get_fs_base_key(ctx)->fbfetch_ms &&
!ctx->gfx_pipeline_state.force_persample_interp &&
!ctx->gfx_pipeline_state.min_samples) {
/* this is the graphics pipeline library path: find/construct all partial pipelines */
@ -357,6 +362,10 @@ equals_gfx_pipeline_state(const void *a, const void *b)
if (STAGE_MASK & STAGE_MASK_OPTIMAL) {
if (sa->optimal_key != sb->optimal_key)
return false;
if (STAGE_MASK & STAGE_MASK_OPTIMAL_SHADOW) {
if (sa->shadow != sb->shadow)
return false;
}
} else {
if (STAGE_MASK & BITFIELD_BIT(MESA_SHADER_TESS_CTRL)) {
if (sa->modules[MESA_SHADER_TESS_CTRL] != sb->modules[MESA_SHADER_TESS_CTRL])
@ -382,10 +391,13 @@ equals_gfx_pipeline_state(const void *a, const void *b)
/* below is a bunch of code to pick the right equals_gfx_pipeline_state template for runtime */
template <zink_pipeline_dynamic_state DYNAMIC_STATE, unsigned STAGE_MASK>
static equals_gfx_pipeline_state_func
get_optimal_gfx_pipeline_stage_eq_func(bool optimal_keys)
get_optimal_gfx_pipeline_stage_eq_func(bool optimal_keys, bool shadow_needs_shader_swizzle)
{
if (optimal_keys)
if (optimal_keys) {
if (shadow_needs_shader_swizzle)
return equals_gfx_pipeline_state<DYNAMIC_STATE, STAGE_MASK | STAGE_MASK_OPTIMAL | STAGE_MASK_OPTIMAL_SHADOW>;
return equals_gfx_pipeline_state<DYNAMIC_STATE, STAGE_MASK | STAGE_MASK_OPTIMAL>;
}
return equals_gfx_pipeline_state<DYNAMIC_STATE, STAGE_MASK>;
}
@ -393,39 +405,40 @@ template <zink_pipeline_dynamic_state DYNAMIC_STATE>
static equals_gfx_pipeline_state_func
get_gfx_pipeline_stage_eq_func(struct zink_gfx_program *prog, bool optimal_keys)
{
bool shadow_needs_shader_swizzle = prog->shaders[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask > 0;
unsigned vertex_stages = prog->stages_present & BITFIELD_MASK(MESA_SHADER_FRAGMENT);
if (vertex_stages & BITFIELD_BIT(MESA_SHADER_TESS_CTRL)) {
if (prog->shaders[MESA_SHADER_TESS_CTRL]->tcs.is_generated)
if (prog->shaders[MESA_SHADER_TESS_CTRL]->non_fs.is_generated)
vertex_stages &= ~BITFIELD_BIT(MESA_SHADER_TESS_CTRL);
}
if (vertex_stages & BITFIELD_BIT(MESA_SHADER_TESS_CTRL)) {
if (vertex_stages == BITFIELD_MASK(MESA_SHADER_FRAGMENT))
/* all stages */
return get_optimal_gfx_pipeline_stage_eq_func<DYNAMIC_STATE,
BITFIELD_MASK(MESA_SHADER_COMPUTE)>(optimal_keys);
BITFIELD_MASK(MESA_SHADER_COMPUTE)>(optimal_keys, shadow_needs_shader_swizzle);
if (vertex_stages == BITFIELD_MASK(MESA_SHADER_GEOMETRY))
/* tess only: includes generated tcs too */
return get_optimal_gfx_pipeline_stage_eq_func<DYNAMIC_STATE,
BITFIELD_MASK(MESA_SHADER_COMPUTE) & ~BITFIELD_BIT(MESA_SHADER_GEOMETRY)>(optimal_keys);
BITFIELD_MASK(MESA_SHADER_COMPUTE) & ~BITFIELD_BIT(MESA_SHADER_GEOMETRY)>(optimal_keys, shadow_needs_shader_swizzle);
if (vertex_stages == (BITFIELD_BIT(MESA_SHADER_VERTEX) | BITFIELD_BIT(MESA_SHADER_GEOMETRY)))
/* geom only */
return get_optimal_gfx_pipeline_stage_eq_func<DYNAMIC_STATE,
BITFIELD_BIT(MESA_SHADER_VERTEX) | BITFIELD_BIT(MESA_SHADER_FRAGMENT) | BITFIELD_BIT(MESA_SHADER_GEOMETRY)>(optimal_keys);
BITFIELD_BIT(MESA_SHADER_VERTEX) | BITFIELD_BIT(MESA_SHADER_FRAGMENT) | BITFIELD_BIT(MESA_SHADER_GEOMETRY)>(optimal_keys, shadow_needs_shader_swizzle);
}
if (vertex_stages == (BITFIELD_MASK(MESA_SHADER_FRAGMENT) & ~BITFIELD_BIT(MESA_SHADER_TESS_CTRL)))
/* all stages but tcs */
return get_optimal_gfx_pipeline_stage_eq_func<DYNAMIC_STATE,
BITFIELD_MASK(MESA_SHADER_COMPUTE) & ~BITFIELD_BIT(MESA_SHADER_TESS_CTRL)>(optimal_keys);
BITFIELD_MASK(MESA_SHADER_COMPUTE) & ~BITFIELD_BIT(MESA_SHADER_TESS_CTRL)>(optimal_keys, shadow_needs_shader_swizzle);
if (vertex_stages == (BITFIELD_MASK(MESA_SHADER_GEOMETRY) & ~BITFIELD_BIT(MESA_SHADER_TESS_CTRL)))
/* tess only: generated tcs */
return get_optimal_gfx_pipeline_stage_eq_func<DYNAMIC_STATE,
BITFIELD_MASK(MESA_SHADER_COMPUTE) & ~(BITFIELD_BIT(MESA_SHADER_GEOMETRY) | BITFIELD_BIT(MESA_SHADER_TESS_CTRL))>(optimal_keys);
BITFIELD_MASK(MESA_SHADER_COMPUTE) & ~(BITFIELD_BIT(MESA_SHADER_GEOMETRY) | BITFIELD_BIT(MESA_SHADER_TESS_CTRL))>(optimal_keys, shadow_needs_shader_swizzle);
if (vertex_stages == (BITFIELD_BIT(MESA_SHADER_VERTEX) | BITFIELD_BIT(MESA_SHADER_GEOMETRY)))
/* geom only */
return get_optimal_gfx_pipeline_stage_eq_func<DYNAMIC_STATE,
BITFIELD_BIT(MESA_SHADER_VERTEX) | BITFIELD_BIT(MESA_SHADER_FRAGMENT) | BITFIELD_BIT(MESA_SHADER_GEOMETRY)>(optimal_keys);
BITFIELD_BIT(MESA_SHADER_VERTEX) | BITFIELD_BIT(MESA_SHADER_FRAGMENT) | BITFIELD_BIT(MESA_SHADER_GEOMETRY)>(optimal_keys, shadow_needs_shader_swizzle);
return get_optimal_gfx_pipeline_stage_eq_func<DYNAMIC_STATE,
BITFIELD_BIT(MESA_SHADER_VERTEX) | BITFIELD_BIT(MESA_SHADER_FRAGMENT)>(optimal_keys);
BITFIELD_BIT(MESA_SHADER_VERTEX) | BITFIELD_BIT(MESA_SHADER_FRAGMENT)>(optimal_keys, shadow_needs_shader_swizzle);
}
equals_gfx_pipeline_state_func

View file

@ -366,7 +366,8 @@ zink_init_zs_attachment(struct zink_context *ctx, struct zink_rt_attrib *rt)
needs_write_z |= transient || rt->clear_color ||
(zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS) && (zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_DEPTH));
bool needs_write_s = rt->clear_stencil || (outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL)) ||
bool needs_write_s = (ctx->dsa_state && (util_writes_stencil(&ctx->dsa_state->base.stencil[0]) || util_writes_stencil(&ctx->dsa_state->base.stencil[1]))) ||
rt->clear_stencil || (outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL)) ||
(zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS) && (zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_STENCIL));
rt->needs_write = needs_write_z | needs_write_s;
rt->invalid = !zsbuf->valid;
@ -589,7 +590,9 @@ setup_framebuffer(struct zink_context *ctx)
ctx->rp_loadop_changed = false;
ctx->rp_layout_changed = false;
ctx->rp_changed = false;
zink_render_update_swapchain(ctx);
if (zink_render_update_swapchain(ctx))
zink_render_fixup_swapchain(ctx);
if (!ctx->fb_changed)
return;
@ -814,6 +817,25 @@ zink_init_render_pass(struct zink_context *ctx)
}
void
zink_render_fixup_swapchain(struct zink_context *ctx)
{
if ((ctx->swapchain_size.width || ctx->swapchain_size.height)) {
unsigned old_w = ctx->fb_state.width;
unsigned old_h = ctx->fb_state.height;
ctx->fb_state.width = ctx->swapchain_size.width;
ctx->fb_state.height = ctx->swapchain_size.height;
ctx->dynamic_fb.info.renderArea.extent.width = MIN2(ctx->dynamic_fb.info.renderArea.extent.width, ctx->fb_state.width);
ctx->dynamic_fb.info.renderArea.extent.height = MIN2(ctx->dynamic_fb.info.renderArea.extent.height, ctx->fb_state.height);
zink_kopper_fixup_depth_buffer(ctx);
if (ctx->fb_state.width != old_w || ctx->fb_state.height != old_h)
ctx->scissor_changed = true;
if (ctx->framebuffer)
zink_update_framebuffer_state(ctx);
ctx->swapchain_size.width = ctx->swapchain_size.height = 0;
}
}
bool
zink_render_update_swapchain(struct zink_context *ctx)
{
bool has_swapchain = false;
@ -827,16 +849,5 @@ zink_render_update_swapchain(struct zink_context *ctx)
zink_surface_swapchain_update(ctx, zink_csurface(ctx->fb_state.cbufs[i]));
}
}
if (has_swapchain && (ctx->swapchain_size.width || ctx->swapchain_size.height)) {
unsigned old_w = ctx->fb_state.width;
unsigned old_h = ctx->fb_state.height;
ctx->fb_state.width = ctx->swapchain_size.width;
ctx->fb_state.height = ctx->swapchain_size.height;
zink_kopper_fixup_depth_buffer(ctx);
if (ctx->fb_state.width != old_w || ctx->fb_state.height != old_h)
ctx->scissor_changed = true;
if (ctx->framebuffer)
zink_update_framebuffer_state(ctx);
ctx->swapchain_size.width = ctx->swapchain_size.height = 0;
}
return has_swapchain;
}

View file

@ -47,9 +47,11 @@ VkImageLayout
zink_tc_renderpass_info_parse(struct zink_context *ctx, const struct tc_renderpass_info *info, unsigned idx, VkPipelineStageFlags *pipeline, VkAccessFlags *access);
bool
zink_init_render_pass(struct zink_context *ctx);
void
bool
zink_render_update_swapchain(struct zink_context *ctx);
void
zink_render_fixup_swapchain(struct zink_context *ctx);
void
zink_init_zs_attachment(struct zink_context *ctx, struct zink_rt_attrib *rt);
void
zink_init_color_attachment(struct zink_context *ctx, unsigned i, struct zink_rt_attrib *rt);

View file

@ -105,6 +105,7 @@ zink_destroy_resource_object(struct zink_screen *screen, struct zink_resource_ob
while (util_dynarray_contains(&obj->views, VkImageView))
VKSCR(DestroyImageView)(screen->dev, util_dynarray_pop(&obj->views, VkImageView), NULL);
}
util_dynarray_fini(&obj->views);
if (obj->is_buffer) {
VKSCR(DestroyBuffer)(screen->dev, obj->buffer, NULL);
VKSCR(DestroyBuffer)(screen->dev, obj->storage_buffer, NULL);
@ -460,6 +461,10 @@ create_ici(struct zink_screen *screen, VkImageCreateInfo *ici, const struct pipe
ici->usage = 0;
ici->queueFamilyIndexCount = 0;
/* assume we're going to be doing some CompressedTexSubImage */
if (util_format_is_compressed(templ->format) && (ici->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT))
ici->flags |= VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT;
if (templ->flags & PIPE_RESOURCE_FLAG_SPARSE)
ici->flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
@ -590,6 +595,8 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
return NULL;
simple_mtx_init(&obj->view_lock, mtx_plain);
util_dynarray_init(&obj->views, NULL);
obj->unordered_read = true;
obj->unordered_write = true;
obj->last_dt_idx = obj->dt_idx = UINT32_MAX; //TODO: unionize
VkMemoryRequirements reqs = {0};
@ -2348,6 +2355,7 @@ zink_screen_resource_init(struct pipe_screen *pscreen)
pscreen->transfer_helper = u_transfer_helper_create(&transfer_vtbl,
U_TRANSFER_HELPER_SEPARATE_Z32S8 | U_TRANSFER_HELPER_SEPARATE_STENCIL |
U_TRANSFER_HELPER_INTERLEAVE_IN_PLACE |
U_TRANSFER_HELPER_MSAA_MAP |
(!screen->have_D24_UNORM_S8_UINT ? U_TRANSFER_HELPER_Z24_IN_Z32F : 0));
if (screen->info.have_KHR_external_memory_fd || screen->info.have_KHR_external_memory_win32) {

View file

@ -89,17 +89,6 @@ uint32_t
zink_debug;
static const struct debug_named_value
zink_descriptor_options[] = {
{ "auto", ZINK_DESCRIPTOR_MODE_AUTO, "Automatically detect best mode" },
{ "lazy", ZINK_DESCRIPTOR_MODE_LAZY, "Don't cache, do least amount of updates" },
DEBUG_NAMED_VALUE_END
};
DEBUG_GET_ONCE_FLAGS_OPTION(zink_descriptor_mode, "ZINK_DESCRIPTORS", zink_descriptor_options, ZINK_DESCRIPTOR_MODE_AUTO)
enum zink_descriptor_mode zink_descriptor_mode;
static const char *
zink_get_vendor(struct pipe_screen *pscreen)
{
@ -523,6 +512,9 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_NATIVE_FENCE_FD:
return screen->instance_info.have_KHR_external_semaphore_capabilities && screen->info.have_KHR_external_semaphore_fd;
case PIPE_CAP_SURFACE_REINTERPRET_BLOCKS:
return screen->info.have_vulkan11 || screen->info.have_KHR_maintenance2;
case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
case PIPE_CAP_MAP_UNSYNCHRONIZED_THREAD_SAFE:
case PIPE_CAP_SHAREABLE_SHADERS:
@ -587,7 +579,8 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return screen->info.feats.features.pipelineStatisticsQuery;
case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
return screen->info.feats.features.robustBufferAccess;
return screen->info.feats.features.robustBufferAccess &&
(screen->info.rb2_feats.robustImageAccess2 || screen->driver_workarounds.lower_robustImageAccess2);
case PIPE_CAP_MULTI_DRAW_INDIRECT:
return screen->info.feats.features.multiDrawIndirect;
@ -1426,6 +1419,10 @@ zink_destroy_screen(struct pipe_screen *pscreen)
if (screen->threaded)
util_queue_destroy(&screen->flush_queue);
simple_mtx_destroy(&screen->semaphores_lock);
while (util_dynarray_contains(&screen->semaphores, VkSemaphore))
VKSCR(DestroySemaphore)(screen->dev, util_dynarray_pop(&screen->semaphores, VkSemaphore), NULL);
simple_mtx_destroy(&screen->queue_lock);
VKSCR(DestroyDevice)(screen->dev, NULL);
VKSCR(DestroyInstance)(screen->instance, NULL);
@ -2308,6 +2305,7 @@ init_driver_workarounds(struct zink_screen *screen)
case VK_DRIVER_ID_MESA_V3DV:
case VK_DRIVER_ID_MESA_PANVK:
case VK_DRIVER_ID_MESA_VENUS:
case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
screen->driver_workarounds.implicit_sync = false;
break;
default:
@ -2346,7 +2344,6 @@ init_driver_workarounds(struct zink_screen *screen)
screen->info.gpl_props.graphicsPipelineLibraryFastLinking ||
screen->is_cpu);
screen->driver_workarounds.broken_l4a4 = screen->info.driver_props.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY;
screen->driver_workarounds.depth_clip_control_missing = !screen->info.have_EXT_depth_clip_control;
if (screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_PROPRIETARY)
/* this completely breaks xfb somehow */
screen->info.have_EXT_extended_dynamic_state2 = false;
@ -2354,6 +2351,37 @@ init_driver_workarounds(struct zink_screen *screen)
/* performance */
screen->info.border_color_feats.customBorderColorWithoutFormat = VK_FALSE;
}
if ((!screen->info.have_EXT_line_rasterization ||
!screen->info.line_rast_feats.stippledBresenhamLines) &&
screen->info.feats.features.geometryShader &&
screen->info.feats.features.sampleRateShading) {
/* we're using stippledBresenhamLines as a proxy for all of these, to
* avoid accidentally changing behavior on VK-drivers where we don't
* want to add emulation.
*/
screen->driver_workarounds.no_linestipple = true;
}
if (screen->info.driver_props.driverID ==
VK_DRIVER_ID_IMAGINATION_PROPRIETARY) {
assert(screen->info.feats.features.geometryShader);
screen->driver_workarounds.no_linesmooth = true;
}
/* This is a workarround for the lack of
* gl_PointSize + glPolygonMode(..., GL_LINE), in the imagination
* proprietary driver.
*/
switch (screen->info.driver_props.driverID) {
case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
screen->driver_workarounds.no_hw_gl_point = true;
break;
default:
screen->driver_workarounds.no_hw_gl_point = false;
break;
}
if (screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_OPEN_SOURCE ||
screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_PROPRIETARY ||
screen->info.driver_props.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY ||
@ -2402,6 +2430,23 @@ init_driver_workarounds(struct zink_screen *screen)
screen->driver_workarounds.needs_sanitised_layer = false;
break;
}
/* these drivers will produce undefined results when using swizzle 1 with combined z/s textures
* TODO: use a future device property when available
*/
switch (screen->info.driver_props.driverID) {
case VK_DRIVER_ID_IMAGINATION_PROPRIETARY:
screen->driver_workarounds.needs_zs_shader_swizzle = true;
break;
default:
screen->driver_workarounds.needs_zs_shader_swizzle = false;
break;
}
/* When robust contexts are advertised but robustImageAccess2 is not available */
screen->driver_workarounds.lower_robustImageAccess2 =
!screen->info.rb2_feats.robustImageAccess2 &&
screen->info.feats.features.robustBufferAccess &&
screen->info.rb_image_feats.robustImageAccess;
/* once more testing has been done, use the #if 0 block */
if (zink_debug & ZINK_DEBUG_RP)
@ -2435,6 +2480,27 @@ zink_get_disk_shader_cache(struct pipe_screen *_screen)
return screen->disk_cache;
}
VkSemaphore
zink_create_semaphore(struct zink_screen *screen)
{
VkSemaphoreCreateInfo sci = {
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
NULL,
0
};
VkSemaphore sem = VK_NULL_HANDLE;
if (util_dynarray_contains(&screen->semaphores, VkSemaphore)) {
simple_mtx_lock(&screen->semaphores_lock);
if (util_dynarray_contains(&screen->semaphores, VkSemaphore))
sem = util_dynarray_pop(&screen->semaphores, VkSemaphore);
simple_mtx_unlock(&screen->semaphores_lock);
}
if (sem)
return sem;
VkResult ret = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &sem);
return ret == VK_SUCCESS ? sem : VK_NULL_HANDLE;
}
static struct zink_screen *
zink_internal_create_screen(const struct pipe_screen_config *config)
{
@ -2451,7 +2517,6 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
screen->abort_on_hang = debug_get_bool_option("ZINK_HANG_ABORT", false);
zink_debug = debug_get_option_zink_debug();
zink_descriptor_mode = debug_get_option_zink_descriptor_mode();
screen->loader_lib = util_dl_open(VK_LIBNAME);
if (!screen->loader_lib)
@ -2560,9 +2625,6 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
screen->desc_set_id[ZINK_DESCRIPTOR_TYPE_IMAGE] = 4;
screen->desc_set_id[ZINK_DESCRIPTOR_BINDLESS] = 5;
}
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_AUTO) {
zink_descriptor_mode = ZINK_DESCRIPTOR_MODE_LAZY;
}
if (screen->info.have_EXT_calibrated_timestamps && !check_have_device_time(screen))
goto fail;
@ -2697,6 +2759,9 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
util_idalloc_mt_init_tc(&screen->buffer_ids);
simple_mtx_init(&screen->semaphores_lock, mtx_plain);
util_dynarray_init(&screen->semaphores, screen);
util_vertex_state_cache_init(&screen->vertex_state_cache,
zink_create_vertex_state, zink_vertex_state_destroy);
screen->base.create_vertex_state = zink_cache_create_vertex_state;
@ -2725,7 +2790,14 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
goto fail;
}
screen->optimal_keys = !screen->need_decompose_attrs && screen->info.have_EXT_non_seamless_cube_map && !screen->driconf.inline_uniforms;
screen->optimal_keys = !screen->need_decompose_attrs &&
screen->info.have_EXT_non_seamless_cube_map &&
!screen->driconf.inline_uniforms &&
!screen->driver_workarounds.no_linestipple &&
!screen->driver_workarounds.no_linesmooth &&
!screen->driver_workarounds.no_hw_gl_point &&
!screen->driver_workarounds.lower_robustImageAccess2 &&
!screen->driver_workarounds.needs_zs_shader_swizzle;
if (!screen->optimal_keys)
screen->info.have_EXT_graphics_pipeline_library = false;

View file

@ -96,6 +96,9 @@ zink_screen_handle_vkresult(struct zink_screen *screen, VkResult ret)
return success;
}
VkSemaphore
zink_create_semaphore(struct zink_screen *screen);
VkFormat
zink_get_format(struct zink_screen *screen, enum pipe_format format);

View file

@ -32,7 +32,8 @@ struct zink_vs_key_base {
bool last_vertex_stage : 1;
bool clip_halfz : 1;
bool push_drawid : 1;
uint8_t pad : 5;
bool robust_access : 1;
uint8_t pad : 4;
};
struct zink_vs_key {
@ -56,21 +57,59 @@ struct zink_vs_key {
unsigned size;
};
struct zink_fs_key {
struct zink_gs_key {
struct zink_vs_key_base base;
uint8_t pad;
bool lower_line_stipple : 1;
bool lower_line_smooth : 1;
bool lower_gl_point : 1;
// not hashed
unsigned size;
};
struct zink_zs_swizzle {
uint8_t s[4];
};
struct zink_zs_swizzle_key {
uint32_t mask;
struct zink_zs_swizzle swizzle[32];
};
struct zink_fs_key_base {
bool point_coord_yinvert : 1;
bool samples : 1;
bool force_dual_color_blend : 1;
bool force_persample_interp : 1;
bool fbfetch_ms : 1;
uint8_t pad : 3;
bool shadow_needs_shader_swizzle : 1; //append zink_zs_swizzle_key after the key data
uint8_t pad : 2;
uint8_t coord_replace_bits;
};
struct zink_fs_key {
struct zink_fs_key_base base;
/* non-optimal bits after this point */
bool lower_line_stipple : 1;
bool lower_line_smooth : 1;
bool robust_access : 1;
uint16_t pad2 : 13;
};
struct zink_tcs_key {
uint8_t patch_vertices;
};
/* when adding a new field, make sure
* ctx->compute_pipeline_state.key.size is set in zink_context_create.
*/
struct zink_cs_key {
bool robust_access : 1;
uint32_t pad : 31;
};
struct zink_shader_key_base {
bool needs_zs_shader_swizzle;
uint32_t nonseamless_cube_mask;
uint32_t inlined_uniform_values[MAX_INLINABLE_UNIFORMS];
};
@ -82,11 +121,14 @@ struct zink_shader_key_base {
*/
struct zink_shader_key {
union {
/* reuse vs key for now with tes/gs since we only use clip_halfz */
/* reuse vs key for now with tes since we only use clip_halfz */
struct zink_vs_key vs;
struct zink_vs_key_base vs_base;
struct zink_tcs_key tcs;
struct zink_gs_key gs;
struct zink_fs_key fs;
struct zink_fs_key_base fs_base;
struct zink_cs_key cs;
} key;
struct zink_shader_key_base base;
unsigned inline_uniforms:1;
@ -97,7 +139,7 @@ union zink_shader_key_optimal {
struct {
struct zink_vs_key_base vs_base;
struct zink_tcs_key tcs;
struct zink_fs_key fs;
struct zink_fs_key_base fs;
};
struct {
uint8_t vs_bits;
@ -120,6 +162,13 @@ zink_shader_key_optimal_no_tcs(uint32_t key)
}
#define ZINK_SHADER_KEY_OPTIMAL_IS_DEFAULT(key) (zink_shader_key_optimal_no_tcs(key) == ZINK_SHADER_KEY_OPTIMAL_DEFAULT)
static inline const struct zink_fs_key_base *
zink_fs_key_base(const struct zink_shader_key *key)
{
assert(key);
return &key->key.fs.base;
}
static inline const struct zink_fs_key *
zink_fs_key(const struct zink_shader_key *key)
{
@ -140,6 +189,13 @@ zink_vs_key(const struct zink_shader_key *key)
return &key->key.vs;
}
static inline const struct zink_gs_key *
zink_gs_key(const struct zink_shader_key *key)
{
assert(key);
return &key->key.gs;
}
static inline const struct zink_tcs_key *
zink_tcs_key(const struct zink_shader_key *key)
{
@ -147,6 +203,11 @@ zink_tcs_key(const struct zink_shader_key *key)
return &key->key.tcs;
}
static inline const struct zink_cs_key *
zink_cs_key(const struct zink_shader_key *key)
{
assert(key);
return &key->key.cs;
}
#endif

View file

@ -411,8 +411,8 @@ zink_bind_blend_state(struct pipe_context *pctx, void *cso)
state->dirty |= !zink_screen(pctx->screen)->have_full_ds3;
bool force_dual_color_blend = zink_screen(pctx->screen)->driconf.dual_color_blend_by_location &&
blend && blend->dual_src_blend && state->blend_state->attachments[0].blendEnable;
if (force_dual_color_blend != zink_get_fs_key(ctx)->force_dual_color_blend)
zink_set_fs_key(ctx)->force_dual_color_blend = force_dual_color_blend;
if (force_dual_color_blend != zink_get_fs_base_key(ctx)->force_dual_color_blend)
zink_set_fs_base_key(ctx)->force_dual_color_blend = force_dual_color_blend;
ctx->blend_state_changed = true;
}
}
@ -510,7 +510,7 @@ zink_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *cso)
{
struct zink_context *ctx = zink_context(pctx);
bool prev_zwrite = ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write : false;
bool prev_zswrite = ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write || ctx->dsa_state->hw_state.stencil_test : false;
ctx->dsa_state = cso;
if (cso) {
@ -521,7 +521,8 @@ zink_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *cso)
ctx->dsa_state_changed = true;
}
}
if (prev_zwrite != (ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write : false)) {
bool zs_write = ctx->dsa_state ? ctx->dsa_state->hw_state.depth_write || ctx->dsa_state->hw_state.stencil_test : false;
if (prev_zswrite != zs_write) {
/* flag renderpass for re-check on next draw */
ctx->rp_layout_changed = true;
}
@ -564,7 +565,10 @@ zink_create_rasterizer_state(struct pipe_context *pctx,
state->base = *rs_state;
state->base.line_stipple_factor++;
state->hw_state.line_stipple_enable = rs_state->line_stipple_enable;
state->hw_state.line_stipple_enable =
rs_state->line_stipple_enable &&
!screen->driver_workarounds.no_linestipple;
assert(rs_state->depth_clip_far == rs_state->depth_clip_near);
state->hw_state.depth_clip = rs_state->depth_clip_near;
@ -575,8 +579,15 @@ zink_create_rasterizer_state(struct pipe_context *pctx,
assert(rs_state->fill_front <= PIPE_POLYGON_MODE_POINT);
if (rs_state->fill_back != rs_state->fill_front)
debug_printf("BUG: vulkan doesn't support different front and back fill modes\n");
state->hw_state.polygon_mode = rs_state->fill_front; // same values
state->cull_mode = rs_state->cull_face; // same bits
if (rs_state->fill_front == PIPE_POLYGON_MODE_POINT &&
screen->driver_workarounds.no_hw_gl_point) {
state->hw_state.polygon_mode = VK_POLYGON_MODE_FILL;
state->cull_mode = VK_CULL_MODE_NONE;
} else {
state->hw_state.polygon_mode = rs_state->fill_front; // same values
state->cull_mode = rs_state->cull_face; // same bits
}
state->front_face = rs_state->front_ccw ?
VK_FRONT_FACE_COUNTER_CLOCKWISE :
@ -584,7 +595,8 @@ zink_create_rasterizer_state(struct pipe_context *pctx,
state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
if (rs_state->line_rectangular) {
if (rs_state->line_smooth)
if (rs_state->line_smooth &&
!screen->driver_workarounds.no_linesmooth)
state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
else
state->hw_state.line_mode = VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
@ -638,7 +650,7 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
ctx->rast_state_changed = true;
if (clip_halfz != ctx->rast_state->base.clip_halfz) {
if (!screen->driver_workarounds.depth_clip_control_missing)
if (screen->info.have_EXT_depth_clip_control)
ctx->gfx_pipeline_state.dirty = true;
else
zink_set_last_vertex_key(ctx)->clip_halfz = ctx->rast_state->base.clip_halfz;
@ -648,6 +660,11 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
if (fabs(ctx->rast_state->base.line_width - line_width) > FLT_EPSILON)
ctx->line_width_changed = true;
bool lower_gl_point = screen->driver_workarounds.no_hw_gl_point;
lower_gl_point &= ctx->rast_state->base.fill_front == PIPE_POLYGON_MODE_POINT;
if (zink_get_gs_key(ctx)->lower_gl_point != lower_gl_point)
zink_set_gs_key(ctx)->lower_gl_point = lower_gl_point;
if (ctx->gfx_pipeline_state.dyn_state1.front_face != ctx->rast_state->front_face) {
ctx->gfx_pipeline_state.dyn_state1.front_face = ctx->rast_state->front_face;
ctx->gfx_pipeline_state.dirty |= !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state;
@ -667,7 +684,7 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
ctx->scissor_changed = true;
if (ctx->rast_state->base.force_persample_interp != force_persample_interp) {
zink_set_fs_key(ctx)->force_persample_interp = ctx->rast_state->base.force_persample_interp;
zink_set_fs_base_key(ctx)->force_persample_interp = ctx->rast_state->base.force_persample_interp;
ctx->gfx_pipeline_state.dirty = true;
}
ctx->gfx_pipeline_state.force_persample_interp = ctx->rast_state->base.force_persample_interp;

View file

@ -125,6 +125,22 @@ init_surface_info(struct zink_surface *surface, struct zink_resource *res, VkIma
}
}
static void
init_pipe_surface_info(struct pipe_context *pctx, struct pipe_surface *psurf, const struct pipe_surface *templ, const struct pipe_resource *pres)
{
unsigned int level = templ->u.tex.level;
psurf->context = pctx;
psurf->format = templ->format;
psurf->width = u_minify(pres->width0, level);
assert(psurf->width);
psurf->height = u_minify(pres->height0, level);
assert(psurf->height);
psurf->nr_samples = templ->nr_samples;
psurf->u.tex.level = level;
psurf->u.tex.first_layer = templ->u.tex.first_layer;
psurf->u.tex.last_layer = templ->u.tex.last_layer;
}
static struct zink_surface *
create_surface(struct pipe_context *pctx,
struct pipe_resource *pres,
@ -134,7 +150,6 @@ create_surface(struct pipe_context *pctx,
{
struct zink_screen *screen = zink_screen(pctx->screen);
struct zink_resource *res = zink_resource(pres);
unsigned int level = templ->u.tex.level;
struct zink_surface *surface = CALLOC_STRUCT(zink_surface);
if (!surface)
@ -163,16 +178,7 @@ create_surface(struct pipe_context *pctx,
pipe_resource_reference(&surface->base.texture, pres);
pipe_reference_init(&surface->base.reference, 1);
surface->base.context = pctx;
surface->base.format = templ->format;
surface->base.width = u_minify(pres->width0, level);
assert(surface->base.width);
surface->base.height = u_minify(pres->height0, level);
assert(surface->base.height);
surface->base.nr_samples = templ->nr_samples;
surface->base.u.tex.level = level;
surface->base.u.tex.first_layer = templ->u.tex.first_layer;
surface->base.u.tex.last_layer = templ->u.tex.last_layer;
init_pipe_surface_info(pctx, &surface->base, templ, pres);
surface->obj = zink_resource(pres)->obj;
init_surface_info(surface, res, ivci);
@ -247,7 +253,7 @@ zink_get_surface(struct zink_context *ctx,
/* wrap a surface for use as a framebuffer attachment */
static struct pipe_surface *
wrap_surface(struct pipe_context *pctx, struct pipe_surface *psurf)
wrap_surface(struct pipe_context *pctx, const struct pipe_surface *psurf)
{
struct zink_ctx_surface *csurf = CALLOC_STRUCT(zink_ctx_surface);
csurf->base = *psurf;
@ -266,10 +272,26 @@ zink_create_surface(struct pipe_context *pctx,
{
struct zink_resource *res = zink_resource(pres);
bool is_array = templ->u.tex.last_layer != templ->u.tex.first_layer;
bool needs_mutable = false;
enum pipe_texture_target target_2d[] = {PIPE_TEXTURE_2D, PIPE_TEXTURE_2D_ARRAY};
if (!res->obj->dt && pres->format != templ->format)
if (!res->obj->dt && pres->format != templ->format) {
/* mutable not set by default */
needs_mutable = !(res->base.b.bind & ZINK_BIND_MUTABLE);
/*
VUID-VkImageViewCreateInfo-image-07072
If image was created with the VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT flag and
format is a non-compressed format, the levelCount and layerCount members of
subresourceRange must both be 1
*/
if (needs_mutable && util_format_is_compressed(pres->format) && templ->u.tex.first_layer != templ->u.tex.last_layer)
return NULL;
}
if (!zink_screen(pctx->screen)->threaded && needs_mutable) {
/* this is fine without tc */
needs_mutable = false;
zink_resource_object_init_mutable(zink_context(pctx), res);
}
if (!zink_get_format(zink_screen(pctx->screen), templ->format))
return NULL;
@ -285,12 +307,19 @@ zink_create_surface(struct pipe_context *pctx,
surface->is_swapchain = true;
psurf = &surface->base;
}
} else
} else if (!needs_mutable) {
psurf = zink_get_surface(zink_context(pctx), pres, templ, &ivci);
if (!psurf)
}
if (!psurf && !needs_mutable)
return NULL;
struct zink_ctx_surface *csurf = (struct zink_ctx_surface*)wrap_surface(pctx, psurf);
struct zink_ctx_surface *csurf = (struct zink_ctx_surface*)wrap_surface(pctx, needs_mutable ? templ : psurf);
csurf->needs_mutable = needs_mutable;
if (needs_mutable) {
csurf->surf = NULL;
pipe_resource_reference(&csurf->base.texture, pres);
init_pipe_surface_info(pctx, &csurf->base, templ, pres);
}
/* TODO: use VK_EXT_multisampled_render_to_single_sampled and skip this entirely */
if (templ->nr_samples) {
@ -352,6 +381,9 @@ zink_surface_destroy(struct pipe_context *pctx,
struct pipe_surface *psurface)
{
struct zink_ctx_surface *csurf = (struct zink_ctx_surface *)psurface;
if (csurf->needs_mutable)
/* this has an extra resource ref */
pipe_resource_reference(&csurf->base.texture, NULL);
zink_surface_reference(zink_screen(pctx->screen), &csurf->surf, NULL);
pipe_surface_release(pctx, (struct pipe_surface**)&csurf->transient);
FREE(csurf);

View file

@ -147,11 +147,6 @@ enum zink_descriptor_type {
ZINK_DESCRIPTOR_NON_BINDLESS_TYPES = ZINK_DESCRIPTOR_BASE_TYPES + 1, /**< for struct sizing */
};
enum zink_descriptor_mode {
ZINK_DESCRIPTOR_MODE_AUTO,
ZINK_DESCRIPTOR_MODE_LAZY,
};
/* indexing for descriptor template management */
enum zink_descriptor_size_index {
ZDS_INDEX_UBO,
@ -507,7 +502,6 @@ struct zink_batch_state {
struct zink_resource *swapchain;
struct util_dynarray acquires;
struct util_dynarray acquire_flags;
struct util_dynarray unref_semaphores;
struct util_queue_fence flush_completed;
@ -689,14 +683,13 @@ struct zink_shader {
union {
struct {
struct zink_shader *generated; // a generated shader that this shader "owns"
} tes;
struct {
struct zink_shader *generated_tcs; // a generated shader that this shader "owns"; only valid in the tes stage
struct zink_shader *generated_gs; // a generated shader that this shader "owns"
bool is_generated; // if this is a driver-created shader (e.g., tcs)
} tcs;
} non_fs;
struct {
uint32_t legacy_shadow_mask; //is_new_style_shadow is false for these
nir_variable *fbfetch; //for fs output
} fs;
};
@ -763,6 +756,7 @@ struct zink_gfx_pipeline_state {
uint32_t vertex_buffers_enabled_mask;
uint32_t vertex_strides[PIPE_MAX_ATTRIBS];
struct zink_vertex_elements_hw_state *element_state;
struct zink_zs_swizzle_key *shadow;
bool sample_locations_enabled;
enum pipe_prim_type shader_rast_prim, rast_prim; /* reduced type or max for unknown */
union {
@ -810,6 +804,9 @@ struct zink_gfx_push_constant {
unsigned framebuffer_is_layered;
float default_inner_level[2];
float default_outer_level[4];
uint32_t line_stipple_pattern;
float viewport_scale[2];
float line_width;
};
/* The order of the enums MUST match the order of the zink_gfx_push_constant
@ -821,6 +818,9 @@ enum zink_gfx_push_constant_member {
ZINK_GFX_PUSHCONST_FRAMEBUFFER_IS_LAYERED,
ZINK_GFX_PUSHCONST_DEFAULT_INNER_LEVEL,
ZINK_GFX_PUSHCONST_DEFAULT_OUTER_LEVEL,
ZINK_GFX_PUSHCONST_LINE_STIPPLE_PATTERN,
ZINK_GFX_PUSHCONST_VIEWPORT_SCALE,
ZINK_GFX_PUSHCONST_LINE_WIDTH,
ZINK_GFX_PUSHCONST_MAX
};
@ -833,9 +833,10 @@ struct zink_shader_module {
uint32_t hash;
bool default_variant;
bool has_nonseamless;
bool needs_zs_shader_swizzle;
uint8_t num_uniforms;
uint8_t key_size;
uint8_t key[0]; /* | key | uniforms | */
uint8_t key[0]; /* | key | uniforms | zs shader swizzle | */
};
struct zink_program {
@ -860,6 +861,7 @@ struct zink_program {
};
#define STAGE_MASK_OPTIMAL (1<<16)
#define STAGE_MASK_OPTIMAL_SHADOW (1<<17)
typedef bool (*equals_gfx_pipeline_state_func)(const void *a, const void *b);
struct zink_gfx_library_key {
@ -1185,6 +1187,9 @@ struct zink_screen {
struct util_queue flush_queue;
struct zink_context *copy_context;
simple_mtx_t semaphores_lock;
struct util_dynarray semaphores;
unsigned buffer_rebind_counter;
unsigned image_rebind_counter;
unsigned robust_ctx_count;
@ -1278,12 +1283,16 @@ struct zink_screen {
struct {
bool broken_l4a4;
bool depth_clip_control_missing;
bool implicit_sync;
bool always_feedback_loop;
bool always_feedback_loop_zs;
bool needs_sanitised_layer;
bool track_renderpasses;
bool no_linestipple;
bool no_linesmooth;
bool no_hw_gl_point;
bool lower_robustImageAccess2;
bool needs_zs_shader_swizzle;
unsigned z16_unscaled_bias;
unsigned z24_unscaled_bias;
} driver_workarounds;
@ -1339,6 +1348,7 @@ struct zink_ctx_surface {
/* TODO: use VK_EXT_multisampled_render_to_single_sampled */
struct zink_ctx_surface *transient; //for use with EXT_multisample_render_to_texture
bool transient_init; //whether the transient surface has data
bool needs_mutable;
};
/* use this cast for framebuffer surfaces */
@ -1409,6 +1419,8 @@ struct zink_sampler_view {
struct zink_buffer_view *buffer_view;
};
struct zink_surface *cube_array;
struct zink_surface *zs_view;
struct zink_zs_swizzle swizzle;
};
struct zink_image_view {
@ -1645,6 +1657,9 @@ struct zink_context {
VkDescriptorImageInfo fbfetch;
/* the current state of the zs swizzle data */
struct zink_zs_swizzle_key zs_swizzle[MESA_SHADER_STAGES];
struct zink_resource *descriptor_res[ZINK_DESCRIPTOR_BASE_TYPES][MESA_SHADER_STAGES][PIPE_MAX_SAMPLERS];
struct {

View file

@ -2344,7 +2344,7 @@ dri_swrast_kms_init_screen(__DRIscreen * sPriv)
if (!configs)
goto destroy_screen;
screen->can_share_buffer = false;
screen->can_share_buffer = true;
screen->auto_fake_front = dri_with_format(sPriv);
screen->lookup_egl_image = dri2_lookup_egl_image;
@ -2399,8 +2399,12 @@ dri2_create_buffer(__DRIscreen * sPriv,
const struct __DriverAPIRec galliumdrm_driver_api = {
.InitScreen = dri2_init_screen,
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
.DestroyContext = dri_destroy_context,
.CreateBuffer = dri2_create_buffer,
.DestroyBuffer = dri_destroy_buffer,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
.AllocateBuffer = dri2_allocate_buffer,
.ReleaseBuffer = dri2_release_buffer,
@ -2421,8 +2425,12 @@ static const struct __DRIDriverVtableExtensionRec galliumdrm_vtable = {
const struct __DriverAPIRec dri_swrast_kms_driver_api = {
.InitScreen = dri_swrast_kms_init_screen,
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
.DestroyContext = dri_destroy_context,
.CreateBuffer = dri2_create_buffer,
.DestroyBuffer = dri_destroy_buffer,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
.AllocateBuffer = dri2_allocate_buffer,
.ReleaseBuffer = dri2_release_buffer,

View file

@ -23,7 +23,7 @@
* \returns
* Zero if a recognized value of \c param is supplied, -1 otherwise.
*/
static int
int
driQueryRendererIntegerCommon(__DRIscreen *psp, int param, unsigned int *value)
{
switch (param) {

View file

@ -3,6 +3,9 @@
#include "dri_util.h"
int
driQueryRendererIntegerCommon(__DRIscreen *psp, int param, unsigned int *value);
extern const
__DRI2rendererQueryExtension dri2RendererQueryExtension;

View file

@ -137,19 +137,35 @@ dri_loader_get_cap(struct dri_screen *screen, enum dri_loader_cap cap)
* This forces 32-bit color to have 24-bit depth, and
* 16-bit color to have 16-bit depth.
*
* \param yuv_depth_range YUV pixel depth range. For non-YUV pixel formats this
* should be \c __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE.
* Otherwise valid values are
* \c __DRI_ATTRIB_YUV_DEPTH_RANGE_LIMITED_BIT and
* \c __DRI_ATTRIB_YUV_DEPTH_RANGE_FULL_BIT. See the
* EGL_EXT_yuv_surface extension spec for more details.
* \param yuv_csc_standard YUV color conversion standard. For non-YUV pixel
* formats this should be
* \c __DRI_ATTRIB_YUV_CSC_STANDARD_NONE. Otherwise
* valid values are
* \c __DRI_ATTRIB_YUV_CSC_STANDARD_601_BIT,
* \c __DRI_ATTRIB_YUV_CSC_STANDARD_709_BIT and
* \c __DRI_ATTRIB_YUV_CSC_STANDARD_2020_BIT. See the
* EGL_EXT_yuv_surface extension spec for more details.
*
* \returns
* Pointer to any array of pointers to the \c __DRIconfig structures created
* for the specified formats. If there is an error, \c NULL is returned.
* Currently the only cause of failure is a bad parameter (i.e., unsupported
* \c format).
*/
static __DRIconfig **
__DRIconfig **
driCreateConfigs(mesa_format format,
const uint8_t * depth_bits, const uint8_t * stencil_bits,
unsigned num_depth_stencil_bits,
const GLenum * db_modes, unsigned num_db_modes,
const uint8_t * msaa_samples, unsigned num_msaa_modes,
GLboolean enable_accum, GLboolean color_depth_match)
GLboolean enable_accum, GLboolean color_depth_match,
GLint yuv_depth_range, GLint yuv_csc_standard)
{
static const struct {
uint32_t masks[4];
@ -188,6 +204,9 @@ driCreateConfigs(mesa_format format,
/* MESA_FORMAT_RGBA_FLOAT16 */
{{ 0, 0, 0, 0},
{ 0, 16, 32, 48 }},
/* Mesa YUV formats */
{{ 0, 0, 0, 0 },
{ -1, -1, -1, -1}},
};
const uint32_t * masks;
@ -201,6 +220,11 @@ driCreateConfigs(mesa_format format,
int green_bits;
int blue_bits;
int alpha_bits;
int yuv_order = __DRI_ATTRIB_YUV_ORDER_NONE;
int yuv_num_planes = 0;
int yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_NONE;
int yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_NONE;
bool is_yuv = false;
bool is_srgb;
bool is_float;
@ -253,6 +277,78 @@ driCreateConfigs(mesa_format format,
masks = format_table[8].masks;
shifts = format_table[8].shifts;
break;
case MESA_FORMAT_YCBCR:
masks = format_table[11].masks;
shifts = format_table[11].shifts;
is_yuv = true; /* FIXME: This should come from formats_info.py */
yuv_order = __DRI_ATTRIB_YUV_ORDER_YUYV_BIT;
yuv_num_planes = 1;
yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT;
yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
break;
case MESA_FORMAT_YUV420_2PLANE:
masks = format_table[11].masks;
shifts = format_table[11].shifts;
is_yuv = true; /* FIXME: This should come from formats_info.py */
yuv_order = __DRI_ATTRIB_YUV_ORDER_YUV_BIT;
yuv_num_planes = 2;
yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT;
yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
break;
case MESA_FORMAT_YVU420_2PLANE:
masks = format_table[11].masks;
shifts = format_table[11].shifts;
is_yuv = true; /* FIXME: This should come from formats_info.py */
yuv_order = __DRI_ATTRIB_YUV_ORDER_YVU_BIT;
yuv_num_planes = 2;
yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT;
yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
break;
case MESA_FORMAT_YUV420_3PLANE:
masks = format_table[11].masks;
shifts = format_table[11].shifts;
is_yuv = true; /* FIXME: This should come from formats_info.py */
yuv_order = __DRI_ATTRIB_YUV_ORDER_YUV_BIT;
yuv_num_planes = 3;
yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT;
yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
break;
case MESA_FORMAT_YVU420_3PLANE:
masks = format_table[11].masks;
shifts = format_table[11].shifts;
is_yuv = true; /* FIXME: This should come from formats_info.py */
yuv_order = __DRI_ATTRIB_YUV_ORDER_YVU_BIT;
yuv_num_planes = 3;
yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT;
yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
break;
case MESA_FORMAT_YCBCR_REV:
masks = format_table[11].masks;
shifts = format_table[11].shifts;
is_yuv = true; /* FIXME: This should come from formats_info.py */
yuv_order = __DRI_ATTRIB_YUV_ORDER_UYVY_BIT;
yuv_num_planes = 1;
yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT;
yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
break;
case MESA_FORMAT_VYUY:
masks = format_table[11].masks;
shifts = format_table[11].shifts;
is_yuv = true; /* FIXME: This should come from formats_info.py */
yuv_order = __DRI_ATTRIB_YUV_ORDER_VYUY_BIT;
yuv_num_planes = 1;
yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT;
yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
break;
case MESA_FORMAT_YVYU:
masks = format_table[11].masks;
shifts = format_table[11].shifts;
is_yuv = true; /* FIXME: This should come from formats_info.py */
yuv_order = __DRI_ATTRIB_YUV_ORDER_YVYU_BIT;
yuv_num_planes = 1;
yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT;
yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
break;
default:
fprintf(stderr, "[%s:%u] Unknown framebuffer type %s (%d).\n",
__func__, __LINE__,
@ -308,7 +404,11 @@ driCreateConfigs(mesa_format format,
modes->greenShift = shifts[1];
modes->blueShift = shifts[2];
modes->alphaShift = shifts[3];
modes->rgbBits = modes->redBits + modes->greenBits
if (is_yuv)
modes->rgbBits = 8;
else
modes->rgbBits = modes->redBits + modes->greenBits
+ modes->blueBits + modes->alphaBits;
modes->accumRedBits = 16 * j;
@ -319,6 +419,8 @@ driCreateConfigs(mesa_format format,
modes->stencilBits = stencil_bits[k];
modes->depthBits = depth_bits[k];
modes->rgbMode = !is_yuv;
if (db_modes[i] == __DRI_ATTRIB_SWAP_NONE) {
modes->doubleBufferMode = GL_FALSE;
modes->swapMethod = __DRI_ATTRIB_SWAP_UNDEFINED;
@ -331,6 +433,13 @@ driCreateConfigs(mesa_format format,
modes->samples = msaa_samples[h];
modes->sRGBCapable = is_srgb;
modes->YUVOrder = yuv_order;
modes->YUVNumberOfPlanes = yuv_num_planes;
modes->YUVSubsample = yuv_subsample;
modes->YUVDepthRange = yuv_depth_range;
modes->YUVCSCStandard = yuv_csc_standard;
modes->YUVPlaneBPP = yuv_plane_bpp;
}
}
}
@ -340,7 +449,7 @@ driCreateConfigs(mesa_format format,
return configs;
}
static __DRIconfig **
__DRIconfig **
driConcatConfigs(__DRIconfig **a, __DRIconfig **b)
{
__DRIconfig **all;
@ -556,7 +665,9 @@ dri_fill_in_modes(struct dri_screen *screen)
depth_buffer_factor, back_buffer_modes,
ARRAY_SIZE(back_buffer_modes),
msaa_modes, 1,
GL_TRUE, !mixed_color_depth);
GL_TRUE, !mixed_color_depth,
__DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
__DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
configs = driConcatConfigs(configs, new_configs);
/* Multi-sample configs without an accumulation buffer. */
@ -566,7 +677,9 @@ dri_fill_in_modes(struct dri_screen *screen)
depth_buffer_factor, back_buffer_modes,
ARRAY_SIZE(back_buffer_modes),
msaa_modes+1, num_msaa_modes-1,
GL_FALSE, !mixed_color_depth);
GL_FALSE, !mixed_color_depth,
__DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
__DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
configs = driConcatConfigs(configs, new_configs);
}
}

View file

@ -169,6 +169,18 @@ dri_destroy_screen_helper(struct dri_screen * screen);
void
dri_destroy_screen(__DRIscreen * sPriv);
__DRIconfig **
driCreateConfigs(mesa_format format,
const uint8_t * depth_bits, const uint8_t * stencil_bits,
unsigned num_depth_stencil_bits,
const GLenum * db_modes, unsigned num_db_modes,
const uint8_t * msaa_samples, unsigned num_msaa_modes,
GLboolean enable_accum, GLboolean color_depth_match,
GLint yuv_depth_range, GLint yuv_csc_standard);
__DRIconfig **
driConcatConfigs(__DRIconfig **a, __DRIconfig **b);
extern const struct __DriverAPIRec dri_swrast_kms_driver_api;
extern const __DRIextension *dri_swrast_kms_driver_extensions[];
extern const struct __DriverAPIRec galliumdrm_driver_api;
@ -179,6 +191,8 @@ extern const struct __DriverAPIRec galliumvk_driver_api;
extern const __DRIextension *galliumvk_driver_extensions[];
extern const __DRIconfigOptionsExtension gallium_config_options;
extern const struct __DriverAPIRec pvr_driver_api;
extern const __DRIextension *pvr_driver_extensions[];
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */

View file

@ -41,7 +41,6 @@
#include <stdbool.h>
#include "dri_util.h"
#include "dri_context.h"
#include "dri_screen.h"
#include "util/u_endian.h"
#include "util/driconf.h"
@ -49,6 +48,7 @@
#include "main/version.h"
#include "main/debug_output.h"
#include "main/errors.h"
#include "util/bitscan.h"
driOptionDescription __dri2ConfigOptions[] = {
DRI_CONF_SECTION_DEBUG
@ -196,6 +196,18 @@ swkmsCreateNewScreen(int scrn, int fd,
driver_configs, data);
}
#if defined(GALLIUM_PVR)
static __DRIscreen *
pvrCreateNewScreen(int scrn, int fd,
const __DRIextension **extensions,
const __DRIconfig ***driver_configs, void *data)
{
return driCreateNewScreen2(scrn, fd, extensions,
pvr_driver_extensions,
driver_configs, data);
}
#endif
/** swrast driver createNewScreen entrypoint. */
static __DRIscreen *
driSWRastCreateNewScreen(int scrn, const __DRIextension **extensions,
@ -290,7 +302,11 @@ driGetConfigAttribIndex(const __DRIconfig *config,
SIMPLE_CASE(__DRI_ATTRIB_SAMPLES, samples);
case __DRI_ATTRIB_RENDER_TYPE:
/* no support for color index mode */
*value = __DRI_ATTRIB_RGBA_BIT;
if (config->modes.rgbMode)
*value = __DRI_ATTRIB_RGBA_BIT;
else
*value = __DRI_ATTRIB_YUV_BIT;
if (config->modes.floatMode)
*value |= __DRI_ATTRIB_FLOAT_BIT;
break;
@ -322,9 +338,9 @@ driGetConfigAttribIndex(const __DRIconfig *config,
SIMPLE_CASE(__DRI_ATTRIB_GREEN_MASK, greenMask);
SIMPLE_CASE(__DRI_ATTRIB_BLUE_MASK, blueMask);
SIMPLE_CASE(__DRI_ATTRIB_ALPHA_MASK, alphaMask);
case __DRI_ATTRIB_MAX_PBUFFER_WIDTH:
case __DRI_ATTRIB_MAX_PBUFFER_HEIGHT:
case __DRI_ATTRIB_MAX_PBUFFER_PIXELS:
SIMPLE_CASE(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth);
SIMPLE_CASE(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight);
SIMPLE_CASE(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels);
case __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH:
case __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT:
case __DRI_ATTRIB_VISUAL_SELECT_GROUP:
@ -358,6 +374,12 @@ driGetConfigAttribIndex(const __DRIconfig *config,
SIMPLE_CASE(__DRI_ATTRIB_GREEN_SHIFT, greenShift);
SIMPLE_CASE(__DRI_ATTRIB_BLUE_SHIFT, blueShift);
SIMPLE_CASE(__DRI_ATTRIB_ALPHA_SHIFT, alphaShift);
SIMPLE_CASE(__DRI_ATTRIB_YUV_ORDER, YUVOrder);
SIMPLE_CASE(__DRI_ATTRIB_YUV_NUMBER_OF_PLANES, YUVNumberOfPlanes);
SIMPLE_CASE(__DRI_ATTRIB_YUV_SUBSAMPLE, YUVSubsample);
SIMPLE_CASE(__DRI_ATTRIB_YUV_DEPTH_RANGE, YUVDepthRange);
SIMPLE_CASE(__DRI_ATTRIB_YUV_CSC_STANDARD, YUVCSCStandard);
SIMPLE_CASE(__DRI_ATTRIB_YUV_PLANE_BPP, YUVPlaneBPP);
default:
/* XXX log an error or smth */
return GL_FALSE;
@ -478,7 +500,11 @@ driCreateContextAttribs(__DRIscreen *screen, int api,
mesa_api = API_OPENGLES;
break;
case __DRI_API_GLES2:
ctx_config.major_version = 2;
mesa_api = API_OPENGLES2;
break;
case __DRI_API_GLES3:
ctx_config.major_version = 3;
mesa_api = API_OPENGLES2;
break;
case __DRI_API_OPENGL_CORE:
@ -639,8 +665,8 @@ driCreateContextAttribs(__DRIscreen *screen, int api,
context->driDrawablePriv = NULL;
context->driReadablePriv = NULL;
if (!dri_create_context(mesa_api, modes, context, &ctx_config, error,
shareCtx)) {
if (!screen->driver->CreateContext(mesa_api, modes, context,
&ctx_config, error, shareCtx)) {
free(context);
return NULL;
}
@ -664,7 +690,14 @@ static __DRIcontext *
driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
__DRIcontext *shared, void *data)
{
return driCreateNewContextForAPI(screen, __DRI_API_OPENGL,
int apifs;
apifs = ffs(screen->api_mask);
if (!apifs)
return NULL;
return driCreateNewContextForAPI(screen, apifs - 1,
config, shared, data);
}
@ -679,7 +712,7 @@ static void
driDestroyContext(__DRIcontext *pcp)
{
if (pcp) {
dri_destroy_context(pcp);
pcp->driScreenPriv->driver->DestroyContext(pcp);
free(pcp);
}
}
@ -732,7 +765,7 @@ static int driBindContext(__DRIcontext *pcp,
dri_get_drawable(prp);
}
return dri_make_current(pcp, pdp, prp);
return pcp->driScreenPriv->driver->MakeCurrent(pcp, pdp, prp);
}
/**
@ -765,10 +798,10 @@ static int driUnbindContext(__DRIcontext *pcp)
return GL_FALSE;
/*
** Call dri_unbind_context before checking for valid drawables
** Call UnbindContext before checking for valid drawables
** to handle surfaceless contexts properly.
*/
dri_unbind_context(pcp);
pcp->driScreenPriv->driver->UnbindContext(pcp);
pdp = pcp->driDrawablePriv;
prp = pcp->driReadablePriv;
@ -1002,6 +1035,21 @@ const __DRIdri2Extension swkmsDRI2Extension = {
.createNewScreen2 = driCreateNewScreen2,
};
#if defined(GALLIUM_PVR)
const __DRIdri2Extension pvrDRI2Extension = {
.base = { __DRI_DRI2, 4 },
.createNewScreen = pvrCreateNewScreen,
.createNewDrawable = driCreateNewDrawable,
.createNewContext = driCreateNewContext,
.getAPIMask = driGetAPIMask,
.createNewContextForAPI = driCreateNewContextForAPI,
.allocateBuffer = dri2AllocateBuffer,
.releaseBuffer = dri2ReleaseBuffer,
.createContextAttribs = driCreateContextAttribs,
.createNewScreen2 = driCreateNewScreen2,
};
#endif
#endif
const __DRIswrastExtension driSWRastExtension = {
@ -1046,6 +1094,11 @@ static const struct {
.mesa_format = MESA_FORMAT_B5G5R5A1_UNORM,
.internal_format = GL_RGB5_A1,
},
{
.image_format = __DRI_IMAGE_FORMAT_ARGB4444,
.mesa_format = MESA_FORMAT_B4G4R4A4_UNORM,
.internal_format = GL_RGBA4,
},
{
.image_format = __DRI_IMAGE_FORMAT_XRGB8888,
.mesa_format = MESA_FORMAT_B8G8R8X8_UNORM,

View file

@ -76,6 +76,10 @@ extern const __DRIdri2Extension swkmsDRI2Extension;
extern const __DRI2configQueryExtension dri2ConfigQueryExtension;
extern const __DRI2flushControlExtension dri2FlushControlExtension;
#if defined(GALLIUM_PVR)
extern const __DRIdri2Extension pvrDRI2Extension;
#endif
/**
* Description of the attributes used to create a config.
*
@ -123,12 +127,25 @@ struct __DriverContextConfig {
*
* Each DRI driver must have one of these structures with all the pointers set
* to appropriate functions within the driver.
*
* When glXCreateContext() is called, for example, it'll call a helper function
* dri_util.c which in turn will jump through the \a CreateContext pointer in
* this structure.
*/
struct __DriverAPIRec {
const __DRIconfig **(*InitScreen) (__DRIscreen * priv);
void (*DestroyScreen)(__DRIscreen *driScrnPriv);
GLboolean (*CreateContext)(gl_api api,
const struct gl_config *glVis,
__DRIcontext *driContextPriv,
const struct __DriverContextConfig *ctx_config,
unsigned *error,
void *sharedContextPrivate);
void (*DestroyContext)(__DRIcontext *driContextPriv);
GLboolean (*CreateBuffer)(__DRIscreen *driScrnPriv,
__DRIdrawable *driDrawPriv,
const struct gl_config *glVis,
@ -138,6 +155,12 @@ struct __DriverAPIRec {
void (*SwapBuffers)(__DRIdrawable *driDrawPriv);
GLboolean (*MakeCurrent)(__DRIcontext *driContextPriv,
__DRIdrawable *driDrawPriv,
__DRIdrawable *driReadPriv);
GLboolean (*UnbindContext)(__DRIcontext *driContextPriv);
__DRIbuffer *(*AllocateBuffer) (__DRIscreen *screenPrivate,
unsigned int attachment,
unsigned int format,

View file

@ -640,9 +640,13 @@ drisw_create_buffer(__DRIscreen * sPriv,
const struct __DriverAPIRec galliumsw_driver_api = {
.InitScreen = drisw_init_screen,
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
.DestroyContext = dri_destroy_context,
.CreateBuffer = drisw_create_buffer,
.DestroyBuffer = dri_destroy_buffer,
.SwapBuffers = drisw_swap_buffers,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
.CopySubBuffer = drisw_copy_sub_buffer,
};

View file

@ -324,7 +324,7 @@ dri3_create_image_from_buffers(xcb_connection_t *c,
bp_reply->width,
bp_reply->height,
image_format_to_fourcc(format),
bp_reply->modifier,
bp_reply->modifier == DRM_FORMAT_MOD_INVALID ? DRM_FORMAT_MOD_LINEAR : bp_reply->modifier,
fds, bp_reply->nfd,
strides, offsets,
0, 0, 0, 0, /* UNDEFINED */
@ -1044,8 +1044,12 @@ const __DRIkopperExtension driKopperExtension = {
const struct __DriverAPIRec galliumvk_driver_api = {
.InitScreen = kopper_init_screen,
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
.DestroyContext = dri_destroy_context,
.CreateBuffer = kopper_create_buffer,
.DestroyBuffer = dri_destroy_buffer,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
.SwapBuffers = kopper_swap_buffers,
.CopySubBuffer = NULL,
};

View file

@ -57,6 +57,10 @@ if with_gallium_softpipe
libdri_c_args += '-DGALLIUM_SOFTPIPE'
endif
if with_gallium_pvr
libdri_c_args += '-DGALLIUM_PVR'
endif
libdri = static_library(
'dri',
files_libdri,

View file

@ -0,0 +1,638 @@
/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* vi: set ts=8 sw=8 sts=8: */
/*************************************************************************/ /*!
@File
@Title PVR DRI interface definition
@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@License MIT
The contents of this file are subject to the MIT license as set out below.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/ /**************************************************************************/
#if !defined(__PVRDRIIFCE_H__)
#define __PVRDRIIFCE_H__
#include <stdint.h>
#include <stdbool.h>
/* API type. */
typedef enum
{
PVRDRI_API_NONE = 0,
PVRDRI_API_GLES1 = 2,
PVRDRI_API_GLES2 = 3,
PVRDRI_API_CL = 4,
PVRDRI_API_GL_COMPAT = 5,
PVRDRI_API_GL_CORE = 6,
} PVRDRIAPIType;
typedef enum
{
PVRDRI_CONFIG_ATTRIB_INVALID = 0,
PVRDRI_CONFIG_ATTRIB_RENDERABLE_TYPE = 1,
PVRDRI_CONFIG_ATTRIB_RGB_MODE = 2,
PVRDRI_CONFIG_ATTRIB_DOUBLE_BUFFER_MODE = 3,
PVRDRI_CONFIG_ATTRIB_RED_BITS = 4,
PVRDRI_CONFIG_ATTRIB_GREEN_BITS = 5,
PVRDRI_CONFIG_ATTRIB_BLUE_BITS = 6,
PVRDRI_CONFIG_ATTRIB_ALPHA_BITS = 7,
PVRDRI_CONFIG_ATTRIB_RGB_BITS = 8,
PVRDRI_CONFIG_ATTRIB_DEPTH_BITS = 9,
PVRDRI_CONFIG_ATTRIB_STENCIL_BITS = 10,
PVRDRI_CONFIG_ATTRIB_SAMPLE_BUFFERS = 11,
PVRDRI_CONFIG_ATTRIB_SAMPLES = 12,
PVRDRI_CONFIG_ATTRIB_BIND_TO_TEXTURE_RGB = 13,
PVRDRI_CONFIG_ATTRIB_BIND_TO_TEXTURE_RGBA = 14,
PVRDRI_CONFIG_ATTRIB_YUV_ORDER = 15,
PVRDRI_CONFIG_ATTRIB_YUV_NUM_OF_PLANES = 16,
PVRDRI_CONFIG_ATTRIB_YUV_SUBSAMPLE = 17,
PVRDRI_CONFIG_ATTRIB_YUV_DEPTH_RANGE = 18,
PVRDRI_CONFIG_ATTRIB_YUV_CSC_STANDARD = 19,
PVRDRI_CONFIG_ATTRIB_YUV_PLANE_BPP = 20,
PVRDRI_CONFIG_ATTRIB_RED_MASK = 21,
PVRDRI_CONFIG_ATTRIB_GREEN_MASK = 22,
PVRDRI_CONFIG_ATTRIB_BLUE_MASK = 23,
PVRDRI_CONFIG_ATTRIB_ALPHA_MASK = 24,
PVRDRI_CONFIG_ATTRIB_SRGB_CAPABLE = 25
} PVRDRIConfigAttrib;
/* EGL_RENDERABLE_TYPE mask bits */
#define PVRDRI_API_BIT_GLES 0x0001
#define PVRDRI_API_BIT_GLES2 0x0004
#define PVRDRI_API_BIT_GL 0x0008
#define PVRDRI_API_BIT_GLES3 0x0040
/* Mesa config formats. These need not match their MESA_FORMAT counterparts */
#define PVRDRI_MESA_FORMAT_NONE 0
#define PVRDRI_MESA_FORMAT_B8G8R8A8_UNORM 1
#define PVRDRI_MESA_FORMAT_B8G8R8X8_UNORM 2
#define PVRDRI_MESA_FORMAT_B5G6R5_UNORM 3
#define PVRDRI_MESA_FORMAT_R8G8B8A8_UNORM 4
#define PVRDRI_MESA_FORMAT_R8G8B8X8_UNORM 5
#define PVRDRI_MESA_FORMAT_YCBCR 6
#define PVRDRI_MESA_FORMAT_YUV420_2PLANE 7
#define PVRDRI_MESA_FORMAT_YVU420_2PLANE 8
#define PVRDRI_MESA_FORMAT_B8G8R8A8_SRGB 9
#define PVRDRI_MESA_FORMAT_R8G8B8A8_SRGB 10
#define PVRDRI_MESA_FORMAT_YUV420_3PLANE 11
#define PVRDRI_MESA_FORMAT_YVU420_3PLANE 12
#define PVRDRI_MESA_FORMAT_YCBCR_REV 13
#define PVRDRI_MESA_FORMAT_YVYU 14
#define PVRDRI_MESA_FORMAT_VYUY 15
typedef struct __DRIimageRec __DRIimage;
typedef struct PVRDRIConfigRec PVRDRIConfig;
/* The PVRDRI_GL defines match their EGL_GL counterparts */
#define PVRDRI_GL_RENDERBUFFER 0x30B9
#define PVRDRI_GL_TEXTURE_2D 0x30B1
#define PVRDRI_GL_TEXTURE_3D 0x30B2
#define PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
#define PVRDRI_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
#define PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
#define PVRDRI_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
#define PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
#define PVRDRI_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
struct __DRIscreenRec;
struct __DRIcontextRec;
struct __DRIdrawableRec;
struct __DRIconfigRec;
struct DRISUPScreen;
struct DRISUPContext;
struct DRISUPDrawable;
struct DRISUPBuffer;
struct PVRDRIContextConfig
{
unsigned int uMajorVersion;
unsigned int uMinorVersion;
uint32_t uFlags;
int iResetStrategy;
unsigned int uPriority;
int iReleaseBehavior;
};
/*
* PVR DRI Support interface V2.
* This structure may change over time, as older interfaces become obsolete.
* For example, the v0 interface may be removed if superseded by newer
* interfaces.
*/
struct PVRDRISupportInterfaceV2
{
struct
{
struct DRISUPScreen *(*CreateScreen)
(struct __DRIscreenRec *psDRIScreen,
int iFD,
bool bUseInvalidate,
void *pvLoaderPrivate,
const struct __DRIconfigRec ***pppsConfigs,
int *piMaxGLES1Version,
int *piMaxGLES2Version);
void (*DestroyScreen)
(struct DRISUPScreen *psDRISUPScreen);
unsigned int (*CreateContext)
(PVRDRIAPIType eAPI,
PVRDRIConfig *psPVRDRIConfig,
struct PVRDRIContextConfig *psCtxConfig,
struct __DRIcontextRec *psDRIContext,
struct DRISUPContext *psDRISUPSharedContext,
struct DRISUPScreen *psDRISUPScreen,
struct DRISUPContext **ppsDRISUPContext);
void (*DestroyContext)
(struct DRISUPContext *psDRISUPContext);
struct DRISUPDrawable *(*CreateDrawable)
(struct __DRIdrawableRec *psDRIDrawable,
struct DRISUPScreen *psDRISUPDrawable,
void *pvLoaderPrivate,
PVRDRIConfig *psPVRDRIConfig);
void (*DestroyDrawable)
(struct DRISUPDrawable *psDRISUPDrawable);
bool (*MakeCurrent)
(struct DRISUPContext *psDRISUPContext,
struct DRISUPDrawable *psDRISUPWrite,
struct DRISUPDrawable *psDRISUPRead);
bool (*UnbindContext)
(struct DRISUPContext *psDRISUPContext);
struct DRISUPBuffer *(*AllocateBuffer)
(struct DRISUPScreen *psDRISUPScreen,
unsigned int uAttachment,
unsigned int uFormat,
int iWidth,
int iHeight,
unsigned int *puName,
unsigned int *puPitch,
unsigned int *puCPP,
unsigned int *puFlags);
void (*ReleaseBuffer)
(struct DRISUPScreen *psDRISUPScreen,
struct DRISUPBuffer *psDRISUPBuffer);
/* Functions to support the DRI TexBuffer extension */
void (*SetTexBuffer2)
(struct DRISUPContext *psDRISUPContext,
int iTarget,
int iFormat,
struct DRISUPDrawable *psDRISUPDrawable);
void (*ReleaseTexBuffer)
(struct DRISUPContext *psDRISUPContext,
int iTarget,
struct DRISUPDrawable *psDRISUPDrawable);
/* Functions to support the DRI Flush extension */
void (*Flush)
(struct DRISUPDrawable *psDRISUPDrawable);
void (*Invalidate)
(struct DRISUPDrawable *psDRISUPDrawable);
void (*FlushWithFlags)
(struct DRISUPContext *psDRISUPContext,
struct DRISUPDrawable *psDRISUPDrawable,
unsigned int uFlags,
unsigned int uThrottleReason);
/* Functions to support the DRI Image extension */
__DRIimage *(*CreateImageFromName)
(struct DRISUPScreen *psDRISUPScreen,
int iWidth,
int iHeight,
int iFourCC,
int iName,
int iPitch,
void *pvLoaderPrivate);
__DRIimage *(*CreateImageFromRenderbuffer)
(struct DRISUPContext *psDRISUPContext,
int iRenderBuffer,
void *pvLoaderPrivate);
void (*DestroyImage)
(__DRIimage *psImage);
__DRIimage *(*CreateImage)
(struct DRISUPScreen *psDRISUPScreen,
int iWidth,
int iHeight,
int iFourCC,
unsigned int uUse,
void *pvLoaderPrivate);
bool (*QueryImage)
(__DRIimage *psImage,
int iAttrib,
int *iValue);
__DRIimage *(*DupImage)
(__DRIimage *psImage,
void *pvLoaderPrivate);
bool (*ValidateImageUsage)
(__DRIimage *psImage,
unsigned int uUse);
__DRIimage *(*CreateImageFromNames)
(struct DRISUPScreen *psDRISUPScreen,
int iWidth,
int iHeight,
int iFourCC,
int *piNames,
int iNumNames,
int *piStrides,
int *piOffsets,
void *pvLoaderPrivate);
__DRIimage *(*FromPlanar)(__DRIimage *psImage,
int iPlane,
void *pvLoaderPrivate);
__DRIimage *(*CreateImageFromTexture)
(struct DRISUPContext *psDRISUPContext,
int iTarget,
unsigned int uTexture,
int iDepth,
int iLevel,
unsigned int *puError,
void *pvLoaderPrivate);
__DRIimage *(*CreateImageFromFDs)
(struct DRISUPScreen *psDRISUPcreen,
int iWidth,
int iHeight,
int iFourCC,
int *piFDs,
int iNumFDs,
int *piStrides,
int *piOffsets,
void *pvLoaderPrivate);
__DRIimage *(*CreateImageFromDMABufs)
(struct DRISUPScreen *psDRISUPScreen,
int iWidth,
int iHeight,
int iFourCC,
int *piFDs,
int iNumFDs,
int *piStrides,
int *piOffsets,
unsigned int uColorSpace,
unsigned int uSampleRange,
unsigned int uHorizSiting,
unsigned int uVertSiting,
unsigned int *puError,
void *pvLoaderPrivate);
int (*GetImageCapabilities)
(struct DRISUPScreen *psDRISUPScreen);
void (*BlitImage)
(struct DRISUPContext *psDRISUPContext,
__DRIimage *psDst,
__DRIimage *psSrc,
int iDstX0,
int iDstY0,
int iDstWidth,
int iDstHeight,
int iSrcX0, int
iSrcY0,
int iSrcWidth,
int iSrcHeight,
int iFlushFlag);
void *(*MapImage)
(struct DRISUPContext *psDRISUPContext,
__DRIimage *psImage,
int iX0,
int iY0,
int iWidth,
int iHeight,
unsigned int uFlags,
int *piStride,
void **ppvData);
void (*UnmapImage)
(struct DRISUPContext *psDRISUPContext,
__DRIimage *psImage,
void *pvData);
__DRIimage *(*CreateImageWithModifiers)
(struct DRISUPScreen *psDRISUPScreen,
int iWidth,
int iHeight,
int iFourCC,
const uint64_t *puModifiers,
const unsigned int uModifierCount,
void *pvLoaderPrivate);
__DRIimage *(*CreateImageFromDMABufs2)
(struct DRISUPScreen *psDRISUPScreen,
int iWidth,
int iHeight,
int iFourCC,
uint64_t uModifier,
int *piFDs,
int iNumFDs,
int *piStrides,
int *piOffsets,
unsigned int uColorSpace,
unsigned int uSampleRange,
unsigned int uHorizSiting,
unsigned int uVertSiting,
unsigned int *puError,
void *pvLoaderPrivate);
bool (*QueryDMABufFormats)
(struct DRISUPScreen *psDRISUPScreen,
int iMax,
int *piFormats,
int *piCount);
bool (*QueryDMABufModifiers)
(struct DRISUPScreen *psDRISUPScreen,
int iFourCC,
int iMax,
uint64_t *puModifiers,
unsigned int *piExternalOnly,
int *piCount);
bool (*QueryDMABufFormatModifierAttribs)
(struct DRISUPScreen *psDRISUPScreen,
uint32_t uFourcc,
uint64_t uModifier,
int iAttrib,
uint64_t *puValue);
__DRIimage *(*CreateImageFromRenderBuffer2)
(struct DRISUPContext *psDRISUPContext,
int iRenderBuffer,
void *pvLoaderPrivate,
unsigned int *puError);
__DRIimage *(*CreateImageFromBuffer)
(struct DRISUPContext *psDRISUPContext,
int iTarget,
void *pvBuffer,
unsigned int *puError,
void *pvLoaderPrivate);
/* Functions to support the DRI Renderer Query extension */
int (*QueryRendererInteger)
(struct DRISUPScreen *psDRISUPScreen,
int iAttribute,
unsigned int *puValue);
int (*QueryRendererString)
(struct DRISUPScreen *psDRISUPScreen,
int iAttribute,
const char **ppszValue);
/* Functions to support the DRI Fence extension */
void *(*CreateFence)
(struct DRISUPContext *psDRISUPContext);
void (*DestroyFence)
(struct DRISUPScreen *psDRISUPScreen,
void *pvFence);
bool (*ClientWaitSync)
(struct DRISUPContext *psDRISUPContext,
void *pvFence,
unsigned int uFlags,
uint64_t uTimeout);
void (*ServerWaitSync)
(struct DRISUPContext *psDRISUPContext,
void *pvFence,
unsigned int uFlags);
unsigned int (*GetFenceCapabilities)
(struct DRISUPScreen *psDRISUPScreen);
void *(*CreateFenceFD)
(struct DRISUPContext *psDRISUPContext,
int iFD);
int (*GetFenceFD)
(struct DRISUPScreen *psDRISUPScreen,
void *pvFence);
unsigned int (*GetNumAPIProcs)
(struct DRISUPScreen *psDRISUPScreen,
PVRDRIAPIType eAPI);
const char *(*GetAPIProcName)
(struct DRISUPScreen *psDRISUPScreen,
PVRDRIAPIType eAPI,
unsigned int uIndex);
void *(*GetAPIProcAddress)
(struct DRISUPScreen *psDRISUPScreen,
PVRDRIAPIType eAPI,
unsigned int uIndex);
void (*SetDamageRegion)
(struct DRISUPDrawable *psDRISUPDrawable,
unsigned int uNRects,
int *piRects);
} v0;
/* The v1 interface is an extension of v0, so v0 is required as well */
struct {
void *(*GetFenceFromCLEvent)
(struct DRISUPScreen *psDRISUPScreen,
intptr_t iCLEvent);
} v1;
/* The v2 interface is an extension of v1, so v1 is required as well */
struct {
int (*GetAPIVersion)
(struct DRISUPScreen *psDRISUPScreen,
PVRDRIAPIType eAPI);
} v2;
/*
* The v3 interface has no additional entry points. It indicates that
* OpenCL event based fences are available, provided the DDK is built
* with OpenCL support.
*/
/* The v4 interface is an extension of v3, so v3 is required as well */
struct {
bool (*HaveGetFenceFromCLEvent)(void);
} v4;
/* The v5 interface is an extension of v4, so v4 is required as well */
struct {
__DRIimage *(*CreateImageFromDMABufs3)
(struct DRISUPScreen *psDRISUPScreen,
int iWidth,
int iHeight,
int iFourCC,
uint64_t uModifier,
int *piFDs,
int iNumFDs,
int *piStrides,
int *piOffsets,
unsigned int uColorSpace,
unsigned int uSampleRange,
unsigned int uHorizSiting,
unsigned int uVertSiting,
uint32_t uFlags,
unsigned int *puError,
void *pvLoaderPrivate);
__DRIimage *(*CreateImageWithModifiers2)
(struct DRISUPScreen *psDRISUPScreen,
int iWidth,
int iHeight,
int iFourCC,
const uint64_t *puModifiers,
const unsigned int uModifierCount,
unsigned int uUsage,
void *pvLoaderPrivate);
__DRIimage *(*CreateImageFromFDs2)
(struct DRISUPScreen *psDRISUPcreen,
int iWidth,
int iHeight,
int iFourCC,
int *piFDs,
int iNumFDs,
uint32_t uFlags,
int *piStrides,
int *piOffsets,
void *pvLoaderPrivate);
void (*SetInFenceFD)
(__DRIimage *psImage,
int iFD);
} v5;
};
struct PVRDRIImageList {
uint32_t uImageMask;
__DRIimage *psBack;
__DRIimage *psFront;
__DRIimage *psPrev;
};
/*
* PVR DRI Support callback interface V2.
* This structure may change over time, as older interfaces become obsolete.
* For example, the v0 interface may be removed if superseded by newer
* interfaces.
*/
struct PVRDRICallbacksV2
{
struct {
bool (*RegisterSupportInterface)
(const void *psInterface,
unsigned int uVersion,
unsigned int uMinVersion);
int (*GetBuffers)
(struct __DRIdrawableRec *psDRIDrawable,
unsigned int uFourCC,
uint32_t *puStamp,
void *pvLoaderPrivate,
uint32_t uBufferMask,
struct PVRDRIImageList *psImageList);
bool (*CreateConfigs)
(struct __DRIconfigRec ***pppsConfigs,
struct __DRIscreenRec *psDRIScreen,
int iPVRDRIMesaFormat,
const uint8_t *puDepthBits,
const uint8_t *puStencilBits,
unsigned int uNumDepthStencilBits,
const unsigned int *puDBModes,
unsigned int uNumDBModes,
const uint8_t *puMSAASamples,
unsigned int uNumMSAAModes,
bool bEnableAccum,
bool bColorDepthMatch,
bool bMutableRenderBuffer,
int iYUVDepthRange,
int iYUVCSCStandard,
uint32_t uMaxPbufferWidth,
uint32_t uMaxPbufferHeight);
struct __DRIconfigRec **(*ConcatConfigs)
(struct __DRIscreenRec *psDRIScreen,
struct __DRIconfigRec **ppsConfigA,
struct __DRIconfigRec **ppsConfigB);
bool (*ConfigQuery)
(const PVRDRIConfig *psConfig,
PVRDRIConfigAttrib eConfigAttrib,
unsigned int *puValueOut);
__DRIimage *(*LookupEGLImage)
(struct __DRIscreenRec *psDRIScreen,
void *pvImage,
void *pvLoaderPrivate);
unsigned int (*GetCapability)
(struct __DRIscreenRec *psDRIScreen,
unsigned int uCapability);
} v0;
/* The v1 interface is an extension of v0, so v0 is required as well */
struct {
void (*FlushFrontBuffer)
(struct __DRIdrawableRec *psDRIDrawable,
void *pvLoaderPrivate);
} v1;
/* The v2 interface is an extension of v1, so v1 is required as well */
struct {
int (*GetDisplayFD)
(struct __DRIscreenRec *psDRIScreen,
void *pvLoaderPrivate);
} v2;
/* The v3 interface is an extension of v2, so v2 is required as well */
struct {
void *(*DrawableGetReferenceHandle)
(struct __DRIdrawableRec *psDRIDrawable);
void (*DrawableAddReference)
(void *pvReferenceHandle);
void (*DrawableRemoveReference)
(void *pvReferenceHandle);
} v3;
/* The v4 interface is an extension of v3, so v3 is required as well */
struct {
void (*DestroyLoaderImageState)
(const struct __DRIscreenRec *psDRIScreen,
void *pvLoaderPrivate);
} v4;
};
#endif /* defined(__PVRDRIIFCE_H__) */

View file

@ -0,0 +1,113 @@
/*************************************************************************/ /*!
@File
@Title Wrapper around drm_fourcc.h
@Description FourCCs and DRM framebuffer modifiers that are not in the
Kernel's and libdrm's drm_fourcc.h can be added here.
@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@License MIT
The contents of this file are subject to the MIT license as set out below.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/ /**************************************************************************/
#ifndef IMG_DRM_FOURCC_H
#define IMG_DRM_FOURCC_H
#if defined(__KERNEL__)
#include <drm/drm_fourcc.h>
#else
/*
* Include types.h to workaround versions of libdrm older than 2.4.68
* not including the correct headers.
*/
#include <linux/types.h>
#include <drm_fourcc.h>
#endif
/*
* Don't get too inspired by this example :)
* ADF doesn't support DRM modifiers, so the memory layout had to be
* included in the fourcc name, but the proper way to specify information
* additional to pixel formats is to use DRM modifiers.
*
* See upstream drm_fourcc.h for the proper naming convention.
*/
#ifndef DRM_FORMAT_BGRA8888_DIRECT_16x4
#define DRM_FORMAT_BGRA8888_DIRECT_16x4 fourcc_code('I', 'M', 'G', '0')
#endif
/*
* Upstream doesn't have a floating point format yet, so let's make one
* up.
* Note: The kernel's core DRM needs to know about this format,
* otherwise it won't be supported and should not be exposed by our
* kernel modules either.
* Refer to the provided kernel patch adding this format.
*/
#if !defined(__KERNEL__)
#define DRM_FORMAT_ABGR16_IMG fourcc_code('I', 'M', 'G', '1')
#endif
/*
* Upstream does not have a packed 10 Bits Per Channel YVU format yet,
* so let`s make one up.
* Note: at the moment this format is not intended to be used with
* a framebuffer, so the kernels core DRM doesn`t need to know
* about this format. This means that the kernel doesn`t need
* to be patched.
*/
#if !defined(__KERNEL__)
#define DRM_FORMAT_YVU444_PACK10_IMG fourcc_code('I', 'M', 'G', '2')
#define DRM_FORMAT_YUV422_2PLANE_PACK10_IMG fourcc_code('I', 'M', 'G', '3')
#define DRM_FORMAT_YUV420_2PLANE_PACK10_IMG fourcc_code('I', 'M', 'G', '4')
#endif
/*
* Value chosen in the middle of 255 pool to minimise the chance of hitting
* the same value potentially defined by other vendors in the drm_fourcc.h
*/
#define DRM_FORMAT_MOD_VENDOR_PVR 0x92
#ifndef DRM_FORMAT_MOD_VENDOR_NONE
#define DRM_FORMAT_MOD_VENDOR_NONE 0
#endif
#ifndef DRM_FORMAT_RESERVED
#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1)
#endif
#ifndef fourcc_mod_code
#define fourcc_mod_code(vendor, val) \
((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL))
#endif
#ifndef DRM_FORMAT_MOD_INVALID
#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED)
#endif
#ifndef DRM_FORMAT_MOD_LINEAR
#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0)
#endif
#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V7 fourcc_mod_code(PVR, 6)
#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V7 fourcc_mod_code(PVR, 12)
#endif /* IMG_DRM_FOURCC_H */

View file

@ -0,0 +1,307 @@
/*************************************************************************/ /*!
@File imgpixfmts.h
@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@License MIT
The contents of this file are subject to the MIT license as set out below.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/ /**************************************************************************/
/******************************************************************************
**
** WARNING: File is autogenerated by parsesystable.py - DO NOT EDIT.
** Use fmts_systable.txt to add new formats.
**
*****************************************************************************/
#if !defined(IMGPIXFMTS_H)
#define IMGPIXFMTS_H
typedef enum _IMG_PIXFMT_
{
IMG_PIXFMT_UNKNOWN = 0,
IMG_PIXFMT_RESERVED_1 = 1,
IMG_PIXFMT_RESERVED_2 = 2,
IMG_PIXFMT_RESERVED_3 = 3,
IMG_PIXFMT_RESERVED_4 = 4,
IMG_PIXFMT_RESERVED_5 = 5,
IMG_PIXFMT_RESERVED_6 = 6,
IMG_PIXFMT_RESERVED_7 = 7,
IMG_PIXFMT_RESERVED_8 = 8,
IMG_PIXFMT_RESERVED_9 = 9,
IMG_PIXFMT_RESERVED_10 = 10,
IMG_PIXFMT_RESERVED_11 = 11,
IMG_PIXFMT_RESERVED_12 = 12,
IMG_PIXFMT_RESERVED_13 = 13,
IMG_PIXFMT_RESERVED_14 = 14,
IMG_PIXFMT_RESERVED_15 = 15,
IMG_PIXFMT_RESERVED_16 = 16,
IMG_PIXFMT_RESERVED_17 = 17,
IMG_PIXFMT_RESERVED_18 = 18,
IMG_PIXFMT_RESERVED_19 = 19,
IMG_PIXFMT_RESERVED_20 = 20,
IMG_PIXFMT_RESERVED_21 = 21,
IMG_PIXFMT_RESERVED_22 = 22,
IMG_PIXFMT_RESERVED_23 = 23,
IMG_PIXFMT_RESERVED_24 = 24,
IMG_PIXFMT_R10G10B10A2_UNORM = 25,
IMG_PIXFMT_RESERVED_26 = 26,
IMG_PIXFMT_RESERVED_27 = 27,
IMG_PIXFMT_B10G10R10A2_UNORM = 28,
IMG_PIXFMT_RESERVED_29 = 29,
IMG_PIXFMT_RESERVED_30 = 30,
IMG_PIXFMT_RESERVED_31 = 31,
IMG_PIXFMT_R8G8B8A8_UNORM = 32,
IMG_PIXFMT_R8G8B8A8_UNORM_SRGB = 33,
IMG_PIXFMT_RESERVED_34 = 34,
IMG_PIXFMT_RESERVED_35 = 35,
IMG_PIXFMT_RESERVED_36 = 36,
IMG_PIXFMT_R8G8B8X8_UNORM = 37,
IMG_PIXFMT_RESERVED_38 = 38,
IMG_PIXFMT_RESERVED_39 = 39,
IMG_PIXFMT_RESERVED_40 = 40,
IMG_PIXFMT_RESERVED_41 = 41,
IMG_PIXFMT_RESERVED_42 = 42,
IMG_PIXFMT_RESERVED_43 = 43,
IMG_PIXFMT_RESERVED_44 = 44,
IMG_PIXFMT_RESERVED_45 = 45,
IMG_PIXFMT_RESERVED_46 = 46,
IMG_PIXFMT_RESERVED_47 = 47,
IMG_PIXFMT_RESERVED_48 = 48,
IMG_PIXFMT_RESERVED_49 = 49,
IMG_PIXFMT_RESERVED_50 = 50,
IMG_PIXFMT_D32_FLOAT = 51,
IMG_PIXFMT_RESERVED_52 = 52,
IMG_PIXFMT_RESERVED_53 = 53,
IMG_PIXFMT_RESERVED_54 = 54,
IMG_PIXFMT_RESERVED_55 = 55,
IMG_PIXFMT_RESERVED_56 = 56,
IMG_PIXFMT_RESERVED_57 = 57,
IMG_PIXFMT_D24_UNORM_X8_TYPELESS = 58,
IMG_PIXFMT_RESERVED_59 = 59,
IMG_PIXFMT_RESERVED_60 = 60,
IMG_PIXFMT_RESERVED_61 = 61,
IMG_PIXFMT_R8G8_UNORM = 62,
IMG_PIXFMT_RESERVED_63 = 63,
IMG_PIXFMT_RESERVED_64 = 64,
IMG_PIXFMT_RESERVED_65 = 65,
IMG_PIXFMT_RESERVED_66 = 66,
IMG_PIXFMT_RESERVED_67 = 67,
IMG_PIXFMT_RESERVED_68 = 68,
IMG_PIXFMT_D16_UNORM = 69,
IMG_PIXFMT_RESERVED_70 = 70,
IMG_PIXFMT_RESERVED_71 = 71,
IMG_PIXFMT_RESERVED_72 = 72,
IMG_PIXFMT_RESERVED_73 = 73,
IMG_PIXFMT_RESERVED_74 = 74,
IMG_PIXFMT_RESERVED_75 = 75,
IMG_PIXFMT_R8_UNORM = 76,
IMG_PIXFMT_RESERVED_77 = 77,
IMG_PIXFMT_RESERVED_78 = 78,
IMG_PIXFMT_RESERVED_79 = 79,
IMG_PIXFMT_RESERVED_80 = 80,
IMG_PIXFMT_S8_UINT = 81,
IMG_PIXFMT_RESERVED_82 = 82,
IMG_PIXFMT_RESERVED_83 = 83,
IMG_PIXFMT_RESERVED_84 = 84,
IMG_PIXFMT_B5G6R5_UNORM = 85,
IMG_PIXFMT_R5G6B5_UNORM = 86,
IMG_PIXFMT_B5G5R5A1_UNORM = 87,
IMG_PIXFMT_B5G5R5X1_UNORM = 88,
IMG_PIXFMT_B8G8R8A8_UNORM = 89,
IMG_PIXFMT_B8G8R8X8_UNORM = 90,
IMG_PIXFMT_B8G8R8A8_UINT = 91,
IMG_PIXFMT_B8G8R8A8_SNORM = 92,
IMG_PIXFMT_B8G8R8A8_SINT = 93,
IMG_PIXFMT_B8G8R8A8_UNORM_SRGB = 94,
IMG_PIXFMT_RESERVED_95 = 95,
IMG_PIXFMT_RESERVED_96 = 96,
IMG_PIXFMT_RESERVED_97 = 97,
IMG_PIXFMT_RESERVED_98 = 98,
IMG_PIXFMT_RESERVED_99 = 99,
IMG_PIXFMT_RESERVED_100 = 100,
IMG_PIXFMT_RESERVED_101 = 101,
IMG_PIXFMT_RESERVED_102 = 102,
IMG_PIXFMT_RESERVED_103 = 103,
IMG_PIXFMT_RESERVED_104 = 104,
IMG_PIXFMT_RESERVED_105 = 105,
IMG_PIXFMT_RESERVED_106 = 106,
IMG_PIXFMT_RESERVED_107 = 107,
IMG_PIXFMT_RESERVED_108 = 108,
IMG_PIXFMT_RESERVED_109 = 109,
IMG_PIXFMT_RESERVED_110 = 110,
IMG_PIXFMT_RESERVED_111 = 111,
IMG_PIXFMT_RESERVED_112 = 112,
IMG_PIXFMT_RESERVED_113 = 113,
IMG_PIXFMT_RESERVED_114 = 114,
IMG_PIXFMT_RESERVED_115 = 115,
IMG_PIXFMT_RESERVED_116 = 116,
IMG_PIXFMT_RESERVED_117 = 117,
IMG_PIXFMT_RESERVED_118 = 118,
IMG_PIXFMT_RESERVED_119 = 119,
IMG_PIXFMT_RESERVED_120 = 120,
IMG_PIXFMT_RESERVED_121 = 121,
IMG_PIXFMT_RESERVED_122 = 122,
IMG_PIXFMT_RESERVED_123 = 123,
IMG_PIXFMT_RESERVED_124 = 124,
IMG_PIXFMT_RESERVED_125 = 125,
IMG_PIXFMT_RESERVED_126 = 126,
IMG_PIXFMT_RESERVED_127 = 127,
IMG_PIXFMT_RESERVED_128 = 128,
IMG_PIXFMT_RESERVED_129 = 129,
IMG_PIXFMT_RESERVED_130 = 130,
IMG_PIXFMT_RESERVED_131 = 131,
IMG_PIXFMT_RESERVED_132 = 132,
IMG_PIXFMT_RESERVED_133 = 133,
IMG_PIXFMT_RESERVED_134 = 134,
IMG_PIXFMT_RESERVED_135 = 135,
IMG_PIXFMT_L8_UNORM = 136,
IMG_PIXFMT_RESERVED_137 = 137,
IMG_PIXFMT_L8A8_UNORM = 138,
IMG_PIXFMT_RESERVED_139 = 139,
IMG_PIXFMT_RESERVED_140 = 140,
IMG_PIXFMT_RESERVED_141 = 141,
IMG_PIXFMT_RESERVED_142 = 142,
IMG_PIXFMT_RESERVED_143 = 143,
IMG_PIXFMT_RESERVED_144 = 144,
IMG_PIXFMT_B4G4R4A4_UNORM = 145,
IMG_PIXFMT_RESERVED_146 = 146,
IMG_PIXFMT_RESERVED_147 = 147,
IMG_PIXFMT_RESERVED_148 = 148,
IMG_PIXFMT_RESERVED_149 = 149,
IMG_PIXFMT_RESERVED_150 = 150,
IMG_PIXFMT_RESERVED_151 = 151,
IMG_PIXFMT_RESERVED_152 = 152,
IMG_PIXFMT_RESERVED_153 = 153,
IMG_PIXFMT_RESERVED_154 = 154,
IMG_PIXFMT_RESERVED_155 = 155,
IMG_PIXFMT_RESERVED_156 = 156,
IMG_PIXFMT_RESERVED_157 = 157,
IMG_PIXFMT_RESERVED_158 = 158,
IMG_PIXFMT_RESERVED_159 = 159,
IMG_PIXFMT_R8G8B8_UNORM = 160,
IMG_PIXFMT_R8G8B8_UNORM_SRGB = 161,
IMG_PIXFMT_RESERVED_162 = 162,
IMG_PIXFMT_RESERVED_163 = 163,
IMG_PIXFMT_RESERVED_164 = 164,
IMG_PIXFMT_RESERVED_165 = 165,
IMG_PIXFMT_RESERVED_166 = 166,
IMG_PIXFMT_RESERVED_167 = 167,
IMG_PIXFMT_RESERVED_168 = 168,
IMG_PIXFMT_RESERVED_169 = 169,
IMG_PIXFMT_RESERVED_170 = 170,
IMG_PIXFMT_UYVY = 171,
IMG_PIXFMT_VYUY = 172,
IMG_PIXFMT_YUYV = 173,
IMG_PIXFMT_YVYU = 174,
IMG_PIXFMT_YVU420_2PLANE = 175,
IMG_PIXFMT_YUV420_2PLANE = 176,
IMG_PIXFMT_YVU420_2PLANE_MACRO_BLOCK = 177,
IMG_PIXFMT_YUV420_3PLANE = 178,
IMG_PIXFMT_YVU420_3PLANE = 179,
IMG_PIXFMT_RESERVED_180 = 180,
IMG_PIXFMT_RESERVED_181 = 181,
IMG_PIXFMT_RESERVED_182 = 182,
IMG_PIXFMT_RESERVED_183 = 183,
IMG_PIXFMT_RESERVED_184 = 184,
IMG_PIXFMT_RESERVED_185 = 185,
IMG_PIXFMT_RESERVED_186 = 186,
IMG_PIXFMT_RESERVED_187 = 187,
IMG_PIXFMT_RESERVED_188 = 188,
IMG_PIXFMT_RESERVED_189 = 189,
IMG_PIXFMT_RESERVED_190 = 190,
IMG_PIXFMT_RESERVED_191 = 191,
IMG_PIXFMT_RESERVED_192 = 192,
IMG_PIXFMT_RESERVED_193 = 193,
IMG_PIXFMT_RESERVED_194 = 194,
IMG_PIXFMT_RESERVED_195 = 195,
IMG_PIXFMT_RESERVED_196 = 196,
IMG_PIXFMT_RESERVED_197 = 197,
IMG_PIXFMT_RESERVED_198 = 198,
IMG_PIXFMT_RESERVED_199 = 199,
IMG_PIXFMT_RESERVED_200 = 200,
IMG_PIXFMT_YVU8_422_2PLANE_PACK8 = 201,
IMG_PIXFMT_RESERVED_202 = 202,
IMG_PIXFMT_YVU10_444_1PLANE_PACK10 = 203,
IMG_PIXFMT_RESERVED_204 = 204,
IMG_PIXFMT_RESERVED_205 = 205,
IMG_PIXFMT_RESERVED_206 = 206,
IMG_PIXFMT_YUV8_422_2PLANE_PACK8 = 207,
IMG_PIXFMT_YUV8_444_3PLANE_PACK8 = 208,
IMG_PIXFMT_RESERVED_209 = 209,
IMG_PIXFMT_RESERVED_210 = 210,
IMG_PIXFMT_RESERVED_211 = 211,
IMG_PIXFMT_RESERVED_212 = 212,
IMG_PIXFMT_RESERVED_213 = 213,
IMG_PIXFMT_RESERVED_214 = 214,
IMG_PIXFMT_RESERVED_215 = 215,
IMG_PIXFMT_RESERVED_216 = 216,
IMG_PIXFMT_RESERVED_217 = 217,
IMG_PIXFMT_RESERVED_218 = 218,
IMG_PIXFMT_RESERVED_219 = 219,
IMG_PIXFMT_RESERVED_220 = 220,
IMG_PIXFMT_RESERVED_221 = 221,
IMG_PIXFMT_RESERVED_222 = 222,
IMG_PIXFMT_RESERVED_223 = 223,
IMG_PIXFMT_RESERVED_224 = 224,
IMG_PIXFMT_RESERVED_225 = 225,
IMG_PIXFMT_RESERVED_226 = 226,
IMG_PIXFMT_RESERVED_227 = 227,
IMG_PIXFMT_RESERVED_228 = 228,
IMG_PIXFMT_RESERVED_229 = 229,
IMG_PIXFMT_RESERVED_230 = 230,
IMG_PIXFMT_RESERVED_231 = 231,
IMG_PIXFMT_RESERVED_232 = 232,
IMG_PIXFMT_RESERVED_233 = 233,
IMG_PIXFMT_RESERVED_234 = 234,
IMG_PIXFMT_RESERVED_235 = 235,
IMG_PIXFMT_RESERVED_236 = 236,
IMG_PIXFMT_RESERVED_237 = 237,
IMG_PIXFMT_RESERVED_238 = 238,
IMG_PIXFMT_RESERVED_239 = 239,
IMG_PIXFMT_RESERVED_240 = 240,
IMG_PIXFMT_RESERVED_241 = 241,
IMG_PIXFMT_RESERVED_242 = 242,
IMG_PIXFMT_RESERVED_243 = 243,
IMG_PIXFMT_RESERVED_244 = 244,
IMG_PIXFMT_YVU8_420_2PLANE_PACK8_P = 245,
IMG_PIXFMT_RESERVED_246 = 246,
IMG_PIXFMT_RESERVED_247 = 247,
IMG_PIXFMT_RESERVED_248 = 248,
IMG_PIXFMT_YUV8_420_2PLANE_PACK8_P = 249,
IMG_PIXFMT_RESERVED_250 = 250,
IMG_PIXFMT_RESERVED_251 = 251,
IMG_PIXFMT_UYVY10_422_1PLANE_PACK10_CUST1 = 252,
IMG_PIXFMT_RESERVED_253 = 253,
IMG_PIXFMT_RESERVED_254 = 254,
IMG_PIXFMT_RESERVED_255 = 255,
IMG_PIXFMT_RESERVED_256 = 256,
IMG_PIXFMT_RESERVED_257 = 257,
IMG_PIXFMT_RESERVED_258 = 258,
IMG_PIXFMT_RESERVED_259 = 259,
IMG_PIXFMT_RESERVED_260 = 260,
IMG_PIXFMT_RESERVED_261 = 261,
IMG_PIXFMT_RESERVED_262 = 262,
IMG_PIXFMT_RESERVED_263 = 263,
IMG_PIXFMT_RESERVED_264 = 264,
#define IMG_PIXFMT_ENUM_COUNT 265
} IMG_PIXFMT;
#endif /* IMGPIXFMTS_H */

View file

@ -0,0 +1,58 @@
/*************************************************************************/ /*!
@File
@Title YUV defines
@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@License MIT
The contents of this file are subject to the MIT license as set out below.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/ /**************************************************************************/
#if !defined(IMGYUV_H)
#define IMGYUV_H
typedef enum
{
IMG_COLORSPACE_UNDEFINED = 0,
IMG_COLORSPACE_BT601_CONFORMANT_RANGE = 1,
IMG_COLORSPACE_BT601_FULL_RANGE = 2,
IMG_COLORSPACE_BT709_CONFORMANT_RANGE = 3,
IMG_COLORSPACE_BT709_FULL_RANGE = 4,
IMG_COLORSPACE_BT2020_CONFORMANT_RANGE = 5,
IMG_COLORSPACE_BT2020_FULL_RANGE = 6,
IMG_COLORSPACE_BT601_CONFORMANT_RANGE_INVERSE = 7,
IMG_COLORSPACE_BT601_FULL_RANGE_INVERSE = 8,
IMG_COLORSPACE_BT709_CONFORMANT_RANGE_INVERSE = 9,
IMG_COLORSPACE_BT709_FULL_RANGE_INVERSE = 10,
IMG_COLORSPACE_BT2020_CONFORMANT_RANGE_INVERSE = 11,
IMG_COLORSPACE_BT2020_FULL_RANGE_INVERSE = 12
} IMG_YUV_COLORSPACE;
typedef enum
{
IMG_CHROMA_INTERP_UNDEFINED = 0,
IMG_CHROMA_INTERP_ZERO = 1,
IMG_CHROMA_INTERP_QUARTER = 2,
IMG_CHROMA_INTERP_HALF = 3,
IMG_CHROMA_INTERP_THREEQUARTERS = 4
} IMG_YUV_CHROMA_INTERP;
#endif /* IMGYUV_H */

View file

@ -0,0 +1,208 @@
/**
* \file context.c
* Mesa context/visual/framebuffer management functions.
* \author Brian Paul
*/
/*
* Mesa 3-D graphics library
* Version: 7.1
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* The contents of this file are subject to the MIT license as set out below.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdlib.h>
#include <assert.h>
#include "main/version.h"
#include "main/errors.h"
#include "dri_support.h"
#include "dri_util.h"
#include "glapi.h"
#include "dispatch.h"
#include "pvrmesa.h"
/**
* This is the default function we plug into all dispatch table slots This
* helps prevents a segfault when someone calls a GL function without first
* checking if the extension is supported.
*/
static int
generic_nop(void)
{
_mesa_warning(NULL, "User called no-op dispatch function (an unsupported extension function?)");
return 0;
}
/**
* Allocate and initialise a new dispatch table.
*/
static struct _glapi_table *
pvrdri_alloc_dispatch_table(void)
{
unsigned int numEntries = _glapi_get_dispatch_table_size();
_glapi_proc *table;
table = malloc(numEntries * sizeof(_glapi_proc));
if (table)
for (unsigned int i = 0; i < numEntries; i++)
table[i] = (_glapi_proc) generic_nop;
return (struct _glapi_table *) table;
}
/**
* Return a pointer to the pointer to the dispatch table of an API in
* PVRDRIScreen.
*/
static struct _glapi_table **
pvrdri_get_dispatch_table_ptr(PVRDRIScreen *psPVRScreen, PVRDRIAPIType eAPI)
{
switch (eAPI) {
case PVRDRI_API_GLES1:
return &psPVRScreen->psOGLES1Dispatch;
case PVRDRI_API_GLES2:
return &psPVRScreen->psOGLES2Dispatch;
case PVRDRI_API_GL_COMPAT:
case PVRDRI_API_GL_CORE:
return &psPVRScreen->psOGLDispatch;
default:
return NULL;
}
}
/**
* Return a pointer to the dispatch table of an API.
*/
static struct _glapi_table *
pvrdri_get_dispatch_table(PVRDRIScreen *psPVRScreen, PVRDRIAPIType eAPI)
{
struct _glapi_table **ppsTable =
pvrdri_get_dispatch_table_ptr(psPVRScreen, eAPI);
return ppsTable ? *ppsTable : NULL;
}
/**
* Free all dispatch tables.
*/
void
pvrdri_free_dispatch_tables(PVRDRIScreen *psPVRScreen)
{
if (psPVRScreen->psOGLES1Dispatch != NULL) {
free(psPVRScreen->psOGLES1Dispatch);
psPVRScreen->psOGLES1Dispatch = NULL;
}
if (psPVRScreen->psOGLES2Dispatch != NULL) {
free(psPVRScreen->psOGLES2Dispatch);
psPVRScreen->psOGLES2Dispatch = NULL;
}
if (psPVRScreen->psOGLDispatch != NULL) {
free(psPVRScreen->psOGLDispatch);
psPVRScreen->psOGLDispatch = NULL;
}
}
static void
pvrdri_add_mesa_dispatch(struct _glapi_table *psTable, PVRDRIAPIType eAPI,
struct DRISUPScreen *psDRISUPScreen,
unsigned int uIdx)
{
const char *asFunc[] = { NULL, NULL };
int iOffset;
const char *psFunc;
_glapi_proc pfFunc;
pfFunc = DRISUPGetAPIProcAddress(psDRISUPScreen, eAPI, uIdx);
if (pfFunc == NULL)
return;
psFunc = DRISUPGetAPIProcName(psDRISUPScreen, eAPI, uIdx);
assert(psFunc != NULL);
asFunc[0] = psFunc;
iOffset = _glapi_add_dispatch(asFunc, "");
if (iOffset == -1) {
_mesa_warning(NULL, "Couldn't add %s to the Mesa dispatch table",
psFunc);
} else {
SET_by_offset(psTable, iOffset, pfFunc);
}
}
static void
pvrdri_set_mesa_dispatch(struct _glapi_table *psTable, PVRDRIAPIType eAPI,
struct DRISUPScreen *psDRISUPScreen,
unsigned int uNumFuncs)
{
for (unsigned int i = 0; i < uNumFuncs; i++)
pvrdri_add_mesa_dispatch(psTable, eAPI, psDRISUPScreen, i);
}
bool
pvrdri_create_dispatch_table(PVRDRIScreen *psPVRScreen, PVRDRIAPIType eAPI)
{
struct DRISUPScreen *psDRISUPScreen = psPVRScreen->psDRISUPScreen;
struct _glapi_table **ppsTable;
unsigned int uNumFuncs;
ppsTable = pvrdri_get_dispatch_table_ptr(psPVRScreen, eAPI);
if (ppsTable == NULL)
return false;
if (*ppsTable != NULL)
return true;
uNumFuncs = DRISUPGetNumAPIProcs(psDRISUPScreen, eAPI);
if (!uNumFuncs)
return false;
*ppsTable = pvrdri_alloc_dispatch_table();
if (*ppsTable == NULL)
return false;
pvrdri_set_mesa_dispatch(*ppsTable, eAPI, psDRISUPScreen, uNumFuncs);
return true;
}
void
pvrdri_set_null_dispatch_table(void)
{
_glapi_set_dispatch(NULL);
}
void
pvrdri_set_dispatch_table(PVRDRIContext *psPVRContext)
{
struct _glapi_table *psTable;
psTable = pvrdri_get_dispatch_table(psPVRContext->psPVRScreen,
psPVRContext->eAPI);
_glapi_set_dispatch(psTable);
}

View file

@ -0,0 +1,46 @@
# Copyright (c) Imagination Technologies Ltd.
#
# The contents of this file are subject to the MIT license as set out below.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
files_libpvr = files(
'mesa_context.c',
'pvrcb.c',
'pvrcompat.c',
'pvrdri.c',
'pvrext.c',
'pvrutil.c',
)
libpvr_c_args = ['-DGALLIUM_PVR']
libpvr_dep = [dep_libdrm]
libpvr = static_library(
'pvr',
[files_libpvr, main_dispatch_h],
include_directories : [
inc_include, inc_util, inc_mesa, inc_mapi, inc_src, inc_gallium,
inc_gallium_aux, inc_pvr,
],
c_args : [libpvr_c_args],
gnu_symbol_visibility : 'hidden',
dependencies : [libpvr_dep],
)

View file

@ -0,0 +1,344 @@
/*
* Copyright (c) Imagination Technologies Ltd.
*
* The contents of this file are subject to the MIT license as set out below.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <assert.h>
#include "dri_screen.h"
#include "pvrdri.h"
int
MODSUPGetBuffers(__DRIdrawable *psDRIDrawable, unsigned int uFourCC,
uint32_t *puStamp, void *pvLoaderPrivate,
uint32_t uBufferMask, struct PVRDRIImageList *psImageList)
{
PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
__DRIscreen *psDRIScreen = psDRIDrawable->driScreenPriv;
struct __DRIimageList sDRIList;
int res;
#if !defined(DRI_IMAGE_HAS_BUFFER_PREV)
uBufferMask &= ~PVRDRI_IMAGE_BUFFER_PREV;
#endif
if (psPVRDrawable->uFourCC != uFourCC) {
psPVRDrawable->uDRIFormat = PVRDRIFourCCToDRIFormat(uFourCC);
psPVRDrawable->uFourCC = uFourCC;
}
res = psDRIScreen->image.loader->getBuffers(psDRIDrawable,
psPVRDrawable->uDRIFormat,
puStamp,
pvLoaderPrivate,
uBufferMask, &sDRIList);
if (res) {
psImageList->uImageMask = sDRIList.image_mask;
psImageList->psBack = sDRIList.back;
psImageList->psFront = sDRIList.front;
psImageList->psPrev = sDRIList.prev;
}
return res;
}
bool
MODSUPCreateConfigs(__DRIconfig ***pppsConfigs, __DRIscreen *psDRIScreen,
int iPVRDRIMesaFormat, const uint8_t *puDepthBits,
const uint8_t *puStencilBits,
unsigned int uNumDepthStencilBits,
const unsigned int *puDBModes, unsigned int uNumDBModes,
const uint8_t *puMSAASamples, unsigned int uNumMSAAModes,
bool bEnableAccum, bool bColorDepthMatch,
UNUSED bool bMutableRenderBuffer,
int iYUVDepthRange, int iYUVCSCStandard,
uint32_t uMaxPbufferWidth, uint32_t uMaxPbufferHeight)
{
__DRIconfig **ppsConfigs;
mesa_format eFormat = PVRDRIMesaFormatToMesaFormat(iPVRDRIMesaFormat);
unsigned int i;
(void) psDRIScreen;
switch (eFormat) {
case MESA_FORMAT_NONE:
__driUtilMessage("%s: Unknown PVR DRI format: %u",
__func__, iPVRDRIMesaFormat);
return false;
default:
break;
}
/*
* The double buffered modes array argument for driCreateConfigs has
* entries of type GLenum.
*/
static_assert(sizeof(GLenum) == sizeof(unsigned int),
"Size mismatch between GLenum and unsigned int");
ppsConfigs = driCreateConfigs(eFormat, puDepthBits, puStencilBits,
uNumDepthStencilBits, (GLenum *) puDBModes,
uNumDBModes, puMSAASamples, uNumMSAAModes,
bEnableAccum, bColorDepthMatch,
iYUVDepthRange, iYUVCSCStandard);
if (!ppsConfigs)
return false;
for (i = 0; ppsConfigs[i]; i++) {
ppsConfigs[i]->modes.maxPbufferWidth = uMaxPbufferWidth;
ppsConfigs[i]->modes.maxPbufferHeight = uMaxPbufferHeight;
ppsConfigs[i]->modes.maxPbufferPixels =
uMaxPbufferWidth * uMaxPbufferHeight;
}
*pppsConfigs = ppsConfigs;
return true;
}
__DRIconfig **
MODSUPConcatConfigs(__DRIscreen *psDRIScreen,
__DRIconfig **ppsConfigA, __DRIconfig **ppsConfigB)
{
(void) psDRIScreen;
return driConcatConfigs(ppsConfigA, ppsConfigB);
}
struct __DRIimageRec *
MODSUPLookupEGLImage(__DRIscreen *psDRIScreen, void *pvImage,
void *pvLoaderPrivate)
{
return psDRIScreen->dri2.image->lookupEGLImage(psDRIScreen,
pvImage,
pvLoaderPrivate);
}
unsigned int
MODSUPGetCapability(__DRIscreen *psDRIScreen, unsigned int uCapability)
{
if (psDRIScreen->image.loader->base.version >= 2 &&
psDRIScreen->image.loader->getCapability) {
enum dri_loader_cap eCapability =
(enum dri_loader_cap) uCapability;
return psDRIScreen->image.loader->getCapability(
psDRIScreen->loaderPrivate,
eCapability);
}
return 0;
}
int
MODSUPGetDisplayFD(__DRIscreen *psDRIScreen, void *pvLoaderPrivate)
{
#if __DRI_IMAGE_LOADER_VERSION >= 5
if (psDRIScreen->image.loader->base.version >= 5 &&
psDRIScreen->image.loader->getDisplayFD)
return psDRIScreen->image.loader->getDisplayFD(pvLoaderPrivate);
#else
(void) psDRIScreen;
(void) pvLoaderPrivate;
#endif
return -1;
}
static bool
PVRDRIConfigQueryUnsigned(const PVRDRIConfig *psConfig,
PVRDRIConfigAttrib eConfigAttrib,
unsigned int *puValueOut)
{
if (!psConfig || !puValueOut)
return false;
switch (eConfigAttrib) {
case PVRDRI_CONFIG_ATTRIB_RENDERABLE_TYPE:
*puValueOut = psConfig->iSupportedAPIs;
return true;
case PVRDRI_CONFIG_ATTRIB_RGB_MODE:
*puValueOut = psConfig->sGLMode.rgbMode;
return true;
case PVRDRI_CONFIG_ATTRIB_DOUBLE_BUFFER_MODE:
*puValueOut = psConfig->sGLMode.doubleBufferMode;
return true;
case PVRDRI_CONFIG_ATTRIB_RED_BITS:
*puValueOut = psConfig->sGLMode.redBits;
return true;
case PVRDRI_CONFIG_ATTRIB_GREEN_BITS:
*puValueOut = psConfig->sGLMode.greenBits;
return true;
case PVRDRI_CONFIG_ATTRIB_BLUE_BITS:
*puValueOut = psConfig->sGLMode.blueBits;
return true;
case PVRDRI_CONFIG_ATTRIB_ALPHA_BITS:
*puValueOut = psConfig->sGLMode.alphaBits;
return true;
case PVRDRI_CONFIG_ATTRIB_RGB_BITS:
*puValueOut = psConfig->sGLMode.rgbBits;
return true;
case PVRDRI_CONFIG_ATTRIB_DEPTH_BITS:
*puValueOut = psConfig->sGLMode.depthBits;
return true;
case PVRDRI_CONFIG_ATTRIB_STENCIL_BITS:
*puValueOut = psConfig->sGLMode.stencilBits;
return true;
case PVRDRI_CONFIG_ATTRIB_SAMPLE_BUFFERS:
*puValueOut = !!psConfig->sGLMode.samples;
return true;
case PVRDRI_CONFIG_ATTRIB_SAMPLES:
*puValueOut = psConfig->sGLMode.samples;
return true;
case PVRDRI_CONFIG_ATTRIB_BIND_TO_TEXTURE_RGB:
*puValueOut = GL_TRUE;
return true;
case PVRDRI_CONFIG_ATTRIB_BIND_TO_TEXTURE_RGBA:
*puValueOut = GL_TRUE;
return true;
#if defined(__DRI_ATTRIB_YUV_BIT)
case PVRDRI_CONFIG_ATTRIB_YUV_ORDER:
*puValueOut = psConfig->sGLMode.YUVOrder;
return true;
case PVRDRI_CONFIG_ATTRIB_YUV_NUM_OF_PLANES:
*puValueOut = psConfig->sGLMode.YUVNumberOfPlanes;
return true;
case PVRDRI_CONFIG_ATTRIB_YUV_SUBSAMPLE:
*puValueOut = psConfig->sGLMode.YUVSubsample;
return true;
case PVRDRI_CONFIG_ATTRIB_YUV_DEPTH_RANGE:
*puValueOut = psConfig->sGLMode.YUVDepthRange;
return true;
case PVRDRI_CONFIG_ATTRIB_YUV_CSC_STANDARD:
*puValueOut = psConfig->sGLMode.YUVCSCStandard;
return true;
case PVRDRI_CONFIG_ATTRIB_YUV_PLANE_BPP:
*puValueOut = psConfig->sGLMode.YUVPlaneBPP;
return true;
#endif
#if !defined(__DRI_ATTRIB_YUV_BIT)
case PVRDRI_CONFIG_ATTRIB_YUV_ORDER:
case PVRDRI_CONFIG_ATTRIB_YUV_NUM_OF_PLANES:
case PVRDRI_CONFIG_ATTRIB_YUV_SUBSAMPLE:
case PVRDRI_CONFIG_ATTRIB_YUV_DEPTH_RANGE:
case PVRDRI_CONFIG_ATTRIB_YUV_CSC_STANDARD:
case PVRDRI_CONFIG_ATTRIB_YUV_PLANE_BPP:
return false;
#endif
case PVRDRI_CONFIG_ATTRIB_RED_MASK:
*puValueOut = psConfig->sGLMode.redMask;
return true;
case PVRDRI_CONFIG_ATTRIB_GREEN_MASK:
*puValueOut = psConfig->sGLMode.greenMask;
return true;
case PVRDRI_CONFIG_ATTRIB_BLUE_MASK:
*puValueOut = psConfig->sGLMode.blueMask;
return true;
case PVRDRI_CONFIG_ATTRIB_ALPHA_MASK:
*puValueOut = psConfig->sGLMode.alphaMask;
return true;
case PVRDRI_CONFIG_ATTRIB_SRGB_CAPABLE:
*puValueOut = psConfig->sGLMode.sRGBCapable;
return true;
case PVRDRI_CONFIG_ATTRIB_INVALID:
errorMessage("%s: Invalid attribute", __func__);
assert(0);
return false;
default:
return false;
}
}
bool
PVRDRIConfigQuery(const PVRDRIConfig *psConfig,
PVRDRIConfigAttrib eConfigAttrib, int *piValueOut)
{
bool bRes;
unsigned int uValue;
bRes = PVRDRIConfigQueryUnsigned(psConfig, eConfigAttrib, &uValue);
if (bRes)
*piValueOut = (int) uValue;
return bRes;
}
bool
MODSUPConfigQuery(const PVRDRIConfig *psConfig,
PVRDRIConfigAttrib eConfigAttrib, unsigned int *puValueOut)
{
return PVRDRIConfigQueryUnsigned(psConfig, eConfigAttrib, puValueOut);
}
void
MODSUPFlushFrontBuffer(struct __DRIdrawableRec *psDRIDrawable,
void *pvLoaderPrivate)
{
PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
__DRIscreen *psDRIScreen = psDRIDrawable->driScreenPriv;
if (!psPVRDrawable->sConfig.sGLMode.doubleBufferMode)
psDRIScreen->image.loader->flushFrontBuffer(psDRIDrawable,
pvLoaderPrivate);
}
void *
MODSUPDrawableGetReferenceHandle(struct __DRIdrawableRec *psDRIDrawable)
{
PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
return psPVRDrawable;
}
void
MODSUPDrawableAddReference(void *pvReferenceHandle)
{
PVRDRIDrawable *psPVRDrawable = pvReferenceHandle;
PVRDRIDrawableAddReference(psPVRDrawable);
}
void
MODSUPDrawableRemoveReference(void *pvReferenceHandle)
{
PVRDRIDrawable *psPVRDrawable = pvReferenceHandle;
PVRDRIDrawableRemoveReference(psPVRDrawable);
}
void
MODSUPDestroyLoaderImageState(const struct __DRIscreenRec *psDRIScreen,
void *pvLoaderPrivate)
{
const __DRIimageLoaderExtension *psImageLoader = psDRIScreen->image.loader;
const __DRIdri2LoaderExtension *psDRI2Loader = psDRIScreen->dri2.loader;
if (psImageLoader && psImageLoader->base.version >= 4 &&
psImageLoader->destroyLoaderImageState) {
psImageLoader->destroyLoaderImageState(pvLoaderPrivate);
} else if (psDRI2Loader && psDRI2Loader->base.version >= 5 &&
psDRI2Loader->destroyLoaderImageState) {
psDRI2Loader->destroyLoaderImageState(pvLoaderPrivate);
}
}

View file

@ -0,0 +1,912 @@
/*
* Copyright (c) Imagination Technologies Ltd.
*
* The contents of this file are subject to the MIT license as set out below.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <pthread.h>
#include <assert.h>
#include <drm_fourcc.h>
#include "pvrdri.h"
#ifndef DRM_FORMAT_MOD_INVALID
#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
#endif
#define _MAKESTRING(x) # x
#define MAKESTRING(x) _MAKESTRING(x)
#define PVRDRI_SUPPORT_LIB "libpvr_dri_support.so"
static void *gpvSupLib;
static int giSupLibRef;
static struct PVRDRISupportInterfaceV2 gsSupV2;
static pthread_mutex_t gsCompatLock = PTHREAD_MUTEX_INITIALIZER;
/* Lookup a function, and set the pointer to the function address */
#define LookupFunc(func, ptr) \
do { \
ptr = dlsym(gpvSupLib, MAKESTRING(func)); \
} while(0)
/* Check if a function exists in the DRI Support interface structure */
#define HaveFuncV2(field) \
((gsSupV2.field) != NULL) \
/* Call a function via the DRI Support interface structure */
#define CallFuncV2(field, ...) \
do { \
if (gsSupV2.field) \
return gsSupV2.field(__VA_ARGS__); \
} while(0)
/* Calculate the start of the PVRDRISupportInterfaceV2 structure */
#define PVRDRIInterfaceV2Start(field) \
(offsetof(struct PVRDRISupportInterfaceV2, field))
/* Calculate the end of the PVRDRISupportInterfaceV2 structure */
#define PVRDRIInterfaceV2End(field) \
(offsetof(struct PVRDRISupportInterfaceV2, field) + \
sizeof((struct PVRDRISupportInterfaceV2 *)0)->field)
static void
CompatLock(void)
{
int ret;
ret = pthread_mutex_lock(&gsCompatLock);
if (ret) {
errorMessage("%s: Failed to lock mutex (%d)", __func__, ret);
abort();
}
}
static void
CompatUnlock(void)
{
int ret;
ret = pthread_mutex_unlock(&gsCompatLock);
if (ret) {
errorMessage("%s: Failed to unlock mutex (%d)", __func__, ret);
abort();
}
}
static void *
LoadLib(const char *path)
{
void *handle;
/* Clear the error */
(void) dlerror();
handle = dlopen(path, RTLD_NOW);
if (handle) {
__driUtilMessage("Loaded %s", path);
} else {
const char *error;
error = dlerror();
if (!error)
error = "unknown error";
errorMessage("%s: Couldn't load %s: %s", __func__, path, error);
}
return handle;
}
static void
UnloadLib(void *handle, const char *name)
{
if (!handle)
return;
/* Clear the error */
(void) dlerror();
if (dlclose(handle)) {
const char *error;
error = dlerror();
if (!error)
error = "unknown error";
errorMessage("%s: Couldn't unload %s: %s", __func__, name, error);
} else {
__driUtilMessage("Unloaded %s", name);
}
}
static bool
LoadSupportLib(void)
{
gpvSupLib = LoadLib(PVRDRI_SUPPORT_LIB);
return gpvSupLib != NULL;
}
static void
UnloadSupportLib(void)
{
UnloadLib(gpvSupLib, PVRDRI_SUPPORT_LIB);
gpvSupLib = NULL;
}
static void
CompatDeinit(void)
{
UnloadSupportLib();
memset(&gsSupV2, 0, sizeof(gsSupV2));
}
bool
PVRDRICompatInit(const struct PVRDRICallbacksV2 *psCallbacksV2,
unsigned int uVersionV2, unsigned int uMinVersionV2)
{
bool (*pfRegisterVersionedCallbacksV2)(const void *pvCallbacks,
unsigned int uVersion,
unsigned int uMinVersion);
bool res;
CompatLock();
res = (giSupLibRef++ != 0);
if (res)
goto Exit;
res = LoadSupportLib();
if (!res)
goto Exit;
LookupFunc(PVRDRIRegisterVersionedCallbacksV2,
pfRegisterVersionedCallbacksV2);
res = (pfRegisterVersionedCallbacksV2 != NULL);
if (!res)
goto Exit;
res = pfRegisterVersionedCallbacksV2(psCallbacksV2,
uVersionV2, uMinVersionV2);
Exit:
if (!res) {
CompatDeinit();
giSupLibRef--;
}
CompatUnlock();
return res;
}
void
PVRDRICompatDeinit(void)
{
CompatLock();
if (--giSupLibRef == 0)
CompatDeinit();
CompatUnlock();
}
bool
MODSUPRegisterSupportInterfaceV2(const void *pvInterface,
unsigned int uVersion,
unsigned int uMinVersion)
{
size_t uStart, uEnd;
memset(&gsSupV2, 0, sizeof(gsSupV2));
if (uVersion < uMinVersion)
return false;
/*
* Minimum versions we support. To prevent the accumulation of old unused
* interfaces in the PVRDRIInterfaceV2 structure, the caller specifies the
* minimum version it supports. This will be pointed to be the psInterface
* argument. Assuming we support that version, we must copy the structure
* passed to us into the correct place in our version of the interface
* structure.
*/
switch (uMinVersion) {
case 0:
uStart = PVRDRIInterfaceV2Start(v0);
break;
case 1:
case 2:
case 3:
case 4:
case 5:
/* These versions require version 0 */
return false;
default:
return false;
}
/* The "default" case should be associated with the latest version */
switch (uVersion) {
default:
case 5:
/* This version is an extension of versions 0 to 4 */
if (uMinVersion > 0)
return false;
uEnd = PVRDRIInterfaceV2End(v5);
break;
case 4:
/* This version is an extension of versions 0 to 3 */
if (uMinVersion > 0)
return false;
uEnd = PVRDRIInterfaceV2End(v4);
break;
case 3:
/*
* This version is an extension of version 2, with no new
* entry points.
*/
case 2:
/* This version is an extension of versions 0 and 1 */
if (uMinVersion > 0)
return false;
uEnd = PVRDRIInterfaceV2End(v2);
break;
case 1:
/* This version is an extension of version 0 */
if (uMinVersion > 0)
return false;
uEnd = PVRDRIInterfaceV2End(v1);
break;
case 0:
uEnd = PVRDRIInterfaceV2End(v0);
break;
}
memcpy(((char *) &gsSupV2) + uStart, pvInterface, uEnd - uStart);
PVRDRIAdjustExtensions(uVersion, uMinVersion);
return true;
}
struct DRISUPScreen *
DRISUPCreateScreen(struct __DRIscreenRec *psDRIScreen, int iFD,
bool bUseInvalidate, void *pvLoaderPrivate,
const struct __DRIconfigRec ***pppsConfigs,
int *piMaxGLES1Version, int *piMaxGLES2Version)
{
CallFuncV2(v0.CreateScreen,
psDRIScreen, iFD, bUseInvalidate, pvLoaderPrivate, pppsConfigs,
piMaxGLES1Version, piMaxGLES2Version);
return NULL;
}
void
DRISUPDestroyScreen(struct DRISUPScreen *psDRISUPScreen)
{
CallFuncV2(v0.DestroyScreen,
psDRISUPScreen);
}
unsigned int
DRISUPCreateContext(PVRDRIAPIType eAPI, PVRDRIConfig *psPVRDRIConfig,
struct PVRDRIContextConfig *psCtxConfig,
struct __DRIcontextRec *psDRIContext,
struct DRISUPContext *psDRISUPSharedContext,
struct DRISUPScreen *psDRISUPScreen,
struct DRISUPContext **ppsDRISUPContext)
{
CallFuncV2(v0.CreateContext,
eAPI, psPVRDRIConfig, psCtxConfig, psDRIContext,
psDRISUPSharedContext, psDRISUPScreen, ppsDRISUPContext);
return __DRI_CTX_ERROR_BAD_API;
}
void
DRISUPDestroyContext(struct DRISUPContext *psDRISUPContext)
{
CallFuncV2(v0.DestroyContext,
psDRISUPContext);
}
struct DRISUPDrawable *
DRISUPCreateDrawable(struct __DRIdrawableRec *psDRIDrawable,
struct DRISUPScreen *psDRISUPScreen,
void *pvLoaderPrivate, PVRDRIConfig *psPVRDRIConfig)
{
CallFuncV2(v0.CreateDrawable,
psDRIDrawable, psDRISUPScreen, pvLoaderPrivate, psPVRDRIConfig);
return NULL;
}
void
DRISUPDestroyDrawable(struct DRISUPDrawable *psDRISUPDrawable)
{
CallFuncV2(v0.DestroyDrawable,
psDRISUPDrawable);
}
bool
DRISUPMakeCurrent(struct DRISUPContext *psDRISUPContext,
struct DRISUPDrawable *psDRISUPWrite,
struct DRISUPDrawable *psDRISUPRead)
{
CallFuncV2(v0.MakeCurrent,
psDRISUPContext, psDRISUPWrite, psDRISUPRead);
return false;
}
bool
DRISUPUnbindContext(struct DRISUPContext *psDRISUPContext)
{
CallFuncV2(v0.UnbindContext,
psDRISUPContext);
return false;
}
struct DRISUPBuffer *
DRISUPAllocateBuffer(struct DRISUPScreen *psDRISUPScreen,
unsigned int uAttachment, unsigned int uFormat,
int iWidth, int iHeight, unsigned int *puName,
unsigned int *puPitch, unsigned int *puCPP,
unsigned int *puFlags)
{
CallFuncV2(v0.AllocateBuffer,
psDRISUPScreen, uAttachment, uFormat, iWidth, iHeight, puName,
puPitch, puCPP, puFlags);
return NULL;
}
void
DRISUPReleaseBuffer(struct DRISUPScreen *psDRISUPScreen,
struct DRISUPBuffer *psDRISUPBuffer)
{
CallFuncV2(v0.ReleaseBuffer,
psDRISUPScreen, psDRISUPBuffer);
}
void
DRISUPSetTexBuffer2(struct DRISUPContext *psDRISUPContext, int iTarget,
int iFormat, struct DRISUPDrawable *psDRISUPDrawable)
{
CallFuncV2(v0.SetTexBuffer2,
psDRISUPContext, iTarget, iFormat, psDRISUPDrawable);
}
void
DRISUPReleaseTexBuffer(struct DRISUPContext *psDRISUPContext, int iTarget,
struct DRISUPDrawable *psDRISUPDrawable)
{
CallFuncV2(v0.ReleaseTexBuffer,
psDRISUPContext, iTarget, psDRISUPDrawable);
}
void
DRISUPFlush(struct DRISUPDrawable *psDRISUPDrawable)
{
CallFuncV2(v0.Flush,
psDRISUPDrawable);
}
void
DRISUPInvalidate(struct DRISUPDrawable *psDRISUPDrawable)
{
CallFuncV2(v0.Invalidate,
psDRISUPDrawable);
}
void
DRISUPFlushWithFlags(struct DRISUPContext *psDRISUPContext,
struct DRISUPDrawable *psDRISUPDrawable,
unsigned int uFlags, unsigned int uThrottleReason)
{
CallFuncV2(v0.FlushWithFlags,
psDRISUPContext, psDRISUPDrawable, uFlags, uThrottleReason);
}
__DRIimage *
DRISUPCreateImageFromName(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC, int iName,
int iPitch, void *pvLoaderPrivate)
{
CallFuncV2(v0.CreateImageFromName,
psDRISUPScreen, iWidth, iHeight, iFourCC, iName, iPitch,
pvLoaderPrivate);
return NULL;
}
__DRIimage *
DRISUPCreateImageFromRenderbuffer(struct DRISUPContext *psDRISUPContext,
int iRenderBuffer, void *pvLoaderPrivate)
{
CallFuncV2(v0.CreateImageFromRenderbuffer,
psDRISUPContext, iRenderBuffer, pvLoaderPrivate);
return NULL;
}
void
DRISUPDestroyImage(__DRIimage *psImage)
{
CallFuncV2(v0.DestroyImage, psImage);
}
__DRIimage *
DRISUPCreateImage(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC, unsigned int uUse,
void *pvLoaderPrivate)
{
CallFuncV2(v0.CreateImage,
psDRISUPScreen, iWidth, iHeight, iFourCC, uUse, pvLoaderPrivate);
return NULL;
}
bool
DRISUPQueryImage(__DRIimage *psImage, int iAttrib, int *piValue)
{
CallFuncV2(v0.QueryImage,
psImage, iAttrib, piValue);
return false;
}
__DRIimage *
DRISUPDupImage(__DRIimage *psImage, void *pvLoaderPrivate)
{
CallFuncV2(v0.DupImage,
psImage, pvLoaderPrivate);
return NULL;
}
bool
DRISUPValidateImageUsage(__DRIimage *psImage, unsigned int uUse)
{
CallFuncV2(v0.ValidateImageUsage,
psImage, uUse);
return false;
}
__DRIimage *
DRISUPCreateImageFromNames(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC,
int *piNames, int iNumNames,
int *piStrides, int *piOffsets,
void *pvLoaderPrivate)
{
CallFuncV2(v0.CreateImageFromNames,
psDRISUPScreen, iWidth, iHeight, iFourCC, piNames, iNumNames,
piStrides, piOffsets, pvLoaderPrivate);
return NULL;
}
__DRIimage *
DRISUPFromPlanar(__DRIimage *psImage, int iPlane, void *pvLoaderPrivate)
{
CallFuncV2(v0.FromPlanar,
psImage, iPlane, pvLoaderPrivate);
return NULL;
}
__DRIimage *
DRISUPCreateImageFromTexture(struct DRISUPContext *psDRISUPContext,
int iTarget, unsigned int uTexture, int iDepth,
int iLevel, unsigned int *puError,
void *pvLoaderPrivate)
{
CallFuncV2(v0.CreateImageFromTexture,
psDRISUPContext, iTarget, uTexture, iDepth, iLevel, puError,
pvLoaderPrivate);
return NULL;
}
__DRIimage *
DRISUPCreateImageFromFDs(struct DRISUPScreen *psDRISUPcreen,
int iWidth, int iHeight, int iFourCC,
int *piFDs, int iNumFDs, int *piStrides,
int *piOffsets, void *pvLoaderPrivate)
{
CallFuncV2(v0.CreateImageFromFDs,
psDRISUPcreen, iWidth, iHeight, iFourCC, piFDs, iNumFDs,
piStrides, piOffsets, pvLoaderPrivate);
return NULL;
}
__DRIimage *
DRISUPCreateImageFromDmaBufs(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC,
int *piFDs, int iNumFDs,
int *piStrides, int *piOffsets,
unsigned int uColorSpace,
unsigned int uSampleRange,
unsigned int uHorizSiting,
unsigned int uVertSiting,
unsigned int *puError,
void *pvLoaderPrivate)
{
CallFuncV2(v0.CreateImageFromDMABufs,
psDRISUPScreen, iWidth, iHeight, iFourCC, piFDs, iNumFDs,
piStrides, piOffsets, uColorSpace, uSampleRange,
uHorizSiting, uVertSiting, puError, pvLoaderPrivate);
return NULL;
}
int
DRISUPGetImageCapabilities(struct DRISUPScreen *psDRISUPScreen)
{
CallFuncV2(v0.GetImageCapabilities,
psDRISUPScreen);
return 0;
}
void
DRISUPBlitImage(struct DRISUPContext *psDRISUPContext,
__DRIimage *psDst, __DRIimage *psSrc, int iDstX0, int iDstY0,
int iDstWidth, int iDstHeight, int iSrcX0, int iSrcY0,
int iSrcWidth, int iSrcHeight, int iFlushFlag)
{
CallFuncV2(v0.BlitImage,
psDRISUPContext, psDst, psSrc, iDstX0, iDstY0,
iDstWidth, iDstHeight, iSrcX0, iSrcY0,
iSrcWidth, iSrcHeight, iFlushFlag);
}
void *
DRISUPMapImage(struct DRISUPContext *psDRISUPContext, __DRIimage* psImage,
int iX0, int iY0, int iWidth, int iHeight, unsigned int uFlags,
int *piStride, void **ppvData)
{
CallFuncV2(v0.MapImage,
psDRISUPContext, psImage, iX0, iY0, iWidth, iHeight, uFlags,
piStride, ppvData);
return NULL;
}
void
DRISUPUnmapImage(struct DRISUPContext *psDRISUPContext, __DRIimage *psImage,
void *pvData)
{
CallFuncV2(v0.UnmapImage,
psDRISUPContext, psImage, pvData);
}
__DRIimage *
DRISUPCreateImageWithModifiers(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC,
const uint64_t *puModifiers,
const unsigned int uModifierCount,
void *pvLoaderPrivate)
{
CallFuncV2(v0.CreateImageWithModifiers,
psDRISUPScreen, iWidth, iHeight, iFourCC, puModifiers,
uModifierCount, pvLoaderPrivate);
return NULL;
}
__DRIimage *
DRISUPCreateImageFromDMABufs2(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC,
uint64_t uModifier, int *piFDs, int iNumFDs,
int *piStrides, int *piOffsets,
unsigned int uColorSpace,
unsigned int uSampleRange,
unsigned int uHorizSiting,
unsigned int uVertSiting,
unsigned int *puError, void *pvLoaderPrivate)
{
CallFuncV2(v0.CreateImageFromDMABufs2,
psDRISUPScreen, iWidth, iHeight, iFourCC, uModifier,
piFDs, iNumFDs, piStrides, piOffsets, uColorSpace, uSampleRange,
uHorizSiting, uVertSiting, puError, pvLoaderPrivate);
return NULL;
}
bool
DRISUPQueryDMABufFormats(struct DRISUPScreen *psDRISUPScreen, int iMax,
int *piFormats, int *piCount)
{
CallFuncV2(v0.QueryDMABufFormats,
psDRISUPScreen, iMax, piFormats, piCount);
return false;
}
bool
DRISUPQueryDMABufModifiers(struct DRISUPScreen *psDRISUPScreen, int iFourCC,
int iMax, uint64_t *puModifiers,
unsigned int *piExternalOnly, int *piCount)
{
CallFuncV2(v0.QueryDMABufModifiers,
psDRISUPScreen, iFourCC, iMax, puModifiers, piExternalOnly,
piCount);
return false;
}
bool
DRISUPQueryDMABufFormatModifierAttribs(struct DRISUPScreen *psDRISUPScreen,
uint32_t iFourCC, uint64_t uModifier,
int iAttrib, uint64_t *puValue)
{
CallFuncV2(v0.QueryDMABufFormatModifierAttribs,
psDRISUPScreen, iFourCC, uModifier, iAttrib, puValue);
return false;
}
__DRIimage *
DRISUPCreateImageFromRenderBuffer2(struct DRISUPContext *psDRISUPContext,
int iRenderBuffer, void *pvLoaderPrivate,
unsigned int *puError)
{
CallFuncV2(v0.CreateImageFromRenderBuffer2,
psDRISUPContext, iRenderBuffer, pvLoaderPrivate, puError);
return NULL;
}
__DRIimage *
DRISUPCreateImageFromBuffer(struct DRISUPContext *psDRISUPContext,
int iTarget, void *pvBuffer,
unsigned int *puError, void *pvLoaderPrivate)
{
CallFuncV2(v0.CreateImageFromBuffer,
psDRISUPContext, iTarget, pvBuffer, puError, pvLoaderPrivate);
return NULL;
}
int
DRISUPQueryRendererInteger(struct DRISUPScreen *psDRISUPScreen,
int iAttribute, unsigned int *puValue)
{
CallFuncV2(v0.QueryRendererInteger,
psDRISUPScreen, iAttribute, puValue);
return -1;
}
int
DRISUPQueryRendererString(struct DRISUPScreen *psDRISUPScreen,
int iAttribute, const char **ppszValue)
{
CallFuncV2(v0.QueryRendererString,
psDRISUPScreen, iAttribute, ppszValue);
return -1;
}
void *
DRISUPCreateFence(struct DRISUPContext *psDRISUPContext)
{
CallFuncV2(v0.CreateFence,
psDRISUPContext);
return NULL;
}
void
DRISUPDestroyFence(struct DRISUPScreen *psDRISUPScreen, void *pvFence)
{
CallFuncV2(v0.DestroyFence,
psDRISUPScreen, pvFence);
}
bool
DRISUPClientWaitSync(struct DRISUPContext *psDRISUPContext, void *pvFence,
unsigned int uFlags, uint64_t uTimeout)
{
CallFuncV2(v0.ClientWaitSync,
psDRISUPContext, pvFence, uFlags, uTimeout);
return false;
}
void
DRISUPServerWaitSync(struct DRISUPContext *psDRISUPContext, void *pvFence,
unsigned int uFlags)
{
CallFuncV2(v0.ServerWaitSync,
psDRISUPContext, pvFence, uFlags);
}
unsigned int
DRISUPGetFenceCapabilities(struct DRISUPScreen *psDRISUPScreen)
{
CallFuncV2(v0.GetFenceCapabilities,
psDRISUPScreen);
return 0;
}
void *
DRISUPCreateFenceFD(struct DRISUPContext *psDRISUPContext, int iFD)
{
CallFuncV2(v0.CreateFenceFD,
psDRISUPContext, iFD);
return NULL;
}
int
DRISUPGetFenceFD(struct DRISUPScreen *psDRISUPScreen, void *pvFence)
{
CallFuncV2(v0.GetFenceFD,
psDRISUPScreen, pvFence);
return -1;
}
void *
DRISUPGetFenceFromCLEvent(struct DRISUPScreen *psDRISUPScreen,
intptr_t iCLEvent)
{
CallFuncV2(v1.GetFenceFromCLEvent,
psDRISUPScreen, iCLEvent);
return NULL;
}
int
DRISUPGetAPIVersion(struct DRISUPScreen *psDRISUPScreen,
PVRDRIAPIType eAPI)
{
CallFuncV2(v2.GetAPIVersion,
psDRISUPScreen, eAPI);
return 0;
}
unsigned int
DRISUPGetNumAPIProcs(struct DRISUPScreen *psDRISUPScreen,
PVRDRIAPIType eAPI)
{
CallFuncV2(v0.GetNumAPIProcs,
psDRISUPScreen, eAPI);
return 0;
}
const char *
DRISUPGetAPIProcName(struct DRISUPScreen *psDRISUPScreen, PVRDRIAPIType eAPI,
unsigned int uIndex)
{
CallFuncV2(v0.GetAPIProcName,
psDRISUPScreen, eAPI, uIndex);
return NULL;
}
void *
DRISUPGetAPIProcAddress(struct DRISUPScreen *psDRISUPScreen,
PVRDRIAPIType eAPI, unsigned int uIndex)
{
CallFuncV2(v0.GetAPIProcAddress,
psDRISUPScreen, eAPI, uIndex);
return NULL;
}
void
DRISUPSetDamageRegion(struct DRISUPDrawable *psDRISUPDrawable,
unsigned int uNRects, int *piRects)
{
CallFuncV2(v0.SetDamageRegion,
psDRISUPDrawable, uNRects, piRects);
}
bool
DRISUPHaveGetFenceFromCLEvent(void)
{
CallFuncV2(v4.HaveGetFenceFromCLEvent);
return true;
}
__DRIimage *
DRISUPCreateImageFromDMABufs3(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC,
uint64_t uModifier, int *piFDs, int iNumFDs,
int *piStrides, int *piOffsets,
unsigned int uColorSpace,
unsigned int uSampleRange,
unsigned int uHorizSiting,
unsigned int uVertSiting,
uint32_t uFlags,
unsigned int *puError, void *pvLoaderPrivate)
{
CallFuncV2(v5.CreateImageFromDMABufs3,
psDRISUPScreen, iWidth, iHeight, iFourCC, uModifier,
piFDs, iNumFDs, piStrides, piOffsets, uColorSpace, uSampleRange,
uHorizSiting, uVertSiting, uFlags, puError, pvLoaderPrivate);
return NULL;
}
__DRIimage *
DRISUPCreateImageWithModifiers2(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC,
const uint64_t *puModifiers,
const unsigned int uModifierCount,
unsigned int uUse,
void *pvLoaderPrivate)
{
CallFuncV2(v5.CreateImageWithModifiers2,
psDRISUPScreen, iWidth, iHeight, iFourCC, puModifiers,
uModifierCount, uUse, pvLoaderPrivate);
return NULL;
}
__DRIimage *
DRISUPCreateImageFromFDs2(struct DRISUPScreen *psDRISUPcreen,
int iWidth, int iHeight, int iFourCC,
int *piFDs, int iNumFDs, uint32_t uFlags,
int *piStrides, int *piOffsets,
void *pvLoaderPrivate)
{
CallFuncV2(v5.CreateImageFromFDs2,
psDRISUPcreen, iWidth, iHeight, iFourCC, piFDs, iNumFDs,
uFlags, piStrides, piOffsets, pvLoaderPrivate);
return NULL;
}
bool
DRISUPHaveSetInFenceFd(void)
{
return HaveFuncV2(v5.SetInFenceFD);
}
void
DRISUPSetInFenceFd(__DRIimage *psImage, int iFd)
{
CallFuncV2(v5.SetInFenceFD,
psImage, iFd);
}

View file

@ -0,0 +1,630 @@
/*
* Copyright (c) Imagination Technologies Ltd.
*
* The contents of this file are subject to the MIT license as set out below.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <string.h>
#include <assert.h>
#include "util/u_atomic.h"
#include <util/xmlconfig.h>
#include <util/driconf.h>
#include "dri_screen.h"
#include "pvrdri.h"
#include "pvrmesa.h"
#define PVR_IMAGE_LOADER_VER_MIN 1
struct PVRBuffer {
__DRIbuffer sDRIBuffer;
struct DRISUPBuffer *psDRISUPBuffer;
};
/*************************************************************************//*!
Local functions
*//**************************************************************************/
static bool
PVRLoaderIsSupported(__DRIscreen *psDRIScreen)
{
if (psDRIScreen->image.loader) {
if (psDRIScreen->image.loader->base.version < PVR_IMAGE_LOADER_VER_MIN) {
__driUtilMessage("%s: Image loader extension version %d but need %d",
__func__, psDRIScreen->image.loader->base.version,
PVR_IMAGE_LOADER_VER_MIN);
return false;
} else if (!psDRIScreen->image.loader->getBuffers) {
__driUtilMessage("%s: Image loader extension missing support for getBuffers",
__func__);
return false;
}
} else {
__driUtilMessage("%s: Image loader extension required", __func__);
return false;
}
return true;
}
static inline struct DRISUPContext *
getSharedContextImpl(void *pvSharedContextPrivate)
{
if (pvSharedContextPrivate == NULL)
return NULL;
return ((PVRDRIContext *) pvSharedContextPrivate)->psDRISUPContext;
}
static void
PVRDRIScreenAddReference(PVRDRIScreen *psPVRScreen)
{
int iRefCount = p_atomic_inc_return(&psPVRScreen->iRefCount);
(void) iRefCount;
assert(iRefCount > 1);
}
static void
PVRDRIScreenRemoveReference(PVRDRIScreen *psPVRScreen)
{
int iRefCount = p_atomic_dec_return(&psPVRScreen->iRefCount);
assert(iRefCount >= 0);
if (iRefCount != 0)
return;
pvrdri_free_dispatch_tables(psPVRScreen);
DRISUPDestroyScreen(psPVRScreen->psDRISUPScreen);
PVRDRICompatDeinit();
free(psPVRScreen);
}
void
PVRDRIDrawableAddReference(PVRDRIDrawable *psPVRDrawable)
{
int iRefCount = p_atomic_inc_return(&psPVRDrawable->iRefCount);
(void) iRefCount;
assert(iRefCount > 1);
}
void
PVRDRIDrawableRemoveReference(PVRDRIDrawable *psPVRDrawable)
{
int iRefCount = p_atomic_dec_return(&psPVRDrawable->iRefCount);
assert(iRefCount >= 0);
if (iRefCount != 0)
return;
DRISUPDestroyDrawable(psPVRDrawable->psDRISUPDrawable);
#if defined(DEBUG)
p_atomic_dec(&psPVRDrawable->psPVRScreen->iDrawableAlloc);
#endif
PVRDRIScreenRemoveReference(psPVRDrawable->psPVRScreen);
free(psPVRDrawable);
}
static void
PVRScreenPrintExtensions(__DRIscreen *psDRIScreen)
{
/* Don't attempt to print anything if LIBGL_DEBUG isn't in the environment */
if (getenv("LIBGL_DEBUG") == NULL)
return;
if (psDRIScreen->extensions) {
const __DRIextension *psScreenExtensionVersionInfo =
PVRDRIScreenExtensionVersionInfo();
int i;
int j;
__driUtilMessage("Supported screen extensions:");
for (i = 0; psDRIScreen->extensions[i]; i++) {
for (j = 0; psScreenExtensionVersionInfo[j].name; j++) {
if (strcmp(psDRIScreen->extensions[i]->name,
psScreenExtensionVersionInfo[j].name) == 0) {
__driUtilMessage("\t%s (supported version: %u - max version: %u)",
psDRIScreen->extensions[i]->name,
psDRIScreen->extensions[i]->version,
psScreenExtensionVersionInfo[j].version);
break;
}
}
if (psScreenExtensionVersionInfo[j].name == NULL) {
__driUtilMessage("\t%s (supported version: %u - max version: unknown)",
psDRIScreen->extensions[i]->name,
psDRIScreen->extensions[i]->version);
}
}
} else {
__driUtilMessage("No screen extensions found");
}
}
/*************************************************************************//*!
Mesa driver API functions
*//**************************************************************************/
static const __DRIconfig **
PVRDRIInitScreen(__DRIscreen *psDRIScreen)
{
PVRDRIScreen *psPVRScreen;
const __DRIconfig **ppsConfigs;
int iMaxGLES1Version, iMaxGLES2Version;
const struct PVRDRICallbacksV2 sDRICallbacksV2 = {
/* Version 0 callbacks */
.v0.RegisterSupportInterface = MODSUPRegisterSupportInterfaceV2,
.v0.GetBuffers = MODSUPGetBuffers,
.v0.CreateConfigs = MODSUPCreateConfigs,
.v0.ConcatConfigs = MODSUPConcatConfigs,
.v0.ConfigQuery = MODSUPConfigQuery,
.v0.LookupEGLImage = MODSUPLookupEGLImage,
.v0.GetCapability = MODSUPGetCapability,
/* Version 1 callbacks */
.v1.FlushFrontBuffer = MODSUPFlushFrontBuffer,
/* Version 2 callbacks */
.v2.GetDisplayFD = MODSUPGetDisplayFD,
/* Version 3 callbacks */
.v3.DrawableGetReferenceHandle = MODSUPDrawableGetReferenceHandle,
.v3.DrawableAddReference = MODSUPDrawableAddReference,
.v3.DrawableRemoveReference = MODSUPDrawableRemoveReference,
/* Version 4 callbacks */
.v4.DestroyLoaderImageState = MODSUPDestroyLoaderImageState,
};
if (!PVRLoaderIsSupported(psDRIScreen))
return NULL;
if (!PVRDRICompatInit(&sDRICallbacksV2, 4, 0))
return NULL;
psPVRScreen = calloc(1, sizeof(*psPVRScreen));
if (psPVRScreen == NULL) {
__driUtilMessage("%s: Couldn't allocate PVRDRIScreen", __func__);
goto ErrorCompatDeinit;
}
psDRIScreen->driverPrivate = psPVRScreen;
psPVRScreen->psDRIScreen = psDRIScreen;
psPVRScreen->iRefCount = 1;
psPVRScreen->psDRISUPScreen =
DRISUPCreateScreen(psDRIScreen, psDRIScreen->fd,
psDRIScreen->dri2.useInvalidate != NULL,
psDRIScreen->loaderPrivate,
&ppsConfigs, &iMaxGLES1Version, &iMaxGLES2Version);
if (!psPVRScreen->psDRISUPScreen)
goto ErrorScreenFree;
psDRIScreen->max_gl_es1_version = iMaxGLES1Version;
psDRIScreen->max_gl_es2_version = iMaxGLES2Version;
psDRIScreen->max_gl_compat_version =
DRISUPGetAPIVersion(psPVRScreen->psDRISUPScreen, PVRDRI_API_GL_COMPAT);
psDRIScreen->max_gl_core_version =
DRISUPGetAPIVersion(psPVRScreen->psDRISUPScreen, PVRDRI_API_GL_CORE);
psDRIScreen->extensions = PVRDRIScreenExtensions();
PVRScreenPrintExtensions(psDRIScreen);
return ppsConfigs;
ErrorScreenFree:
psDRIScreen->driverPrivate = NULL;
free(psPVRScreen);
ErrorCompatDeinit:
PVRDRICompatDeinit();
return NULL;
}
static void
PVRDRIDestroyScreen(__DRIscreen *psDRIScreen)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
#if defined(DEBUG)
if (psPVRScreen->iBufferAlloc != 0 ||
psPVRScreen->iDrawableAlloc != 0 ||
psPVRScreen->iContextAlloc != 0) {
errorMessage("%s: Outstanding allocations: Contexts: %d Drawables: %d Buffers: %d",
__func__, psPVRScreen->iContextAlloc,
psPVRScreen->iDrawableAlloc, psPVRScreen->iBufferAlloc);
if (psPVRScreen->iRefCount > 1) {
errorMessage("%s: PVRDRIScreen resources will not be freed until its %d references are removed",
__func__, psPVRScreen->iRefCount - 1);
}
}
#endif
PVRDRIScreenRemoveReference(psPVRScreen);
}
static int
PVRDRIScreenSupportedAPIs(PVRDRIScreen *psPVRScreen)
{
unsigned int api_mask = psPVRScreen->psDRIScreen->api_mask;
int supported = 0;
if ((api_mask & (1 << __DRI_API_GLES)) != 0)
supported |= PVRDRI_API_BIT_GLES;
if ((api_mask & (1 << __DRI_API_GLES2)) != 0)
supported |= PVRDRI_API_BIT_GLES2;
if ((api_mask & (1 << __DRI_API_GLES3)) != 0)
supported |= PVRDRI_API_BIT_GLES3;
if ((api_mask & (1 << __DRI_API_OPENGL)) != 0)
supported |= PVRDRI_API_BIT_GL;
if ((api_mask & (1 << __DRI_API_OPENGL_CORE)) != 0)
supported |= PVRDRI_API_BIT_GL;
return supported;
}
static GLboolean
PVRDRICreateContext(gl_api eMesaAPI, const struct gl_config *psGLMode,
__DRIcontext *psDRIContext,
const struct __DriverContextConfig *psCtxConfig,
unsigned int *puError, void *pvSharedContextPrivate)
{
__DRIscreen *psDRIScreen = psDRIContext->driScreenPriv;
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
PVRDRIContext *psPVRContext;
struct DRISUPContext *psDRISUPContext;
struct DRISUPContext *psDRISUPSharedContext;
struct PVRDRIContextConfig sCtxConfig;
PVRDRIAPIType eAPI;
psDRISUPSharedContext = getSharedContextImpl(pvSharedContextPrivate);
sCtxConfig.uMajorVersion = psCtxConfig->major_version;
sCtxConfig.uMinorVersion = psCtxConfig->minor_version;
sCtxConfig.uFlags = psCtxConfig->flags;
sCtxConfig.iResetStrategy = __DRI_CTX_RESET_NO_NOTIFICATION;
sCtxConfig.uPriority = __DRI_CTX_PRIORITY_MEDIUM;
sCtxConfig.iReleaseBehavior = __DRI_CTX_RELEASE_BEHAVIOR_FLUSH;
psPVRContext = calloc(1, sizeof(*psPVRContext));
if (psPVRContext == NULL) {
__driUtilMessage("%s: Couldn't allocate PVRDRIContext", __func__);
*puError = __DRI_CTX_ERROR_NO_MEMORY;
return GL_FALSE;
}
psPVRContext->psDRIContext = psDRIContext;
psPVRContext->psPVRScreen = psPVRScreen;
if (psGLMode)
psPVRContext->sConfig.sGLMode = *psGLMode;
switch (eMesaAPI) {
case API_OPENGLES:
eAPI = PVRDRI_API_GLES1;
break;
case API_OPENGLES2:
eAPI = PVRDRI_API_GLES2;
break;
case API_OPENGL_COMPAT:
eAPI = PVRDRI_API_GL_COMPAT;
break;
case API_OPENGL_CORE:
eAPI = PVRDRI_API_GL_CORE;
break;
default:
__driUtilMessage("%s: Unsupported API: %d",
__func__, (int) eMesaAPI);
*puError = __DRI_CTX_ERROR_BAD_API;
goto ErrorContextFree;
}
psPVRContext->eAPI = eAPI;
if ((psCtxConfig->attribute_mask &
__DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY) != 0) {
sCtxConfig.iResetStrategy = psCtxConfig->reset_strategy;
}
if ((psCtxConfig->attribute_mask &
__DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR) != 0) {
sCtxConfig.iReleaseBehavior = psCtxConfig->release_behavior;
}
if ((psCtxConfig->attribute_mask &
__DRIVER_CONTEXT_ATTRIB_PRIORITY) != 0) {
sCtxConfig.uPriority = psCtxConfig->priority;
}
*puError = DRISUPCreateContext(eAPI, &psPVRContext->sConfig, &sCtxConfig,
psDRIContext, psDRISUPSharedContext,
psPVRScreen->psDRISUPScreen,
&psDRISUPContext);
if (*puError != __DRI_CTX_ERROR_SUCCESS)
goto ErrorContextFree;
psPVRContext->psDRISUPContext = psDRISUPContext;
if (!pvrdri_create_dispatch_table(psPVRScreen, eAPI)) {
__driUtilMessage("%s: Couldn't create dispatch table", __func__);
*puError = __DRI_CTX_ERROR_BAD_API;
goto ErrorContextDestroy;
}
#if defined(DEBUG)
p_atomic_inc(&psPVRScreen->iContextAlloc);
#endif
psDRIContext->driverPrivate = (void *) psPVRContext;
PVRDRIScreenAddReference(psPVRScreen);
*puError = __DRI_CTX_ERROR_SUCCESS;
return GL_TRUE;
ErrorContextDestroy:
DRISUPDestroyContext(psPVRContext->psDRISUPContext);
ErrorContextFree:
free(psPVRContext);
return GL_FALSE;
}
static void
PVRDRIDestroyContext(__DRIcontext *psDRIContext)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
PVRDRIScreen *psPVRScreen = psPVRContext->psPVRScreen;
DRISUPDestroyContext(psPVRContext->psDRISUPContext);
#if defined(DEBUG)
p_atomic_dec(&psPVRScreen->iContextAlloc);
#endif
PVRDRIScreenRemoveReference(psPVRScreen);
free(psPVRContext);
}
static GLboolean
PVRDRICreateBuffer(__DRIscreen *psDRIScreen, __DRIdrawable *psDRIDrawable,
const struct gl_config *psGLMode, GLboolean bIsPixmap)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
PVRDRIDrawable *psPVRDrawable = NULL;
/* No known callers ever set this to true */
if (bIsPixmap)
return GL_FALSE;
if (!psGLMode) {
__driUtilMessage("%s: Invalid GL config", __func__);
return GL_FALSE;
}
psPVRDrawable = calloc(1, sizeof(*psPVRDrawable));
if (!psPVRDrawable) {
__driUtilMessage("%s: Couldn't allocate PVR drawable", __func__);
goto ErrorDrawableFree;
}
psDRIDrawable->driverPrivate = (void *) psPVRDrawable;
psPVRDrawable->iRefCount = 1;
psPVRDrawable->psDRIDrawable = psDRIDrawable;
psPVRDrawable->psPVRScreen = psPVRScreen;
psPVRDrawable->sConfig.sGLMode = *psGLMode;
psPVRDrawable->sConfig.iSupportedAPIs =
PVRDRIScreenSupportedAPIs(psPVRScreen);
psPVRDrawable->psDRISUPDrawable =
DRISUPCreateDrawable(psDRIDrawable, psPVRScreen->psDRISUPScreen,
psDRIDrawable->loaderPrivate,
&psPVRDrawable->sConfig);
if (!psPVRDrawable->psDRISUPDrawable) {
__driUtilMessage("%s: Couldn't create DRI Support drawable",
__func__);
goto ErrorDrawableFree;
}
/* Initialisation is completed in MakeCurrent */
#if defined(DEBUG)
p_atomic_inc(&psPVRScreen->iDrawableAlloc);
#endif
PVRDRIScreenAddReference(psPVRScreen);
return GL_TRUE;
ErrorDrawableFree:
DRISUPDestroyDrawable(psPVRDrawable->psDRISUPDrawable);
free(psPVRDrawable);
psDRIDrawable->driverPrivate = NULL;
return GL_FALSE;
}
static void
PVRDRIDestroyBuffer(__DRIdrawable *psDRIDrawable)
{
PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
PVRDRIDrawableRemoveReference(psPVRDrawable);
}
static GLboolean
PVRDRIMakeCurrent(__DRIcontext *psDRIContext,
__DRIdrawable *psDRIWrite, __DRIdrawable *psDRIRead)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
struct DRISUPDrawable *psDRISUPWrite;
struct DRISUPDrawable *psDRISUPRead;
if (psDRIWrite) {
PVRDRIDrawable *psPVRWrite = psDRIWrite->driverPrivate;
psDRISUPWrite = psPVRWrite->psDRISUPDrawable;
} else {
psDRISUPWrite = NULL;
}
if (psDRIRead) {
PVRDRIDrawable *psPVRRead = psDRIRead->driverPrivate;
psDRISUPRead = psPVRRead->psDRISUPDrawable;
} else {
psDRISUPRead = NULL;
}
if (!DRISUPMakeCurrent(psPVRContext->psDRISUPContext,
psDRISUPWrite, psDRISUPRead))
goto ErrorUnlock;
pvrdri_set_dispatch_table(psPVRContext);
return GL_TRUE;
ErrorUnlock:
return GL_FALSE;
}
static GLboolean
PVRDRIUnbindContext(__DRIcontext *psDRIContext)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
pvrdri_set_null_dispatch_table();
DRISUPUnbindContext(psPVRContext->psDRISUPContext);
return GL_TRUE;
}
static __DRIbuffer *
PVRDRIAllocateBuffer(__DRIscreen *psDRIScreen, unsigned int uAttachment,
unsigned int uFormat, int iWidth, int iHeight)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
struct PVRBuffer *psBuffer;
psBuffer = calloc(1, sizeof(*psBuffer));
if (psBuffer == NULL) {
__driUtilMessage("%s: Failed to allocate buffer", __func__);
return NULL;
}
psBuffer->psDRISUPBuffer =
DRISUPAllocateBuffer(psPVRScreen->psDRISUPScreen, uAttachment, uFormat,
iWidth, iHeight, &psBuffer->sDRIBuffer.name,
&psBuffer->sDRIBuffer.pitch,
&psBuffer->sDRIBuffer.cpp,
&psBuffer->sDRIBuffer.flags);
if (!psBuffer->psDRISUPBuffer) {
__driUtilMessage("%s: Failed to create DRI Support buffer", __func__);
goto ErrorFreeDRIBuffer;
}
psBuffer->sDRIBuffer.attachment = uAttachment;
#if defined(DEBUG)
p_atomic_inc(&psPVRScreen->iBufferAlloc);
#endif
return &psBuffer->sDRIBuffer;
ErrorFreeDRIBuffer:
free(psBuffer);
return NULL;
}
static void
PVRDRIReleaseBuffer(__DRIscreen *psDRIScreen, __DRIbuffer *psDRIBuffer)
{
struct PVRBuffer *psPVRBuffer = (struct PVRBuffer *) psDRIBuffer;
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
DRISUPReleaseBuffer(psPVRScreen->psDRISUPScreen,
psPVRBuffer->psDRISUPBuffer);
#if defined(DEBUG)
p_atomic_dec(&psPVRScreen->iBufferAlloc);
#endif
free(psPVRBuffer);
}
static char *
PVRDRIGetXMLConfigOptions(const char *pszDriverName)
{
const driOptionDescription asConfigOptions[] =
{
DRI_CONF_SECTION_MISCELLANEOUS
DRI_CONF_OPT_B("pvr_driconf_not_used", true,
"The PowerVR driver does not use DRIConf")
DRI_CONF_SECTION_END
};
(void) pszDriverName;
return driGetOptionsXml(&asConfigOptions[0], ARRAY_SIZE(asConfigOptions));
}
const struct __DriverAPIRec pvr_driver_api = {
.InitScreen = PVRDRIInitScreen,
.DestroyScreen = PVRDRIDestroyScreen,
.CreateContext = PVRDRICreateContext,
.DestroyContext = PVRDRIDestroyContext,
.CreateBuffer = PVRDRICreateBuffer,
.DestroyBuffer = PVRDRIDestroyBuffer,
.SwapBuffers = NULL,
.MakeCurrent = PVRDRIMakeCurrent,
.UnbindContext = PVRDRIUnbindContext,
.AllocateBuffer = PVRDRIAllocateBuffer,
.ReleaseBuffer = PVRDRIReleaseBuffer,
};
static const struct __DRIDriverVtableExtensionRec pvr_vtable = {
.base = {__DRI_DRIVER_VTABLE, 1},
.vtable = &pvr_driver_api,
};
const __DRIconfigOptionsExtension pvr_config_options = {
.base = { __DRI_CONFIG_OPTIONS, 2 },
.getXml = PVRDRIGetXMLConfigOptions,
};
const __DRIextension *pvr_driver_extensions[] = {
&driCoreExtension.base,
&driImageDriverExtension.base,
&pvrDRI2Extension.base,
&pvr_vtable.base,
&pvr_config_options.base,
NULL
};

View file

@ -0,0 +1,190 @@
/*
* Copyright (c) Imagination Technologies Ltd.
*
* The contents of this file are subject to the MIT license as set out below.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#if !defined(__PVRDRI_H__)
#define __PVRDRI_H__
#include <stdbool.h>
#include <stdint.h>
#include <inttypes.h>
#include <glapi/glapi.h>
#include "main/mtypes.h"
#include "util/macros.h"
#include "dri_util.h"
#include "pvrdri_support.h"
struct PVRDRIConfigRec {
struct gl_config sGLMode;
int iSupportedAPIs;
};
/* PVR screen data */
typedef struct PVRDRIScreen_TAG {
/* DRI screen structure pointer */
__DRIscreen *psDRIScreen;
/* Opaque PVR DRI Support screen structure pointer */
struct DRISUPScreen *psDRISUPScreen;
/* Reference count */
int iRefCount;
#if defined(DEBUG)
/* Counters of outstanding allocations */
int iContextAlloc;
int iDrawableAlloc;
int iBufferAlloc;
#endif
/* PVR OGLES 1 dispatch table */
struct _glapi_table *psOGLES1Dispatch;
/* PVR OGLES 2/3 dispatch table */
struct _glapi_table *psOGLES2Dispatch;
/* PVR OGL dispatch table */
struct _glapi_table *psOGLDispatch;
} PVRDRIScreen;
/* PVR context data */
typedef struct PVRDRIContext_TAG {
/* Pointer to DRI context */
__DRIcontext *psDRIContext;
/* Opaque PVR DRI Support context structure pointer */
struct DRISUPContext *psDRISUPContext;
/* Pointer to PVRDRIScreen structure */
PVRDRIScreen *psPVRScreen;
/* GL config */
PVRDRIConfig sConfig;
/* API */
PVRDRIAPIType eAPI;
} PVRDRIContext;
/* PVR drawable data */
typedef struct PVRDRIDrawable_TAG {
PVRDRIScreen *psPVRScreen;
__DRIdrawable *psDRIDrawable;
int iRefCount;
PVRDRIConfig sConfig;
struct DRISUPDrawable *psDRISUPDrawable;
unsigned int uFourCC;
unsigned int uDRIFormat;
} PVRDRIDrawable;
/*************************************************************************//*!
pvrdri.c
*//**************************************************************************/
void PVRDRIDrawableAddReference(PVRDRIDrawable *psPVRDrawable);
void PVRDRIDrawableRemoveReference(PVRDRIDrawable *psPVRDrawable);
/*************************************************************************//*!
pvrutil.c
*//**************************************************************************/
void PRINTFLIKE(1, 2) __driUtilMessage(const char *f, ...);
void PRINTFLIKE(1, 2) errorMessage(const char *f, ...);
mesa_format PVRDRIMesaFormatToMesaFormat(int pvrdri_mesa_format);
int PVRDRIFormatToFourCC(int dri_format);
int PVRDRIFourCCToDRIFormat(int iFourCC);
/*************************************************************************//*!
pvrext.c
*//**************************************************************************/
const __DRIextension **PVRDRIScreenExtensions(void);
const __DRIextension *PVRDRIScreenExtensionVersionInfo(void);
void PVRDRIAdjustExtensions(unsigned int uVersion, unsigned int uMinVersion);
/*************************************************************************//*!
pvrcompat.c
*//**************************************************************************/
bool PVRDRICompatInit(const struct PVRDRICallbacksV2 *psCallbacksV2,
unsigned int uVersionV2, unsigned int uMinVersionV2);
void PVRDRICompatDeinit(void);
bool MODSUPRegisterSupportInterfaceV2(const void *pvInterface,
unsigned int uVersion,
unsigned int uMinVersion);
/*************************************************************************//*!
pvrcb.c
*//**************************************************************************/
int MODSUPGetBuffers(struct __DRIdrawableRec *psDRIDrawable,
unsigned int uFourCC, uint32_t *puStamp,
void *pvLoaderPrivate, uint32_t uBufferMask,
struct PVRDRIImageList *psImageList);
bool MODSUPCreateConfigs(struct __DRIconfigRec ***psConfigs,
struct __DRIscreenRec *psDRIScreen,
int iPVRDRIMesaFormat, const uint8_t *puDepthBits,
const uint8_t *puStencilBits,
unsigned int uNumDepthStencilBits,
const unsigned int *puDBModes,
unsigned int uNumDBModes,
const uint8_t *puMSAASamples,
unsigned int uNumMSAAModes, bool bEnableAccum,
bool bColorDepthMatch, bool bMutableRenderBuffer,
int iYUVDepthRange, int iYUVCSCStandard,
uint32_t uMaxPbufferWidth, uint32_t uMaxPbufferHeight);
struct __DRIconfigRec **MODSUPConcatConfigs(struct __DRIscreenRec *psDRIScreen,
struct __DRIconfigRec **ppsConfigA,
struct __DRIconfigRec **ppsConfigB);
__DRIimage *MODSUPLookupEGLImage(struct __DRIscreenRec *psDRIScreen,
void *pvImage, void *pvLoaderPrivate);
unsigned int MODSUPGetCapability(struct __DRIscreenRec *psDRIScreen,
unsigned int uCapability);
int MODSUPGetDisplayFD(struct __DRIscreenRec *psDRIScreen,
void *pvLoaderPrivate);
bool PVRDRIConfigQuery(const PVRDRIConfig *psConfig,
PVRDRIConfigAttrib eConfigAttrib, int *piValueOut);
bool MODSUPConfigQuery(const PVRDRIConfig *psConfig,
PVRDRIConfigAttrib eConfigAttrib,
unsigned int *puValueOut);
void MODSUPFlushFrontBuffer(struct __DRIdrawableRec *psDRIDrawable,
void *pvLoaderPrivate);
void *MODSUPDrawableGetReferenceHandle(struct __DRIdrawableRec *psDRIDrawable);
void MODSUPDrawableAddReference(void *pvReferenceHandle);
void MODSUPDrawableRemoveReference(void *pvReferenceHandle);
void MODSUPDestroyLoaderImageState(const struct __DRIscreenRec *psDRIScreen,
void *pvLoaderPrivate);
#endif /* defined(__PVRDRI_H__) */

View file

@ -0,0 +1,233 @@
/*
* Copyright (c) Imagination Technologies Ltd.
*
* The contents of this file are subject to the MIT license as set out below.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#if !defined(__PVRDRI_SUPPORT_H__)
#define __PVRDRI_SUPPORT_H__
#include <stdint.h>
#include <stdbool.h>
#include "dri_support.h"
struct DRISUPScreen *DRISUPCreateScreen(struct __DRIscreenRec *psDRIScreen,
int iFD, bool bUseInvalidate,
void *pvLoaderPrivate,
const struct __DRIconfigRec ***pppsConfigs,
int *piMaxGLES1Version,
int *piMaxGLES2Version);
void DRISUPDestroyScreen(struct DRISUPScreen *psDRISUPScreen);
unsigned int DRISUPCreateContext(PVRDRIAPIType eAPI,
PVRDRIConfig *psPVRDRIConfig,
struct PVRDRIContextConfig *psCtxConfig,
struct __DRIcontextRec *psDRIContext,
struct DRISUPContext *psDRISUPSharedContext,
struct DRISUPScreen *psDRISUPScreen,
struct DRISUPContext **ppsDRISUPContext);
void DRISUPDestroyContext(struct DRISUPContext *psDRISUPContext);
struct DRISUPDrawable *DRISUPCreateDrawable(struct __DRIdrawableRec *psDRIDrawable,
struct DRISUPScreen *psDRISUPScreen,
void *pvLoaderPrivate,
PVRDRIConfig *psPVRDRIConfig);
void DRISUPDestroyDrawable(struct DRISUPDrawable *psDRISUPDrawable);
bool DRISUPMakeCurrent(struct DRISUPContext *psDRISUPContext,
struct DRISUPDrawable *psDRISUPWrite,
struct DRISUPDrawable *psDRISUPRead);
bool DRISUPUnbindContext(struct DRISUPContext *psDRISUPContext);
struct DRISUPBuffer *DRISUPAllocateBuffer(struct DRISUPScreen *psDRISUPScreen,
unsigned int uAttchment,
unsigned int uFormat,
int iWidth, int iHeight,
unsigned int *puName,
unsigned int *puPitch,
unsigned int *puCPP,
unsigned int *puFlags);
void DRISUPReleaseBuffer(struct DRISUPScreen *psDRISUPScreen,
struct DRISUPBuffer *psDRISUPBuffer);
void DRISUPSetTexBuffer2(struct DRISUPContext *psDRISUPContext,
int iTarget, int iFormat,
struct DRISUPDrawable *psDRISUPDrawable);
void DRISUPReleaseTexBuffer(struct DRISUPContext *psDRISUPContext,
int iTarget,
struct DRISUPDrawable *psDRISUPDrawable);
void DRISUPFlush(struct DRISUPDrawable *psDRISUPDrawable);
void DRISUPInvalidate(struct DRISUPDrawable *psDRISUPDrawable);
void DRISUPFlushWithFlags(struct DRISUPContext *psDRISUPContext,
struct DRISUPDrawable *psDRISUPDrawable,
unsigned int uFlags, unsigned int uThrottleReason);
__DRIimage *DRISUPCreateImageFromName(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC,
int iName, int iPitch,
void *pvLoaderPrivate);
__DRIimage *DRISUPCreateImageFromRenderbuffer(struct DRISUPContext *psDRISUPContext,
int iRenderBuffer,
void *pvLoaderPrivate);
void DRISUPDestroyImage(__DRIimage *psImage);
__DRIimage *DRISUPCreateImage(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC,
unsigned int uUse, void *pvLoaderPrivate);
bool DRISUPQueryImage(__DRIimage *psImage, int iAttrib, int *piValue);
__DRIimage *DRISUPDupImage(__DRIimage *psImage, void *pvLoaderPrivate);
bool DRISUPValidateImageUsage(__DRIimage *psImage, unsigned int uUse);
__DRIimage *DRISUPCreateImageFromNames(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC,
int *piNames, int iNumNames,
int *piStrides, int *piOffsets,
void *pvLoaderPrivate);
__DRIimage *DRISUPFromPlanar(__DRIimage *psImage, int iPlane,
void *pvLoaderPrivate);
__DRIimage *DRISUPCreateImageFromTexture(struct DRISUPContext *psDRISUPContext,
int iTarget, unsigned int uTexture,
int iDepth, int iLevel,
unsigned int *puError,
void *pvLoaderPrivate);
__DRIimage *DRISUPCreateImageFromFDs(struct DRISUPScreen *psDRISUPcreen,
int iWidth, int iHeight, int iFourCC,
int *piFDs, int iNumFDs,
int *piStrides, int *piOffsets,
void *pvLoaderPrivate);
__DRIimage *DRISUPCreateImageFromDmaBufs(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC,
int *piFDs, int iNumFDs,
int *piStrides, int *piOffsets,
unsigned int uColorSpace,
unsigned int uSampleRange,
unsigned int uHorizSiting,
unsigned int uVertSiting,
unsigned int *puError,
void *pvLoaderPrivate);
int DRISUPGetImageCapabilities(struct DRISUPScreen *psDRISUPScreen);
void DRISUPBlitImage(struct DRISUPContext *psDRISUPContext,
__DRIimage *psDst, __DRIimage *psSrc,
int iDstX0, int iDstY0, int iDstWidth, int iDstHeight,
int iSrcX0, int iSrcY0, int iSrcWidth, int iSrcHeight,
int iFlushFlag);
void *DRISUPMapImage(struct DRISUPContext *psDRISUPContext,
__DRIimage *psImage,
int iX0, int iY0, int iWidth, int iHeight,
unsigned int uFlags, int *piStride, void **ppvData);
void DRISUPUnmapImage(struct DRISUPContext *psDRISUPContext,
__DRIimage *psImage, void *pvData);
__DRIimage *DRISUPCreateImageWithModifiers(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight, int iFourCC,
const uint64_t *puModifiers,
const unsigned int uModifierCount,
void *pvLoaderPrivate);
__DRIimage *DRISUPCreateImageFromDMABufs2(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight,
int iFourCC, uint64_t uModifier,
int *piFDs, int iNumFDs,
int *piStrides, int *piOffsets,
unsigned int uColorSpace,
unsigned int uSampleRange,
unsigned int uHorizSiting,
unsigned int uVertSiting,
unsigned int *puError,
void *pvLoaderPrivate);
bool DRISUPQueryDMABufFormats(struct DRISUPScreen *psDRISUPScreen, int iMax,
int *piFormats, int *piCount);
bool DRISUPQueryDMABufModifiers(struct DRISUPScreen *psDRISUPScreen,
int iFourCC, int iMax, uint64_t *puModifiers,
unsigned int *piExternalOnly, int *piCount);
bool DRISUPQueryDMABufFormatModifierAttribs(struct DRISUPScreen *psDRISUPScreen,
uint32_t uFourcc,
uint64_t uModifier,
int iAttrib, uint64_t *puValue);
__DRIimage *DRISUPCreateImageFromRenderBuffer2(struct DRISUPContext *psDRISUPContext,
int iRenderBuffer,
void *pvLoaderPrivate,
unsigned int *puError);
__DRIimage *DRISUPCreateImageFromBuffer(struct DRISUPContext *psDRISUPContext,
int iTarget, void *pvBuffer,
unsigned int *puError,
void *pvLoaderPrivate);
int DRISUPQueryRendererInteger(struct DRISUPScreen *psDRISUPScreen,
int iAttribute, unsigned int *puValue);
int DRISUPQueryRendererString(struct DRISUPScreen *psDRISUPScreen,
int iAttribute, const char **ppszValue);
void *DRISUPCreateFence(struct DRISUPContext *psDRISUPContext);
void DRISUPDestroyFence(struct DRISUPScreen *psDRISUPScreen, void *pvFence);
bool DRISUPClientWaitSync(struct DRISUPContext *psDRISUPContext,
void *pvFence, unsigned int uFlags,
uint64_t uTimeout);
void DRISUPServerWaitSync(struct DRISUPContext *psDRISUPContext,
void *pvFence, unsigned int uFlags);
unsigned int DRISUPGetFenceCapabilities(struct DRISUPScreen *psDRISUPScreen);
void *DRISUPCreateFenceFD(struct DRISUPContext *psDRISUPContext, int iFD);
int DRISUPGetFenceFD(struct DRISUPScreen *psDRISUPScreen, void *pvFence);
void *DRISUPGetFenceFromCLEvent(struct DRISUPScreen *psDRISUPScreen,
intptr_t iCLEvent);
int DRISUPGetAPIVersion(struct DRISUPScreen *psDRISUPScreen,
PVRDRIAPIType eAPI);
unsigned int DRISUPGetNumAPIProcs(struct DRISUPScreen *psDRISUPScreen,
PVRDRIAPIType eAPI);
const char *DRISUPGetAPIProcName(struct DRISUPScreen *psDRISUPScreen,
PVRDRIAPIType eAPI, unsigned int uIndex);
void *DRISUPGetAPIProcAddress(struct DRISUPScreen *psDRISUPScreen,
PVRDRIAPIType eAPI, unsigned int uIndex);
void DRISUPSetDamageRegion(struct DRISUPDrawable *psDRISUPDrawable,
unsigned int uNRects, int *piRects);
bool DRISUPHaveGetFenceFromCLEvent(void);
__DRIimage *DRISUPCreateImageFromDMABufs3(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight,
int iFourCC, uint64_t uModifier,
int *piFDs, int iNumFDs,
int *piStrides, int *piOffsets,
unsigned int uColorSpace,
unsigned int uSampleRange,
unsigned int uHorizSiting,
unsigned int uVertSiting,
uint32_t uFlags,
unsigned int *puError,
void *pvLoaderPrivate);
__DRIimage *DRISUPCreateImageWithModifiers2(struct DRISUPScreen *psDRISUPScreen,
int iWidth, int iHeight,
int iFourCC,
const uint64_t *puModifiers,
const unsigned int uModifierCount,
unsigned int uUse,
void *pvLoaderPrivate);
__DRIimage *DRISUPCreateImageFromFDs2(struct DRISUPScreen *psDRISUPcreen,
int iWidth, int iHeight, int iFourCC,
int *piFDs, int iNumFDs, uint32_t uFlags,
int *piStrides, int *piOffsets,
void *pvLoaderPrivate);
bool DRISUPHaveSetInFenceFd(void);
void DRISUPSetInFenceFd(__DRIimage *psImage, int iFd);
#endif /* defined(__PVRDRI_SUPPORT_H__) */

View file

@ -0,0 +1,796 @@
/*
* Copyright (c) Imagination Technologies Ltd.
*
* The contents of this file are subject to the MIT license as set out below.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
* EXTENSION SUPPORT
*
* As the driver supports a range of Mesa versions it can be the case that it
* needs to support different extensions and extension versions depending on
* the version of Mesa that it's built against. As a guide the following rules
* should be followed:
*
* 1) If an extension appears in some supported versions of Mesa but not others
* then it should be protected by the extension define, e.g.:
* #if defined(__DRI_IMAGE)
* <code>
* #endif
*
* However, if it appears in all versions then there's no need for it to
* be protected.
*
* 2) Each driver supported extension should have a define for the maximum
* version supported by the driver. This should be used when initialising
* the corresponding extension structure. The Mesa extension version define
* should *NOT* be used.
*
* 3) If the driver supports a range of versions for a given extension then
* it should protect the extension code based on the Mesa extension version
* define. For example, if the driver has to support versions 7 to 8 of the
* __DRI_IMAGE extension then any fields, in the __DRIimageExtension
* structure, that appear in version 8 but not 7 should be protected as
* follows:
* #if (__DRI_IMAGE_VERSION >= 8)
* .createImageFromDmaBufs = PVRDRICreateImageFromDmaBufs,
* #endif
*
* Obviously any other associated code should also be protected in the same
* way.
*/
#include "dri_util.h"
#include "dri_query_renderer.h"
#include "dri_support.h"
#include "pvrdri.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"
#include "EGL/eglmesaext.h"
/* Maximum version numbers for each supported extension */
#define PVR_DRI_TEX_BUFFER_VERSION 3
#define PVR_DRI2_FLUSH_VERSION 4
#define PVR_DRI_IMAGE_VERSION 21
#define PVR_DRI2_ROBUSTNESS_VERSION 1
#define PVR_DRI2_FENCE_VERSION 2
#define PVR_DRI2_RENDERER_QUERY_VERSION 1
#define PVR_DRI2_BUFFER_DAMAGE_VERSION 1
static void
PVRDRIExtSetTexBuffer(__DRIcontext *psDRIContext, GLint iTarget,
GLint iFormat, __DRIdrawable *psDRIDrawable)
{
PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
DRISUPSetTexBuffer2(psPVRContext->psDRISUPContext,
iTarget, iFormat, psPVRDrawable->psDRISUPDrawable);
}
static void
PVRDRIExtReleaseTexBuffer(__DRIcontext *psDRIContext, GLint iTarget,
__DRIdrawable *psDRIDrawable)
{
PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
DRISUPReleaseTexBuffer(psPVRContext->psDRISUPContext,
iTarget, psPVRDrawable->psDRISUPDrawable);
}
static __DRItexBufferExtension pvrDRITexBufferExtension = {
.base = {
.name = __DRI_TEX_BUFFER,
.version = PVR_DRI_TEX_BUFFER_VERSION,
},
.setTexBuffer = NULL,
.setTexBuffer2 = PVRDRIExtSetTexBuffer,
.releaseTexBuffer = PVRDRIExtReleaseTexBuffer,
};
static void
PVRDRI2Flush(__DRIdrawable *psDRIDrawable)
{
PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
DRISUPFlush(psPVRDrawable->psDRISUPDrawable);
}
static void
PVRDRI2Invalidate(__DRIdrawable *psDRIDrawable)
{
PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
DRISUPInvalidate(psPVRDrawable->psDRISUPDrawable);
}
static void
PVRDRI2FlushWithFlags(__DRIcontext *psDRIContext,
__DRIdrawable *psDRIDrawable,
unsigned int uFlags,
enum __DRI2throttleReason eThrottleReason)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
struct DRISUPDrawable *psDRISUPDrawable;
if ((uFlags & __DRI2_FLUSH_DRAWABLE) != 0) {
PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
psDRISUPDrawable = psPVRDrawable->psDRISUPDrawable;
} else {
psDRISUPDrawable = NULL;
}
DRISUPFlushWithFlags(psPVRContext->psDRISUPContext, psDRISUPDrawable,
uFlags, (unsigned int) eThrottleReason);
}
static __DRI2flushExtension pvrDRI2FlushExtension = {
.base = {
.name = __DRI2_FLUSH,
.version = PVR_DRI2_FLUSH_VERSION,
},
.flush = PVRDRI2Flush,
.invalidate = PVRDRI2Invalidate,
.flush_with_flags = PVRDRI2FlushWithFlags,
};
static __DRIimage *
PVRDRICreateImageFromName(__DRIscreen *psDRIScreen, int iWidth, int iHeight,
int iFormat, int iName, int iPitch,
void *pvLoaderPrivate)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
int iFourCC = PVRDRIFormatToFourCC(iFormat);
return DRISUPCreateImageFromName(psPVRScreen->psDRISUPScreen,
iWidth, iHeight, iFourCC, iName, iPitch,
pvLoaderPrivate);
}
static __DRIimage *
PVRDRICreateImageFromRenderbuffer(__DRIcontext *psDRIContext,
int iRenderBuffer, void *pvLoaderPrivate)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
return DRISUPCreateImageFromRenderbuffer(psPVRContext->psDRISUPContext,
iRenderBuffer, pvLoaderPrivate);
}
static void
PVRDRIDestroyImage(__DRIimage *psImage)
{
DRISUPDestroyImage(psImage);
}
static __DRIimage *
PVRDRICreateImage(__DRIscreen *psDRIScreen, int iWidth, int iHeight,
int iFormat, unsigned int uUse, void *pvLoaderPrivate)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
int iFourCC = PVRDRIFormatToFourCC(iFormat);
return DRISUPCreateImage(psPVRScreen->psDRISUPScreen, iWidth, iHeight,
iFourCC, uUse, pvLoaderPrivate);
}
static GLboolean
PVRDRIQueryImage(__DRIimage *psImage, int iAttrib, int *piValue)
{
int iFourCC;
switch (iAttrib) {
case __DRI_IMAGE_ATTRIB_FORMAT:
if (DRISUPQueryImage(psImage,
__DRI_IMAGE_ATTRIB_FOURCC, &iFourCC)) {
*piValue = PVRDRIFourCCToDRIFormat(iFourCC);
return GL_TRUE;
}
return GL_FALSE;
default:
return DRISUPQueryImage(psImage, iAttrib, piValue);
}
}
static __DRIimage *
PVRDRIDupImage(__DRIimage *psImage, void *pvLoaderPrivate)
{
return DRISUPDupImage(psImage, pvLoaderPrivate);
}
static GLboolean
PVRDRIValidateImageUsage(__DRIimage *psImage, unsigned int uUse)
{
return DRISUPValidateImageUsage(psImage, uUse);
}
static __DRIimage *
PVRDRICreateImageFromNames(__DRIscreen *psDRIScreen, int iWidth, int iHeight,
int iFourCC, int *piNames, int iNumNames,
int *piStrides, int *piOffsets,
void *pvLoaderPrivate)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPCreateImageFromNames(psPVRScreen->psDRISUPScreen,
iWidth, iHeight, iFourCC,
piNames, iNumNames,
piStrides, piOffsets, pvLoaderPrivate);
}
static __DRIimage *
PVRDRIFromPlanar(__DRIimage *psImage, int iPlane, void *pvLoaderPrivate)
{
return DRISUPFromPlanar(psImage, iPlane, pvLoaderPrivate);
}
static __DRIimage *
PVRDRICreateImageFromTexture(__DRIcontext *psDRIContext, int iTarget,
unsigned int uTexture, int iDepth, int iLevel,
unsigned int *puError, void *pvLoaderPrivate)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
int iEGLTarget;
switch (iTarget) {
case GL_TEXTURE_2D:
iEGLTarget = PVRDRI_GL_TEXTURE_2D;
break;
case GL_TEXTURE_3D:
iEGLTarget = PVRDRI_GL_TEXTURE_3D;
break;
case GL_TEXTURE_CUBE_MAP:
iEGLTarget = PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
break;
default:
errorMessage("%s: GL Target %d is not supported",
__func__, iTarget);
*puError = __DRI_IMAGE_ERROR_BAD_PARAMETER;
return NULL;
}
return DRISUPCreateImageFromTexture(psPVRContext->psDRISUPContext,
iEGLTarget, uTexture, iDepth, iLevel,
puError, pvLoaderPrivate);
}
static __DRIimage *
PVRDRICreateImageFromFds(__DRIscreen *psDRIScreen, int iWidth, int iHeight,
int iFourCC, int *piFDs, int iNumFDs,
int *piStrides, int *piOffsets,
void *pvLoaderPrivate)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPCreateImageFromFDs(psPVRScreen->psDRISUPScreen,
iWidth, iHeight, iFourCC, piFDs, iNumFDs,
piStrides, piOffsets, pvLoaderPrivate);
}
static __DRIimage *
PVRDRICreateImageFromDmaBufs(__DRIscreen *psDRIScreen,
int iWidth, int iHeight, int iFourCC,
int *piFDs, int iNumFDs,
int *piStrides, int *piOffsets,
enum __DRIYUVColorSpace eColorSpace,
enum __DRISampleRange eSampleRange,
enum __DRIChromaSiting eHorizSiting,
enum __DRIChromaSiting eVertSiting,
unsigned int *puError, void *pvLoaderPrivate)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPCreateImageFromDmaBufs(psPVRScreen->psDRISUPScreen,
iWidth, iHeight, iFourCC,
piFDs, iNumFDs, piStrides, piOffsets,
(unsigned int) eColorSpace,
(unsigned int) eSampleRange,
(unsigned int) eHorizSiting,
(unsigned int) eVertSiting,
puError, pvLoaderPrivate);
}
static void
PVRDRIBlitImage(__DRIcontext *psDRIContext,
__DRIimage *psDst, __DRIimage *psSrc,
int iDstX0, int iDstY0, int iDstWidth, int iDstHeight,
int iSrcX0, int iSrcY0, int iSrcWidth, int iSrcHeight,
int iFlushFlag)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
return DRISUPBlitImage(psPVRContext->psDRISUPContext,
psDst, psSrc,
iDstX0, iDstY0, iDstWidth, iDstHeight,
iSrcX0, iSrcY0, iSrcWidth, iSrcHeight,
iFlushFlag);
}
static int
PVRDRIGetCapabilities(__DRIscreen *psDRIScreen)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPGetImageCapabilities(psPVRScreen->psDRISUPScreen);
}
static void *
PVRDRIMapImage(__DRIcontext *psDRIContext, __DRIimage *psImage,
int iX0, int iY0, int iWidth, int iHeight,
unsigned int iFlags, int *piStride, void **ppvData)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
return DRISUPMapImage(psPVRContext->psDRISUPContext, psImage,
iX0, iY0, iWidth, iHeight, iFlags, piStride,
ppvData);
}
static void
PVRDRIUnmapImage(__DRIcontext *psDRIContext, __DRIimage *psImage,
void *pvData)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
return DRISUPUnmapImage(psPVRContext->psDRISUPContext, psImage, pvData);
}
static __DRIimage *
PVRDRICreateImageWithModifiers(__DRIscreen *psDRIScreen,
int iWidth, int iHeight, int iFormat,
const uint64_t *puModifiers,
const unsigned int uModifierCount,
void *pvLoaderPrivate)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
int iFourCC = PVRDRIFormatToFourCC(iFormat);
return DRISUPCreateImageWithModifiers(psPVRScreen->psDRISUPScreen,
iWidth, iHeight, iFourCC,
puModifiers, uModifierCount,
pvLoaderPrivate);
}
static __DRIimage *
PVRDRICreateImageFromDmaBufs2(__DRIscreen *psDRIScreen,
int iWidth, int iHeight,
int iFourCC, uint64_t uModifier,
int *piFDs, int iNumFDs,
int *piStrides, int *piOffsets,
enum __DRIYUVColorSpace eColorSpace,
enum __DRISampleRange eSampleRange,
enum __DRIChromaSiting eHorizSiting,
enum __DRIChromaSiting eVertSiting,
unsigned int *puError, void *pvLoaderPrivate)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPCreateImageFromDMABufs2(psPVRScreen->psDRISUPScreen,
iWidth, iHeight, iFourCC, uModifier,
piFDs, iNumFDs, piStrides, piOffsets,
(unsigned int) eColorSpace,
(unsigned int) eSampleRange,
(unsigned int) eHorizSiting,
(unsigned int) eVertSiting,
puError, pvLoaderPrivate);
}
static GLboolean
PVRDRIQueryDmaBufFormats(__DRIscreen *psDRIScreen, int iMax,
int *piFormats, int *piCount)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPQueryDMABufFormats(psPVRScreen->psDRISUPScreen, iMax,
piFormats, piCount);
}
static GLboolean
PVRDRIQueryDmaBufModifiers(__DRIscreen *psDRIScreen, int iFourCC, int iMax,
uint64_t *puModifiers,
unsigned int *puExternalOnly, int *piCount)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPQueryDMABufModifiers(psPVRScreen->psDRISUPScreen, iFourCC,
iMax,
puModifiers, puExternalOnly, piCount);
}
static GLboolean
PVRDRIQueryDmaBufFormatModifierAttribs(__DRIscreen *psDRIScreen,
uint32_t uFourCC, uint64_t uModifier,
int iAttrib, uint64_t *puValue)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
struct DRISUPScreen *psDRISUPScreen = psPVRScreen->psDRISUPScreen;
return DRISUPQueryDMABufFormatModifierAttribs(psDRISUPScreen, uFourCC,
uModifier, iAttrib, puValue);
}
static __DRIimage *
PVRDRICreateImageFromRenderbuffer2(__DRIcontext *psDRIContext,
int iRenderBuffer, void *pvLoaderPrivate,
unsigned int *puError)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
struct DRISUPContext *psDRISUPContext = psPVRContext->psDRISUPContext;
return DRISUPCreateImageFromRenderBuffer2(psDRISUPContext, iRenderBuffer,
pvLoaderPrivate, puError);
}
static __DRIimage *
PVRDRICreateImageFromDmaBufs3(__DRIscreen *psDRIScreen,
int iWidth, int iHeight,
int iFourCC, uint64_t uModifier,
int *piFDs, int iNumFDs,
int *piStrides, int *piOffsets,
enum __DRIYUVColorSpace eColorSpace,
enum __DRISampleRange eSampleRange,
enum __DRIChromaSiting eHorizSiting,
enum __DRIChromaSiting eVertSiting,
uint32_t uFlags, unsigned int *puError,
void *pvLoaderPrivate)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPCreateImageFromDMABufs3(psPVRScreen->psDRISUPScreen,
iWidth, iHeight, iFourCC, uModifier,
piFDs, iNumFDs, piStrides, piOffsets,
(unsigned int) eColorSpace,
(unsigned int) eSampleRange,
(unsigned int) eHorizSiting,
(unsigned int) eVertSiting,
uFlags, puError, pvLoaderPrivate);
}
static __DRIimage *
PVRDRICreateImageWithModifiers2(__DRIscreen *psDRIScreen,
int iWidth, int iHeight, int iFormat,
const uint64_t *puModifiers,
const unsigned int uModifierCount,
unsigned int uUse,
void *pvLoaderPrivate)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
int iFourCC = PVRDRIFormatToFourCC(iFormat);
return DRISUPCreateImageWithModifiers2(psPVRScreen->psDRISUPScreen,
iWidth, iHeight, iFourCC,
puModifiers, uModifierCount,
uUse, pvLoaderPrivate);
}
static __DRIimage *
PVRDRICreateImageFromFds2(__DRIscreen *psDRIScreen, int iWidth, int iHeight,
int iFourCC, int *piFDs, int iNumFDs,
uint32_t uFlags, int *piStrides, int *piOffsets,
void *pvLoaderPrivate)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPCreateImageFromFDs2(psPVRScreen->psDRISUPScreen,
iWidth, iHeight, iFourCC, piFDs, iNumFDs,
uFlags, piStrides, piOffsets,
pvLoaderPrivate);
}
static void
PVRDRISetInFenceFd(__DRIimage *psImage, int iFd)
{
return DRISUPSetInFenceFd(psImage, iFd);
}
#if defined(EGL_IMG_cl_image)
static __DRIimage *
PVRDRICreateImageFromBuffer(__DRIcontext *psDRIContext, int iTarget,
void *pvBuffer, unsigned int *puError,
void *pvLoaderPrivate)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
return DRISUPCreateImageFromBuffer(psPVRContext->psDRISUPContext, iTarget,
pvBuffer, puError, pvLoaderPrivate);
}
#endif
static __DRIimageExtension pvrDRIImage = {
.base = {
.name = __DRI_IMAGE,
.version = PVR_DRI_IMAGE_VERSION,
},
.createImageFromName = PVRDRICreateImageFromName,
.createImageFromRenderbuffer = PVRDRICreateImageFromRenderbuffer,
.destroyImage = PVRDRIDestroyImage,
.createImage = PVRDRICreateImage,
.queryImage = PVRDRIQueryImage,
.dupImage = PVRDRIDupImage,
.validateUsage = PVRDRIValidateImageUsage,
.createImageFromNames = PVRDRICreateImageFromNames,
.fromPlanar = PVRDRIFromPlanar,
.createImageFromTexture = PVRDRICreateImageFromTexture,
.createImageFromFds = PVRDRICreateImageFromFds,
.createImageFromDmaBufs = PVRDRICreateImageFromDmaBufs,
.blitImage = PVRDRIBlitImage,
.getCapabilities = PVRDRIGetCapabilities,
.mapImage = PVRDRIMapImage,
.unmapImage = PVRDRIUnmapImage,
.createImageWithModifiers = PVRDRICreateImageWithModifiers,
.createImageFromDmaBufs2 = PVRDRICreateImageFromDmaBufs2,
.queryDmaBufFormats = PVRDRIQueryDmaBufFormats,
.queryDmaBufModifiers = PVRDRIQueryDmaBufModifiers,
.queryDmaBufFormatModifierAttribs =
PVRDRIQueryDmaBufFormatModifierAttribs,
.createImageFromRenderbuffer2 = PVRDRICreateImageFromRenderbuffer2,
.createImageFromDmaBufs3 = PVRDRICreateImageFromDmaBufs3,
.createImageWithModifiers2 = PVRDRICreateImageWithModifiers2,
.createImageFromFds2 = PVRDRICreateImageFromFds2,
.setInFenceFd = PVRDRISetInFenceFd,
#if defined(EGL_IMG_cl_image)
.createImageFromBuffer = PVRDRICreateImageFromBuffer,
#endif
};
static __DRIrobustnessExtension pvrDRIRobustness = {
.base = {
.name = __DRI2_ROBUSTNESS,
.version = PVR_DRI2_ROBUSTNESS_VERSION,
}
};
static int
PVRDRIQueryRendererInteger(__DRIscreen *psDRIScreen, int iAttribute,
unsigned int *puValue)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
int res;
res = DRISUPQueryRendererInteger(psPVRScreen->psDRISUPScreen,
iAttribute, puValue);
if (res == -1)
return driQueryRendererIntegerCommon(psDRIScreen, iAttribute, puValue);
return res;
}
static int
PVRDRIQueryRendererString(__DRIscreen *psDRIScreen, int iAttribute,
const char **ppszValue)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPQueryRendererString(psPVRScreen->psDRISUPScreen, iAttribute,
ppszValue);
}
static const __DRI2rendererQueryExtension pvrDRIRendererQueryExtension = {
.base = {
.name = __DRI2_RENDERER_QUERY,
.version = PVR_DRI2_RENDERER_QUERY_VERSION,
},
.queryInteger = PVRDRIQueryRendererInteger,
.queryString = PVRDRIQueryRendererString,
};
static void *
PVRDRICreateFenceEXT(__DRIcontext *psDRIContext)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
return DRISUPCreateFence(psPVRContext->psDRISUPContext);
}
static void
PVRDRIDestroyFenceEXT(__DRIscreen *psDRIScreen, void *pvFence)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPDestroyFence(psPVRScreen->psDRISUPScreen, pvFence);
}
static GLboolean
PVRDRIClientWaitSyncEXT(__DRIcontext *psDRIContext, void *pvFence,
unsigned int uFlags, uint64_t uTimeout)
{
struct DRISUPContext *psDRISUPContext;
if (psDRIContext) {
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
psDRISUPContext = psPVRContext->psDRISUPContext;
} else {
psDRISUPContext = NULL;
}
return DRISUPClientWaitSync(psDRISUPContext, pvFence, uFlags, uTimeout);
}
static void
PVRDRIServerWaitSyncEXT(__DRIcontext *psDRIContext, void *pvFence,
unsigned int uFlags)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
return DRISUPServerWaitSync(psPVRContext->psDRISUPContext, pvFence, uFlags);
}
static unsigned int
PVRDRIGetFenceCapabilitiesEXT(__DRIscreen *psDRIScreen)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPGetFenceCapabilities(psPVRScreen->psDRISUPScreen);
}
static void *
PVRDRICreateFenceFdEXT(__DRIcontext *psDRIContext, int iFD)
{
PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
return DRISUPCreateFenceFD(psPVRContext->psDRISUPContext, iFD);
}
static int
PVRDRIGetFenceFdEXT(__DRIscreen *psDRIScreen, void *pvFence)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPGetFenceFD(psPVRScreen->psDRISUPScreen, pvFence);
}
static void *
PVRDRIGetFenceFromClEventEXT(__DRIscreen *psDRIScreen, intptr_t iClEvent)
{
PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
return DRISUPGetFenceFromCLEvent(psPVRScreen->psDRISUPScreen, iClEvent);
}
__DRI2fenceExtension pvrDRIFenceExtension = {
.base = {
.name = __DRI2_FENCE,
.version = PVR_DRI2_FENCE_VERSION,
},
.create_fence = PVRDRICreateFenceEXT,
.get_fence_from_cl_event = PVRDRIGetFenceFromClEventEXT,
.destroy_fence = PVRDRIDestroyFenceEXT,
.client_wait_sync = PVRDRIClientWaitSyncEXT,
.server_wait_sync = PVRDRIServerWaitSyncEXT,
.get_capabilities = PVRDRIGetFenceCapabilitiesEXT,
.create_fence_fd = PVRDRICreateFenceFdEXT,
.get_fence_fd = PVRDRIGetFenceFdEXT,
};
static void
PVRDRISetDamageRegion(__DRIdrawable *psDRIDrawable,
unsigned int uNRects, int *piRects)
{
PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
DRISUPSetDamageRegion(psPVRDrawable->psDRISUPDrawable, uNRects, piRects);
}
const __DRI2bufferDamageExtension pvrDRIbufferDamageExtension = {
.base = {
.name = __DRI2_BUFFER_DAMAGE,
.version = PVR_DRI2_BUFFER_DAMAGE_VERSION,
},
.set_damage_region = PVRDRISetDamageRegion,
};
/*
* Extension lists
*
* NOTE: When adding a new screen extension asScreenExtensionVersionInfo
* should also be updated accordingly.
*/
static const __DRIextension *apsScreenExtensions[] = {
&pvrDRITexBufferExtension.base,
&pvrDRI2FlushExtension.base,
&pvrDRIImage.base,
&pvrDRIRobustness.base,
&pvrDRIRendererQueryExtension.base,
&pvrDRIFenceExtension.base,
&pvrDRIbufferDamageExtension.base,
&dri2ConfigQueryExtension.base,
NULL
};
static const __DRIextension asScreenExtensionVersionInfo[] = {
{.name = __DRI_TEX_BUFFER,.version = __DRI_TEX_BUFFER_VERSION},
{.name = __DRI2_FLUSH,.version = __DRI2_FLUSH_VERSION},
{.name = __DRI_IMAGE,.version = __DRI_IMAGE_VERSION},
{.name = __DRI2_ROBUSTNESS,.version = __DRI2_ROBUSTNESS_VERSION},
{.name = __DRI2_RENDERER_QUERY,.version = __DRI2_RENDERER_QUERY_VERSION},
{.name = __DRI2_FENCE,.version = __DRI2_FENCE_VERSION},
{.name = __DRI2_BUFFER_DAMAGE,.version = __DRI2_BUFFER_DAMAGE_VERSION},
{.name = __DRI2_CONFIG_QUERY,.version = __DRI2_CONFIG_QUERY_VERSION},
{.name = NULL,.version = 0},
};
const __DRIextension **
PVRDRIScreenExtensions(void)
{
return apsScreenExtensions;
}
const __DRIextension *
PVRDRIScreenExtensionVersionInfo(void)
{
return asScreenExtensionVersionInfo;
}
void
PVRDRIAdjustExtensions(unsigned int uVersion, unsigned int uMinVersion)
{
/* __DRI2fenceExtension adjustment */
switch (uVersion) {
default:
case 5:
case 4:
/* Is the KHR_cl_event2 EGL extension supported? */
if (!DRISUPHaveGetFenceFromCLEvent())
pvrDRIFenceExtension.get_fence_from_cl_event = NULL;
break;
case 3:
break;
case 2:
case 1:
case 0:
/* The KHR_cl_event2 EGL extension is not supported */
pvrDRIFenceExtension.get_fence_from_cl_event = NULL;
break;
}
/* __DRIimageExtension adjustment */
switch (uVersion) {
default:
case 5:
if (!DRISUPHaveSetInFenceFd())
pvrDRIImage.setInFenceFd = NULL;
break;
case 4:
case 3:
case 2:
case 1:
case 0:
/*
* The following are not supported:
* createImageFromDmaBufs3
* createImageWithModifiers2
* createImageFromFds2
* setInFenceFd
*/
pvrDRIImage.base.version = 17;
break;
}
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) Imagination Technologies Ltd.
*
* The contents of this file are subject to the MIT license as set out below.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#if !defined(__PVRMESA_H__)
#define __PVRMESA_H__
#include "pvrdri.h"
void pvrdri_free_dispatch_tables(PVRDRIScreen *psPVRScreen);
bool pvrdri_create_dispatch_table(PVRDRIScreen *psPVRScreen,
PVRDRIAPIType eAPI);
void pvrdri_set_null_dispatch_table(void);
void pvrdri_set_dispatch_table(PVRDRIContext *psPVRContext);
#endif /* !defined(__PVRMESA_H__) */

View file

@ -0,0 +1,272 @@
/*
* Copyright (c) Imagination Technologies Ltd.
*
* The contents of this file are subject to the MIT license as set out below.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "drm-uapi/drm_fourcc.h"
#include "dri_util.h"
#include "pvrdri.h"
#define MESSAGE_LENGTH_MAX 1024
/*
* Define before including android/log.h and dlog.h as this is used by these
* headers.
*/
#define LOG_TAG "PVR-MESA"
#if defined(HAVE_ANDROID_PLATFORM)
#include <android/log.h>
#define err_printf(f, args...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, f, ##args))
#define dbg_printf(f, args...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, f, ##args))
#else
#define err_printf(f, args...) fprintf(stderr, f "\n", ##args)
#define dbg_printf(f, args...) fprintf(stderr, "LibGL: " f "\n", ##args)
#endif /* HAVE_ANDROID_PLATFORM */
/* Standard error message */
void PRINTFLIKE(1, 2)
errorMessage(const char *f, ...)
{
char message[MESSAGE_LENGTH_MAX];
va_list args;
va_start(args, f);
vsnprintf(message, sizeof message, f, args);
va_end(args);
err_printf("%s", message);
}
void PRINTFLIKE(1, 2)
__driUtilMessage(const char *f, ...)
{
char message[MESSAGE_LENGTH_MAX];
va_list args;
/*
* On Android, always print messages; otherwise, only print if
* the environment variable LIBGL_DEBUG=verbose.
*/
#if !defined(HAVE_ANDROID_PLATFORM)
char *ev = getenv("LIBGL_DEBUG");
if (!ev || strcmp(ev, "verbose") != 0)
return;
#endif
va_start(args, f);
vsnprintf(message, sizeof message, f, args);
va_end(args);
dbg_printf("%s", message);
}
mesa_format
PVRDRIMesaFormatToMesaFormat(int pvrdri_mesa_format)
{
switch (pvrdri_mesa_format) {
case PVRDRI_MESA_FORMAT_NONE:
return MESA_FORMAT_NONE;
case PVRDRI_MESA_FORMAT_B8G8R8A8_UNORM:
return MESA_FORMAT_B8G8R8A8_UNORM;
case PVRDRI_MESA_FORMAT_B8G8R8X8_UNORM:
return MESA_FORMAT_B8G8R8X8_UNORM;
case PVRDRI_MESA_FORMAT_B5G6R5_UNORM:
return MESA_FORMAT_B5G6R5_UNORM;
case PVRDRI_MESA_FORMAT_R8G8B8A8_UNORM:
return MESA_FORMAT_R8G8B8A8_UNORM;
case PVRDRI_MESA_FORMAT_R8G8B8X8_UNORM:
return MESA_FORMAT_R8G8B8X8_UNORM;
case PVRDRI_MESA_FORMAT_YCBCR:
return MESA_FORMAT_YCBCR;
case PVRDRI_MESA_FORMAT_YUV420_2PLANE:
return MESA_FORMAT_YUV420_2PLANE;
case PVRDRI_MESA_FORMAT_YVU420_2PLANE:
return MESA_FORMAT_YVU420_2PLANE;
case PVRDRI_MESA_FORMAT_B8G8R8A8_SRGB:
return MESA_FORMAT_B8G8R8A8_SRGB;
case PVRDRI_MESA_FORMAT_R8G8B8A8_SRGB:
return MESA_FORMAT_R8G8B8A8_SRGB;
case PVRDRI_MESA_FORMAT_YUV420_3PLANE:
return MESA_FORMAT_YUV420_3PLANE;
case PVRDRI_MESA_FORMAT_YVU420_3PLANE:
return MESA_FORMAT_YVU420_3PLANE;
case PVRDRI_MESA_FORMAT_YCBCR_REV:
return MESA_FORMAT_YCBCR_REV;
case PVRDRI_MESA_FORMAT_YVYU:
return MESA_FORMAT_YVYU;
case PVRDRI_MESA_FORMAT_VYUY:
return MESA_FORMAT_VYUY;
default:
__driUtilMessage("%s: Unknown format: %d", __func__, pvrdri_mesa_format);
break;
}
return MESA_FORMAT_NONE;
}
int
PVRDRIFormatToFourCC(int dri_format)
{
switch (dri_format) {
case __DRI_IMAGE_FORMAT_RGB565:
return DRM_FORMAT_RGB565;
case __DRI_IMAGE_FORMAT_XRGB8888:
return DRM_FORMAT_XRGB8888;
case __DRI_IMAGE_FORMAT_ARGB8888:
return DRM_FORMAT_ARGB8888;
case __DRI_IMAGE_FORMAT_ABGR8888:
return DRM_FORMAT_ABGR8888;
case __DRI_IMAGE_FORMAT_XBGR8888:
return DRM_FORMAT_XBGR8888;
case __DRI_IMAGE_FORMAT_R8:
return DRM_FORMAT_R8;
case __DRI_IMAGE_FORMAT_GR88:
return DRM_FORMAT_GR88;
case __DRI_IMAGE_FORMAT_NONE:
return 0;
case __DRI_IMAGE_FORMAT_XRGB2101010:
return DRM_FORMAT_XRGB2101010;
case __DRI_IMAGE_FORMAT_ARGB2101010:
return DRM_FORMAT_ARGB2101010;
case __DRI_IMAGE_FORMAT_SARGB8:
return __DRI_IMAGE_FOURCC_SARGB8888;
case __DRI_IMAGE_FORMAT_ARGB1555:
return DRM_FORMAT_ARGB1555;
case __DRI_IMAGE_FORMAT_R16:
return DRM_FORMAT_R16;
case __DRI_IMAGE_FORMAT_GR1616:
return DRM_FORMAT_GR1616;
case __DRI_IMAGE_FORMAT_YUYV:
return DRM_FORMAT_YUYV;
case __DRI_IMAGE_FORMAT_XBGR2101010:
return DRM_FORMAT_XBGR2101010;
case __DRI_IMAGE_FORMAT_ABGR2101010:
return DRM_FORMAT_ABGR2101010;
case __DRI_IMAGE_FORMAT_SABGR8:
return __DRI_IMAGE_FOURCC_SABGR8888;
case __DRI_IMAGE_FORMAT_UYVY:
return DRM_FORMAT_UYVY;
case __DRI_IMAGE_FORMAT_ARGB4444:
return DRM_FORMAT_ARGB4444;
case __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG:
return DRM_FORMAT_YVU444_PACK10_IMG;
case __DRI_IMAGE_FORMAT_BGR888:
return DRM_FORMAT_BGR888;
case __DRI_IMAGE_FORMAT_AXBXGXRX106106106106:
return DRM_FORMAT_AXBXGXRX106106106106;
case __DRI_IMAGE_FORMAT_NV12:
return DRM_FORMAT_NV12;
case __DRI_IMAGE_FORMAT_NV21:
return DRM_FORMAT_NV21;
case __DRI_IMAGE_FORMAT_YU12:
return DRM_FORMAT_YUV420;
case __DRI_IMAGE_FORMAT_YV12:
return DRM_FORMAT_YVU420;
case __DRI_IMAGE_FORMAT_YVYU:
return DRM_FORMAT_YVYU;
case __DRI_IMAGE_FORMAT_VYUY:
return DRM_FORMAT_VYUY;
default:
__driUtilMessage("%s: Unknown format: %d", __func__, dri_format);
break;
}
return 0;
}
int
PVRDRIFourCCToDRIFormat(int iFourCC)
{
switch (iFourCC) {
case 0:
return __DRI_IMAGE_FORMAT_NONE;
case DRM_FORMAT_RGB565:
return __DRI_IMAGE_FORMAT_RGB565;
case DRM_FORMAT_XRGB8888:
return __DRI_IMAGE_FORMAT_XRGB8888;
case DRM_FORMAT_ARGB8888:
return __DRI_IMAGE_FORMAT_ARGB8888;
case DRM_FORMAT_ABGR8888:
return __DRI_IMAGE_FORMAT_ABGR8888;
case DRM_FORMAT_XBGR8888:
return __DRI_IMAGE_FORMAT_XBGR8888;
case DRM_FORMAT_R8:
return __DRI_IMAGE_FORMAT_R8;
case DRM_FORMAT_GR88:
return __DRI_IMAGE_FORMAT_GR88;
case DRM_FORMAT_XRGB2101010:
return __DRI_IMAGE_FORMAT_XRGB2101010;
case DRM_FORMAT_ARGB2101010:
return __DRI_IMAGE_FORMAT_ARGB2101010;
case __DRI_IMAGE_FOURCC_SARGB8888:
return __DRI_IMAGE_FORMAT_SARGB8;
case DRM_FORMAT_ARGB1555:
return __DRI_IMAGE_FORMAT_ARGB1555;
case DRM_FORMAT_R16:
return __DRI_IMAGE_FORMAT_R16;
case DRM_FORMAT_GR1616:
return __DRI_IMAGE_FORMAT_GR1616;
case DRM_FORMAT_YUYV:
return __DRI_IMAGE_FORMAT_YUYV;
case DRM_FORMAT_XBGR2101010:
return __DRI_IMAGE_FORMAT_XBGR2101010;
case DRM_FORMAT_ABGR2101010:
return __DRI_IMAGE_FORMAT_ABGR2101010;
case __DRI_IMAGE_FOURCC_SABGR8888:
return __DRI_IMAGE_FORMAT_SABGR8;
case DRM_FORMAT_UYVY:
return __DRI_IMAGE_FORMAT_UYVY;
case DRM_FORMAT_ARGB4444:
return __DRI_IMAGE_FORMAT_ARGB4444;
case DRM_FORMAT_YVU444_PACK10_IMG:
return __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG;
case DRM_FORMAT_BGR888:
return __DRI_IMAGE_FORMAT_BGR888;
case DRM_FORMAT_AXBXGXRX106106106106:
return __DRI_IMAGE_FORMAT_AXBXGXRX106106106106;
case DRM_FORMAT_NV12:
return __DRI_IMAGE_FORMAT_NV12;
case DRM_FORMAT_NV21:
return __DRI_IMAGE_FORMAT_NV21;
case DRM_FORMAT_YUV420:
return __DRI_IMAGE_FORMAT_YU12;
case DRM_FORMAT_YVU420:
return __DRI_IMAGE_FORMAT_YV12;
case DRM_FORMAT_YVYU:
return __DRI_IMAGE_FORMAT_YVYU;
case DRM_FORMAT_VYUY:
return __DRI_IMAGE_FORMAT_VYUY;
default:
__driUtilMessage("%s: Unknown format: %d", __func__, iFourCC);
break;
}
return 0;
}

View file

@ -189,6 +189,8 @@ enum pipe_format {
PIPE_FORMAT_L16_UNORM, /**< ushort luminance */
PIPE_FORMAT_UYVY,
PIPE_FORMAT_YUYV,
PIPE_FORMAT_YVYU,
PIPE_FORMAT_VYUY,
PIPE_FORMAT_Z16_UNORM,
PIPE_FORMAT_Z16_UNORM_S8_UINT,
PIPE_FORMAT_Z32_UNORM,
@ -627,6 +629,8 @@ pipe_format_to_chroma_format(enum pipe_format format)
return PIPE_VIDEO_CHROMA_FORMAT_420;
case PIPE_FORMAT_UYVY:
case PIPE_FORMAT_YUYV:
case PIPE_FORMAT_VYUY:
case PIPE_FORMAT_YVYU:
case PIPE_FORMAT_YV16:
case PIPE_FORMAT_Y8_U8_V8_422_UNORM:
case PIPE_FORMAT_Y8_U8V8_422_UNORM:

View file

@ -151,6 +151,16 @@ if with_gallium_svga
else
driver_svga = declare_dependency()
endif
if with_gallium_pvr
subdir('drivers/pvr')
else
driver_pvr = declare_dependency()
endif
if with_gallium_pvr_alias
subdir('drivers/pvr_alias')
else
driver_pvr_alias = declare_dependency()
endif
if with_gallium_virgl
subdir('winsys/virgl/common')
subdir('winsys/virgl/drm')
@ -187,6 +197,11 @@ if with_gallium_rusticl
subdir('frontends/rusticl')
subdir('targets/rusticl')
endif
if with_gallium_pvr
subdir('frontends/pvr')
else
libpvr = []
endif
if with_dri
subdir('frontends/dri')
subdir('targets/dri')

View file

@ -50,7 +50,7 @@ libgallium_dri = shared_library(
link_with : [
libdri, libmesa, libgalliumvl,
libgallium, libglapi, libpipe_loader_static, libws_null, libwsw, libswdri,
libswkmsdri,
libswkmsdri, libpvr,
],
dependencies : [
dep_selinux, dep_libdrm, dep_llvm, dep_thread, idep_xmlconfig, idep_mesautil,
@ -58,7 +58,7 @@ libgallium_dri = shared_library(
driver_kmsro, driver_v3d, driver_vc4, driver_freedreno, driver_etnaviv,
driver_tegra, driver_i915, driver_svga, driver_virgl,
driver_panfrost, driver_iris, driver_lima, driver_zink, driver_d3d12,
driver_asahi, driver_crocus
driver_asahi, driver_crocus, driver_pvr, driver_pvr_alias
],
# Will be deleted during installation, see install_megadrivers.py
install : true,
@ -115,7 +115,9 @@ foreach d : [[with_gallium_kmsro, [
[with_gallium_lima, 'lima_dri.so'],
[with_gallium_zink, 'zink_dri.so'],
[with_gallium_d3d12, 'd3d12_dri.so'],
[with_gallium_asahi, 'asahi_dri.so']]
[with_gallium_asahi, 'asahi_dri.so'],
[with_gallium_pvr, 'pvr_dri.so'],
[with_gallium_pvr_alias, gallium_pvr_alias + '_dri.so']]
if d[0]
gallium_dri_drivers += d[1]
endif

View file

@ -10,6 +10,16 @@ PUBLIC const __DRIextension **__driDriverGetExtensions_##drivername(void) \
return galliumdrm_driver_extensions; \
}
#define DEFINE_LOADER_PVR_ENTRYPOINT(drivername) \
const __DRIextension **__driDriverGetExtensions_##drivername(void); \
PUBLIC const __DRIextension **__driDriverGetExtensions_##drivername(void) \
{ \
return pvr_driver_extensions; \
}
#define DEFINE_LOADER_PVR_ALIAS_ENTRYPOINT(drivername) \
DEFINE_LOADER_PVR_ENTRYPOINT(drivername)
#if defined(GALLIUM_SOFTPIPE)
const __DRIextension **__driDriverGetExtensions_swrast(void);
@ -144,3 +154,11 @@ PUBLIC const __DRIextension **__driDriverGetExtensions_zink(void)
#if defined(GALLIUM_D3D12)
DEFINE_LOADER_DRM_ENTRYPOINT(d3d12);
#endif
#if defined(GALLIUM_PVR)
DEFINE_LOADER_PVR_ENTRYPOINT(pvr);
#endif
#if defined(GALLIUM_PVR_ALIAS)
DEFINE_LOADER_PVR_ALIAS_ENTRYPOINT(GALLIUM_PVR_ALIAS);
#endif

View file

@ -52,6 +52,7 @@
#include "loader.h"
#include "util/u_debug.h"
#include "util/macros.h"
#include "util/os_file.h"
/* For importing wl_buffer */
#if HAVE_WAYLAND_PLATFORM
@ -164,6 +165,14 @@ image_get_buffers(__DRIdrawable *driDrawable,
surf->dri_private, buffer_mask, buffers);
}
static int
dri_get_display_fd(void *loaderPrivate)
{
struct gbm_dri_device *dri = loaderPrivate;
return dri->base.v0.fd;
}
static void
swrast_get_drawable_info(__DRIdrawable *driDrawable,
int *x,
@ -245,20 +254,22 @@ static const __DRIimageLookupExtension image_lookup_extension = {
};
static const __DRIdri2LoaderExtension dri2_loader_extension = {
.base = { __DRI_DRI2_LOADER, 4 },
.base = { __DRI_DRI2_LOADER, 6 },
.getBuffers = dri_get_buffers,
.flushFrontBuffer = dri_flush_front_buffer,
.getBuffersWithFormat = dri_get_buffers_with_format,
.getCapability = dri_get_capability,
.getDisplayFD = dri_get_display_fd,
};
static const __DRIimageLoaderExtension image_loader_extension = {
.base = { __DRI_IMAGE_LOADER, 2 },
.base = { __DRI_IMAGE_LOADER, 5 },
.getBuffers = image_get_buffers,
.flushFrontBuffer = dri_flush_front_buffer,
.getCapability = dri_get_capability,
.getDisplayFD = dri_get_display_fd,
};
static const __DRIswrastLoaderExtension swrast_loader_extension = {
@ -431,12 +442,12 @@ dri_screen_create_dri2(struct gbm_dri_device *dri, char *driver_name)
return -1;
if (dri->dri2->base.version >= 4) {
dri->screen = dri->dri2->createNewScreen2(0, dri->base.v0.fd,
dri->screen = dri->dri2->createNewScreen2(0, dri->fd,
dri->loader_extensions,
dri->driver_extensions,
&dri->driver_configs, dri);
} else {
dri->screen = dri->dri2->createNewScreen(0, dri->base.v0.fd,
dri->screen = dri->dri2->createNewScreen(0, dri->fd,
dri->loader_extensions,
&dri->driver_configs, dri);
}
@ -503,8 +514,20 @@ static int
dri_screen_create(struct gbm_dri_device *dri)
{
char *driver_name;
int dup_fd, new_fd;
bool is_different_gpu;
driver_name = loader_get_driver_for_fd(dri->base.v0.fd);
dup_fd = os_dupfd_cloexec(dri->fd);
if (dup_fd < 0)
return -1;
new_fd = loader_get_user_preferred_fd(dup_fd, &is_different_gpu);
if (new_fd == dup_fd)
close(new_fd);
else
dri->fd = new_fd;
driver_name = loader_get_driver_for_fd(dri->fd);
if (!driver_name)
return -1;
@ -564,11 +587,21 @@ static const struct gbm_dri_visual gbm_dri_visuals_table[] = {
{ 10, 5, 0, 11 },
{ 5, 5, 5, 1 },
},
{
GBM_FORMAT_ARGB4444, __DRI_IMAGE_FORMAT_ARGB4444,
{ 8, 4, 0, 12 },
{ 4, 4, 4, 4 },
},
{
GBM_FORMAT_RGB565, __DRI_IMAGE_FORMAT_RGB565,
{ 11, 5, 0, -1 },
{ 5, 6, 5, 0 },
},
{
GBM_FORMAT_BGR888, __DRI_IMAGE_FORMAT_BGR888,
{ 0, 8, 16, -1 },
{ 8, 8, 8, 0 },
},
{
GBM_FORMAT_XRGB8888, __DRI_IMAGE_FORMAT_XRGB8888,
{ 16, 8, 0, -1 },
@ -619,6 +652,11 @@ static const struct gbm_dri_visual gbm_dri_visuals_table[] = {
{ 0, 16, 32, 48 },
{ 16, 16, 16, 16 },
},
{
GBM_FORMAT_AXBXGXRX106106106106, __DRI_IMAGE_FORMAT_AXBXGXRX106106106106,
{ 6, 22, 38, 54 },
{ 10, 10, 10, 10 },
},
{
GBM_FORMAT_XBGR16161616F, __DRI_IMAGE_FORMAT_XBGR16161616F,
{ 0, 16, 32, -1 },
@ -631,6 +669,12 @@ static const struct gbm_dri_visual gbm_dri_visuals_table[] = {
{ 16, 16, 16, 16 },
true,
},
{
GBM_FORMAT_YUYV, __DRI_IMAGE_FORMAT_YUYV,
},
{
GBM_FORMAT_YVU444_PACK10_IMG, __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG,
},
};
static int
@ -1302,8 +1346,11 @@ gbm_dri_bo_map(struct gbm_bo *_bo,
if (!dri->context)
dri->context = dri->dri2->createNewContext(dri->screen, NULL,
NULL, NULL);
assert(dri->context);
mtx_unlock(&dri->mutex);
if (!dri->context) {
errno = ENOSYS;
return NULL;
}
/* GBM flags and DRI flags are the same, so just pass them on */
return dri->image->mapImage(dri->context, bo->image, x, y,
@ -1412,6 +1459,40 @@ gbm_dri_surface_destroy(struct gbm_surface *_surf)
free(surf);
}
static int
gbm_dri_bo_blit(struct gbm_bo *_dst_bo, struct gbm_bo *_src_bo,
int dst_x0, int dst_y0, int dst_width, int dst_height,
int src_x0, int src_y0, int src_width, int src_height,
enum gbm_blit_flags flags)
{
struct gbm_dri_device *dri = gbm_dri_device(_dst_bo->gbm);
struct gbm_dri_bo *dst_bo = gbm_dri_bo(_dst_bo);
struct gbm_dri_bo *src_bo = gbm_dri_bo(_src_bo);
if (!dri->image || dri->image->base.version < 9 || !dri->image->blitImage) {
errno = ENOSYS;
return 0;
}
mtx_lock(&dri->mutex);
if (!dri->context)
dri->context = dri->dri2->createNewContext(dri->screen, NULL,
NULL, NULL);
mtx_unlock(&dri->mutex);
if (!dri->context) {
errno = ENOSYS;
return 0;
}
/* GBM flags and DRI flags are the same, so just pass them on */
dri->image->blitImage(dri->context, dst_bo->image, src_bo->image,
dst_x0, dst_y0, dst_width, dst_height,
src_x0, src_y0, src_width, src_height,
flags);
return 1;
}
static void
dri_destroy(struct gbm_device *gbm)
{
@ -1428,6 +1509,9 @@ dri_destroy(struct gbm_device *gbm)
dlclose(dri->driver);
free(dri->driver_name);
if (dri->fd >= 0 && dri->fd != dri->base.v0.fd)
close (dri->fd);
free(dri);
}
@ -1449,6 +1533,8 @@ dri_device_create(int fd, uint32_t gbm_backend_version)
if (!dri)
return NULL;
dri->fd = fd;
dri->base.v0.fd = fd;
dri->base.v0.backend_version = gbm_backend_version;
dri->base.v0.bo_create = gbm_dri_bo_create;
@ -1473,6 +1559,8 @@ dri_device_create(int fd, uint32_t gbm_backend_version)
dri->base.v0.name = "drm";
dri->base.v1.bo_blit = gbm_dri_bo_blit;
dri->visual_table = gbm_dri_visuals_table;
dri->num_visuals = ARRAY_SIZE(gbm_dri_visuals_table);

View file

@ -62,6 +62,8 @@ struct gbm_dri_visual {
struct gbm_dri_device {
struct gbm_device base;
int fd;
void *driver;
char *driver_name; /* Name of the DRI module, without the _dri suffix */
bool software; /* A software driver was loaded */
@ -195,4 +197,10 @@ gbm_dri_bo_unmap_dumb(struct gbm_dri_bo *bo)
bo->map = NULL;
}
static inline int
gbm_dri_device_get_fd(struct gbm_dri_device *dri)
{
return dri->fd;
}
#endif

View file

@ -277,6 +277,7 @@ gbm_bo_get_bpp(struct gbm_bo *bo)
case GBM_FORMAT_ABGR16161616:
case GBM_FORMAT_XBGR16161616F:
case GBM_FORMAT_ABGR16161616F:
case GBM_FORMAT_AXBXGXRX106106106106:
return 64;
}
}
@ -827,6 +828,37 @@ gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc)
return desc->name;
}
/**
* Blit from one buffer object to another
*
* \param dst_bo The destination buffer object
* \param src_bo The source buffer object
* \param dst_x0 The X coordinate (top left origin) of the destination rectangle
* \param dst_y0 The Y coordinate (top left origin) of the destination rectangle
* \param dst_width The width of the destination rectangle
* \param dst_height The height of the destination rectangle
* \param src_x0 The X coordinate (top left origin) of the source rectangle
* \param src_y0 The Y coordinate (top left origin) of the source rectangle
* \param src_width The width of the source rectangle
* \param src_height The height of the source rectangle
* \param flags The flags for the blit
* \return 1 on success, 0 otherwise
*/
GBM_EXPORT int
gbm_bo_blit(struct gbm_bo *dst_bo, struct gbm_bo *src_bo,
int dst_x0, int dst_y0, int dst_width, int dst_height,
int src_x0, int src_y0, int src_width, int src_height,
enum gbm_blit_flags flags)
{
if (dst_bo->gbm->v0.backend_version >= 1)
return dst_bo->gbm->v1.bo_blit(dst_bo, src_bo,
dst_x0, dst_y0, dst_width, dst_height,
src_x0, src_y0, src_width, src_height,
flags);
else
return 0;
}
/**
* A global table of functions and global variables defined in the core GBM
* code that need to be accessed directly by GBM backends.

View file

@ -171,6 +171,12 @@ enum gbm_bo_format {
#define GBM_FORMAT_ABGR16161616F __gbm_fourcc_code('A', 'B', '4', 'H') /* [63:0] A:B:G:R 16:16:16:16 little endian */
/*
* RGBA format with 10-bit components packed in 64-bit per pixel, with 6 bits
* of unused padding per component:
*/
#define GBM_FORMAT_AXBXGXRX106106106106 __gbm_fourcc_code('A', 'B', '1', '0') /* [63:0] A:x:B:x:G:x:R:x 10:6:10:6:10:6:10:6 little endian */
/* packed YCbCr */
#define GBM_FORMAT_YUYV __gbm_fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */
#define GBM_FORMAT_YVYU __gbm_fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */
@ -179,6 +185,8 @@ enum gbm_bo_format {
#define GBM_FORMAT_AYUV __gbm_fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
#define GBM_FORMAT_YVU444_PACK10_IMG __gbm_fourcc_code('I', 'M', 'G', '2') /* [31:0] unused:Y:Cr:Cb 2:10:10:10 little endian */
/*
* 2 plane YCbCr
* index 0 = Y plane, [7:0] Y
@ -266,6 +274,21 @@ enum gbm_bo_flags {
GBM_BO_USE_FRONT_RENDERING = (1 << 6),
};
/**
* Flags to control the behaviour of a blit - these are passed to
* gbm_bo_blit().
*/
enum gbm_blit_flags {
/**
* Force blit execution in finite time
*/
GBM_BLIT_FLAG_FLUSH = 0x0001,
/**
* Flush, and wait for the blit to complete
*/
GBM_BLIT_FLAG_FINISH = 0x0002
};
int
gbm_device_get_fd(struct gbm_device *gbm);
@ -462,6 +485,12 @@ gbm_surface_destroy(struct gbm_surface *surface);
char *
gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc);
int
gbm_bo_blit(struct gbm_bo *dst_bo, struct gbm_bo *src_bo,
int dst_x0, int dst_y0, int dst_width, int dst_height,
int src_x0, int src_y0, int src_width, int src_height,
enum gbm_blit_flags flags);
#ifdef __cplusplus
}
#endif

View file

@ -106,6 +106,21 @@ struct gbm_device_abi0 {
struct gbm_device_v0_abi0 v0;
};
#define GBM_BACKEND_ABI_VERSION_abi1 1
struct gbm_device_v1_abi1 {
int (*bo_blit)(struct gbm_bo *dst_bo, struct gbm_bo *src_bo,
int dst_x0, int dst_y0, int dst_width, int dst_height,
int src_x0, int src_y0, int src_width, int src_height,
enum gbm_blit_flags flags);
};
struct gbm_device_abi1 {
/* Hack to make a gbm_device detectable by its first element. */
struct gbm_device *(*dummy)(int);
struct gbm_device_v0_abi0 v0;
struct gbm_device_v1_abi1 v1;
};
/**
* GBM buffer object interface corresponding to GBM_BACKEND_ABI_VERSION = 0
*
@ -364,8 +379,11 @@ int main(int argc, char **argv)
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_has_free_buffers);
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_destroy);
CHECK_MEMBER_CURRENT(gbm_device_v1, _abi1, bo_blit);
/* Size of ABI-versioned substructures verified by above member checks */
CHECK_SIZE_CURRENT (gbm_device, _abi0);
CHECK_SIZE (gbm_device, _abi0, _abi1);
CHECK_SIZE_CURRENT (gbm_device, _abi1);
/* Check current gbm_bo ABI against gbm_bo_abi0*/

View file

@ -157,6 +157,13 @@ struct gbm_device_v0 {
void (*surface_destroy)(struct gbm_surface *surface);
};
struct gbm_device_v1 {
int (*bo_blit)(struct gbm_bo *dst_bo, struct gbm_bo *src_bo,
int dst_x0, int dst_y0, int dst_width, int dst_height,
int src_x0, int src_y0, int src_width, int src_height,
enum gbm_blit_flags flags);
};
/**
* The device used for the memory allocation.
*
@ -169,6 +176,7 @@ struct gbm_device {
/* Hack to make a gbm_device detectable by its first element. */
struct gbm_device *(*dummy)(int);
struct gbm_device_v0 v0;
struct gbm_device_v1 v1;
};
/**

Some files were not shown because too many files have changed in this diff Show more