From 3ba6ecc0509c0f034ea91d9cfe8eab6dfd2945cd Mon Sep 17 00:00:00 2001 From: James Deng Date: Fri, 1 Mar 2024 19:54:35 +0800 Subject: [PATCH] Update for v1.0alpha2 --- boot/opensbi/Config.in | 11 + boot/opensbi/opensbi.mk | 7 +- boot/uboot/Config.in | 7 + boot/uboot/uboot.mk | 5 +- fs/cpio/cpio.mk | 1 + fs/cpio/dracut.conf | 5 +- linux/Config.in | 17 +- linux/linux.mk | 5 +- package/busybox/0009-support-chinese.patch | 61 + .../0009-support-reboot-to-bootloader.patch | 90 + package/dracut/busybox-init-module-setup.sh | 3 +- package/dracut/dracut.mk | 2 + package/dracut/rescue-module-setup.sh | 19 + ...mpile-time-issue-on-very-old-kernels.patch | 44 - package/eudev/Config.in | 2 +- package/eudev/S10udev | 59 + package/eudev/eudev.hash | 4 +- package/eudev/eudev.mk | 15 +- .../ffmpeg/0005-support-spacemit-mpp.patch | 658 ++ package/ffmpeg/Config.in | 7 + package/ffmpeg/ffmpeg.mk | 6 + ...3-fix-compatibility-with-python-3.11.patch | 48 + package/glmark2/glmark2.mk | 3 - ...ync-add-support-for-pre-v4.7-kernels.patch | 92 + ...d-disable-nouveau-tests-for-static-b.patch | 43 - ...Add-sync_fence_info-and-sync_pt_info.patch | 212 + ...nc_file_info-and-sync_get_fence_info.patch | 148 + package/libdrm/libdrm.hash | 6 - package/libdrm/libdrm.mk | 54 +- .../0008-afalg-engine-support-aes-ecb.patch | 232 + package/libopenssl/libopenssl.mk | 1 - package/linux-tools/linux-tool-perf.mk.in | 2 +- package/lmbench/lmbench.mk | 9 +- ...e-err-when-sysroot-has-mount_setattr.patch | 12 + .../mesa3d/0001-Add-PVR-Gallium-driver.patch | 5425 +++++++++++++++++ ...t-proper-value-for-LIBCLC_INCLUDEDIR.patch | 41 - ...Add-some-new-DRI-formats-and-fourccs.patch | 81 + ...tion-to-disable-optional-neon-suppor.patch | 84 - ...3-GL_EXT_sparse_texture-entry-points.patch | 91 + ...r-Include-stddef.h-to-fix-build-erro.patch | 40 - ...-support-for-various-GLES-extensions.patch | 106 + package/mesa3d/0004-Fix-uClibc-build.patch | 70 - .../0005-Add-EGL_IMG_cl_image-extension.patch | 178 + ...MakeCurrent-for-the-case-where-nothi.patch | 48 + ...er_pixel_local_storage2-entry-points.patch | 84 + ..._framebuffer_downsample-entry-points.patch | 85 + .../0009-GL_OVR_multiview-entry-points.patch | 53 + ...iview_multisampled_render_to_texture.patch | 68 + ...all-wayland-drm.xml-to-the-configure.patch | 57 + ...fer-sharing-in-the-kms_swrast-driver.patch | 27 + ...-add-support-for-RGB565-back-buffers.patch | 46 + ...nd-post-maximum-damage-when-blitting.patch | 33 + ...d-flush-the-drawable-before-blitting.patch | 34 + ...supported-API-in-driCreateNewContext.patch | 54 + package/mesa3d/0017-gbm-add-gbm_bo_blit.patch | 215 + ...assert-if-DRI-context-creation-fails.patch | 44 + ...0019-egl-wayland-add-pbuffer-support.patch | 476 ++ ...l-eglBindAPI-workaround-for-dEQP-bug.patch | 29 + ...EXT_multi_draw_indirect-entry-points.patch | 56 + ...2-dri-add-support-for-YUV-DRI-config.patch | 541 ++ ...-egl-add-support-for-EXT_yuv_surface.patch | 541 ++ ...__DRI_IMAGE_COMPONENTS-define-for-EG.patch | 35 + ...yland-expose-EXT_yuv_surface-support.patch | 74 + .../0026-gbm-add-some-new-GBM-formats.patch | 134 + .../mesa3d/0027-egl-add-null-platform.patch | 1485 +++++ ...-support-for-EXT_image_gl_colorspace.patch | 205 + ...-meson-force-C-2011-for-thread_local.patch | 35 + ...port-for-swap-intervals-other-than-1.patch | 787 +++ ...d-support-for-explicit-synchronisati.patch | 215 + ...pport-for-DRM-image-format-modifiers.patch | 384 ++ ...ry-the-supported-ES2-context-version.patch | 171 + ...-allow-libGL-to-be-built-without-GLX.patch | 153 + ...-process-non-resized-window-movement.patch | 38 + ..._framebuffer_object-from-ARB-version.patch | 372 ++ ...port-for-async-flip-with-front-buffe.patch | 321 + .../mesa3d/0038-gbm-add-pbuffer-support.patch | 229 + ...-null-expose-EXT_yuv_surface-support.patch | 376 ++ ...serve-the-original-FD-for-driver-use.patch | 442 ++ ...near-buffer-is-not-needed-with-DRM-f.patch | 131 + ...ffer-is-not-needed-with-DRM-format-m.patch | 303 + ...-support-for-DRI_PRIME-GPU-selection.patch | 267 + ...-support-for-DRI_PRIME-GPU-selection.patch | 364 ++ ...-egl-null-introduce-NULL_DRM_DISPLAY.patch | 120 + ...-the-DRI3-and-Present-XCB-reply-poin.patch | 28 + ...an-wsi-make-the-display-FD-available.patch | 757 +++ ...r-wsi-add-PowerVR-Vulkan-WSI-library.patch | 3239 ++++++++++ ...i-Disable-use-of-VK_EXT_pci_bus_info.patch | 80 + ...ault-to-force_bgra8_unorm_first-true.patch | 34 + ...nable-additional-formats-for-Display.patch | 27 + ...lly-revert-pbuffer-attribute-removal.patch | 51 + ...ffer-config-attribs-to-0-for-non-pbu.patch | 66 + ...GL_ARB_geometry_shader4-entry-points.patch | 146 + ...and-add-EGL_BUFFER_PRESERVED-support.patch | 285 + .../0056-glapi-restore-exec-dynamic.patch | 28 + ...-meson-check-mtls-if-has_exe_wrapper.patch | 42 + ...d-PVR-WSI-library-to-destroy-surface.patch | 271 + ...wayland.swapchain.simulate_oom.min_i.patch | 45 + ...nd-allocate-memory-for-swapchain-mod.patch | 64 + ...riptor-mode-selection-infrastructure.patch | 108 + ...x-draw-vectorize-aaline-computations.patch | 37 + ...lium-draw-properly-fix-short-aalines.patch | 175 + ...w-do-not-use-trig-to-compute-tangent.patch | 38 + ...my-queries-for-ARB_pipeline_statisti.patch | 117 + ...mesa-do-not-require-optional-queries.patch | 127 + ...-docs-zink-update-query-requirements.patch | 62 + ...lper-to-create-passthrough-GS-shader.patch | 162 + ...r-workaround-for-missing-linestipple.patch | 97 + ...k-add-line-stippling-lowering-passes.patch | 255 + ...t-vars-with-nir_var_shader_temp-mode.patch | 53 + ...0072-zink-give-gs-its-own-shader-key.patch | 104 + ...process-non-optimal-key-passes-first.patch | 58 + ...-to-generate-any-vertex-shader-stage.patch | 237 + .../mesa3d/0075-zink-lower-line-stipple.patch | 288 + ...lain-about-missing-line-stipple-supp.patch | 37 + ...-dynarray-Add-an-append_array-helper.patch | 35 + ...0078-zink-do-not-lower-gs-intrinsics.patch | 66 + ...k-do-not-lower-gs-intrinscs-take-two.patch | 28 + ...0080-zink-add-gl_point-lowering-pass.patch | 135 + ...nk-rename-zink_set_line_stipple_keys.patch | 57 + ...workaround-for-missing-gl_point_size.patch | 171 + .../mesa3d/0083-zink-fix-rebase-mistake.patch | 29 + ...t-leave-needless-shader-temps-around.patch | 38 + ...ynamic-color-attachment-state-for-0-.patch | 49 + ...-fix-line-stipple-varying-allocation.patch | 41 + ...zink-add-line-smooth-lowering-passes.patch | 311 + ...-lower-smooth-lines-if-not-supported.patch | 215 + ...9-zink-fix-line-smooth-interpolation.patch | 82 + ...-PIPE_CAP_IMAGE_ATOMIC_FLOAT_ADD-if-.patch | 933 +++ ...-PIPE_CAP_SHADER_ATOMIC_INT64-if-we-.patch | 37 + ...-Fix-VK-driver-setup-for-HWCI_START_.patch | 48 + ...lain-that-MSAA-transfer_map-must-be-.patch | 34 + ...e-Drop-interleave-handling-from-the-.patch | 45 + ...r-Use-common-code-for-interleaved-un.patch | 78 + ...r-Merge-in-place-and-split-z-s-inter.patch | 286 + ...sfer_helper-resolve-MSAA-surfaces-wh.patch | 62 + ...rt-for-not-seeing-any-more-MSAA-imag.patch | 39 + ...earing-smooth-lines-after-workaround.patch | 33 + ...wapchain-render-update-fixups-into-s.patch | 107 + ...ential-corner-case-with-dynamic-rend.patch | 32 + ...namic-render-area-when-doing-swapcha.patch | 32 + ...-of-asserts-for-starting-dynamic-ren.patch | 46 + .../mesa3d/0104-zink-delete-dead-code.patch | 51 + ...odules_changed-in-optimal-path-if-a-.patch | 64 + ...ulation-stuff-behind-optimal_keys-ch.patch | 105 + ...nk-simplify-some-depth-texturing-spv.patch | 60 + ...ird-indentation-in-zink_set_sampler_.patch | 67 + ...shadow-tex-code-in-match_tex_dests_i.patch | 50 + ...ptimal-key-for-pipeline-library-hash.patch | 29 + ...-base-key-fix-optimal-fs-key-packing.patch | 258 + ...ink-add-a-condition-to-needs_write_s.patch | 29 + .../0113-zink-fix-the-stencil-write.patch | 38 + ...-nir_shader_instructions_pass-for-ni.patch | 142 + ...115-gallium-draw-assert-shader-stage.patch | 31 + ...draw-support-lowering-stipple-smooth.patch | 143 + .../0117-zink-lower-stipple-smooth.patch | 80 + ...zink-prune-old-swapchains-on-present.patch | 43 + .../mesa3d/0119-zink-whitespace-fixup.patch | 390 ++ ...epth_clip_control_missing-workaround.patch | 86 + ...til-function-for-creating-semaphores.patch | 54 + ...22-zink-add-a-binary-semaphore-cache.patch | 92 + ...ore-caching-to-zink_reset_batch_stat.patch | 87 + ...te-semaphore-creation-where-possible.patch | 105 + ...some-dynarray-concat-descriptor-code.patch | 38 + ...ass-checking-for-lod-overflow-in-txf.patch | 101 + .../mesa3d/0127-zink-add-zink_cs_key.patch | 78 + ...128-zink-add-VK_EXT_image_robustness.patch | 27 + ...dd-robust_access-field-to-shader-key.patch | 50 + ...nvalid-txf-when-imageRobustAccess2-i.patch | 187 + ...3-profile-to-allow-imageRobustAccess.patch | 96 + ...yle-shadow-tex-mask-for-fragment-sha.patch | 83 + ...ex-dest-rewriting-into-separate-func.patch | 150 + ...ra_data-param-to-zink_shader_compile.patch | 87 + ...-track-depth-swizzle-on-samplerviews.patch | 74 + ...ader-key-member-to-indicate-depth-te.patch | 153 + ...k-depth-sampler-splatting-in-shaders.patch | 149 + ...ine-fast-pathing-for-any-programs-us.patch | 33 + ...-program-module-parts-of-shadow-text.patch | 252 + ...ther-samplerview-for-shadow-textures.patch | 148 + ...-remove-old-depth-swizzle-workaround.patch | 48 + ...swizzle-data-block-to-shader-compile.patch | 201 + ...k-reorder-commands-more-aggressively.patch | 46 + ...nhamLines-requirement-for-non-strict.patch | 188 + ...-PIPE_CAP_SURFACE_REINTERPRET_BLOCKS.patch | 47 + ...0146-zink-ralloc-zink_shader-structs.patch | 45 + .../0147-zink-fix-compute-shader-leaks.patch | 37 + ...ogram-shader-caches-from-the-program.patch | 48 + ...ce-objects-views-array-during-destru.patch | 30 + ...zink-fix-indentation-of-rebind_image.patch | 76 + ...r-a-fb-rebind-if-fb-binds-exist-in-r.patch | 28 + ...-null-surface-when-trying-to-retain-.patch | 29 + ...ipe_surface-init-for-new-surface-cre.patch | 69 + .../0154-zink-const-ify-a-surface-param.patch | 26 + ...e-mutable-init-on-surface-creation-w.patch | 133 + ...ressed-format-layer-count-when-creat.patch | 38 + ...port-DRM-format-modifier-being-intre.patch | 28 + ...orrect-line-mode-check-for-bresenham.patch | 30 + ...disable-implicit_sync-for-IMG-driver.patch | 26 + ...mask-change-logic-when-binding-sampl.patch | 80 + ...shadow-swizzle-for-all-shader-stages.patch | 167 + .../0162-zink-minor-formatting-change.patch | 27 + ...d-needs_zs_shader_swizzle-shader-key.patch | 176 + ...adow-swizzle-pass-to-all-zs-textures.patch | 159 + ...tencil-needs-shader-swizzle-workarou.patch | 58 + ...undefined-swizzle-1-for-z-s-textures.patch | 132 + ...zink-rename-shadow-key-to-zs-swizzle.patch | 339 + ...atibility-to-old-style-DRI-interface.patch | 31 + package/mesa3d/Config.in | 8 + package/mesa3d/mesa3d.hash | 5 - package/mesa3d/mesa3d.mk | 16 +- package/python-sip/python-sip.mk | 4 +- package/qt5/qt5base/qt5base.mk | 4 + .../0002-add-WL_EGL_PLATFORM-define.patch | 13 + package/tinyalsa/tinyalsa.mk | 2 +- package/udev/udev.mk | 3 +- package/unrar/unrar.mk | 2 +- ...yland-scanner-is-not-always-required.patch | 44 + ...ble-bo-geometry-out-of-bounds-messag.patch | 29 + ...ncy-on-screenshooter-client-protocol.patch | 38 - ...e-to-find-libudev-when-linking-the-c.patch | 33 + ...-checks-for-dmabufs-with-DRM-modifie.patch | 63 + ...tests-test-client-depends-on-libudev.patch | 25 + ...w-linear-framebuffers-if-no-KMS-modi.patch | 53 + ...weston-set-default-compositor-to-gpu.patch | 27 + package/weston/run_weston.sh | 6 + package/weston/weston.hash | 4 - package/weston/weston.ini | 10 + package/weston/weston.mk | 14 +- ...ple-values-in-test-isn-t-supported-a.patch | 29 + toolchain/Config.in | 5 + toolchain/toolchain-external/Config.in | 6 + .../Config.in.options | 4 + .../toolchain-external-jdsk-riscv64/Config.in | 19 + .../Config.in.options | 9 + .../toolchain-external-jdsk-riscv64.hash | 2 + .../toolchain-external-jdsk-riscv64.mk | 16 + 235 files changed, 33436 insertions(+), 434 deletions(-) create mode 100644 package/busybox/0009-support-chinese.patch create mode 100644 package/busybox/0009-support-reboot-to-bootloader.patch create mode 100755 package/dracut/rescue-module-setup.sh delete mode 100644 package/eudev/0002-Fix-compile-time-issue-on-very-old-kernels.patch create mode 100644 package/ffmpeg/0005-support-spacemit-mpp.patch create mode 100644 package/glmark2/0003-fix-compatibility-with-python-3.11.patch create mode 100644 package/libdrm/0001-libsync-add-support-for-pre-v4.7-kernels.patch delete mode 100644 package/libdrm/0001-tests-meson.build-disable-nouveau-tests-for-static-b.patch create mode 100644 package/libdrm/0002-Add-sync_fence_info-and-sync_pt_info.patch create mode 100644 package/libdrm/0003-Add-sync_file_info-and-sync_get_fence_info.patch delete mode 100644 package/libdrm/libdrm.hash create mode 100644 package/libopenssl/0008-afalg-engine-support-aes-ecb.patch mode change 100644 => 100755 package/lmbench/lmbench.mk create mode 100644 package/ltp-testsuite/0002-fix-compile-err-when-sysroot-has-mount_setattr.patch create mode 100644 package/mesa3d/0001-Add-PVR-Gallium-driver.patch delete mode 100644 package/mesa3d/0001-meson-Set-proper-value-for-LIBCLC_INCLUDEDIR.patch create mode 100644 package/mesa3d/0002-dri-Add-some-new-DRI-formats-and-fourccs.patch delete mode 100644 package/mesa3d/0002-vc4-add-meson-option-to-disable-optional-neon-suppor.patch create mode 100644 package/mesa3d/0003-GL_EXT_sparse_texture-entry-points.patch delete mode 100644 package/mesa3d/0003-src-util-rand_xor-Include-stddef.h-to-fix-build-erro.patch create mode 100644 package/mesa3d/0004-Add-support-for-various-GLES-extensions.patch delete mode 100644 package/mesa3d/0004-Fix-uClibc-build.patch create mode 100644 package/mesa3d/0005-Add-EGL_IMG_cl_image-extension.patch create mode 100644 package/mesa3d/0006-egl-optimise-eglMakeCurrent-for-the-case-where-nothi.patch create mode 100644 package/mesa3d/0007-GL_EXT_shader_pixel_local_storage2-entry-points.patch create mode 100644 package/mesa3d/0008-GL_IMG_framebuffer_downsample-entry-points.patch create mode 100644 package/mesa3d/0009-GL_OVR_multiview-entry-points.patch create mode 100644 package/mesa3d/0010-Add-OVR_multiview_multisampled_render_to_texture.patch create mode 100644 package/mesa3d/0011-wayland-drm-install-wayland-drm.xml-to-the-configure.patch create mode 100644 package/mesa3d/0012-Enable-buffer-sharing-in-the-kms_swrast-driver.patch create mode 100644 package/mesa3d/0013-egl-wayland-add-support-for-RGB565-back-buffers.patch create mode 100644 package/mesa3d/0014-egl-wayland-post-maximum-damage-when-blitting.patch create mode 100644 package/mesa3d/0015-egl-wayland-flush-the-drawable-before-blitting.patch create mode 100644 package/mesa3d/0016-dri-use-a-supported-API-in-driCreateNewContext.patch create mode 100644 package/mesa3d/0017-gbm-add-gbm_bo_blit.patch create mode 100644 package/mesa3d/0018-gbm-don-t-assert-if-DRI-context-creation-fails.patch create mode 100644 package/mesa3d/0019-egl-wayland-add-pbuffer-support.patch create mode 100644 package/mesa3d/0020-egl-eglBindAPI-workaround-for-dEQP-bug.patch create mode 100644 package/mesa3d/0021-GL_EXT_multi_draw_indirect-entry-points.patch create mode 100644 package/mesa3d/0022-dri-add-support-for-YUV-DRI-config.patch create mode 100644 package/mesa3d/0023-egl-add-support-for-EXT_yuv_surface.patch create mode 100644 package/mesa3d/0024-dri-add-missing-__DRI_IMAGE_COMPONENTS-define-for-EG.patch create mode 100644 package/mesa3d/0025-egl-wayland-expose-EXT_yuv_surface-support.patch create mode 100644 package/mesa3d/0026-gbm-add-some-new-GBM-formats.patch create mode 100644 package/mesa3d/0027-egl-add-null-platform.patch create mode 100644 package/mesa3d/0028-egl-add-support-for-EXT_image_gl_colorspace.patch create mode 100644 package/mesa3d/0029-meson-force-C-2011-for-thread_local.patch create mode 100644 package/mesa3d/0030-dri2-add-support-for-swap-intervals-other-than-1.patch create mode 100644 package/mesa3d/0031-null_platform-add-support-for-explicit-synchronisati.patch create mode 100644 package/mesa3d/0032-egl-null-add-support-for-DRM-image-format-modifiers.patch create mode 100644 package/mesa3d/0033-egl-query-the-supported-ES2-context-version.patch create mode 100644 package/mesa3d/0034-meson-allow-libGL-to-be-built-without-GLX.patch create mode 100644 package/mesa3d/0035-egl-wayland-process-non-resized-window-movement.patch create mode 100644 package/mesa3d/0036-Separate-EXT_framebuffer_object-from-ARB-version.patch create mode 100644 package/mesa3d/0037-egl-null-add-support-for-async-flip-with-front-buffe.patch create mode 100644 package/mesa3d/0038-gbm-add-pbuffer-support.patch create mode 100644 package/mesa3d/0039-egl-null-expose-EXT_yuv_surface-support.patch create mode 100644 package/mesa3d/0040-dri-preserve-the-original-FD-for-driver-use.patch create mode 100644 package/mesa3d/0041-egl-wayland-a-linear-buffer-is-not-needed-with-DRM-f.patch create mode 100644 package/mesa3d/0042-dri3-a-linear-buffer-is-not-needed-with-DRM-format-m.patch create mode 100644 package/mesa3d/0043-egl-drm-add-support-for-DRI_PRIME-GPU-selection.patch create mode 100644 package/mesa3d/0044-egl-null-add-support-for-DRI_PRIME-GPU-selection.patch create mode 100644 package/mesa3d/0045-egl-null-introduce-NULL_DRM_DISPLAY.patch create mode 100644 package/mesa3d/0046-vulkan-wsi-check-the-DRI3-and-Present-XCB-reply-poin.patch create mode 100644 package/mesa3d/0047-vulkan-wsi-make-the-display-FD-available.patch create mode 100644 package/mesa3d/0048-pvr-wsi-add-PowerVR-Vulkan-WSI-library.patch create mode 100644 package/mesa3d/0049-vulkan-wsi-Disable-use-of-VK_EXT_pci_bus_info.patch create mode 100644 package/mesa3d/0050-vulkan-wsi-default-to-force_bgra8_unorm_first-true.patch create mode 100644 package/mesa3d/0051-vulkan-wsi-enable-additional-formats-for-Display.patch create mode 100644 package/mesa3d/0052-mesa-partially-revert-pbuffer-attribute-removal.patch create mode 100644 package/mesa3d/0053-egl_dri2-set-pbuffer-config-attribs-to-0-for-non-pbu.patch create mode 100644 package/mesa3d/0054-GL_ARB_geometry_shader4-entry-points.patch create mode 100644 package/mesa3d/0055-egl-wayland-add-EGL_BUFFER_PRESERVED-support.patch create mode 100644 package/mesa3d/0056-glapi-restore-exec-dynamic.patch create mode 100644 package/mesa3d/0057-Revert-meson-check-mtls-if-has_exe_wrapper.patch create mode 100644 package/mesa3d/0058-vulkan-wsi-extend-PVR-WSI-library-to-destroy-surface.patch create mode 100644 package/mesa3d/0059-vulkan-wsi-dEQP-wayland.swapchain.simulate_oom.min_i.patch create mode 100644 package/mesa3d/0060-vulkan-wsi-wayland-allocate-memory-for-swapchain-mod.patch create mode 100644 package/mesa3d/0061-zink-remove-descriptor-mode-selection-infrastructure.patch create mode 100644 package/mesa3d/0062-aux-draw-vectorize-aaline-computations.patch create mode 100644 package/mesa3d/0063-gallium-draw-properly-fix-short-aalines.patch create mode 100644 package/mesa3d/0064-gallium-draw-do-not-use-trig-to-compute-tangent.patch create mode 100644 package/mesa3d/0065-mesa-support-dummy-queries-for-ARB_pipeline_statisti.patch create mode 100644 package/mesa3d/0066-mesa-do-not-require-optional-queries.patch create mode 100644 package/mesa3d/0067-docs-zink-update-query-requirements.patch create mode 100644 package/mesa3d/0068-nir-Add-helper-to-create-passthrough-GS-shader.patch create mode 100644 package/mesa3d/0069-zink-setup-driver-workaround-for-missing-linestipple.patch create mode 100644 package/mesa3d/0070-zink-add-line-stippling-lowering-passes.patch create mode 100644 package/mesa3d/0071-zink-emit-vars-with-nir_var_shader_temp-mode.patch create mode 100644 package/mesa3d/0072-zink-give-gs-its-own-shader-key.patch create mode 100644 package/mesa3d/0073-zink-process-non-optimal-key-passes-first.patch create mode 100644 package/mesa3d/0074-zink-allow-to-generate-any-vertex-shader-stage.patch create mode 100644 package/mesa3d/0075-zink-lower-line-stipple.patch create mode 100644 package/mesa3d/0076-zink-do-not-complain-about-missing-line-stipple-supp.patch create mode 100644 package/mesa3d/0077-util-dynarray-Add-an-append_array-helper.patch create mode 100644 package/mesa3d/0078-zink-do-not-lower-gs-intrinsics.patch create mode 100644 package/mesa3d/0079-zink-do-not-lower-gs-intrinscs-take-two.patch create mode 100644 package/mesa3d/0080-zink-add-gl_point-lowering-pass.patch create mode 100644 package/mesa3d/0081-zink-rename-zink_set_line_stipple_keys.patch create mode 100644 package/mesa3d/0082-zink-add-driver-workaround-for-missing-gl_point_size.patch create mode 100644 package/mesa3d/0083-zink-fix-rebase-mistake.patch create mode 100644 package/mesa3d/0084-zink-do-not-leave-needless-shader-temps-around.patch create mode 100644 package/mesa3d/0085-zink-Don-t-set-dynamic-color-attachment-state-for-0-.patch create mode 100644 package/mesa3d/0086-zink-fix-line-stipple-varying-allocation.patch create mode 100644 package/mesa3d/0087-zink-add-line-smooth-lowering-passes.patch create mode 100644 package/mesa3d/0088-zink-lower-smooth-lines-if-not-supported.patch create mode 100644 package/mesa3d/0089-zink-fix-line-smooth-interpolation.patch create mode 100644 package/mesa3d/0090-zink-Only-expose-PIPE_CAP_IMAGE_ATOMIC_FLOAT_ADD-if-.patch create mode 100644 package/mesa3d/0091-zink-Only-expose-PIPE_CAP_SHADER_ATOMIC_INT64-if-we-.patch create mode 100644 package/mesa3d/0092-ci-Fix-VK-driver-setup-for-HWCI_START_.patch create mode 100644 package/mesa3d/0093-docs-gallium-Explain-that-MSAA-transfer_map-must-be-.patch create mode 100644 package/mesa3d/0094-u_transfer_helpre-Drop-interleave-handling-from-the-.patch create mode 100644 package/mesa3d/0095-u_transfer_helper-Use-common-code-for-interleaved-un.patch create mode 100644 package/mesa3d/0096-u_transfer_helper-Merge-in-place-and-split-z-s-inter.patch create mode 100644 package/mesa3d/0097-zink-Have-u_transfer_helper-resolve-MSAA-surfaces-wh.patch create mode 100644 package/mesa3d/0098-zink-Add-an-assert-for-not-seeing-any-more-MSAA-imag.patch create mode 100644 package/mesa3d/0099-zink-fix-disappearing-smooth-lines-after-workaround.patch create mode 100644 package/mesa3d/0100-zink-split-out-swapchain-render-update-fixups-into-s.patch create mode 100644 package/mesa3d/0101-zink-catch-a-potential-corner-case-with-dynamic-rend.patch create mode 100644 package/mesa3d/0102-zink-re-clamp-dynamic-render-area-when-doing-swapcha.patch create mode 100644 package/mesa3d/0103-zink-add-a-bunch-of-asserts-for-starting-dynamic-ren.patch create mode 100644 package/mesa3d/0104-zink-delete-dead-code.patch create mode 100644 package/mesa3d/0105-zink-only-flag-modules_changed-in-optimal-path-if-a-.patch create mode 100644 package/mesa3d/0106-zink-put-line-emulation-stuff-behind-optimal_keys-ch.patch create mode 100644 package/mesa3d/0107-zink-simplify-some-depth-texturing-spv.patch create mode 100644 package/mesa3d/0108-zink-fix-some-weird-indentation-in-zink_set_sampler_.patch create mode 100644 package/mesa3d/0109-zink-unify-some-shadow-tex-code-in-match_tex_dests_i.patch create mode 100644 package/mesa3d/0110-zink-use-optimal-key-for-pipeline-library-hash.patch create mode 100644 package/mesa3d/0111-zink-add-a-fs-base-key-fix-optimal-fs-key-packing.patch create mode 100644 package/mesa3d/0112-zink-add-a-condition-to-needs_write_s.patch create mode 100644 package/mesa3d/0113-zink-fix-the-stencil-write.patch create mode 100644 package/mesa3d/0114-gallium-draw-use-nir_shader_instructions_pass-for-ni.patch create mode 100644 package/mesa3d/0115-gallium-draw-assert-shader-stage.patch create mode 100644 package/mesa3d/0116-gallium-draw-support-lowering-stipple-smooth.patch create mode 100644 package/mesa3d/0117-zink-lower-stipple-smooth.patch create mode 100644 package/mesa3d/0118-zink-prune-old-swapchains-on-present.patch create mode 100644 package/mesa3d/0119-zink-whitespace-fixup.patch create mode 100644 package/mesa3d/0120-zink-remove-depth_clip_control_missing-workaround.patch create mode 100644 package/mesa3d/0121-zink-add-a-util-function-for-creating-semaphores.patch create mode 100644 package/mesa3d/0122-zink-add-a-binary-semaphore-cache.patch create mode 100644 package/mesa3d/0123-zink-move-semaphore-caching-to-zink_reset_batch_stat.patch create mode 100644 package/mesa3d/0124-zink-consolidate-semaphore-creation-where-possible.patch create mode 100644 package/mesa3d/0125-zink-simplify-some-dynarray-concat-descriptor-code.patch create mode 100644 package/mesa3d/0126-zink-add-pass-checking-for-lod-overflow-in-txf.patch create mode 100644 package/mesa3d/0127-zink-add-zink_cs_key.patch create mode 100644 package/mesa3d/0128-zink-add-VK_EXT_image_robustness.patch create mode 100644 package/mesa3d/0129-zink-add-robust_access-field-to-shader-key.patch create mode 100644 package/mesa3d/0130-zink-lower-LOD-invalid-txf-when-imageRobustAccess2-i.patch create mode 100644 package/mesa3d/0131-zink-update-gl43-profile-to-allow-imageRobustAccess.patch create mode 100644 package/mesa3d/0132-zink-flag-old-style-shadow-tex-mask-for-fragment-sha.patch create mode 100644 package/mesa3d/0133-zink-break-out-tex-dest-rewriting-into-separate-func.patch create mode 100644 package/mesa3d/0134-zink-add-an-extra_data-param-to-zink_shader_compile.patch create mode 100644 package/mesa3d/0135-zink-track-depth-swizzle-on-samplerviews.patch create mode 100644 package/mesa3d/0136-zink-add-a-fs-shader-key-member-to-indicate-depth-te.patch create mode 100644 package/mesa3d/0137-zink-rework-depth-sampler-splatting-in-shaders.patch create mode 100644 package/mesa3d/0138-zink-block-pipeline-fast-pathing-for-any-programs-us.patch create mode 100644 package/mesa3d/0139-zink-plug-in-the-program-module-parts-of-shadow-text.patch create mode 100644 package/mesa3d/0140-zink-create-another-samplerview-for-shadow-textures.patch create mode 100644 package/mesa3d/0141-zink-remove-old-depth-swizzle-workaround.patch create mode 100644 package/mesa3d/0142-zink-pass-depth-swizzle-data-block-to-shader-compile.patch create mode 100644 package/mesa3d/0143-zink-reorder-commands-more-aggressively.patch create mode 100644 package/mesa3d/0144-zink-relax-bresenhamLines-requirement-for-non-strict.patch create mode 100644 package/mesa3d/0145-zink-set-PIPE_CAP_SURFACE_REINTERPRET_BLOCKS.patch create mode 100644 package/mesa3d/0146-zink-ralloc-zink_shader-structs.patch create mode 100644 package/mesa3d/0147-zink-fix-compute-shader-leaks.patch create mode 100644 package/mesa3d/0148-zink-allocate-program-shader-caches-from-the-program.patch create mode 100644 package/mesa3d/0149-zink-free-resource-objects-views-array-during-destru.patch create mode 100644 package/mesa3d/0150-zink-fix-indentation-of-rebind_image.patch create mode 100644 package/mesa3d/0151-zink-only-try-for-a-fb-rebind-if-fb-binds-exist-in-r.patch create mode 100644 package/mesa3d/0152-zink-account-for-null-surface-when-trying-to-retain-.patch create mode 100644 package/mesa3d/0153-zink-break-out-pipe_surface-init-for-new-surface-cre.patch create mode 100644 package/mesa3d/0154-zink-const-ify-a-surface-param.patch create mode 100644 package/mesa3d/0155-zink-don-t-handle-mutable-init-on-surface-creation-w.patch create mode 100644 package/mesa3d/0156-zink-verify-compressed-format-layer-count-when-creat.patch create mode 100644 package/mesa3d/0157-Kopper-Fix-unsupport-DRM-format-modifier-being-intre.patch create mode 100644 package/mesa3d/0158-zink-fix-incorrect-line-mode-check-for-bresenham.patch create mode 100644 package/mesa3d/0159-zink-disable-implicit_sync-for-IMG-driver.patch create mode 100644 package/mesa3d/0160-zink-fix-shadow-mask-change-logic-when-binding-sampl.patch create mode 100644 package/mesa3d/0161-zink-track-shadow-swizzle-for-all-shader-stages.patch create mode 100644 package/mesa3d/0162-zink-minor-formatting-change.patch create mode 100644 package/mesa3d/0163-zink-add-needs_zs_shader_swizzle-shader-key.patch create mode 100644 package/mesa3d/0164-zink-extend-shadow-swizzle-pass-to-all-zs-textures.patch create mode 100644 package/mesa3d/0165-zink-add-depth-stencil-needs-shader-swizzle-workarou.patch create mode 100644 package/mesa3d/0166-zink-workaround-undefined-swizzle-1-for-z-s-textures.patch create mode 100644 package/mesa3d/0167-zink-rename-shadow-key-to-zs-swizzle.patch create mode 100644 package/mesa3d/0168-kopper-add-compatibility-to-old-style-DRI-interface.patch delete mode 100644 package/mesa3d/mesa3d.hash create mode 100644 package/qt5/qt5wayland/0002-add-WL_EGL_PLATFORM-define.patch create mode 100644 package/wayland/0001-build-the-wayland-scanner-is-not-always-required.patch create mode 100644 package/weston/0001-backend-drm-disable-bo-geometry-out-of-bounds-messag.patch delete mode 100644 package/weston/0001-tests-Add-dependency-on-screenshooter-client-protocol.patch create mode 100644 package/weston/0002-meson-fix-failure-to-find-libudev-when-linking-the-c.patch create mode 100644 package/weston/0003-libweston-reduce-checks-for-dmabufs-with-DRM-modifie.patch create mode 100644 package/weston/0004-tests-test-client-depends-on-libudev.patch create mode 100644 package/weston/0005-backend-drm-allow-linear-framebuffers-if-no-KMS-modi.patch create mode 100644 package/weston/0006-weston-set-default-compositor-to-gpu.patch create mode 100644 package/weston/run_weston.sh delete mode 100644 package/weston/weston.hash create mode 100644 package/weston/weston.ini create mode 100644 package/wqy-zenhei/0001-fix-Having-multiple-values-in-test-isn-t-supported-a.patch create mode 100755 toolchain/toolchain-external/toolchain-external-jdsk-riscv64/Config.in create mode 100755 toolchain/toolchain-external/toolchain-external-jdsk-riscv64/Config.in.options create mode 100755 toolchain/toolchain-external/toolchain-external-jdsk-riscv64/toolchain-external-jdsk-riscv64.hash create mode 100755 toolchain/toolchain-external/toolchain-external-jdsk-riscv64/toolchain-external-jdsk-riscv64.mk diff --git a/boot/opensbi/Config.in b/boot/opensbi/Config.in index 86f848f1..fac78f99 100644 --- a/boot/opensbi/Config.in +++ b/boot/opensbi/Config.in @@ -29,6 +29,9 @@ config BR2_TARGET_OPENSBI_CUSTOM_VERSION config BR2_TARGET_OPENSBI_CUSTOM_TARBALL bool "Custom tarball" +config BR2_TARGET_OPENSBI_CUSTOM_LOCAL + bool "Custom local dir" + config BR2_TARGET_OPENSBI_CUSTOM_GIT bool "Custom Git repository" @@ -42,6 +45,14 @@ config BR2_TARGET_OPENSBI_CUSTOM_TARBALL_LOCATION string "URL of custom OpenSBI tarball" depends on BR2_TARGET_OPENSBI_CUSTOM_TARBALL +config BR2_TARGET_OPENSBI_CUSTOM_LOCAL_DIR + string "URL of custom OpenSBI dir" + depends on BR2_TARGET_OPENSBI_CUSTOM_LOCAL + help + $(TOPDIR)/../path/to/your/opensbi-dir, + TOPDIR is your buildroot root dir + + if BR2_TARGET_OPENSBI_CUSTOM_GIT config BR2_TARGET_OPENSBI_CUSTOM_REPO_URL diff --git a/boot/opensbi/opensbi.mk b/boot/opensbi/opensbi.mk index dd113a0b..9a1aeda2 100644 --- a/boot/opensbi/opensbi.mk +++ b/boot/opensbi/opensbi.mk @@ -6,7 +6,10 @@ OPENSBI_VERSION = $(call qstrip,$(BR2_TARGET_OPENSBI_VERSION)) -ifeq ($(BR2_TARGET_OPENSBI_CUSTOM_TARBALL),y) +ifeq ($(BR2_TARGET_OPENSBI_CUSTOM_LOCAL),y) +OPENSBI_SITE = $(BR2_TARGET_OPENSBI_CUSTOM_LOCAL_DIR) +OPENSBI_SITE_METHOD = local +else ifeq ($(BR2_TARGET_OPENSBI_CUSTOM_TARBALL),y) # Handle custom OpenSBI tarballs as specified by the configuration OPENSBI_TARBALL = $(call qstrip,$(BR2_TARGET_OPENSBI_CUSTOM_TARBALL_LOCATION)) OPENSBI_SITE = $(patsubst %/,%,$(dir $(OPENSBI_TARBALL))) @@ -78,6 +81,8 @@ define OPENSBI_INSTALL_IMAGES_CMDS $(BINARIES_DIR)/fw_$(f).bin $(INSTALL) -m 0644 -D $(@D)/build/platform/$(OPENSBI_PLAT)/firmware/fw_$(f).elf \ $(BINARIES_DIR)/fw_$(f).elf + $(INSTALL) -m 0644 -D $(@D)/build/platform/$(OPENSBI_PLAT)/firmware/fw_$(f).itb \ + $(BINARIES_DIR)/fw_$(f).itb ) endef endif diff --git a/boot/uboot/Config.in b/boot/uboot/Config.in index 085397d0..a86a6f3c 100644 --- a/boot/uboot/Config.in +++ b/boot/uboot/Config.in @@ -51,6 +51,9 @@ config BR2_TARGET_UBOOT_CUSTOM_VERSION config BR2_TARGET_UBOOT_CUSTOM_TARBALL bool "Custom tarball" +config BR2_TARGET_UBOOT_CUSTOM_DIR + bool "Custom local dir" + config BR2_TARGET_UBOOT_CUSTOM_GIT bool "Custom Git repository" @@ -70,6 +73,10 @@ config BR2_TARGET_UBOOT_CUSTOM_TARBALL_LOCATION string "URL of custom U-Boot tarball" depends on BR2_TARGET_UBOOT_CUSTOM_TARBALL +config BR2_TARGET_UBOOT_CUSTOM_DIR_LOCATION + string "URL of custom U-Boot local dir" + depends on BR2_TARGET_UBOOT_CUSTOM_DIR + if BR2_TARGET_UBOOT_CUSTOM_GIT || BR2_TARGET_UBOOT_CUSTOM_HG || BR2_TARGET_UBOOT_CUSTOM_SVN config BR2_TARGET_UBOOT_CUSTOM_REPO_URL diff --git a/boot/uboot/uboot.mk b/boot/uboot/uboot.mk index c3e38293..5e77b267 100644 --- a/boot/uboot/uboot.mk +++ b/boot/uboot/uboot.mk @@ -20,7 +20,10 @@ UBOOT_INSTALL_IMAGES = YES UBOOT_DEPENDENCIES = host-pkgconf $(BR2_MAKE_HOST_DEPENDENCY) UBOOT_MAKE = $(BR2_MAKE) -ifeq ($(BR2_TARGET_UBOOT_CUSTOM_TARBALL),y) +ifeq ($(BR2_TARGET_UBOOT_CUSTOM_DIR),y) +UBOOT_SITE = $(BR2_TARGET_UBOOT_CUSTOM_DIR_LOCATION) +UBOOT_SITE_METHOD = local +else ifeq ($(BR2_TARGET_UBOOT_CUSTOM_TARBALL),y) # Handle custom U-Boot tarballs as specified by the configuration UBOOT_TARBALL = $(call qstrip,$(BR2_TARGET_UBOOT_CUSTOM_TARBALL_LOCATION)) UBOOT_SITE = $(patsubst %/,%,$(dir $(UBOOT_TARBALL))) diff --git a/fs/cpio/cpio.mk b/fs/cpio/cpio.mk index 00ab6a8f..6506e6d2 100644 --- a/fs/cpio/cpio.mk +++ b/fs/cpio/cpio.mk @@ -23,6 +23,7 @@ define ROOTFS_CPIO_ADD_INIT fi mkdir -p $(TARGET_DIR)/dev mknod -m 0622 $(TARGET_DIR)/dev/console c 5 1 + mknod -m 0622 $(TARGET_DIR)/dev/null c 1 3 endef endif # BR2_ROOTFS_DEVICE_CREATION_STATIC diff --git a/fs/cpio/dracut.conf b/fs/cpio/dracut.conf index 2337736c..77f3ad4e 100644 --- a/fs/cpio/dracut.conf +++ b/fs/cpio/dracut.conf @@ -15,7 +15,9 @@ do_strip=no # Dracut modules needed add_dracutmodules+=" \ -busybox-init +busybox-init \ +busybox \ +rescue \ " # Modules to ignore @@ -24,7 +26,6 @@ bash \ biosdevname \ btrfs \ bluetooth \ -busybox \ caps \ cifs \ crypt \ diff --git a/linux/Config.in b/linux/Config.in index e9f5ffe9..ec3fcf22 100644 --- a/linux/Config.in +++ b/linux/Config.in @@ -85,6 +85,11 @@ config BR2_LINUX_KERNEL_CUSTOM_TARBALL to use a make variable like $(TOPDIR) to reference the root of the Buildroot tree. +config BR2_LINUX_KERNEL_CUSTOM_DIR + bool "Custom local dir" + help + allows to specify a URL to your local kernel dir + config BR2_LINUX_KERNEL_CUSTOM_GIT bool "Custom Git repository" help @@ -94,7 +99,7 @@ config BR2_LINUX_KERNEL_CUSTOM_GIT config BR2_LINUX_KERNEL_CUSTOM_HG bool "Custom Mercurial repository" help - This option allows Buildroot to get the Linux kernel source + This option allows Buildroot to get the Linux kernel source code from a Mercurial repository. config BR2_LINUX_KERNEL_CUSTOM_SVN @@ -113,6 +118,15 @@ config BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION string "URL of custom kernel tarball" depends on BR2_LINUX_KERNEL_CUSTOM_TARBALL +config BR2_LINUX_KERNEL_CUSTOM_DIR_LOCATION + string "URL of custom kernel local dir" + depends on BR2_LINUX_KERNEL_CUSTOM_DIR + help + example: $(TOPDIR)/../to/your/kernel-dir + $(TOPDIR) to reference the root of + the Buildroot tree. + + if BR2_LINUX_KERNEL_CUSTOM_GIT || BR2_LINUX_KERNEL_CUSTOM_HG || BR2_LINUX_KERNEL_CUSTOM_SVN config BR2_LINUX_KERNEL_CUSTOM_REPO_URL @@ -134,6 +148,7 @@ config BR2_LINUX_KERNEL_VERSION default BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE \ if BR2_LINUX_KERNEL_CUSTOM_VERSION default "custom" if BR2_LINUX_KERNEL_CUSTOM_TARBALL + default "custom" if BR2_LINUX_KERNEL_CUSTOM_DIR default BR2_LINUX_KERNEL_CUSTOM_REPO_VERSION \ if BR2_LINUX_KERNEL_CUSTOM_GIT || BR2_LINUX_KERNEL_CUSTOM_HG || BR2_LINUX_KERNEL_CUSTOM_SVN diff --git a/linux/linux.mk b/linux/linux.mk index 03d89cd2..d18e52c4 100644 --- a/linux/linux.mk +++ b/linux/linux.mk @@ -17,7 +17,10 @@ LINUX_CPE_ID_PRODUCT = linux_kernel LINUX_CPE_ID_PREFIX = cpe:2.3:o # Compute LINUX_SOURCE and LINUX_SITE from the configuration -ifeq ($(BR2_LINUX_KERNEL_CUSTOM_TARBALL),y) +ifeq ($(BR2_LINUX_KERNEL_CUSTOM_DIR),y) +LINUX_SITE = $(BR2_LINUX_KERNEL_CUSTOM_DIR_LOCATION) +LINUX_SITE_METHOD = local +else ifeq ($(BR2_LINUX_KERNEL_CUSTOM_TARBALL),y) LINUX_TARBALL = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION)) LINUX_SITE = $(patsubst %/,%,$(dir $(LINUX_TARBALL))) LINUX_SOURCE = $(notdir $(LINUX_TARBALL)) diff --git a/package/busybox/0009-support-chinese.patch b/package/busybox/0009-support-chinese.patch new file mode 100644 index 00000000..ec9af3b1 --- /dev/null +++ b/package/busybox/0009-support-chinese.patch @@ -0,0 +1,61 @@ +From ab160332a117007df37bfe27abf5802d3db5f235 Mon Sep 17 00:00:00 2001 +From: max +Date: Mon, 22 Jan 2024 10:23:07 +0800 +Subject: [PATCH] support chinese + +--- + libbb/printable_string.c | 5 +++++ + libbb/unicode.c | 4 ++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/libbb/printable_string.c b/libbb/printable_string.c +index a814fd0..65d792e 100644 +--- a/libbb/printable_string.c ++++ b/libbb/printable_string.c +@@ -28,8 +28,10 @@ const char* FAST_FUNC printable_string2(uni_stat_t *stats, const char *str) + } + if (c < ' ') + break; ++/* + if (c >= 0x7f) + break; ++*/ + s++; + } + +@@ -42,7 +44,10 @@ const char* FAST_FUNC printable_string2(uni_stat_t *stats, const char *str) + unsigned char c = *d; + if (c == '\0') + break; ++ /* + if (c < ' ' || c >= 0x7f) ++ */ ++ if (c < ' ') + *d = '?'; + d++; + } +diff --git a/libbb/unicode.c b/libbb/unicode.c +index e98cbbf..afbcc10 100644 +--- a/libbb/unicode.c ++++ b/libbb/unicode.c +@@ -1027,7 +1027,7 @@ static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char + while ((int)--width >= 0); + break; + } +- *d++ = (c >= ' ' && c < 0x7f) ? c : '?'; ++ *d++ = (c >= ' ' /* && c < 0x7f */) ? c : '?'; + src++; + } + *d = '\0'; +@@ -1035,7 +1035,7 @@ static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char + d = dst = xstrndup(src, width); + while (*d) { + unsigned char c = *d; +- if (c < ' ' || c >= 0x7f) ++ if (c < ' ' /* || c >= 0x7f */) + *d = '?'; + d++; + } +-- +2.25.1 + diff --git a/package/busybox/0009-support-reboot-to-bootloader.patch b/package/busybox/0009-support-reboot-to-bootloader.patch new file mode 100644 index 00000000..099c8aca --- /dev/null +++ b/package/busybox/0009-support-reboot-to-bootloader.patch @@ -0,0 +1,90 @@ +From 65af285e2b025d93fb44147d26dbf4c00dda2a23 Mon Sep 17 00:00:00 2001 +From: max +Date: Wed, 24 Jan 2024 16:07:20 +0800 +Subject: [PATCH] support reboot to bootloader + +--- + init/halt.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 46 insertions(+), 1 deletion(-) + +diff --git a/init/halt.c b/init/halt.c +index fe3cb9e..9118e7a 100644 +--- a/init/halt.c ++++ b/init/halt.c +@@ -93,6 +93,20 @@ + + #include "libbb.h" + #include "reboot.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define LINUX_REBOOT_MAGIC1 0xfee1dead ++#define LINUX_REBOOT_MAGIC2 672274793 ++#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4 + + #if ENABLE_FEATURE_WTMP + #include +@@ -162,13 +176,14 @@ static int init_was_not_there(void) + #endif + + int halt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +-int halt_main(int argc UNUSED_PARAM, char **argv) ++int halt_main(int argc , char **argv) + { + static const int magic[] = { + RB_HALT_SYSTEM, + RB_POWER_OFF, + RB_AUTOBOOT + }; ++ + static const smallint signals[] = { SIGUSR1, SIGUSR2, SIGTERM }; + + int delay = 0; +@@ -187,6 +202,36 @@ int halt_main(int argc UNUSED_PARAM, char **argv) + for (which = 0; "hpr"[which] != applet_name[0]; which++) + continue; + ++ if((argc == 1) ||(argc != 1 && !strcmp(argv[1],"bootloader"))) { ++ char buf[100]; ++ int pid, ret; ++ ++ sync(); ++ ++ /* Attempt to unmount the SD card first. ++ * No need to bother checking for errors. ++ */ ++ pid = fork(); ++ if (pid == 0) { ++ /* ask vdc to unmount it */ ++ /*execl("/system/bin/vdc", "/system/bin/vdc", "volume", "unmount", ++ getenv("EXTERNAL_STORAGE"), "force", NULL);*/ ++ } else if (pid > 0) { ++ /* wait until vdc succeeds or fails */ ++ waitpid(pid, &ret, 0); ++ } ++ ++ if(argc == 1) ++ ret = reboot(magic[which]); ++ else ++ ret = syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, ++ LINUX_REBOOT_CMD_RESTART2, argv[1]); ++ if (ret < 0) { ++ snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno)); ++ } ++ ++ } ++ + /* Parse and handle arguments */ + /* We support -w even if !ENABLE_FEATURE_WTMP, + * in order to not break scripts. +-- +2.25.1 + diff --git a/package/dracut/busybox-init-module-setup.sh b/package/dracut/busybox-init-module-setup.sh index d6ea9435..b9880e02 100644 --- a/package/dracut/busybox-init-module-setup.sh +++ b/package/dracut/busybox-init-module-setup.sh @@ -55,5 +55,6 @@ install() { /etc/group \ /etc/passwd \ /etc/shadow \ - /etc/hostname + /etc/hostname \ + /lib/firmware/esos.elf } diff --git a/package/dracut/dracut.mk b/package/dracut/dracut.mk index 3eb9bcc4..52a4f2fa 100644 --- a/package/dracut/dracut.mk +++ b/package/dracut/dracut.mk @@ -43,6 +43,8 @@ ifeq ($(BR2_INIT_BUSYBOX),y) define HOST_DRACUT_POST_INSTALL_BUSYBOX_INIT_MODULE $(INSTALL) -D -m 0755 package/dracut/busybox-init-module-setup.sh \ $(HOST_DIR)/lib/dracut/modules.d/05busybox-init/module-setup.sh + $(INSTALL) -D -m 0755 package/dracut/rescue-module-setup.sh \ + $(HOST_DIR)/lib/dracut/modules.d/03rescue/module-setup.sh endef HOST_DRACUT_POST_INSTALL_HOOKS += HOST_DRACUT_POST_INSTALL_BUSYBOX_INIT_MODULE endif diff --git a/package/dracut/rescue-module-setup.sh b/package/dracut/rescue-module-setup.sh new file mode 100755 index 00000000..1eda52ac --- /dev/null +++ b/package/dracut/rescue-module-setup.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# called by dracut +check() { + # do not add this module by default + return 255 +} + +# called by dracut +depends() { + return 0 +} + +# called by dracut +install() { + inst_multiple -o ps grep more cat rm strace free showmount \ + ping netstat rpcinfo vi scp ping6 ssh \ + fsck fsck.ext2 fsck.ext4 fsck.ext3 fsck.ext4dev fsck.f2fs fsck.vfat e2fsck resize2fs mount +} diff --git a/package/eudev/0002-Fix-compile-time-issue-on-very-old-kernels.patch b/package/eudev/0002-Fix-compile-time-issue-on-very-old-kernels.patch deleted file mode 100644 index 46961cc9..00000000 --- a/package/eudev/0002-Fix-compile-time-issue-on-very-old-kernels.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 09b536e0b9d0964674936901ab9d2954f935c8b4 Mon Sep 17 00:00:00 2001 -From: Stefan Ott -Date: Wed, 5 Apr 2023 18:20:37 +0200 -Subject: [PATCH] Fix compile-time issue on very old kernels - -Kernel versions prior to 3.4 did not have V4L2_CAP_DEVICE_CAPS and -compiling against such a kernel will fail. - -This patch introduces a version check and makes eudev fall back to -v2cap.capabilities on these kernels. - -Upstream: https://github.com/eudev-project/eudev/commit/09b536e0b9d0964674936901ab9d2954f935c8b4 -Signed-off-by: Stefan Ott ---- - src/v4l_id/v4l_id.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/v4l_id/v4l_id.c b/src/v4l_id/v4l_id.c -index 6bf45effe..702d5b687 100644 ---- a/src/v4l_id/v4l_id.c -+++ b/src/v4l_id/v4l_id.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - #include - - #include "util.h" -@@ -71,9 +72,11 @@ int main(int argc, char *argv[]) { - printf("ID_V4L_VERSION=2\n"); - printf("ID_V4L_PRODUCT=%s\n", v2cap.card); - printf("ID_V4L_CAPABILITIES=:"); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) - if (v2cap.capabilities & V4L2_CAP_DEVICE_CAPS) - capabilities = v2cap.device_caps; - else -+#endif - capabilities = v2cap.capabilities; - if ((capabilities & V4L2_CAP_VIDEO_CAPTURE) > 0 || - (capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) > 0) --- -2.40.0 - diff --git a/package/eudev/Config.in b/package/eudev/Config.in index 6e7bbe46..0e5bd0ce 100644 --- a/package/eudev/Config.in +++ b/package/eudev/Config.in @@ -16,7 +16,7 @@ config BR2_PACKAGE_EUDEV Upstart, older kernels, various toolchains and anything else required by users and various distributions. - https://github.com/eudev-project/eudev + https://wiki.gentoo.org/wiki/Project:Eudev if BR2_PACKAGE_EUDEV diff --git a/package/eudev/S10udev b/package/eudev/S10udev index 4e799d65..fe4d3550 100644 --- a/package/eudev/S10udev +++ b/package/eudev/S10udev @@ -21,13 +21,72 @@ UDEV_CONFIG=/etc/udev/udev.conf test -r $UDEV_CONFIG || exit 6 . $UDEV_CONFIG +# we need to unmount /dev/pts/ and remount it later over the devtmpfs +unmount_devpts() { + if mountpoint -q /dev/pts/; then + umount -n -l /dev/pts/ + fi + + if mountpoint -q /dev/shm/; then + umount -n -l /dev/shm/ + fi +} + +# mount a devtmpfs over /dev, if somebody did not already do it +mount_devtmpfs() { + if grep -E -q "^[^[:space:]]+ /dev devtmpfs" /proc/mounts; then + mount -n -o remount,nosuid,mode=0755 -t devtmpfs devtmpfs /dev + return + fi + + if ! mount -n -o nosuid,mode=0755 -t devtmpfs devtmpfs /dev; then + echo "udev requires devtmpfs support, not started" + fi + + return 0 +} + +create_dev_makedev() { + if [ -e /sbin/MAKEDEV ]; then + ln -sf /sbin/MAKEDEV /dev/MAKEDEV + else + ln -sf /bin/true /dev/MAKEDEV + fi +} + +make_static_nodes() { + [ -e /lib/modules/$(uname -r)/modules.devname ] || return 0 + [ -x /usr/bin/kmod ] || return 0 + + /usr/bin/kmod static-nodes --format=tmpfiles --output=/proc/self/fd/1 | \ + while read type name mode uid gid age arg; do + [ -e $name ] && continue + case "$type" in + c|b|c!|b!) mknod -m $mode $name $type $(echo $arg | sed 's/:/ /') ;; + d|d!) mkdir $name ;; + *) echo "unparseable line ($type $name $mode $uid $gid $age $arg)" >&2 ;; + esac + done +} + case "$1" in start) + if ! mountpoint -q /dev/; then + unmount_devpts + mount_devtmpfs + fi + + make_static_nodes + + # clean up parts of the database created by the initramfs udev + udevadm info --cleanup-db + printf "Populating %s using udev: " "${udev_root:-/dev}" [ -e /proc/sys/kernel/hotplug ] && printf '\000\000\000\000' > /proc/sys/kernel/hotplug /sbin/udevd -d || { echo "FAIL"; exit 1; } udevadm trigger --type=subsystems --action=add udevadm trigger --type=devices --action=add + create_dev_makedev udevadm settle --timeout=30 || echo "udevadm settle failed" echo "done" ;; diff --git a/package/eudev/eudev.hash b/package/eudev/eudev.hash index fe6c7ef0..fda04813 100644 --- a/package/eudev/eudev.hash +++ b/package/eudev/eudev.hash @@ -1,3 +1,5 @@ +# From http://dev.gentoo.org/~blueness/eudev/ +md5 60b135a189523f333cea5f71a3345c8d eudev-3.2.10.tar.gz # Locally calculated -sha256 19847cafec67897da855fde56f9dc7d92e21c50e450aa79068a7e704ed44558b eudev-3.2.11.tar.gz +sha256 87bb028d470fd1b85169349b44c55d5b733733dc2d50ddf1196e026725ead034 eudev-3.2.10.tar.gz sha256 ab15fd526bd8dd18a9e77ebc139656bf4d33e97fc7238cd11bf60e2b9b8666c6 COPYING diff --git a/package/eudev/eudev.mk b/package/eudev/eudev.mk index feb55052..5d18b388 100644 --- a/package/eudev/eudev.mk +++ b/package/eudev/eudev.mk @@ -4,8 +4,8 @@ # ################################################################################ -EUDEV_VERSION = 3.2.11 -EUDEV_SITE = https://github.com/eudev-project/eudev/releases/download/v$(EUDEV_VERSION) +EUDEV_VERSION = 3.2.10 +EUDEV_SITE = http://dev.gentoo.org/~blueness/eudev EUDEV_LICENSE = GPL-2.0+ (programs), LGPL-2.1+ (libraries) EUDEV_LICENSE_FILES = COPYING EUDEV_INSTALL_STAGING = YES @@ -57,12 +57,13 @@ endef HOST_EUDEV_DEPENDENCIES = host-gperf host-pkgconf +HOST_EUDEV_SYSCONFDIR = $(if $(BR2_PACKAGE_SYSTEMD),/usr/lib,/etc) HOST_EUDEV_CONF_OPTS = \ --prefix=/usr \ --sbindir=/sbin \ --libexecdir=/lib \ --with-rootlibdir=/lib \ - --sysconfdir=/etc \ + --sysconfdir=$(HOST_EUDEV_SYSCONFDIR) \ --disable-blkid \ --disable-introspection \ --disable-kmod \ @@ -81,5 +82,13 @@ define HOST_EUDEV_BUILD_HWDB endef HOST_EUDEV_TARGET_FINALIZE_HOOKS += HOST_EUDEV_BUILD_HWDB +# Note: this will run in the filesystem context, so will use a copy +# of tharget/, not the real one, so the files are still available on +# re-builds (foo-rebuild, etc...) +define HOST_EUDEV_RM_HWDB_SRC + rm -rf $(TARGET_DIR)/$(HOST_EUDEV_SYSCONFDIR)/udev/hwdb.d/ +endef +HOST_EUDEV_ROOTFS_PRE_CMD_HOOKS += HOST_EUDEV_RM_HWDB_SRC + $(eval $(autotools-package)) $(eval $(host-autotools-package)) diff --git a/package/ffmpeg/0005-support-spacemit-mpp.patch b/package/ffmpeg/0005-support-spacemit-mpp.patch new file mode 100644 index 00000000..86e1b69a --- /dev/null +++ b/package/ffmpeg/0005-support-spacemit-mpp.patch @@ -0,0 +1,658 @@ +From ad231da546c0680c5895fc7a31d52a6e4af966da Mon Sep 17 00:00:00 2001 +From: fuqiang +Date: Tue, 26 Dec 2023 20:01:37 +0800 +Subject: [PATCH] support spacemit mpp + +--- + configure | 6 +- + libavcodec/Makefile | 2 + + libavcodec/allcodecs.c | 2 + + libavcodec/stcodecdec.c | 553 ++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 562 insertions(+), 1 deletion(-) + create mode 100755 libavcodec/stcodecdec.c + +diff --git a/configure b/configure +index 01bb1dd..52561c1 100755 +--- a/configure ++++ b/configure +@@ -345,6 +345,7 @@ External library support: + --enable-omx enable OpenMAX IL code [no] + --enable-omx-rpi enable OpenMAX IL code for Raspberry Pi [no] + --enable-rkmpp enable Rockchip Media Process Platform code [no] ++ --enable-stcodec enable Spacemit Media Process Platform code [no] + --disable-v4l2-m2m disable V4L2 mem2mem code [autodetect] + --disable-vaapi disable Video Acceleration API (mainly Unix/Intel) code [autodetect] + --disable-vdpau disable Nvidia Video Decode and Presentation API for Unix code [autodetect] +@@ -1730,6 +1731,7 @@ EXTERNAL_LIBRARY_GPL_LIST=" + libxavs + libxavs2 + libxvid ++ stcodec + " + + EXTERNAL_LIBRARY_NONFREE_LIST=" +@@ -3092,6 +3094,7 @@ h264_vaapi_encoder_select="cbs_h264 vaapi_encode" + h264_v4l2m2m_decoder_deps="v4l2_m2m h264_v4l2_m2m" + h264_v4l2m2m_decoder_select="h264_mp4toannexb_bsf" + h264_v4l2m2m_encoder_deps="v4l2_m2m h264_v4l2_m2m" ++h264_stcodec_decoder_deps="stcodec" + hevc_amf_encoder_deps="amf" + hevc_cuvid_decoder_deps="cuvid" + hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf" +@@ -3109,6 +3112,7 @@ hevc_vaapi_encoder_select="cbs_h265 vaapi_encode" + hevc_v4l2m2m_decoder_deps="v4l2_m2m hevc_v4l2_m2m" + hevc_v4l2m2m_decoder_select="hevc_mp4toannexb_bsf" + hevc_v4l2m2m_encoder_deps="v4l2_m2m hevc_v4l2_m2m" ++hevc_stcodec_decoder_deps="stcodec" + mjpeg_cuvid_decoder_deps="cuvid" + mjpeg_qsv_decoder_select="qsvdec" + mjpeg_qsv_encoder_deps="libmfx" +@@ -6547,7 +6551,7 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r + die "ERROR: rkmpp requires --enable-libdrm"; } + } + enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 42" VSScript.h vsscript_init +- ++enabled stcodec + + if enabled gcrypt; then + GCRYPT_CONFIG="${cross_prefix}libgcrypt-config" +diff --git a/libavcodec/Makefile b/libavcodec/Makefile +index b3d284d..ff56ed6 100644 +--- a/libavcodec/Makefile ++++ b/libavcodec/Makefile +@@ -385,6 +385,7 @@ OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o h264_levels.o + OBJS-$(CONFIG_H264_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o + OBJS-$(CONFIG_H264_V4L2M2M_DECODER) += v4l2_m2m_dec.o + OBJS-$(CONFIG_H264_V4L2M2M_ENCODER) += v4l2_m2m_enc.o ++OBJS-$(CONFIG_H264_STCODEC_DECODER) += stcodecdec.o + OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o + OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o + OBJS-$(CONFIG_HCA_DECODER) += hcadec.o +@@ -405,6 +406,7 @@ OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o + OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o + OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o + OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o ++OBJS-$(CONFIG_HEVC_STCODEC_DECODER) += stcodecdec.o + OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o + OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadata.o hq_hqadsp.o \ + canopus.o +diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c +index 2e9a358..9981106 100644 +--- a/libavcodec/allcodecs.c ++++ b/libavcodec/allcodecs.c +@@ -148,11 +148,13 @@ extern AVCodec ff_h264_mediacodec_decoder; + extern AVCodec ff_h264_mmal_decoder; + extern AVCodec ff_h264_qsv_decoder; + extern AVCodec ff_h264_rkmpp_decoder; ++extern AVCodec ff_h264_stcodec_decoder; + extern AVCodec ff_hap_encoder; + extern AVCodec ff_hap_decoder; + extern AVCodec ff_hevc_decoder; + extern AVCodec ff_hevc_qsv_decoder; + extern AVCodec ff_hevc_rkmpp_decoder; ++extern AVCodec ff_hevc_stcodec_decoder; + extern AVCodec ff_hevc_v4l2m2m_decoder; + extern AVCodec ff_hnm4_video_decoder; + extern AVCodec ff_hq_hqa_decoder; +diff --git a/libavcodec/stcodecdec.c b/libavcodec/stcodecdec.c +new file mode 100755 +index 0000000..763e1b2 +--- /dev/null ++++ b/libavcodec/stcodecdec.c +@@ -0,0 +1,553 @@ ++/* ++ * Spacemit MPP Video Decoder ++ * Copyright 2022-2023 SPACEMIT. All rights reserved. ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "avcodec.h" ++#include "internal.h" ++#include "decode.h" ++#include "h264_parse.h" ++#include "hevc_parse.h" ++#include "hwconfig.h" ++#include "libavutil/buffer.h" ++#include "libavutil/common.h" ++#include "libavutil/frame.h" ++#include "libavutil/hwcontext.h" ++#include "libavutil/hwcontext_drm.h" ++#include "libavutil/imgutils.h" ++#include "libavutil/log.h" ++#include "vdec.h" ++ ++#define PACKET_SIZE (2 * 1024 * 1024) ++ ++typedef struct { ++ MppVdecCtx* pVdecCtx; ++ MppVdecPara* pVdecPara; ++ MppPacket* pPacket; ++ MppFrame* pFrame; ++ enum AVPixelFormat ePixFmt; ++ ++ char eos_reached; ++ ++ AVBufferRef* frames_ref; ++ AVBufferRef* device_ref; ++} STCODECDecoder; ++ ++typedef struct { ++ AVClass* av_class; ++ AVBufferRef* decoder_ref; ++} STCODECDecodeContext; ++ ++typedef struct { ++ MppFrame* pFrame; ++ AVBufferRef* decoder_ref; ++} STCODECFrameContext; ++ ++static MppCodingType stcodec_get_codingtype(AVCodecContext* avctx) { ++ switch (avctx->codec_id) { ++ case AV_CODEC_ID_H264: ++ return CODING_H264; ++ case AV_CODEC_ID_HEVC: ++ return CODING_H265; ++ case AV_CODEC_ID_VP8: ++ return CODING_VP8; ++ case AV_CODEC_ID_VP9: ++ return CODING_VP9; ++ case AV_CODEC_ID_MJPEG: ++ return CODING_MJPEG; ++ default: ++ return CODING_UNKNOWN; ++ } ++} ++ ++static int get_stride(int width, int align) { ++ return (width + align - 1) & (~(align - 1)); ++} ++ ++static int stcodec_send_data_to_decoder(AVCodecContext* avctx, uint8_t* buffer, ++ int size, int64_t pts) { ++ STCODECDecodeContext* st_context = avctx->priv_data; ++ STCODECDecoder* decoder = (STCODECDecoder*)st_context->decoder_ref->data; ++ int ret = 0; ++ ++ if (!buffer && 0 == size) { ++ // a NULL packet, need to send EOS to decoder. ++ PACKET_SetEos(decoder->pPacket, 1); ++ PACKET_SetLength(decoder->pPacket, 0); ++ } else { ++ // debug ++ av_log(avctx, AV_LOG_DEBUG, "%x %x %x %x %x length = %d\n", *buffer, ++ *(buffer + 1), *(buffer + 2), *(buffer + 3), *(buffer + 4), size); ++ ++ PACKET_SetDataPointer(decoder->pPacket, buffer); ++ PACKET_SetLength(decoder->pPacket, size); ++ PACKET_SetPts(decoder->pPacket, pts); ++ PACKET_SetEos(decoder->pPacket, 0); ++ av_log(avctx, AV_LOG_DEBUG, "input pts : %ld\n", pts); ++ } ++ ++ // send packet to decoder, the packet will be copyed in decoder, so can ++ // release it here. ++ ret = VDEC_Decode(decoder->pVdecCtx, PACKET_GetBaseData(decoder->pPacket)); ++ if (ret) { ++ if (ret == MPP_DATAQUEUE_FULL) { ++ // input unblock mode will go here. ++ av_log(avctx, AV_LOG_DEBUG, "Buffer full writing %d bytes to decoder\n", ++ size); ++ ret = AVERROR(EAGAIN); // here something wrong, maybe return 0 ++ } else { ++ ret = AVERROR_UNKNOWN; ++ } ++ } else { ++ av_log(avctx, AV_LOG_DEBUG, "Write %d bytes to decoder\n", size); ++ } ++ ++ return ret; // here something wrong, maybe return 0 ++} ++ ++static int stcodec_close_decoder(AVCodecContext* avctx) { ++ STCODECDecodeContext* st_context = avctx->priv_data; ++ av_log(NULL, AV_LOG_DEBUG, "stcodec close decoder\n"); ++ av_buffer_unref(&st_context->decoder_ref); ++ return 0; ++} ++ ++static void stcodec_release_stcodec_decoder(void* opaque, uint8_t* data) { ++ STCODECDecoder* decoder = (STCODECDecoder*)data; ++ if (decoder->pVdecCtx) { ++ av_log(NULL, AV_LOG_ERROR, "stcodec release decoder\n"); ++ VDEC_ResetChannel(decoder->pVdecCtx); ++ VDEC_DestoryChannel(decoder->pVdecCtx); ++ decoder->pVdecCtx = NULL; ++ } ++ av_buffer_unref(&decoder->frames_ref); ++ av_buffer_unref(&decoder->device_ref); ++ av_free(decoder); ++} ++ ++static int stcodec_init_decoder(AVCodecContext* avctx) { ++ STCODECDecodeContext* st_context = avctx->priv_data; ++ STCODECDecoder* decoder = NULL; ++ MppCodingType codectype = CODING_UNKNOWN; ++ int ret; ++/* ++ if (avctx->width > 4096 || avctx->height > 2160 || avctx->width <= 640 || ++ avctx->height <= 480) { ++ av_log(avctx, AV_LOG_ERROR, ++ "STCODEC Decoder do not support the size (%d x %d), too big or too " ++ "small!\n", ++ avctx->width, avctx->height); ++ ret = AVERROR_UNKNOWN; ++ goto fail; ++ } ++*/ ++ avctx->pix_fmt = ff_get_format(avctx, avctx->codec->pix_fmts); ++ av_log(avctx, AV_LOG_ERROR, "------------------------ Use pixel format %d\n", avctx->pix_fmt); ++ ++ // create a decoder and a ref to it ++ decoder = av_mallocz(sizeof(STCODECDecoder)); ++ if (!decoder) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to av_mallocz STCODECDecoder\n"); ++ ret = AVERROR(ENOMEM); ++ goto fail; ++ } ++ ++ decoder->ePixFmt = avctx->pix_fmt; ++ ++ st_context->decoder_ref = av_buffer_create( ++ (uint8_t*)decoder, sizeof(*decoder), stcodec_release_stcodec_decoder, ++ NULL, AV_BUFFER_FLAG_READONLY); ++ if (!st_context->decoder_ref) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to create ref of STCODECDecoder!\n"); ++ av_free(decoder); ++ ret = AVERROR(ENOMEM); ++ goto fail; ++ } ++ ++ av_log(avctx, AV_LOG_DEBUG, "Initializing STCODEC decoder.\n"); ++ ++ codectype = stcodec_get_codingtype(avctx); ++ if (CODING_UNKNOWN == codectype) { ++ av_log(avctx, AV_LOG_ERROR, "Unknown codec type (%d).\n", avctx->codec_id); ++ av_free(decoder); ++ ret = AVERROR_UNKNOWN; ++ goto fail; ++ } ++ ++ // Create the MPP context ++ decoder->pVdecCtx = VDEC_CreateChannel(); ++ if (!decoder->pVdecCtx) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to create STCODEC VDEC channel.\n"); ++ av_free(decoder); ++ ret = AVERROR_UNKNOWN; ++ goto fail; ++ } ++ ++ // set para ++ decoder->pVdecCtx->stVdecPara.eCodingType = codectype; ++ decoder->pVdecCtx->stVdecPara.bInputBlockModeEnable = MPP_FALSE; ++ decoder->pVdecCtx->stVdecPara.bOutputBlockModeEnable = MPP_TRUE; ++ decoder->pVdecCtx->stVdecPara.nWidth = avctx->width; ++ decoder->pVdecCtx->stVdecPara.nHeight = avctx->height; ++ decoder->pVdecCtx->stVdecPara.nStride = get_stride(avctx->width, 8); ++ decoder->pVdecCtx->stVdecPara.eOutputPixelFormat = PIXEL_FORMAT_NV12; ++ decoder->pVdecCtx->eCodecType = CODEC_V4L2_LINLONV5V7; ++ decoder->pVdecCtx->stVdecPara.nScale = 1; ++ decoder->pVdecCtx->stVdecPara.nHorizonScaleDownRatio = 1; ++ decoder->pVdecCtx->stVdecPara.nVerticalScaleDownRatio = 1; ++ decoder->pVdecCtx->stVdecPara.nRotateDegree = 0; ++ decoder->pVdecCtx->stVdecPara.bThumbnailMode = 0; ++ decoder->pVdecCtx->stVdecPara.bIsInterlaced = MPP_FALSE; ++ ++ // vdec init ++ ret = VDEC_Init(decoder->pVdecCtx); ++ if (ret) { ++ av_log(avctx, AV_LOG_ERROR, ++ "Failed to initialize STCODEC VDEV (ret = %d).\n", ret); ++ VDEC_DestoryChannel(decoder->pVdecCtx); ++ av_free(decoder); ++ ret = AVERROR_UNKNOWN; ++ goto fail; ++ } ++ ++ av_log(avctx, AV_LOG_ERROR, "init 1.\n"); ++ // mpp packet init ++ decoder->pPacket = PACKET_Create(); ++ if (!decoder->pPacket) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to initialize STCODEC packet.\n"); ++ VDEC_DestoryChannel(decoder->pVdecCtx); ++ av_free(decoder); ++ ret = AVERROR_UNKNOWN; ++ goto fail; ++ } ++ PACKET_Alloc(decoder->pPacket, PACKET_SIZE); ++ ++ av_log(avctx, AV_LOG_ERROR, "init 2.\n"); ++ // mpp frame init ++ decoder->pFrame = FRAME_Create(); ++ if (!decoder->pFrame) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to initialize STCODEC frame.\n"); ++ PACKET_Destory(decoder->pPacket); ++ VDEC_DestoryChannel(decoder->pVdecCtx); ++ av_free(decoder); ++ ret = AVERROR_UNKNOWN; ++ goto fail; ++ } ++ ++ av_log(avctx, AV_LOG_ERROR, "init 3.\n"); ++ av_log(avctx, AV_LOG_DEBUG, "STCODEC decoder initialized successfully.\n"); ++ ++ decoder->device_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_DRM); ++ if (!decoder->device_ref) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to av_hwdevice_ctx_alloc\n"); ++ ret = AVERROR(ENOMEM); ++ goto fail; ++ } ++ av_log(avctx, AV_LOG_ERROR, "init 4.\n"); ++ ret = av_hwdevice_ctx_init(decoder->device_ref); ++ if (ret < 0) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to av_hwdevice_ctx_init\n"); ++ goto fail; ++ } ++ av_log(avctx, AV_LOG_ERROR, "init 5.\n"); ++ ++ decoder->frames_ref = av_hwframe_ctx_alloc(decoder->device_ref); ++ if (!decoder->frames_ref) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to av_hwframe_ctx_alloc\n"); ++ ret = AVERROR(ENOMEM); ++ goto fail; ++ } ++ av_log(avctx, AV_LOG_ERROR, "init 6.\n"); ++ ++ AVHWFramesContext* hwframes; ++ hwframes = (AVHWFramesContext*)decoder->frames_ref->data; ++ hwframes->format = AV_PIX_FMT_DRM_PRIME; ++ hwframes->sw_format = AV_PIX_FMT_NV12; ++ hwframes->width = avctx->width; ++ hwframes->height = avctx->height; ++ ret = av_hwframe_ctx_init(decoder->frames_ref); ++ if (ret < 0) goto fail; ++ ++ av_log(avctx, AV_LOG_DEBUG, "Initialized successfully.\n"); ++ av_log(avctx, AV_LOG_ERROR, "init 7.\n"); ++ return 0; ++ ++fail: ++ av_log(avctx, AV_LOG_ERROR, "init 8.\n"); ++ av_log(avctx, AV_LOG_ERROR, ++ "Failed to initialize STCODEC decoder, please check!\n"); ++ stcodec_close_decoder(avctx); ++ return ret; ++} ++ ++static int stcodec_send_packet(AVCodecContext* avctx, const AVPacket* avpkt) { ++ STCODECDecodeContext* st_context = avctx->priv_data; ++ STCODECDecoder* decoder = (STCODECDecoder*)st_context->decoder_ref->data; ++ int ret; ++ av_log(avctx, AV_LOG_DEBUG, "start send packet, pts(%ld)\n", avpkt->pts); ++ ++ // handle EOF ++ if (!avpkt->size) { ++ av_log(avctx, AV_LOG_ERROR, "Get EOS from parser!\n"); ++ decoder->eos_reached = 1; ++ // write a NULL data to decoder to inform it the EOS. ++ ret = stcodec_send_data_to_decoder(avctx, NULL, 0, 0); ++ if (ret) ++ av_log(avctx, AV_LOG_ERROR, "Failed to send EOS to decoder (ret = %d)\n", ++ ret); ++ return ret; ++ } ++ ++ // now send packet ++ ret = ++ stcodec_send_data_to_decoder(avctx, avpkt->data, avpkt->size, avpkt->pts); ++ if (ret) { ++ av_log(avctx, AV_LOG_DEBUG, ++ "Failed to write data to decoder (code = %d (%s))\n", ret, ++ av_err2str(ret)); ++ } else { ++ av_log(avctx, AV_LOG_DEBUG, ++ "OK! Write data to decoder, (size = %d) (ret = %d)\n", avpkt->size, ++ ret); ++ } ++ ++ return ret; ++} ++ ++static void stcodec_release_frame(void* opaque, uint8_t* data) { ++ AVDRMFrameDescriptor* desc = (AVDRMFrameDescriptor*)data; ++ AVBufferRef* framecontextref = (AVBufferRef*)opaque; ++ STCODECFrameContext* framecontext = ++ (STCODECFrameContext*)framecontextref->data; ++ ++ av_log(NULL, AV_LOG_DEBUG, "stcodec release frame\n"); ++ ++ VDEC_ReturnOutputFrame( ++ ((STCODECDecoder*)framecontext->decoder_ref->data)->pVdecCtx, ++ FRAME_GetBaseData(framecontext->pFrame)); ++ ++ if (((STCODECDecoder*)framecontext->decoder_ref->data)->ePixFmt == ++ AV_PIX_FMT_DRM_PRIME) { ++ av_free(desc); ++ } ++ av_buffer_unref(&framecontext->decoder_ref); ++ av_buffer_unref(&framecontextref); ++} ++ ++static int stcodec_receive_frame(AVCodecContext* avctx, AVFrame* frame) { ++ STCODECDecodeContext* st_context = avctx->priv_data; ++ STCODECDecoder* decoder = (STCODECDecoder*)st_context->decoder_ref->data; ++ AVPacket pkt = {0}; ++ int freeslots; ++ STCODECFrameContext* framecontext = NULL; ++ AVBufferRef* framecontextref = NULL; ++ MppFrame* mppframe = FRAME_Create(); ++ AVDRMFrameDescriptor* desc = NULL; ++ AVDRMLayerDescriptor* layer = NULL; ++ int ret = -1; ++ ++ av_log(avctx, AV_LOG_DEBUG, "start receive frame\n"); ++ ++ if (!decoder->eos_reached) { ++ // we get the available input queue num in decoder ++ VDEC_GetParam(decoder->pVdecCtx, &(decoder->pVdecPara)); ++ freeslots = decoder->pVdecPara->nInputQueueLeftNum; ++ av_log(avctx, AV_LOG_ERROR, "--------- Input queue left %d seat!!\n", freeslots); ++ ++ if (freeslots > 0) { ++ ret = ff_decode_get_packet(avctx, &pkt); ++ if (ret < 0 && ret != AVERROR_EOF) { ++ av_log(avctx, AV_LOG_ERROR, ++ "Failed to ff_decode_get_packet (ret = %d (%s))\n", ret, ++ av_err2str(ret)); ++ return ret; ++ } ++ ++ ret = stcodec_send_packet(avctx, &pkt); ++ av_packet_unref(&pkt); ++ ++ if (ret < 0) { ++ av_log(avctx, AV_LOG_ERROR, ++ "Failed to send packet to decoder (code = %d (%s))\n", ret, ++ av_err2str(ret)); ++ return ret; ++ } ++ } ++ ++ // make sure we keep decoder full ++ VDEC_GetParam(decoder->pVdecCtx, &(decoder->pVdecPara)); ++ freeslots = decoder->pVdecPara->nInputQueueLeftNum; ++ av_log(avctx, AV_LOG_ERROR, "========== Input queue left %d seat!!\n", freeslots); ++ if (freeslots > 0) return AVERROR(EAGAIN); ++ } ++ ++ ret = VDEC_RequestOutputFrame(decoder->pVdecCtx, FRAME_GetBaseData(mppframe)); ++ av_log(avctx, AV_LOG_DEBUG, "Request frame (ret = %d)\n", ret); ++ ++ if (ret == MPP_CODER_EOS && mppframe == NULL) { ++ av_log(avctx, AV_LOG_ERROR, "EOS 1!\n"); ++ return AVERROR_EOF; ++ } ++ ++ if (ret == MPP_CODER_EOS || ++ FRAME_GetEos(mppframe) == 1 /* || decoder->eos_reached*/) { ++ av_log(avctx, AV_LOG_ERROR, "EOS 2!\n"); ++ VDEC_ReturnOutputFrame(decoder->pVdecCtx, FRAME_GetBaseData(mppframe)); ++ return AVERROR_EOF; ++ } ++ ++ if (!ret) { ++ av_log(NULL, AV_LOG_DEBUG, "stcodec request a frame\n"); ++ ++ // setup general frame fields ++ frame->format = avctx->pix_fmt; ++ frame->width = avctx->width; ++ frame->height = avctx->height; ++ // frame->pts = FRAME_GetPts(decoder->pFrame); ++ frame->interlaced_frame = 0; ++ frame->top_field_first = 0; ++ ++ framecontextref = av_buffer_allocz(sizeof(*framecontext)); ++ if (!framecontextref) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to alloc AvBufferRef\n"); ++ ret = AVERROR(ENOMEM); ++ return ret; ++ } ++ ++ // MPP decoder needs to be closed only when all frames have been released. ++ framecontext = (STCODECFrameContext*)framecontextref->data; ++ framecontext->decoder_ref = av_buffer_ref(st_context->decoder_ref); ++ framecontext->pFrame = mppframe; ++ ++ if (avctx->pix_fmt == AV_PIX_FMT_DRM_PRIME) { ++ desc = av_mallocz(sizeof(AVDRMFrameDescriptor)); ++ if (!desc) { ++ ret = AVERROR(ENOMEM); ++ return ret; ++ } ++ ++ desc->nb_objects = 1; ++ desc->objects[0].fd = FRAME_GetFD(mppframe, 0); ++ desc->objects[0].size = frame->width * frame->height * 3 / 2; ++ av_log(avctx, AV_LOG_DEBUG, "fd=%d size=%ld\n", desc->objects[0].fd, ++ desc->objects[0].size); ++ desc->nb_layers = 1; ++ layer = &desc->layers[0]; ++ layer->format = DRM_FORMAT_NV12; ++ layer->nb_planes = 2; ++ ++ layer->planes[0].object_index = 0; ++ layer->planes[0].offset = 0; ++ layer->planes[0].pitch = frame->width; ++ ++ layer->planes[1].object_index = 0; ++ layer->planes[1].offset = frame->width * frame->height; ++ layer->planes[1].pitch = frame->width; ++ ++ frame->data[0] = (uint8_t*)desc; ++ frame->buf[0] = ++ av_buffer_create((uint8_t*)desc, sizeof(*desc), stcodec_release_frame, ++ framecontextref, AV_BUFFER_FLAG_READONLY); ++ } else if (avctx->pix_fmt == AV_PIX_FMT_NV12) { ++ frame->linesize[0] = get_stride(avctx->width, 8); ++ frame->linesize[1] = get_stride(avctx->width, 8); ++ frame->data[0] = FRAME_GetDataPointer(mppframe, 0); ++ frame->data[1] = frame->data[0] + frame->width * frame->height; ++ frame->buf[0] = av_buffer_create( ++ (uint8_t*)(frame->data[0]), sizeof(frame->data[0]), ++ stcodec_release_frame, framecontextref, AV_BUFFER_FLAG_READONLY); ++ } ++ ++ if (!frame->buf[0]) { ++ av_log(avctx, AV_LOG_ERROR, ++ "Failed to create AVDRMFrameDescriptor ref\n"); ++ ret = AVERROR(ENOMEM); ++ return ret; ++ } ++ ++ frame->hw_frames_ctx = av_buffer_ref(decoder->frames_ref); ++ if (!frame->hw_frames_ctx) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to create hw_frames_ctx\n"); ++ ret = AVERROR(ENOMEM); ++ return ret; ++ } ++ ++ } else { ++ // return AVERROR_UNKNOWN; ++ return AVERROR(EAGAIN); ++ } ++ ++ return 0; // return AVERROR(EAGAIN); ++} ++ ++static void stcodec_flush(AVCodecContext* avctx) { ++ STCODECDecodeContext* st_context = avctx->priv_data; ++ STCODECDecoder* decoder = (STCODECDecoder*)st_context->decoder_ref->data; ++ int ret = -1; ++ ++ av_log(avctx, AV_LOG_ERROR, "Flush.\n"); ++/* ++ ret = VDEC_ResetChannel(decoder->pVdecCtx); ++ if (ret) ++ av_log(avctx, AV_LOG_ERROR, "Failed to reset VDEC Channel (code = %d)\n", ++ ret); ++*/ ++ decoder->eos_reached = 0; ++} ++ ++static const AVCodecHWConfigInternal* const stcodec_hw_configs[] = { ++ HW_CONFIG_INTERNAL(DRM_PRIME), NULL}; ++ ++#define STCODEC_DEC_CLASS(NAME) \ ++ static const AVClass stcodec_##NAME##_dec_class = { \ ++ .class_name = "stcodec_" #NAME "_dec", \ ++ .version = LIBAVUTIL_VERSION_INT, \ ++ }; ++ ++#define STCODEC_DEC(NAME, ID, BSFS) \ ++ STCODEC_DEC_CLASS(NAME) \ ++ AVCodec ff_##NAME##_stcodec_decoder = { \ ++ .name = #NAME "_stcodec", \ ++ .long_name = NULL_IF_CONFIG_SMALL(#NAME " (stcodec decoder)"), \ ++ .type = AVMEDIA_TYPE_VIDEO, \ ++ .id = ID, \ ++ .priv_data_size = sizeof(STCODECDecodeContext), \ ++ .init = stcodec_init_decoder, \ ++ .close = stcodec_close_decoder, \ ++ .receive_frame = stcodec_receive_frame, \ ++ .flush = stcodec_flush, \ ++ .priv_class = &stcodec_##NAME##_dec_class, \ ++ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | \ ++ AV_CODEC_CAP_HARDWARE, \ ++ .pix_fmts = \ ++ (const enum AVPixelFormat[]){AV_PIX_FMT_DRM_PRIME, AV_PIX_FMT_NV12, \ ++ AV_PIX_FMT_NONE}, \ ++ .hw_configs = stcodec_hw_configs, \ ++ .bsfs = BSFS, \ ++ .wrapper_name = "stcodec", \ ++ }; ++ ++STCODEC_DEC(h264, AV_CODEC_ID_H264, "h264_mp4toannexb") ++STCODEC_DEC(hevc, AV_CODEC_ID_HEVC, "hevc_mp4toannexb") ++STCODEC_DEC(mjpeg, AV_CODEC_ID_MJPEG, NULL) +-- +2.25.1 + diff --git a/package/ffmpeg/Config.in b/package/ffmpeg/Config.in index 52029c2a..08be8d5b 100644 --- a/package/ffmpeg/Config.in +++ b/package/ffmpeg/Config.in @@ -18,6 +18,7 @@ config BR2_PACKAGE_FFMPEG_ARCH_SUPPORTS menuconfig BR2_PACKAGE_FFMPEG bool "ffmpeg" depends on BR2_PACKAGE_FFMPEG_ARCH_SUPPORTS + select BR2_PACKAGE_MPP help FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. @@ -32,6 +33,12 @@ config BR2_PACKAGE_FFMPEG_GPL allow use of GPL code, the resulting libs and binaries will be under GPL +config BR2_PACKAGE_FFMPEG_SPACEMIT_CODEC + bool "Enable spacemit hardware codec" + depends on BR2_PACKAGE_FFMPEG_GPL + help + allow use of spacemit hardware codec + config BR2_PACKAGE_FFMPEG_NONFREE bool "Enable nonfree code" help diff --git a/package/ffmpeg/ffmpeg.mk b/package/ffmpeg/ffmpeg.mk index ce285bcc..19434cc8 100644 --- a/package/ffmpeg/ffmpeg.mk +++ b/package/ffmpeg/ffmpeg.mk @@ -66,6 +66,12 @@ else FFMPEG_CONF_OPTS += --disable-gpl endif +ifeq ($(BR2_PACKAGE_FFMPEG_SPACEMIT_CODEC),y) +FFMPEG_DEPENDENCIES += mpp +FFMPEG_CONF_OPTS += --extra-libs=-lspacemit_mpp +FFMPEG_CONF_OPTS += --enable-stcodec +endif + ifeq ($(BR2_PACKAGE_FFMPEG_NONFREE),y) FFMPEG_CONF_OPTS += --enable-nonfree else diff --git a/package/glmark2/0003-fix-compatibility-with-python-3.11.patch b/package/glmark2/0003-fix-compatibility-with-python-3.11.patch new file mode 100644 index 00000000..53037e4c --- /dev/null +++ b/package/glmark2/0003-fix-compatibility-with-python-3.11.patch @@ -0,0 +1,48 @@ +From 67ac4d9efb240a9179e056efd79ba5c5ee436c5e Mon Sep 17 00:00:00 2001 +From: dengbo +Date: Tue, 21 Nov 2023 20:09:24 +0800 +Subject: [PATCH] fix compatibility with python-3.11 + +--- + waflib/ConfigSet.py | 2 +- + waflib/Context.py | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/waflib/ConfigSet.py b/waflib/ConfigSet.py +index 16142a2..87de4ad 100644 +--- a/waflib/ConfigSet.py ++++ b/waflib/ConfigSet.py +@@ -140,7 +140,7 @@ class ConfigSet(object): + Utils.writef(filename,''.join(buf)) + def load(self,filename): + tbl=self.table +- code=Utils.readf(filename,m='rU') ++ code=Utils.readf(filename,m='r') + for m in re_imp.finditer(code): + g=m.group + tbl[g(2)]=eval(g(3)) +diff --git a/waflib/Context.py b/waflib/Context.py +index 8f2cbfb..77f310e 100644 +--- a/waflib/Context.py ++++ b/waflib/Context.py +@@ -109,7 +109,7 @@ class Context(ctx): + cache[node]=True + self.pre_recurse(node) + try: +- function_code=node.read('rU',encoding) ++ function_code=node.read('r',encoding) + exec(compile(function_code,node.abspath(),'exec'),self.exec_dict) + finally: + self.post_recurse(node) +@@ -340,7 +340,7 @@ def load_module(path,encoding=None): + pass + module=imp.new_module(WSCRIPT_FILE) + try: +- code=Utils.readf(path,m='rU',encoding=encoding) ++ code=Utils.readf(path,m='r',encoding=encoding) + except EnvironmentError: + raise Errors.WafError('Could not read the file %r'%path) + module_dir=os.path.dirname(path) +-- +2.34.1 + diff --git a/package/glmark2/glmark2.mk b/package/glmark2/glmark2.mk index bac9d9ff..e8d6f71d 100644 --- a/package/glmark2/glmark2.mk +++ b/package/glmark2/glmark2.mk @@ -10,9 +10,6 @@ GLMARK2_LICENSE = GPL-3.0+, SGIv1 GLMARK2_LICENSE_FILES = COPYING COPYING.SGI GLMARK2_DEPENDENCIES = host-pkgconf jpeg libegl libpng -# The bundled waf script is too old for >= python3.11 -GLMARK2_NEEDS_EXTERNAL_WAF = YES - ifeq ($(BR2_PACKAGE_GLMARK2_FLAVOR_DRM_GLESV2),y) GLMARK2_DEPENDENCIES += libdrm libgbm libgles udev GLMARK2_FLAVORS += drm-glesv2 diff --git a/package/libdrm/0001-libsync-add-support-for-pre-v4.7-kernels.patch b/package/libdrm/0001-libsync-add-support-for-pre-v4.7-kernels.patch new file mode 100644 index 00000000..ddd29818 --- /dev/null +++ b/package/libdrm/0001-libsync-add-support-for-pre-v4.7-kernels.patch @@ -0,0 +1,92 @@ +From 3dda0a2fff3346dce61cec8db864fd493c775e61 Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Tue, 13 Jun 2017 15:52:44 +0100 +Subject: [PATCH 1/3] libsync: add support for pre-v4.7 kernels + +Add support for the the sync merge ioctl supported by older kernels. +--- + libsync.h | 44 +++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 41 insertions(+), 3 deletions(-) + +diff --git a/libsync.h b/libsync.h +index f1a2f96d..c3b8a385 100644 +--- a/libsync.h ++++ b/libsync.h +@@ -40,6 +40,10 @@ + extern "C" { + #endif + ++#ifndef SYNC_IOC_MAGIC ++#define SYNC_IOC_MAGIC '>' ++#endif ++ + #ifndef SYNC_IOC_MERGE + /* duplicated from linux/sync_file.h to avoid build-time dependency + * on new (v4.7) kernel headers. Once distro's are mostly using +@@ -53,10 +57,22 @@ struct sync_merge_data { + uint32_t flags; + uint32_t pad; + }; +-#define SYNC_IOC_MAGIC '>' + #define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data) + #endif + ++#ifndef SYNC_IOC_LEGACY_MERGE ++/* the legacy definitions are based on the contents of ++ * drivers/staging/android/uapi/sync.h in the v4.4 kernel. ++ */ ++struct sync_legacy_merge_data { ++ int32_t fd2; ++ char name[32]; ++ int32_t fence; ++}; ++ ++#define SYNC_IOC_LEGACY_MERGE _IOWR(SYNC_IOC_MAGIC, 1, \ ++ struct sync_legacy_merge_data) ++#endif + + static inline int sync_wait(int fd, int timeout) + { +@@ -83,6 +99,24 @@ static inline int sync_wait(int fd, int timeout) + return ret; + } + ++static inline int sync_legacy_merge(const char *name, int fd1, int fd2) ++{ ++ struct sync_legacy_merge_data data; ++ int ret; ++ ++ data.fd2 = fd2; ++ strncpy(data.name, name, sizeof(data.name)); ++ ++ do { ++ ret = ioctl(fd1, SYNC_IOC_LEGACY_MERGE, &data); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) ++ return ret; ++ ++ return data.fence; ++} ++ + static inline int sync_merge(const char *name, int fd1, int fd2) + { + struct sync_merge_data data = {0}; +@@ -95,8 +129,12 @@ static inline int sync_merge(const char *name, int fd1, int fd2) + ret = ioctl(fd1, SYNC_IOC_MERGE, &data); + } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); + +- if (ret < 0) +- return ret; ++ if (ret < 0) { ++ if (errno == ENOTTY) ++ return sync_legacy_merge(name, fd1, fd2); ++ else ++ return ret; ++ } + + return data.fence; + } +-- +2.34.1 + diff --git a/package/libdrm/0001-tests-meson.build-disable-nouveau-tests-for-static-b.patch b/package/libdrm/0001-tests-meson.build-disable-nouveau-tests-for-static-b.patch deleted file mode 100644 index e2e18e12..00000000 --- a/package/libdrm/0001-tests-meson.build-disable-nouveau-tests-for-static-b.patch +++ /dev/null @@ -1,43 +0,0 @@ -From c9036706b9f724f09ac6288f82b53f2e76264ec7 Mon Sep 17 00:00:00 2001 -From: Peter Seiderer -Date: Mon, 25 Nov 2019 15:59:15 +0100 -Subject: [PATCH] tests/meson.build: disable nouveau tests for static build - -Signed-off-by: Peter Seiderer ---- -Notes: - - - the existing test/check for static build in meson.build does not - catch this case because e.g. the buildroot toolchain - br-arm-full-static-2019.05.1 provides an empty libdl.a - - 169 # Among others FreeBSD does not have a separate dl library. - 170 if not cc.has_function('dlsym') - 171 dep_dl = cc.find_library('dl', required : with_nouveau) - 172 else - 173 dep_dl = [] - 174 endif ---- - tests/meson.build | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/tests/meson.build b/tests/meson.build -index 6c8ddd9..f7cb5f0 100644 ---- a/tests/meson.build -+++ b/tests/meson.build -@@ -44,8 +44,11 @@ endif - if with_etnaviv - subdir('etnaviv') - endif -+lib_type = get_option('default_library') - if with_nouveau -- subdir('nouveau') -+ if lib_type != 'static' -+ subdir('nouveau') -+ endif - endif - - drmsl = executable( --- -2.24.0 - diff --git a/package/libdrm/0002-Add-sync_fence_info-and-sync_pt_info.patch b/package/libdrm/0002-Add-sync_fence_info-and-sync_pt_info.patch new file mode 100644 index 00000000..8c5af89a --- /dev/null +++ b/package/libdrm/0002-Add-sync_fence_info-and-sync_pt_info.patch @@ -0,0 +1,212 @@ +From 354474609ec628105deec54972bd478bb11403cf Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Thu, 24 Aug 2017 13:28:38 +0100 +Subject: [PATCH 2/3] Add sync_fence_info and sync_pt_info + +For pre-4.7 kernels, sync_fence_info returns the data from the +SYNC_IOC_FENCE_INFO ioctl. For newer kernels, the SYNC_IOC_FILE_INFO +ioctl is called, and the data converted to SYNC_IOC_FENCE_INFO form. +--- + libsync.h | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 172 insertions(+) + +diff --git a/libsync.h b/libsync.h +index c3b8a385..44f7330d 100644 +--- a/libsync.h ++++ b/libsync.h +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -74,6 +75,54 @@ struct sync_legacy_merge_data { + struct sync_legacy_merge_data) + #endif + ++#ifndef SYNC_IOC_FILE_INFO ++/* duplicated from linux/sync_file.h to avoid a build-time dependency ++ * on new (v4.7) kernel headers. ++ */ ++struct sync_fence_info { ++ char obj_name[32]; ++ char driver_name[32]; ++ int32_t status; ++ uint32_t flags; ++ uint64_t timestamp_ns; ++}; ++ ++struct sync_file_info { ++ char name[32]; ++ int32_t status; ++ uint32_t flags; ++ uint32_t num_fences; ++ uint32_t pad; ++ uint64_t sync_fence_info; ++}; ++ ++#define SYNC_IOC_FILE_INFO _IOWR(SYNC_IOC_MAGIC, 4, struct sync_file_info) ++#endif ++ ++#ifndef SYNC_IOC_LEGACY_FENCE_INFO ++/* the legacy definitions are based on the contents of ++ * drivers/staging/android/uapi/sync.h in the v4.4 kernel. ++ */ ++struct sync_pt_info { ++ uint32_t len; ++ char obj_name[32]; ++ char driver_name[32]; ++ int32_t status; ++ uint64_t timestamp_ns; ++ uint8_t driver_data[0]; ++}; ++ ++struct sync_fence_info_data { ++ uint32_t len; ++ char name[32]; ++ int32_t status; ++ uint8_t pt_info[0]; ++}; ++ ++#define SYNC_IOC_LEGACY_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2, \ ++ struct sync_fence_info_data) ++#endif ++ + static inline int sync_wait(int fd, int timeout) + { + struct pollfd fds = {0}; +@@ -179,6 +228,129 @@ static inline int sync_accumulate(const char *name, int *fd1, int fd2) + return 0; + } + ++static inline struct sync_pt_info *sync_pt_info( ++ struct sync_fence_info_data *info, ++ struct sync_pt_info *pt_info) ++{ ++ if (!pt_info) ++ pt_info = (struct sync_pt_info *)info->pt_info; ++ else ++ pt_info = (struct sync_pt_info *)((uint8_t *)pt_info + ++ pt_info->len); ++ ++ if ((uint32_t)((uint8_t *)pt_info - (uint8_t *)info) >= info->len) ++ return NULL; ++ ++ return pt_info; ++} ++ ++static inline struct sync_fence_info_data *sync_legacy_fence_info(int fd) ++{ ++ const uint32_t len = 4096; ++ struct sync_fence_info_data *info = malloc(len); ++ int ret; ++ ++ if (!info) ++ return NULL; ++ ++ info->len = len; ++ ++ do { ++ ret = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, info); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) { ++ free(info); ++ return NULL; ++ } ++ ++ return info; ++} ++ ++static inline struct sync_fence_info_data *fence_info_from_file_info( ++ struct sync_file_info *file_info, ++ uint32_t num_fences) ++{ ++ struct sync_fence_info_data *info; ++ size_t info_len; ++ struct sync_pt_info *pt_info = NULL; ++ struct sync_fence_info *fence_info; ++ uint32_t i; ++ ++ info_len = sizeof(*info) + num_fences * sizeof(*pt_info); ++ info = malloc(info_len); ++ if (!info) ++ return NULL; ++ ++ info->len = info_len; ++ strncpy(info->name, file_info->name, sizeof(info->name)); ++ info->status = file_info->status; ++ ++ fence_info = (struct sync_fence_info *)(uintptr_t) ++ file_info->sync_fence_info; ++ for (i = 0; i < num_fences; i++) { ++ pt_info = sync_pt_info(info, pt_info); ++ assert(pt_info); ++ ++ pt_info->len = sizeof(*pt_info); ++ strncpy(pt_info->obj_name, fence_info->obj_name, ++ sizeof(pt_info->obj_name)); ++ strncpy(pt_info->driver_name, fence_info->driver_name, ++ sizeof(pt_info->driver_name)); ++ pt_info->status = fence_info->status; ++ pt_info->timestamp_ns = fence_info->timestamp_ns; ++ ++ fence_info++; ++ } ++ ++ return info; ++} ++ ++static inline struct sync_fence_info_data *sync_fence_info(int fd) ++{ ++ struct sync_fence_info_data *info = NULL; ++ struct sync_file_info initial_info = {""}; ++ struct sync_file_info *file_info; ++ int ret; ++ ++ do { ++ ret = ioctl(fd, SYNC_IOC_FILE_INFO, &initial_info); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) { ++ if (errno == ENOTTY) ++ return sync_legacy_fence_info(fd); ++ else ++ return NULL; ++ } ++ ++ file_info = calloc(1, sizeof(*file_info) + initial_info.num_fences * ++ sizeof(struct sync_fence_info)); ++ if (!file_info) ++ return NULL; ++ ++ file_info->num_fences = initial_info.num_fences; ++ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1); ++ ++ do { ++ ret = ioctl(fd, SYNC_IOC_FILE_INFO, file_info); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) ++ goto free_file_info; ++ ++ info = fence_info_from_file_info(file_info, initial_info.num_fences); ++ ++free_file_info: ++ free(file_info); ++ ++ return info; ++} ++ ++static inline void sync_fence_info_free(struct sync_fence_info_data *info) ++{ ++ free(info); ++} + #if defined(__cplusplus) + } + #endif +-- +2.34.1 + diff --git a/package/libdrm/0003-Add-sync_file_info-and-sync_get_fence_info.patch b/package/libdrm/0003-Add-sync_file_info-and-sync_get_fence_info.patch new file mode 100644 index 00000000..71cd27ee --- /dev/null +++ b/package/libdrm/0003-Add-sync_file_info-and-sync_get_fence_info.patch @@ -0,0 +1,148 @@ +From a3188f2de5c1c45d4f9ec0a30ee3d30e4c82d6ea Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Mon, 9 Mar 2020 14:52:17 +0000 +Subject: [PATCH 3/3] Add sync_file_info and sync_get_fence_info + +For pre-4.7 kernels, sync_file_info calls the SYNC_IOC_FENCE_INFO ioctl, +and converts the data to SYNC_IOC_FILE_INFO form. For newer kernels, +sync_file_info returns data from the SYNC_IOC_FILE_INFO ioctl. + +This patch depends on patch "Add sync_fence_info and sync_pt_info", +which added legacy sync info support, using the structure and ioctl +definitions at the top of the patch, as well as the sync_pt_info +function. +--- + libsync.h | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 117 insertions(+) + +diff --git a/libsync.h b/libsync.h +index 44f7330d..54acb6fa 100644 +--- a/libsync.h ++++ b/libsync.h +@@ -351,6 +351,123 @@ static inline void sync_fence_info_free(struct sync_fence_info_data *info) + { + free(info); + } ++ ++static inline struct sync_fence_info *sync_get_fence_info( ++ struct sync_file_info *file_info) ++{ ++ return (struct sync_fence_info *)(uintptr_t)file_info->sync_fence_info; ++} ++ ++static inline struct sync_file_info *file_info_from_info_data( ++ struct sync_fence_info_data *info) ++{ ++ struct sync_pt_info *pt_info = NULL; ++ uint32_t num_fences = 0; ++ struct sync_file_info *file_info; ++ struct sync_fence_info *fence_info; ++ uint32_t i; ++ ++ while ((pt_info = sync_pt_info(info, pt_info)) != NULL) ++ num_fences++; ++ ++ file_info = calloc(1, sizeof(*file_info) + num_fences * ++ sizeof(*fence_info)); ++ if (!file_info) ++ return NULL; ++ ++ strncpy(file_info->name, info->name, sizeof(file_info->name)); ++ file_info->status = info->status; ++ file_info->num_fences = num_fences; ++ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1); ++ ++ fence_info = sync_get_fence_info(file_info); ++ for (i = 0; i < num_fences; i++) { ++ pt_info = sync_pt_info(info, pt_info); ++ assert(pt_info); ++ ++ strncpy(fence_info->obj_name, pt_info->obj_name, ++ sizeof(fence_info->obj_name)); ++ strncpy(fence_info->driver_name, pt_info->driver_name, ++ sizeof(fence_info->driver_name)); ++ fence_info->status = pt_info->status; ++ fence_info->timestamp_ns = pt_info->timestamp_ns; ++ ++ fence_info++; ++ } ++ ++ return file_info; ++} ++ ++static inline struct sync_file_info *sync_legacy_file_info(int fd) ++{ ++ const uint32_t len = 4096; ++ struct sync_fence_info_data *info = malloc(len); ++ struct sync_file_info *file_info; ++ int ret; ++ ++ if (!info) ++ return NULL; ++ ++ info->len = len; ++ ++ do { ++ ret = ioctl(fd, SYNC_IOC_LEGACY_FENCE_INFO, info); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) { ++ free(info); ++ return NULL; ++ } ++ ++ file_info = file_info_from_info_data(info); ++ ++ free(info); ++ ++ return file_info; ++} ++ ++static inline void sync_file_info_free(struct sync_file_info *file_info) ++{ ++ free(file_info); ++} ++ ++static inline struct sync_file_info *sync_file_info(int fd) ++{ ++ struct sync_file_info initial_info = {""}; ++ struct sync_file_info *file_info; ++ int ret; ++ ++ do { ++ ret = ioctl(fd, SYNC_IOC_FILE_INFO, &initial_info); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) { ++ if (errno == ENOTTY) ++ return sync_legacy_file_info(fd); ++ else ++ return NULL; ++ } ++ ++ file_info = calloc(1, sizeof(*file_info) + initial_info.num_fences * ++ sizeof(struct sync_fence_info)); ++ if (!file_info) ++ return NULL; ++ ++ file_info->num_fences = initial_info.num_fences; ++ file_info->sync_fence_info = (uint64_t)(uintptr_t)(file_info + 1); ++ ++ do { ++ ret = ioctl(fd, SYNC_IOC_FILE_INFO, file_info); ++ } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); ++ ++ if (ret < 0) { ++ sync_file_info_free(file_info); ++ return NULL; ++ } ++ ++ return file_info; ++} ++ + #if defined(__cplusplus) + } + #endif +-- +2.34.1 + diff --git a/package/libdrm/libdrm.hash b/package/libdrm/libdrm.hash deleted file mode 100644 index 87cc1706..00000000 --- a/package/libdrm/libdrm.hash +++ /dev/null @@ -1,6 +0,0 @@ -# From https://lists.x.org/archives/xorg-announce/2023-February/003323.html -sha256 554cfbfe0542bddb391b4e3e05bfbbfc3e282b955bd56218d21c0616481f65eb libdrm-2.4.115.tar.xz -sha512 0c38d3cfd76f627b899f052527c2939d5fc87a417422dceb0761839ba21e69736703a87ba170b5ba7a4aca2506a240760c8c97ca1781a7fb78468225295293bd libdrm-2.4.115.tar.xz - -# Hash for license file -sha256 d0a616a9020dc0271e36e6dd4bad174b4e2c2a42636f13785f8e18dd5f85fd83 data/meson.build diff --git a/package/libdrm/libdrm.mk b/package/libdrm/libdrm.mk index 52ac13b7..b64db069 100644 --- a/package/libdrm/libdrm.mk +++ b/package/libdrm/libdrm.mk @@ -4,7 +4,7 @@ # ################################################################################ -LIBDRM_VERSION = 2.4.115 +LIBDRM_VERSION = 2.4.110 LIBDRM_SOURCE = libdrm-$(LIBDRM_VERSION).tar.xz LIBDRM_SITE = https://dri.freedesktop.org/libdrm LIBDRM_LICENSE = MIT @@ -16,8 +16,8 @@ LIBDRM_DEPENDENCIES = \ host-pkgconf LIBDRM_CONF_OPTS = \ - -Dcairo-tests=disabled \ - -Dman-pages=disabled + -Dcairo-tests=false \ + -Dman-pages=false ifeq ($(BR2_PACKAGE_LIBATOMIC_OPS),y) LIBDRM_DEPENDENCIES += libatomic_ops @@ -27,70 +27,70 @@ endif endif ifeq ($(BR2_PACKAGE_LIBDRM_INTEL),y) -LIBDRM_CONF_OPTS += -Dintel=enabled +LIBDRM_CONF_OPTS += -Dintel=true LIBDRM_DEPENDENCIES += libpciaccess else -LIBDRM_CONF_OPTS += -Dintel=disabled +LIBDRM_CONF_OPTS += -Dintel=false endif ifeq ($(BR2_PACKAGE_LIBDRM_RADEON),y) -LIBDRM_CONF_OPTS += -Dradeon=enabled +LIBDRM_CONF_OPTS += -Dradeon=true else -LIBDRM_CONF_OPTS += -Dradeon=disabled +LIBDRM_CONF_OPTS += -Dradeon=false endif ifeq ($(BR2_PACKAGE_LIBDRM_AMDGPU),y) -LIBDRM_CONF_OPTS += -Damdgpu=enabled +LIBDRM_CONF_OPTS += -Damdgpu=true else -LIBDRM_CONF_OPTS += -Damdgpu=disabled +LIBDRM_CONF_OPTS += -Damdgpu=false endif ifeq ($(BR2_PACKAGE_LIBDRM_NOUVEAU),y) -LIBDRM_CONF_OPTS += -Dnouveau=enabled +LIBDRM_CONF_OPTS += -Dnouveau=true else -LIBDRM_CONF_OPTS += -Dnouveau=disabled +LIBDRM_CONF_OPTS += -Dnouveau=false endif ifeq ($(BR2_PACKAGE_LIBDRM_VMWGFX),y) -LIBDRM_CONF_OPTS += -Dvmwgfx=enabled +LIBDRM_CONF_OPTS += -Dvmwgfx=true else -LIBDRM_CONF_OPTS += -Dvmwgfx=disabled +LIBDRM_CONF_OPTS += -Dvmwgfx=false endif ifeq ($(BR2_PACKAGE_LIBDRM_OMAP),y) -LIBDRM_CONF_OPTS += -Domap=enabled +LIBDRM_CONF_OPTS += -Domap=true else -LIBDRM_CONF_OPTS += -Domap=disabled +LIBDRM_CONF_OPTS += -Domap=false endif ifeq ($(BR2_PACKAGE_LIBDRM_ETNAVIV),y) -LIBDRM_CONF_OPTS += -Detnaviv=enabled +LIBDRM_CONF_OPTS += -Detnaviv=true else -LIBDRM_CONF_OPTS += -Detnaviv=disabled +LIBDRM_CONF_OPTS += -Detnaviv=false endif ifeq ($(BR2_PACKAGE_LIBDRM_EXYNOS),y) -LIBDRM_CONF_OPTS += -Dexynos=enabled +LIBDRM_CONF_OPTS += -Dexynos=true else -LIBDRM_CONF_OPTS += -Dexynos=disabled +LIBDRM_CONF_OPTS += -Dexynos=false endif ifeq ($(BR2_PACKAGE_LIBDRM_FREEDRENO),y) -LIBDRM_CONF_OPTS += -Dfreedreno=enabled +LIBDRM_CONF_OPTS += -Dfreedreno=true else -LIBDRM_CONF_OPTS += -Dfreedreno=disabled +LIBDRM_CONF_OPTS += -Dfreedreno=false endif ifeq ($(BR2_PACKAGE_LIBDRM_TEGRA),y) -LIBDRM_CONF_OPTS += -Dtegra=enabled +LIBDRM_CONF_OPTS += -Dtegra=true else -LIBDRM_CONF_OPTS += -Dtegra=disabled +LIBDRM_CONF_OPTS += -Dtegra=false endif ifeq ($(BR2_PACKAGE_LIBDRM_VC4),y) -LIBDRM_CONF_OPTS += -Dvc4=enabled +LIBDRM_CONF_OPTS += -Dvc4=true else -LIBDRM_CONF_OPTS += -Dvc4=disabled +LIBDRM_CONF_OPTS += -Dvc4=false endif ifeq ($(BR2_PACKAGE_HAS_UDEV),y) @@ -101,10 +101,10 @@ LIBDRM_CONF_OPTS += -Dudev=false endif ifeq ($(BR2_PACKAGE_VALGRIND),y) -LIBDRM_CONF_OPTS += -Dvalgrind=enabled +LIBDRM_CONF_OPTS += -Dvalgrind=true LIBDRM_DEPENDENCIES += valgrind else -LIBDRM_CONF_OPTS += -Dvalgrind=disabled +LIBDRM_CONF_OPTS += -Dvalgrind=false endif ifeq ($(BR2_PACKAGE_LIBDRM_INSTALL_TESTS),y) diff --git a/package/libopenssl/0008-afalg-engine-support-aes-ecb.patch b/package/libopenssl/0008-afalg-engine-support-aes-ecb.patch new file mode 100644 index 00000000..b9b2b26c --- /dev/null +++ b/package/libopenssl/0008-afalg-engine-support-aes-ecb.patch @@ -0,0 +1,232 @@ +From e3e0e0f6741cfd44a1b28dff73b394b4afcf04ae Mon Sep 17 00:00:00 2001 +From: yanhaodong +Date: Wed, 17 Jan 2024 20:25:02 +0800 +Subject: [PATCH] afalg engine support aes-ecb + +--- + engines/e_afalg.c | 106 +++++++++++++++++++++++++++++++++++++++++----- + engines/e_afalg.h | 12 ++++++ + 2 files changed, 107 insertions(+), 11 deletions(-) + +diff --git a/engines/e_afalg.c b/engines/e_afalg.c +index 14d1d47..18582a8 100644 +--- a/engines/e_afalg.c ++++ b/engines/e_afalg.c +@@ -77,7 +77,9 @@ static int afalg_destroy(ENGINE *e); + static int afalg_init(ENGINE *e); + static int afalg_finish(ENGINE *e); + static const EVP_CIPHER *afalg_aes_cbc(int nid); +-static cbc_handles *get_cipher_handle(int nid); ++static const EVP_CIPHER *afalg_aes_ecb(int nid); ++static cbc_handles *cbc_get_cipher_handle(int nid); ++static ecb_handles *ecb_get_cipher_handle(int nid); + static int afalg_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid); + static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, +@@ -95,11 +97,17 @@ static int afalg_cipher_nids[] = { + NID_aes_128_cbc, + NID_aes_192_cbc, + NID_aes_256_cbc, ++ NID_aes_128_ecb, ++ NID_aes_192_ecb, ++ NID_aes_256_ecb, + }; + + static cbc_handles cbc_handle[] = {{AES_KEY_SIZE_128, NULL}, + {AES_KEY_SIZE_192, NULL}, + {AES_KEY_SIZE_256, NULL}}; ++static ecb_handles ecb_handle[] = {{AES_KEY_SIZE_128, NULL}, ++ {AES_KEY_SIZE_192, NULL}, ++ {AES_KEY_SIZE_256, NULL}}; + + static ossl_inline int io_setup(unsigned n, aio_context_t *ctx) + { +@@ -567,6 +575,11 @@ static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + case NID_aes_256_cbc: + ciphername = "cbc(aes)"; + break; ++ case NID_aes_128_ecb: ++ case NID_aes_192_ecb: ++ case NID_aes_256_ecb: ++ ciphername = "ecb(aes)"; ++ break; + default: + ALG_WARN("%s(%d): Unsupported Cipher type %d\n", __FILE__, __LINE__, + ciphertype); +@@ -686,7 +699,7 @@ static int afalg_cipher_cleanup(EVP_CIPHER_CTX *ctx) + return 1; + } + +-static cbc_handles *get_cipher_handle(int nid) ++static cbc_handles *cbc_get_cipher_handle(int nid) + { + switch (nid) { + case NID_aes_128_cbc: +@@ -700,9 +713,23 @@ static cbc_handles *get_cipher_handle(int nid) + } + } + ++static ecb_handles *ecb_get_cipher_handle(int nid) ++{ ++ switch (nid) { ++ case NID_aes_128_ecb: ++ return &ecb_handle[AES_ECB_128]; ++ case NID_aes_192_ecb: ++ return &ecb_handle[AES_ECB_192]; ++ case NID_aes_256_ecb: ++ return &ecb_handle[AES_ECB_256]; ++ default: ++ return NULL; ++ } ++} ++ + static const EVP_CIPHER *afalg_aes_cbc(int nid) + { +- cbc_handles *cipher_handle = get_cipher_handle(nid); ++ cbc_handles *cipher_handle = cbc_get_cipher_handle(nid); + if (cipher_handle->_hidden == NULL + && ((cipher_handle->_hidden = + EVP_CIPHER_meth_new(nid, +@@ -727,6 +754,33 @@ static const EVP_CIPHER *afalg_aes_cbc(int nid) + return cipher_handle->_hidden; + } + ++static const EVP_CIPHER *afalg_aes_ecb(int nid) ++{ ++ ecb_handles *cipher_handle = ecb_get_cipher_handle(nid); ++ if (cipher_handle->_hidden == NULL ++ && ((cipher_handle->_hidden = ++ EVP_CIPHER_meth_new(nid, ++ AES_BLOCK_SIZE, ++ cipher_handle->key_size)) == NULL ++ || !EVP_CIPHER_meth_set_iv_length(cipher_handle->_hidden, ++ AES_IV_LEN) ++ || !EVP_CIPHER_meth_set_flags(cipher_handle->_hidden, ++ EVP_CIPH_ECB_MODE | ++ EVP_CIPH_FLAG_DEFAULT_ASN1) ++ || !EVP_CIPHER_meth_set_init(cipher_handle->_hidden, ++ afalg_cipher_init) ++ || !EVP_CIPHER_meth_set_do_cipher(cipher_handle->_hidden, ++ afalg_do_cipher) ++ || !EVP_CIPHER_meth_set_cleanup(cipher_handle->_hidden, ++ afalg_cipher_cleanup) ++ || !EVP_CIPHER_meth_set_impl_ctx_size(cipher_handle->_hidden, ++ sizeof(afalg_ctx)))) { ++ EVP_CIPHER_meth_free(cipher_handle->_hidden); ++ cipher_handle->_hidden= NULL; ++ } ++ return cipher_handle->_hidden; ++} ++ + static int afalg_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid) + { +@@ -743,6 +797,11 @@ static int afalg_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + case NID_aes_256_cbc: + *cipher = afalg_aes_cbc(nid); + break; ++ case NID_aes_128_ecb: ++ case NID_aes_192_ecb: ++ case NID_aes_256_ecb: ++ *cipher = afalg_aes_ecb(nid); ++ break; + default: + *cipher = NULL; + r = 0; +@@ -771,10 +830,22 @@ static int bind_afalg(ENGINE *e) + * time. + */ + for(i = 0; i < OSSL_NELEM(afalg_cipher_nids); i++) { +- if (afalg_aes_cbc(afalg_cipher_nids[i]) == NULL) { +- AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); +- return 0; +- } ++ switch (i) { ++ case NID_aes_128_cbc: ++ case NID_aes_192_cbc: ++ case NID_aes_256_cbc: ++ if (afalg_aes_cbc(afalg_cipher_nids[i]) == NULL) { ++ AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); ++ break; ++ } ++ case NID_aes_128_ecb: ++ case NID_aes_192_ecb: ++ case NID_aes_256_ecb: ++ if (afalg_aes_ecb(afalg_cipher_nids[i]) == NULL) { ++ AFALGerr(AFALG_F_BIND_AFALG, AFALG_R_INIT_FAILED); ++ break; ++ } ++ } + } + + if (!ENGINE_set_ciphers(e, afalg_ciphers)) { +@@ -886,12 +957,24 @@ static int afalg_finish(ENGINE *e) + return 1; + } + +-static int free_cbc(void) ++static int free_cipher(void) + { + short unsigned int i; + for(i = 0; i < OSSL_NELEM(afalg_cipher_nids); i++) { +- EVP_CIPHER_meth_free(cbc_handle[i]._hidden); +- cbc_handle[i]._hidden = NULL; ++ switch (i) { ++ case NID_aes_128_cbc: ++ case NID_aes_192_cbc: ++ case NID_aes_256_cbc: ++ EVP_CIPHER_meth_free(cbc_handle[i]._hidden); ++ cbc_handle[i]._hidden = NULL; ++ break; ++ case NID_aes_128_ecb: ++ case NID_aes_192_ecb: ++ case NID_aes_256_ecb: ++ EVP_CIPHER_meth_free(ecb_handle[i]._hidden); ++ ecb_handle[i]._hidden = NULL; ++ break; ++ } + } + return 1; + } +@@ -899,7 +982,8 @@ static int free_cbc(void) + static int afalg_destroy(ENGINE *e) + { + ERR_unload_AFALG_strings(); +- free_cbc(); ++ free_cipher(); ++ + return 1; + } + +diff --git a/engines/e_afalg.h b/engines/e_afalg.h +index 3323c89..e68d441 100644 +--- a/engines/e_afalg.h ++++ b/engines/e_afalg.h +@@ -59,12 +59,24 @@ enum { + AES_CBC_256 + }; + ++enum { ++ AES_ECB_128 = 0, ++ AES_ECB_192, ++ AES_ECB_256 ++}; ++ + struct cbc_cipher_handles { + int key_size; + EVP_CIPHER *_hidden; + }; + ++struct ecb_cipher_handles { ++ int key_size; ++ EVP_CIPHER *_hidden; ++}; ++ + typedef struct cbc_cipher_handles cbc_handles; ++typedef struct ecb_cipher_handles ecb_handles; + + struct afalg_aio_st { + int efd; +-- +2.25.1 + diff --git a/package/libopenssl/libopenssl.mk b/package/libopenssl/libopenssl.mk index 651283a8..87a91caa 100644 --- a/package/libopenssl/libopenssl.mk +++ b/package/libopenssl/libopenssl.mk @@ -82,7 +82,6 @@ define LIBOPENSSL_CONFIGURE_CMDS no-tests \ no-fuzz-libfuzzer \ no-fuzz-afl \ - no-afalgeng \ $(if $(BR2_PACKAGE_LIBOPENSSL_ENABLE_CHACHA),,no-chacha) \ $(if $(BR2_PACKAGE_LIBOPENSSL_ENABLE_RC2),,no-rc2) \ $(if $(BR2_PACKAGE_LIBOPENSSL_ENABLE_RC4),,no-rc4) \ diff --git a/package/linux-tools/linux-tool-perf.mk.in b/package/linux-tools/linux-tool-perf.mk.in index ee308a85..54159975 100644 --- a/package/linux-tools/linux-tool-perf.mk.in +++ b/package/linux-tools/linux-tool-perf.mk.in @@ -20,7 +20,7 @@ endif PERF_MAKE_FLAGS = \ $(LINUX_MAKE_FLAGS) \ - JOBS=$(PARALLEL_JOBS) \ + JOBS=1 \ ARCH=$(PERF_ARCH) \ DESTDIR=$(TARGET_DIR) \ prefix=/usr \ diff --git a/package/lmbench/lmbench.mk b/package/lmbench/lmbench.mk old mode 100644 new mode 100755 index b0f99ff1..f04650f5 --- a/package/lmbench/lmbench.mk +++ b/package/lmbench/lmbench.mk @@ -40,7 +40,14 @@ define LMBENCH_BUILD_CMDS endef define LMBENCH_INSTALL_TARGET_CMDS - $(TARGET_MAKE_ENV) $(MAKE) CFLAGS="$(TARGET_CFLAGS)" OS=$(ARCH) CC="$(TARGET_CC)" BASE=$(TARGET_DIR)/usr -C $(@D)/src install + $(INSTALL) -d $(TARGET_DIR)/usr/bin/lmbench + $(INSTALL) -d $(TARGET_DIR)/usr/bin/lmbench/scripts + $(INSTALL) -d $(TARGET_DIR)/usr/bin/lmbench/bin + + cp -rf $(@D)/scripts/* $(TARGET_DIR)/usr/bin/lmbench/scripts + cp -rf $(@D)/bin/* $(TARGET_DIR)/usr/bin/lmbench/bin + rm -f $(TARGET_DIR)/usr/bin/lmbench/bin/*.o + endef $(eval $(generic-package)) diff --git a/package/ltp-testsuite/0002-fix-compile-err-when-sysroot-has-mount_setattr.patch b/package/ltp-testsuite/0002-fix-compile-err-when-sysroot-has-mount_setattr.patch new file mode 100644 index 00000000..6b235c3c --- /dev/null +++ b/package/ltp-testsuite/0002-fix-compile-err-when-sysroot-has-mount_setattr.patch @@ -0,0 +1,12 @@ +diff --git a/include/lapi/fsmount.h b/include/lapi/fsmount.h +index 07eb42f..1bcc5b4 100644 +--- a/include/lapi/fsmount.h ++++ b/include/lapi/fsmount.h +@@ -48,6 +48,7 @@ + # define ST_NOSYMFOLLOW 0x2000 /* do not follow symlinks */ + #endif + ++#define HAVE_STRUCT_MOUNT_ATTR 1 + #ifndef HAVE_STRUCT_MOUNT_ATTR + /* + * mount_setattr() diff --git a/package/mesa3d/0001-Add-PVR-Gallium-driver.patch b/package/mesa3d/0001-Add-PVR-Gallium-driver.patch new file mode 100644 index 00000000..081b0977 --- /dev/null +++ b/package/mesa3d/0001-Add-PVR-Gallium-driver.patch @@ -0,0 +1,5425 @@ +From 0c36f5c4c29a82a7c9f5c03dea1f92f1bc121609 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 21 Mar 2022 19:08:33 +0000 +Subject: [PATCH 001/168] Add PVR Gallium driver + +The driver is essentially a Gallium frontend for the proprietary +Imagination Technologies driver. It makes use of the Gallium DRI +infrastructure, but little else. +--- + meson.build | 20 +- + meson_options.txt | 8 +- + src/gallium/drivers/pvr/meson.build | 23 + + src/gallium/drivers/pvr_alias/meson.build | 23 + + src/gallium/frontends/dri/dri2.c | 8 + + .../frontends/dri/dri_query_renderer.c | 2 +- + .../frontends/dri/dri_query_renderer.h | 3 + + src/gallium/frontends/dri/dri_screen.c | 4 +- + src/gallium/frontends/dri/dri_screen.h | 14 + + src/gallium/frontends/dri/dri_util.c | 40 +- + src/gallium/frontends/dri/dri_util.h | 23 + + src/gallium/frontends/dri/drisw.c | 4 + + src/gallium/frontends/dri/meson.build | 4 + + src/gallium/frontends/pvr/dri_support.h | 633 ++++++++++++ + src/gallium/frontends/pvr/img_drm_fourcc.h | 113 +++ + src/gallium/frontends/pvr/imgpixfmts.h | 307 ++++++ + src/gallium/frontends/pvr/imgyuv.h | 58 ++ + src/gallium/frontends/pvr/mesa_context.c | 208 ++++ + src/gallium/frontends/pvr/meson.build | 46 + + src/gallium/frontends/pvr/pvrcb.c | 344 +++++++ + src/gallium/frontends/pvr/pvrcompat.c | 912 ++++++++++++++++++ + src/gallium/frontends/pvr/pvrdri.c | 630 ++++++++++++ + src/gallium/frontends/pvr/pvrdri.h | 190 ++++ + src/gallium/frontends/pvr/pvrdri_support.h | 233 +++++ + src/gallium/frontends/pvr/pvrext.c | 796 +++++++++++++++ + src/gallium/frontends/pvr/pvrmesa.h | 36 + + src/gallium/frontends/pvr/pvrutil.c | 238 +++++ + src/gallium/meson.build | 15 + + src/gallium/targets/dri/meson.build | 8 +- + src/gallium/targets/dri/target.c | 18 + + src/meson.build | 2 + + 31 files changed, 4945 insertions(+), 18 deletions(-) + create mode 100644 src/gallium/drivers/pvr/meson.build + create mode 100644 src/gallium/drivers/pvr_alias/meson.build + create mode 100644 src/gallium/frontends/pvr/dri_support.h + create mode 100644 src/gallium/frontends/pvr/img_drm_fourcc.h + create mode 100644 src/gallium/frontends/pvr/imgpixfmts.h + create mode 100644 src/gallium/frontends/pvr/imgyuv.h + create mode 100644 src/gallium/frontends/pvr/mesa_context.c + create mode 100644 src/gallium/frontends/pvr/meson.build + create mode 100644 src/gallium/frontends/pvr/pvrcb.c + create mode 100644 src/gallium/frontends/pvr/pvrcompat.c + create mode 100644 src/gallium/frontends/pvr/pvrdri.c + create mode 100644 src/gallium/frontends/pvr/pvrdri.h + create mode 100644 src/gallium/frontends/pvr/pvrdri_support.h + create mode 100644 src/gallium/frontends/pvr/pvrext.c + create mode 100644 src/gallium/frontends/pvr/pvrmesa.h + create mode 100644 src/gallium/frontends/pvr/pvrutil.c + +diff --git a/meson.build b/meson.build +index 302fc622a98..4d250401a74 100644 +--- a/meson.build ++++ b/meson.build +@@ -192,16 +192,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 +234,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 +246,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') +diff --git a/meson_options.txt b/meson_options.txt +index 6f307018815..c3f0a0f3889 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -75,10 +75,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', +diff --git a/src/gallium/drivers/pvr/meson.build b/src/gallium/drivers/pvr/meson.build +new file mode 100644 +index 00000000000..4f3e2005ee4 +--- /dev/null ++++ b/src/gallium/drivers/pvr/meson.build +@@ -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' ++) +diff --git a/src/gallium/drivers/pvr_alias/meson.build b/src/gallium/drivers/pvr_alias/meson.build +new file mode 100644 +index 00000000000..128efd7b5fb +--- /dev/null ++++ b/src/gallium/drivers/pvr_alias/meson.build +@@ -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) ++) +diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c +index 2e5adf390d0..2dbb6a97070 100644 +--- a/src/gallium/frontends/dri/dri2.c ++++ b/src/gallium/frontends/dri/dri2.c +@@ -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, +diff --git a/src/gallium/frontends/dri/dri_query_renderer.c b/src/gallium/frontends/dri/dri_query_renderer.c +index b63192fddcf..0813a160434 100644 +--- a/src/gallium/frontends/dri/dri_query_renderer.c ++++ b/src/gallium/frontends/dri/dri_query_renderer.c +@@ -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) { +diff --git a/src/gallium/frontends/dri/dri_query_renderer.h b/src/gallium/frontends/dri/dri_query_renderer.h +index 59b3ff8e5b3..a9461fde051 100644 +--- a/src/gallium/frontends/dri/dri_query_renderer.h ++++ b/src/gallium/frontends/dri/dri_query_renderer.h +@@ -3,6 +3,9 @@ + + #include "dri_util.h" + ++int ++driQueryRendererIntegerCommon(__DRIscreen *psp, int param, unsigned int *value); ++ + extern const + __DRI2rendererQueryExtension dri2RendererQueryExtension; + +diff --git a/src/gallium/frontends/dri/dri_screen.c b/src/gallium/frontends/dri/dri_screen.c +index e3be46ad2eb..27a8cd88efc 100644 +--- a/src/gallium/frontends/dri/dri_screen.c ++++ b/src/gallium/frontends/dri/dri_screen.c +@@ -143,7 +143,7 @@ dri_loader_get_cap(struct dri_screen *screen, enum dri_loader_cap cap) + * 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, +@@ -340,7 +340,7 @@ driCreateConfigs(mesa_format format, + return configs; + } + +-static __DRIconfig ** ++__DRIconfig ** + driConcatConfigs(__DRIconfig **a, __DRIconfig **b) + { + __DRIconfig **all; +diff --git a/src/gallium/frontends/dri/dri_screen.h b/src/gallium/frontends/dri/dri_screen.h +index 0e3bb59796b..7b168e4d4ad 100644 +--- a/src/gallium/frontends/dri/dri_screen.h ++++ b/src/gallium/frontends/dri/dri_screen.h +@@ -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: */ +diff --git a/src/gallium/frontends/dri/dri_util.c b/src/gallium/frontends/dri/dri_util.c +index ed102450ecf..787e29dcd4f 100644 +--- a/src/gallium/frontends/dri/dri_util.c ++++ b/src/gallium/frontends/dri/dri_util.c +@@ -41,7 +41,6 @@ + + #include + #include "dri_util.h" +-#include "dri_context.h" + #include "dri_screen.h" + #include "util/u_endian.h" + #include "util/driconf.h" +@@ -196,6 +195,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, +@@ -639,8 +650,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; + } +@@ -679,7 +690,7 @@ static void + driDestroyContext(__DRIcontext *pcp) + { + if (pcp) { +- dri_destroy_context(pcp); ++ pcp->driScreenPriv->driver->DestroyContext(pcp); + free(pcp); + } + } +@@ -732,7 +743,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 +776,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 +1013,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 = { +diff --git a/src/gallium/frontends/dri/dri_util.h b/src/gallium/frontends/dri/dri_util.h +index 6e6bd76fba7..edcdae378df 100644 +--- a/src/gallium/frontends/dri/dri_util.h ++++ b/src/gallium/frontends/dri/dri_util.h +@@ -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, +diff --git a/src/gallium/frontends/dri/drisw.c b/src/gallium/frontends/dri/drisw.c +index b5c0b7a8ae2..4a0a27eae7e 100644 +--- a/src/gallium/frontends/dri/drisw.c ++++ b/src/gallium/frontends/dri/drisw.c +@@ -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, + }; + +diff --git a/src/gallium/frontends/dri/meson.build b/src/gallium/frontends/dri/meson.build +index f02aaeb20ca..c38ee981fec 100644 +--- a/src/gallium/frontends/dri/meson.build ++++ b/src/gallium/frontends/dri/meson.build +@@ -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, +diff --git a/src/gallium/frontends/pvr/dri_support.h b/src/gallium/frontends/pvr/dri_support.h +new file mode 100644 +index 00000000000..955f01cb7d5 +--- /dev/null ++++ b/src/gallium/frontends/pvr/dri_support.h +@@ -0,0 +1,633 @@ ++/* -*- 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 ++#include ++ ++/* 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 ++ ++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__) */ +diff --git a/src/gallium/frontends/pvr/img_drm_fourcc.h b/src/gallium/frontends/pvr/img_drm_fourcc.h +new file mode 100644 +index 00000000000..8d570ff8f53 +--- /dev/null ++++ b/src/gallium/frontends/pvr/img_drm_fourcc.h +@@ -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 ++#else ++/* ++ * Include types.h to workaround versions of libdrm older than 2.4.68 ++ * not including the correct headers. ++ */ ++#include ++ ++#include ++#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 */ +diff --git a/src/gallium/frontends/pvr/imgpixfmts.h b/src/gallium/frontends/pvr/imgpixfmts.h +new file mode 100644 +index 00000000000..da12a0fb5f6 +--- /dev/null ++++ b/src/gallium/frontends/pvr/imgpixfmts.h +@@ -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 */ +diff --git a/src/gallium/frontends/pvr/imgyuv.h b/src/gallium/frontends/pvr/imgyuv.h +new file mode 100644 +index 00000000000..7ae8fd19ac0 +--- /dev/null ++++ b/src/gallium/frontends/pvr/imgyuv.h +@@ -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 */ +diff --git a/src/gallium/frontends/pvr/mesa_context.c b/src/gallium/frontends/pvr/mesa_context.c +new file mode 100644 +index 00000000000..d36bae5ac54 +--- /dev/null ++++ b/src/gallium/frontends/pvr/mesa_context.c +@@ -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 ++#include ++ ++#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); ++} +diff --git a/src/gallium/frontends/pvr/meson.build b/src/gallium/frontends/pvr/meson.build +new file mode 100644 +index 00000000000..e13b8be687b +--- /dev/null ++++ b/src/gallium/frontends/pvr/meson.build +@@ -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], ++) +diff --git a/src/gallium/frontends/pvr/pvrcb.c b/src/gallium/frontends/pvr/pvrcb.c +new file mode 100644 +index 00000000000..060f1761cf2 +--- /dev/null ++++ b/src/gallium/frontends/pvr/pvrcb.c +@@ -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 ++ ++#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); ++ } ++} +diff --git a/src/gallium/frontends/pvr/pvrcompat.c b/src/gallium/frontends/pvr/pvrcompat.c +new file mode 100644 +index 00000000000..782c900101c +--- /dev/null ++++ b/src/gallium/frontends/pvr/pvrcompat.c +@@ -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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#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); ++} +diff --git a/src/gallium/frontends/pvr/pvrdri.c b/src/gallium/frontends/pvr/pvrdri.c +new file mode 100644 +index 00000000000..3a910a9f1f9 +--- /dev/null ++++ b/src/gallium/frontends/pvr/pvrdri.c +@@ -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 ++#include ++ ++#include "util/u_atomic.h" ++#include ++#include ++ ++#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 ++}; +diff --git a/src/gallium/frontends/pvr/pvrdri.h b/src/gallium/frontends/pvr/pvrdri.h +new file mode 100644 +index 00000000000..58591d83fdf +--- /dev/null ++++ b/src/gallium/frontends/pvr/pvrdri.h +@@ -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 ++#include ++#include ++ ++#include ++ ++#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__) */ +diff --git a/src/gallium/frontends/pvr/pvrdri_support.h b/src/gallium/frontends/pvr/pvrdri_support.h +new file mode 100644 +index 00000000000..f735354440c +--- /dev/null ++++ b/src/gallium/frontends/pvr/pvrdri_support.h +@@ -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 ++#include ++ ++#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__) */ +diff --git a/src/gallium/frontends/pvr/pvrext.c b/src/gallium/frontends/pvr/pvrext.c +new file mode 100644 +index 00000000000..f34863b6d1b +--- /dev/null ++++ b/src/gallium/frontends/pvr/pvrext.c +@@ -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) ++ * ++ * #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; ++ } ++} +diff --git a/src/gallium/frontends/pvr/pvrmesa.h b/src/gallium/frontends/pvr/pvrmesa.h +new file mode 100644 +index 00000000000..5e1c9c1b2e6 +--- /dev/null ++++ b/src/gallium/frontends/pvr/pvrmesa.h +@@ -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__) */ +diff --git a/src/gallium/frontends/pvr/pvrutil.c b/src/gallium/frontends/pvr/pvrutil.c +new file mode 100644 +index 00000000000..e1a1d1cac07 +--- /dev/null ++++ b/src/gallium/frontends/pvr/pvrutil.c +@@ -0,0 +1,238 @@ ++/* ++ * 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 ++#include ++#include ++#include ++ ++#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 ++#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; ++ 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; ++ 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; ++ default: ++ __driUtilMessage("%s: Unknown format: %d", __func__, iFourCC); ++ break; ++ } ++ ++ return 0; ++} +diff --git a/src/gallium/meson.build b/src/gallium/meson.build +index 148c7220382..b589e94f71b 100644 +--- a/src/gallium/meson.build ++++ b/src/gallium/meson.build +@@ -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') +diff --git a/src/gallium/targets/dri/meson.build b/src/gallium/targets/dri/meson.build +index d0a9b91b5a2..1fd98bc46f0 100644 +--- a/src/gallium/targets/dri/meson.build ++++ b/src/gallium/targets/dri/meson.build +@@ -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 +diff --git a/src/gallium/targets/dri/target.c b/src/gallium/targets/dri/target.c +index d506869cbb4..e66bdaa2c5e 100644 +--- a/src/gallium/targets/dri/target.c ++++ b/src/gallium/targets/dri/target.c +@@ -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 +diff --git a/src/meson.build b/src/meson.build +index 1e9a39b52df..3c468e86a53 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -24,6 +24,8 @@ inc_src = include_directories('.') + inc_gallium = include_directories('gallium/include') + inc_gallium_aux = include_directories('gallium/auxiliary') + inc_amd_common = include_directories('amd/common') ++inc_pvr = include_directories('mesa/main', 'mapi/glapi', ++ 'gallium/frontends/dri') + inc_tool = include_directories('tool') + inc_virtio_gpu = include_directories('virtio/virtio-gpu') + pps_datasources = [] +-- +2.17.1 + diff --git a/package/mesa3d/0001-meson-Set-proper-value-for-LIBCLC_INCLUDEDIR.patch b/package/mesa3d/0001-meson-Set-proper-value-for-LIBCLC_INCLUDEDIR.patch deleted file mode 100644 index e3c70c3f..00000000 --- a/package/mesa3d/0001-meson-Set-proper-value-for-LIBCLC_INCLUDEDIR.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7b46756a99aca7f27a45c3b99460f088570f6f53 Mon Sep 17 00:00:00 2001 -From: Romain Naour -Date: Wed, 17 Apr 2019 23:07:42 +0200 -Subject: [PATCH] meson: Set proper value for LIBCLC_INCLUDEDIR - -LIBCLC_INCLUDEDIR is the location where mesa3d OpenCL implementation -will look for OpenCL "headers" on the target, when building the OpenCL -kernels. - -The value returned by pkg-config for includedir is relevant when -cross-compiling, on the build machine. But in this specific case, we -really need a value that is valid on the target. - -Those headers are installed by the libclc package in /usr/share so -that they are not removed by Buildroot target-finalize logic. - -Based on the patch for autotools provided by Valentin Korenblit. - -Signed-off-by: Romain Naour -Signed-off-by: Bernd Kuhls -[rebased for 20.2.0 & 20.3.0] ---- - src/gallium/frontends/clover/meson.build | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/gallium/frontends/clover/meson.build b/src/gallium/frontends/clover/meson.build -index 62ac5f5278d..ecdeb39669c 100644 ---- a/src/gallium/frontends/clover/meson.build -+++ b/src/gallium/frontends/clover/meson.build -@@ -27,7 +27,7 @@ - '-DCL_USE_DEPRECATED_OPENCL_2_0_APIS', - '-DCL_USE_DEPRECATED_OPENCL_2_1_APIS', - '-DCL_USE_DEPRECATED_OPENCL_2_2_APIS', -- '-DLIBCLC_INCLUDEDIR="@0@/"'.format(dep_clc.get_variable(pkgconfig : 'includedir')), -+ '-DLIBCLC_INCLUDEDIR="/usr/share"', - '-DLIBCLC_LIBEXECDIR="@0@/"'.format(dep_clc.get_variable(pkgconfig : 'libexecdir')) - ] - clover_spirv_cpp_args = [] --- -2.20.1 - diff --git a/package/mesa3d/0002-dri-Add-some-new-DRI-formats-and-fourccs.patch b/package/mesa3d/0002-dri-Add-some-new-DRI-formats-and-fourccs.patch new file mode 100644 index 00000000..ed3bcb81 --- /dev/null +++ b/package/mesa3d/0002-dri-Add-some-new-DRI-formats-and-fourccs.patch @@ -0,0 +1,81 @@ +From 42541e6a51d0d7914c5b44486110ce6cffaa9594 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jun 2014 12:07:01 +0100 +Subject: [PATCH 002/168] dri: Add some new DRI formats and fourccs + +Add ARGB4444 DRI format and fourcc. +Add YVU444_PACK10_IMG DRI format and fourcc. +Add BGR888 DRI format and fourcc. +--- + include/GL/internal/dri_interface.h | 5 +++++ + include/drm-uapi/drm_fourcc.h | 1 + + src/egl/drivers/dri2/egl_dri2.c | 1 + + src/gallium/frontends/dri/dri_util.c | 5 +++++ + 4 files changed, 12 insertions(+) + +diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h +index 7f1f48243e1..8cc16b99f31 100644 +--- a/include/GL/internal/dri_interface.h ++++ b/include/GL/internal/dri_interface.h +@@ -1229,6 +1229,9 @@ 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_USE_SHARE 0x0001 + #define __DRI_IMAGE_USE_SCANOUT 0x0002 +@@ -1260,6 +1263,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. +diff --git a/include/drm-uapi/drm_fourcc.h b/include/drm-uapi/drm_fourcc.h +index b8f59ae191f..fd84decbd53 100644 +--- a/include/drm-uapi/drm_fourcc.h ++++ b/include/drm-uapi/drm_fourcc.h +@@ -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: +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index 8e2767ab311..457255a8ec0 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -2770,6 +2770,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: +diff --git a/src/gallium/frontends/dri/dri_util.c b/src/gallium/frontends/dri/dri_util.c +index 787e29dcd4f..e8729dac712 100644 +--- a/src/gallium/frontends/dri/dri_util.c ++++ b/src/gallium/frontends/dri/dri_util.c +@@ -1072,6 +1072,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, +-- +2.17.1 + diff --git a/package/mesa3d/0002-vc4-add-meson-option-to-disable-optional-neon-suppor.patch b/package/mesa3d/0002-vc4-add-meson-option-to-disable-optional-neon-suppor.patch deleted file mode 100644 index bb5ef00a..00000000 --- a/package/mesa3d/0002-vc4-add-meson-option-to-disable-optional-neon-suppor.patch +++ /dev/null @@ -1,84 +0,0 @@ -From e3b47c1b84964c62b3e1fa782f1ffa4be0ae62f9 Mon Sep 17 00:00:00 2001 -From: Peter Seiderer -Date: Mon, 9 Mar 2020 13:01:14 +0100 -Subject: [PATCH] vc4: add meson option to disable optional neon support - -Not all toolchains are able to compile the runtime -optional vc4 neon support, so add an meson option -to force disabling it at compile time. - -[Upstream: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4114] -Signed-off-by: Peter Seiderer -Signed-off-by: Bernd Kuhls -[rebased for 20.2.0, 20.3.0 & 21.1.0] ---- - meson_options.txt | 7 +++++++ - src/gallium/drivers/vc4/meson.build | 4 ++-- - src/gallium/drivers/vc4/vc4_tiling.h | 4 ++-- - 3 files changed, 11 insertions(+), 4 deletions(-) - -diff --git a/meson_options.txt b/meson_options.txt -index a39596a6f19..0f6b6c62b55 100644 ---- a/meson_options.txt -+++ b/meson_options.txt -@@ -123,6 +123,13 @@ option( - choices : ['auto', 'true', 'false', 'enabled', 'disabled'], - description : 'enable gallium va frontend.', - ) -+option( -+ 'gallium-vc4-neon', -+ type : 'combo', -+ value : 'auto', -+ choices : ['auto', 'disabled'], -+ description : 'enable gallium vc4 optional neon support.', -+) - option( - 'va-libs-path', - type : 'string', -diff --git a/src/gallium/drivers/vc4/meson.build b/src/gallium/drivers/vc4/meson.build -index 5ce5af5f6b4..e3f7d8d62ae 100644 ---- a/src/gallium/drivers/vc4/meson.build -+++ b/src/gallium/drivers/vc4/meson.build -@@ -84,7 +84,7 @@ files_libvc4 = files( - vc4_c_args = [] - - libvc4_neon = [] --if host_machine.cpu_family() == 'arm' -+if host_machine.cpu_family() == 'arm' and get_option('gallium-vc4-neon') != 'disabled' - libvc4_neon = static_library( - 'vc4_neon', - 'vc4_tiling_lt_neon.c', -@@ -93,7 +93,7 @@ if host_machine.cpu_family() == 'arm' - ], - c_args : '-mfpu=neon', - ) -- vc4_c_args += '-DUSE_ARM_ASM' -+ vc4_c_args += '-DVC4_TILING_LT_NEON' - endif - - if dep_simpenrose.found() -diff --git a/src/gallium/drivers/vc4/vc4_tiling.h b/src/gallium/drivers/vc4/vc4_tiling.h -index 66767e7f1f8..7446f1c3d0c 100644 ---- a/src/gallium/drivers/vc4/vc4_tiling.h -+++ b/src/gallium/drivers/vc4/vc4_tiling.h -@@ -89,7 +89,7 @@ vc4_load_lt_image(void *dst, uint32_t dst_stride, - void *src, uint32_t src_stride, - int cpp, const struct pipe_box *box) - { --#ifdef USE_ARM_ASM -+#ifdef VC4_TILING_LT_NEON - if (util_get_cpu_caps()->has_neon) { - vc4_load_lt_image_neon(dst, dst_stride, src, src_stride, - cpp, box); -@@ -105,7 +105,7 @@ vc4_store_lt_image(void *dst, uint32_t dst_stride, - void *src, uint32_t src_stride, - int cpp, const struct pipe_box *box) - { --#ifdef USE_ARM_ASM -+#ifdef VC4_TILING_LT_NEON - if (util_get_cpu_caps()->has_neon) { - vc4_store_lt_image_neon(dst, dst_stride, src, src_stride, - cpp, box); --- -2.25.1 - diff --git a/package/mesa3d/0003-GL_EXT_sparse_texture-entry-points.patch b/package/mesa3d/0003-GL_EXT_sparse_texture-entry-points.patch new file mode 100644 index 00000000..9495e769 --- /dev/null +++ b/package/mesa3d/0003-GL_EXT_sparse_texture-entry-points.patch @@ -0,0 +1,91 @@ +From 169d67ed43459bcbc31afe533a795a93f41fe6d4 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 12 Aug 2015 09:11:51 +0100 +Subject: [PATCH 003/168] GL_EXT_sparse_texture entry points + +--- + src/mapi/glapi/gen/EXT_sparse_texture.xml | 44 +++++++++++++++++++++++ + src/mapi/glapi/gen/es_EXT.xml | 3 ++ + src/mapi/glapi/gen/static_data.py | 1 + + 3 files changed, 48 insertions(+) + create mode 100644 src/mapi/glapi/gen/EXT_sparse_texture.xml + +diff --git a/src/mapi/glapi/gen/EXT_sparse_texture.xml b/src/mapi/glapi/gen/EXT_sparse_texture.xml +new file mode 100644 +index 00000000000..ebeab7d1f9a +--- /dev/null ++++ b/src/mapi/glapi/gen/EXT_sparse_texture.xml +@@ -0,0 +1,44 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml +index e96f5b83f71..79761210760 100644 +--- a/src/mapi/glapi/gen/es_EXT.xml ++++ b/src/mapi/glapi/gen/es_EXT.xml +@@ -1459,6 +1459,9 @@ + + + ++ ++ ++ + + + +diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py +index adddef3f3db..ce1e4561139 100644 +--- a/src/mapi/glapi/gen/static_data.py ++++ b/src/mapi/glapi/gen/static_data.py +@@ -1701,6 +1701,7 @@ offsets = { + "DrawElementsUserBuf": 1665, + "MultiDrawArraysUserBuf": 1666, + "MultiDrawElementsUserBuf": 1667, ++ "TexPageCommitmentEXT": 1668, + } + + functions = [ +-- +2.17.1 + diff --git a/package/mesa3d/0003-src-util-rand_xor-Include-stddef.h-to-fix-build-erro.patch b/package/mesa3d/0003-src-util-rand_xor-Include-stddef.h-to-fix-build-erro.patch deleted file mode 100644 index 538aa74e..00000000 --- a/package/mesa3d/0003-src-util-rand_xor-Include-stddef.h-to-fix-build-erro.patch +++ /dev/null @@ -1,40 +0,0 @@ -From fdc8b5a205e2116408aeb9fd305e57f656e2e89d Mon Sep 17 00:00:00 2001 -From: Bernd Kuhls -Date: Sun, 9 Aug 2020 17:06:26 +0200 -Subject: [PATCH] src/util/rand_xor: Include stddef.h to fix build error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fixes - -In file included from ../src/util/rand_xor.c:29: -output/host/x86_64-buildroot-linux-uclibc/sysroot/usr/include/sys/random.h:27:35: - error: unknown type name ‘size_t’ - extern int getrandom(void *__buf, size_t count, unsigned int flags) - -seen with gcc version 8.3.0 (Buildroot 2020.02) and uClibc. - -Patch sent upstream: -https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6248 - -Signed-off-by: Bernd Kuhls ---- - src/util/rand_xor.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/util/rand_xor.c b/src/util/rand_xor.c -index 81b64f1ea71..fcb481487fa 100644 ---- a/src/util/rand_xor.c -+++ b/src/util/rand_xor.c -@@ -25,6 +25,7 @@ - #include "detect_os.h" - - #if !DETECT_OS_WINDOWS -+#include - #if defined(HAVE_GETRANDOM) - #include - #endif --- -2.27.0 - diff --git a/package/mesa3d/0004-Add-support-for-various-GLES-extensions.patch b/package/mesa3d/0004-Add-support-for-various-GLES-extensions.patch new file mode 100644 index 00000000..f02893be --- /dev/null +++ b/package/mesa3d/0004-Add-support-for-various-GLES-extensions.patch @@ -0,0 +1,106 @@ +From 56a75ad069d020aa69d4a3cde3422401b06f1e3a Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 10 Mar 2014 12:27:03 +0000 +Subject: [PATCH 004/168] Add support for various GLES extensions + +Add support for: + EXT_occlusion_query_boolean + IMG_multisampled_render_to_texture + OES_matrix_palette +--- + src/mapi/glapi/gen/es_EXT.xml | 41 ++++++++++++++++++++++++------- + src/mapi/glapi/gen/static_data.py | 6 +++++ + 2 files changed, 38 insertions(+), 9 deletions(-) + +diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml +index 79761210760..03c78ef9ca5 100644 +--- a/src/mapi/glapi/gen/es_EXT.xml ++++ b/src/mapi/glapi/gen/es_EXT.xml +@@ -285,28 +285,25 @@ + + + +- ++ + + + +- +- ++ + + +- ++ + + + +- ++ + + +- ++ + + + +- ++ + + + +@@ -680,6 +677,32 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py +index ce1e4561139..c815f13d116 100644 +--- a/src/mapi/glapi/gen/static_data.py ++++ b/src/mapi/glapi/gen/static_data.py +@@ -1702,6 +1702,12 @@ offsets = { + "MultiDrawArraysUserBuf": 1666, + "MultiDrawElementsUserBuf": 1667, + "TexPageCommitmentEXT": 1668, ++ "CurrentPaletteMatrixOES" : 1669, ++ "LoadPaletteFromModelViewMatrixOES" : 1670, ++ "MatrixIndexPointerOES" : 1671, ++ "WeightPointerOES" : 1672, ++ "RenderbufferStorageMultisampleIMG" : 1673, ++ "FramebufferTexture2DMultisampleIMG" : 1674, + } + + functions = [ +-- +2.17.1 + diff --git a/package/mesa3d/0004-Fix-uClibc-build.patch b/package/mesa3d/0004-Fix-uClibc-build.patch deleted file mode 100644 index 95ca95fd..00000000 --- a/package/mesa3d/0004-Fix-uClibc-build.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 09ce52fe375a6fc1ccf51b6b691aaa2c3f53fbd5 Mon Sep 17 00:00:00 2001 -From: Bernd Kuhls -Date: Fri, 3 Jun 2022 16:26:03 +0200 -Subject: [PATCH] Fix uClibc build -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fixes build errors with uClibc and gcc-9.3.0: - -../src/gallium/drivers/lima/lima_texture.c:47:15: error: expected - declaration specifiers or ‘...’ before ‘__builtin_offsetof’ - 47 | static_assert(offsetof(lima_tex_desc, va) == 24, - "lima_tex_desc->va offset isn't 24"); - -../src/egl/main/egldisplay.c: In function ‘_eglGetNativePlatformFromEnv’: - ../src/egl/main/egldisplay.c:101:4: error: implicit declaration of - function ‘static_assert’ [-Werror=implicit-function-declaration] 101 | - static_assert(ARRAY_SIZE(egl_platforms) == _EGL_NUM_PLATFORMS, - -../src/util/macros.h:74:4: error: implicit declaration of function - ‘static_assert’ [-Werror=implicit-function-declaration] - 74 | static_assert(cond, #cond); \ - | ^~~~~~~~~~~~~ - -Patch sent upstream: -https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13898 - -Signed-off-by: Bernd Kuhls ---- - src/util/compiler.h | 10 ++++++++++ - src/util/macros.h | 1 + - 2 files changed, 11 insertions(+) - -diff --git a/src/util/compiler.h b/src/util/compiler.h -index d184ad455af..b5c56807acc 100644 ---- a/src/util/compiler.h -+++ b/src/util/compiler.h -@@ -36,6 +36,16 @@ - - #include - -+/* -+ * C11 static_assert() macro -+ * assert.h only defines that name for C11 and above -+ */ -+#if !defined(__cplusplus) -+#ifndef static_assert -+#define static_assert _Static_assert -+#endif -+#endif -+ - #include "util/macros.h" - - -diff --git a/src/util/macros.h b/src/util/macros.h -index 22b18303826..8f73ee72693 100644 ---- a/src/util/macros.h -+++ b/src/util/macros.h -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include "util/compiler.h" - - /* Compute the size of an array */ - #ifndef ARRAY_SIZE --- -2.34.1 - diff --git a/package/mesa3d/0005-Add-EGL_IMG_cl_image-extension.patch b/package/mesa3d/0005-Add-EGL_IMG_cl_image-extension.patch new file mode 100644 index 00000000..361a1852 --- /dev/null +++ b/package/mesa3d/0005-Add-EGL_IMG_cl_image-extension.patch @@ -0,0 +1,178 @@ +From bc7244906f23b0ea66835c7dde2523598659051c Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 11 Mar 2014 11:50:53 +0000 +Subject: [PATCH 005/168] Add EGL_IMG_cl_image extension + +Add support for the experimental EGL_IMG_cl_image extension to EGL, and +the DRI2 EGL driver. +--- + include/EGL/eglmesaext.h | 5 +++ + include/GL/internal/dri_interface.h | 13 +++++++ + src/egl/drivers/dri2/egl_dri2.c | 58 +++++++++++++++++++++++++---- + src/egl/main/eglapi.c | 1 + + src/egl/main/egldisplay.h | 2 + + 5 files changed, 72 insertions(+), 7 deletions(-) + +diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h +index f0395a8a58c..5d11f3e488e 100644 +--- a/include/EGL/eglmesaext.h ++++ b/include/EGL/eglmesaext.h +@@ -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 +diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h +index 8cc16b99f31..9f7d805825f 100644 +--- a/include/GL/internal/dri_interface.h ++++ b/include/GL/internal/dri_interface.h +@@ -1723,6 +1723,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); + }; + + +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index 457255a8ec0..5ed9898993b 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -1024,6 +1024,10 @@ 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 (dri2_dpy->flush_control) +@@ -2465,17 +2469,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 * +@@ -2554,7 +2554,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); +@@ -3300,6 +3342,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; +diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c +index 041f35aa7b6..002c94aac2c 100644 +--- a/src/egl/main/eglapi.c ++++ b/src/egl/main/eglapi.c +@@ -613,6 +613,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 + } + +diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h +index 28c2b299608..b4b2a2fe22b 100644 +--- a/src/egl/main/egldisplay.h ++++ b/src/egl/main/egldisplay.h +@@ -157,6 +157,8 @@ struct _egl_extensions + + EGLBoolean WL_bind_wayland_display; + EGLBoolean WL_create_wayland_buffer_from_image; ++ ++ EGLBoolean IMG_cl_image; + }; + + struct _egl_display +-- +2.17.1 + diff --git a/package/mesa3d/0006-egl-optimise-eglMakeCurrent-for-the-case-where-nothi.patch b/package/mesa3d/0006-egl-optimise-eglMakeCurrent-for-the-case-where-nothi.patch new file mode 100644 index 00000000..a78608b8 --- /dev/null +++ b/package/mesa3d/0006-egl-optimise-eglMakeCurrent-for-the-case-where-nothi.patch @@ -0,0 +1,48 @@ +From 11641a07afb125f69f376f43dcd51352bd0b731b Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 15 Sep 2015 14:15:31 +0100 +Subject: [PATCH 006/168] egl: optimise eglMakeCurrent for the case where + nothing has changed + +When an application calls eglMakeCurrent with a context, draw surface and +read surface that match those that are currently bound to the calling +thread don't perform a flush as this is an expensive operation. +--- + src/egl/main/eglapi.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c +index 002c94aac2c..5e69f1cb856 100644 +--- a/src/egl/main/eglapi.c ++++ b/src/egl/main/eglapi.c +@@ -935,6 +935,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); +@@ -988,8 +989,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); +-- +2.17.1 + diff --git a/package/mesa3d/0007-GL_EXT_shader_pixel_local_storage2-entry-points.patch b/package/mesa3d/0007-GL_EXT_shader_pixel_local_storage2-entry-points.patch new file mode 100644 index 00000000..0eaec85e --- /dev/null +++ b/package/mesa3d/0007-GL_EXT_shader_pixel_local_storage2-entry-points.patch @@ -0,0 +1,84 @@ +From a47e58027d672fe1a3e1b1d11113b799322e7344 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 4 Feb 2016 14:09:26 +0000 +Subject: [PATCH 007/168] GL_EXT_shader_pixel_local_storage2 entry points + +--- + .../gen/EXT_shader_pixel_local_storage2.xml | 35 +++++++++++++++++++ + src/mapi/glapi/gen/es_EXT.xml | 3 ++ + src/mapi/glapi/gen/static_data.py | 3 ++ + 3 files changed, 41 insertions(+) + create mode 100644 src/mapi/glapi/gen/EXT_shader_pixel_local_storage2.xml + +diff --git a/src/mapi/glapi/gen/EXT_shader_pixel_local_storage2.xml b/src/mapi/glapi/gen/EXT_shader_pixel_local_storage2.xml +new file mode 100644 +index 00000000000..20e186c0f0d +--- /dev/null ++++ b/src/mapi/glapi/gen/EXT_shader_pixel_local_storage2.xml +@@ -0,0 +1,35 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml +index 03c78ef9ca5..0ed0e003bae 100644 +--- a/src/mapi/glapi/gen/es_EXT.xml ++++ b/src/mapi/glapi/gen/es_EXT.xml +@@ -1485,6 +1485,9 @@ + + + ++ ++ ++ + + + +diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py +index c815f13d116..45780fb35f0 100644 +--- a/src/mapi/glapi/gen/static_data.py ++++ b/src/mapi/glapi/gen/static_data.py +@@ -1708,6 +1708,9 @@ offsets = { + "WeightPointerOES" : 1672, + "RenderbufferStorageMultisampleIMG" : 1673, + "FramebufferTexture2DMultisampleIMG" : 1674, ++ "ClearPixelLocalStorageuiEXT" : 1675, ++ "FramebufferPixelLocalStorageSizeEXT" : 1676, ++ "GetFramebufferPixelLocalStorageSizeEXT" : 1677, + } + + functions = [ +-- +2.17.1 + diff --git a/package/mesa3d/0008-GL_IMG_framebuffer_downsample-entry-points.patch b/package/mesa3d/0008-GL_IMG_framebuffer_downsample-entry-points.patch new file mode 100644 index 00000000..d1c50060 --- /dev/null +++ b/package/mesa3d/0008-GL_IMG_framebuffer_downsample-entry-points.patch @@ -0,0 +1,85 @@ +From 9cbd33f64209a30f7b27d996c550af2d36d9bd1d Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 4 Feb 2016 14:09:26 +0000 +Subject: [PATCH 008/168] GL_IMG_framebuffer_downsample entry points + +--- + .../glapi/gen/IMG_framebuffer_downsample.xml | 37 +++++++++++++++++++ + src/mapi/glapi/gen/es_EXT.xml | 3 ++ + src/mapi/glapi/gen/static_data.py | 2 + + 3 files changed, 42 insertions(+) + create mode 100644 src/mapi/glapi/gen/IMG_framebuffer_downsample.xml + +diff --git a/src/mapi/glapi/gen/IMG_framebuffer_downsample.xml b/src/mapi/glapi/gen/IMG_framebuffer_downsample.xml +new file mode 100644 +index 00000000000..b5ce77dfb08 +--- /dev/null ++++ b/src/mapi/glapi/gen/IMG_framebuffer_downsample.xml +@@ -0,0 +1,37 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml +index 0ed0e003bae..94696d535b9 100644 +--- a/src/mapi/glapi/gen/es_EXT.xml ++++ b/src/mapi/glapi/gen/es_EXT.xml +@@ -1488,6 +1488,9 @@ + + + ++ ++ ++ + + + +diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py +index 45780fb35f0..460064e1769 100644 +--- a/src/mapi/glapi/gen/static_data.py ++++ b/src/mapi/glapi/gen/static_data.py +@@ -1711,6 +1711,8 @@ offsets = { + "ClearPixelLocalStorageuiEXT" : 1675, + "FramebufferPixelLocalStorageSizeEXT" : 1676, + "GetFramebufferPixelLocalStorageSizeEXT" : 1677, ++ "FramebufferTexture2DDownsampleIMG" : 1678, ++ "FramebufferTextureLayerDownsampleIMG" : 1679, + } + + functions = [ +-- +2.17.1 + diff --git a/package/mesa3d/0009-GL_OVR_multiview-entry-points.patch b/package/mesa3d/0009-GL_OVR_multiview-entry-points.patch new file mode 100644 index 00000000..b994fb20 --- /dev/null +++ b/package/mesa3d/0009-GL_OVR_multiview-entry-points.patch @@ -0,0 +1,53 @@ +From 3ed890874b9d2ccb163ee94c705b18375c8e0cc6 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 11 Jul 2016 12:45:30 +0100 +Subject: [PATCH 009/168] GL_OVR_multiview entry points + +--- + src/mapi/glapi/gen/gl_API.xml | 17 +++++++++++++++++ + src/mapi/glapi/gen/static_data.py | 1 + + 2 files changed, 18 insertions(+) + +diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml +index 8ead49dbc3d..2526770fe35 100644 +--- a/src/mapi/glapi/gen/gl_API.xml ++++ b/src/mapi/glapi/gen/gl_API.xml +@@ -12683,6 +12683,23 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py +index 460064e1769..3337856b3b6 100644 +--- a/src/mapi/glapi/gen/static_data.py ++++ b/src/mapi/glapi/gen/static_data.py +@@ -1713,6 +1713,7 @@ offsets = { + "GetFramebufferPixelLocalStorageSizeEXT" : 1677, + "FramebufferTexture2DDownsampleIMG" : 1678, + "FramebufferTextureLayerDownsampleIMG" : 1679, ++ "FramebufferTextureMultiviewOVR" : 1680, + } + + functions = [ +-- +2.17.1 + diff --git a/package/mesa3d/0010-Add-OVR_multiview_multisampled_render_to_texture.patch b/package/mesa3d/0010-Add-OVR_multiview_multisampled_render_to_texture.patch new file mode 100644 index 00000000..8487aa18 --- /dev/null +++ b/package/mesa3d/0010-Add-OVR_multiview_multisampled_render_to_texture.patch @@ -0,0 +1,68 @@ +From 7797b0fb638351ae1ad5484baa43ce2dd212871b Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 11 Jul 2016 13:29:51 +0100 +Subject: [PATCH 010/168] Add OVR_multiview_multisampled_render_to_texture + +--- + ...ltiview_multisampled_render_to_texture.xml | 21 +++++++++++++++++++ + src/mapi/glapi/gen/es_EXT.xml | 3 +++ + src/mapi/glapi/gen/static_data.py | 1 + + 3 files changed, 25 insertions(+) + create mode 100644 src/mapi/glapi/gen/OVR_multiview_multisampled_render_to_texture.xml + +diff --git a/src/mapi/glapi/gen/OVR_multiview_multisampled_render_to_texture.xml b/src/mapi/glapi/gen/OVR_multiview_multisampled_render_to_texture.xml +new file mode 100644 +index 00000000000..86bebc728e9 +--- /dev/null ++++ b/src/mapi/glapi/gen/OVR_multiview_multisampled_render_to_texture.xml +@@ -0,0 +1,21 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml +index 94696d535b9..b59e85d3281 100644 +--- a/src/mapi/glapi/gen/es_EXT.xml ++++ b/src/mapi/glapi/gen/es_EXT.xml +@@ -1485,6 +1485,9 @@ + + + ++ ++ ++ + + + +diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py +index 3337856b3b6..2255385128c 100644 +--- a/src/mapi/glapi/gen/static_data.py ++++ b/src/mapi/glapi/gen/static_data.py +@@ -1714,6 +1714,7 @@ offsets = { + "FramebufferTexture2DDownsampleIMG" : 1678, + "FramebufferTextureLayerDownsampleIMG" : 1679, + "FramebufferTextureMultiviewOVR" : 1680, ++ "FramebufferTextureMultisampleMultiviewOVR" : 1681, + } + + functions = [ +-- +2.17.1 + diff --git a/package/mesa3d/0011-wayland-drm-install-wayland-drm.xml-to-the-configure.patch b/package/mesa3d/0011-wayland-drm-install-wayland-drm.xml-to-the-configure.patch new file mode 100644 index 00000000..12904c89 --- /dev/null +++ b/package/mesa3d/0011-wayland-drm-install-wayland-drm.xml-to-the-configure.patch @@ -0,0 +1,57 @@ +From 191fd54bcb96ec12be4107737345695bc6f662ac Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 18 Aug 2016 15:52:28 +0100 +Subject: [PATCH 011/168] wayland-drm: install wayland-drm.xml to the + configured pkgdatadir + +Add a pkg-config file as well so that it can be located without hardcoding the +path. +--- + src/egl/wayland/wayland-drm/meson.build | 15 +++++++++++++++ + src/egl/wayland/wayland-drm/wayland-drm.pc.in | 7 +++++++ + 2 files changed, 22 insertions(+) + create mode 100644 src/egl/wayland/wayland-drm/wayland-drm.pc.in + +diff --git a/src/egl/wayland/wayland-drm/meson.build b/src/egl/wayland/wayland-drm/meson.build +index b4782a013c9..f291ef9f55e 100644 +--- a/src/egl/wayland/wayland-drm/meson.build ++++ b/src/egl/wayland/wayland-drm/meson.build +@@ -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, +diff --git a/src/egl/wayland/wayland-drm/wayland-drm.pc.in b/src/egl/wayland/wayland-drm/wayland-drm.pc.in +new file mode 100644 +index 00000000000..d08ccdaf6ce +--- /dev/null ++++ b/src/egl/wayland/wayland-drm/wayland-drm.pc.in +@@ -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@ +\ No newline at end of file +-- +2.17.1 + diff --git a/package/mesa3d/0012-Enable-buffer-sharing-in-the-kms_swrast-driver.patch b/package/mesa3d/0012-Enable-buffer-sharing-in-the-kms_swrast-driver.patch new file mode 100644 index 00000000..c92d2e56 --- /dev/null +++ b/package/mesa3d/0012-Enable-buffer-sharing-in-the-kms_swrast-driver.patch @@ -0,0 +1,27 @@ +From 7411e88f1ddbe42864614954887d0aca0f0bbce0 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 26 Oct 2016 16:24:28 +0100 +Subject: [PATCH 012/168] Enable buffer sharing in the kms_swrast driver + +Enable buffer sharing, so that a DRI driver can be loaded by a +Wayland client when kms_swrast is being used by the compositor. +--- + src/gallium/frontends/dri/dri2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c +index 2dbb6a97070..eca2986eeb9 100644 +--- a/src/gallium/frontends/dri/dri2.c ++++ b/src/gallium/frontends/dri/dri2.c +@@ -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; + +-- +2.17.1 + diff --git a/package/mesa3d/0013-egl-wayland-add-support-for-RGB565-back-buffers.patch b/package/mesa3d/0013-egl-wayland-add-support-for-RGB565-back-buffers.patch new file mode 100644 index 00000000..451ab424 --- /dev/null +++ b/package/mesa3d/0013-egl-wayland-add-support-for-RGB565-back-buffers.patch @@ -0,0 +1,46 @@ +From be55dbacf71a760ef10930355295ba1ce21af8ff Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 28 Feb 2017 16:08:47 +0000 +Subject: [PATCH 013/168] egl/wayland: add support for RGB565 back buffers + +--- + src/egl/drivers/dri2/platform_wayland.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c +index 93bb97c54e0..850a197d952 100644 +--- a/src/egl/drivers/dri2/platform_wayland.c ++++ b/src/egl/drivers/dri2/platform_wayland.c +@@ -1096,18 +1096,27 @@ back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer) + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + __DRIimage *image; +- int name, pitch; ++ int name, pitch, format; + + image = dri2_surf->back->dri_image; + + 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->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 +-- +2.17.1 + diff --git a/package/mesa3d/0014-egl-wayland-post-maximum-damage-when-blitting.patch b/package/mesa3d/0014-egl-wayland-post-maximum-damage-when-blitting.patch new file mode 100644 index 00000000..affd5d2c --- /dev/null +++ b/package/mesa3d/0014-egl-wayland-post-maximum-damage-when-blitting.patch @@ -0,0 +1,33 @@ +From 3d5b7866ca7900e3361ef33467c2f6ebb6834344 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 8 Nov 2017 15:15:20 +0000 +Subject: [PATCH 014/168] egl/wayland: post maximum damage when blitting + +When blitting, as part of the "is_different_gpu" case when swapping +buffers, the blit is done using the full surface dimensions, ignoring +the damage region. This results in corruption of the non damaged region +on screen. Workaround this by posting maximum damage when blitting. + +A better fix would be to limit the blit to the damaged region, at least +when the number of damage rectangles is 1. +--- + src/egl/drivers/dri2/platform_wayland.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c +index 850a197d952..73a443b4b40 100644 +--- a/src/egl/drivers/dri2/platform_wayland.c ++++ b/src/egl/drivers/dri2/platform_wayland.c +@@ -1593,7 +1593,8 @@ 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); + +-- +2.17.1 + diff --git a/package/mesa3d/0015-egl-wayland-flush-the-drawable-before-blitting.patch b/package/mesa3d/0015-egl-wayland-flush-the-drawable-before-blitting.patch new file mode 100644 index 00000000..2e789413 --- /dev/null +++ b/package/mesa3d/0015-egl-wayland-flush-the-drawable-before-blitting.patch @@ -0,0 +1,34 @@ +From 8390d311042bb9b54e6d39193a00276f34a6ad8a Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 8 Nov 2017 15:26:25 +0000 +Subject: [PATCH 015/168] egl/wayland: flush the drawable before blitting + +Flush the drawable before blitting in the "is_different_gpu" case when +swapping buffers, and pass the flush flag to the blitImage call. The +change brings the code into line with the way the DRI3 GLX code works. + +For the PowerVR driver, the drawable parameters that will be used in +the flush have been obtained previously, including any native fence +associated with the blit source. The blit will result in a new native +fence for the source, and make the one in the drawable parameters +invalid. +--- + src/egl/drivers/dri2/platform_wayland.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c +index 73a443b4b40..8f1c5101441 100644 +--- a/src/egl/drivers/dri2/platform_wayland.c ++++ b/src/egl/drivers/dri2/platform_wayland.c +@@ -1607,7 +1607,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); +-- +2.17.1 + diff --git a/package/mesa3d/0016-dri-use-a-supported-API-in-driCreateNewContext.patch b/package/mesa3d/0016-dri-use-a-supported-API-in-driCreateNewContext.patch new file mode 100644 index 00000000..e84dfba8 --- /dev/null +++ b/package/mesa3d/0016-dri-use-a-supported-API-in-driCreateNewContext.patch @@ -0,0 +1,54 @@ +From b788d8ee10adf01acd6d139ea7f73ab6f58fcc45 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 23 Nov 2017 15:50:21 +0000 +Subject: [PATCH 016/168] dri: use a supported API in driCreateNewContext + +Don't assume the screen supports OpenGL when creating a new context, +use an API that the screen supports. +--- + src/gallium/frontends/dri/dri_util.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/frontends/dri/dri_util.c b/src/gallium/frontends/dri/dri_util.c +index e8729dac712..6c3ce760ab0 100644 +--- a/src/gallium/frontends/dri/dri_util.c ++++ b/src/gallium/frontends/dri/dri_util.c +@@ -48,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 +@@ -489,7 +490,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: +@@ -675,7 +680,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); + } + +-- +2.17.1 + diff --git a/package/mesa3d/0017-gbm-add-gbm_bo_blit.patch b/package/mesa3d/0017-gbm-add-gbm_bo_blit.patch new file mode 100644 index 00000000..162faedd --- /dev/null +++ b/package/mesa3d/0017-gbm-add-gbm_bo_blit.patch @@ -0,0 +1,215 @@ +From 4e73467f49320e7647ec8e95a754f7574733838f Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 28 Nov 2017 16:27:38 +0000 +Subject: [PATCH 017/168] gbm: add gbm_bo_blit + +For the GBM DRI backend, gbm_bo_blit is a wrapper around blitImage in +the DRI Image extension. +--- + src/gbm/backends/dri/gbm_dri.c | 33 +++++++++++++++++++++++++++++++++ + src/gbm/main/gbm.c | 31 +++++++++++++++++++++++++++++++ + src/gbm/main/gbm.h | 21 +++++++++++++++++++++ + src/gbm/main/gbm_abi_check.c | 20 +++++++++++++++++++- + src/gbm/main/gbm_backend_abi.h | 8 ++++++++ + 5 files changed, 112 insertions(+), 1 deletion(-) + +diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c +index 36cee87a2fd..6dad8d97d17 100644 +--- a/src/gbm/backends/dri/gbm_dri.c ++++ b/src/gbm/backends/dri/gbm_dri.c +@@ -1412,6 +1412,37 @@ 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); ++ assert(dri->context); ++ mtx_unlock(&dri->mutex); ++ ++ /* 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) + { +@@ -1473,6 +1504,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); + +diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c +index 599f7aae9b6..27e9f5bcd03 100644 +--- a/src/gbm/main/gbm.c ++++ b/src/gbm/main/gbm.c +@@ -827,6 +827,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. +diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h +index 1a1e2caecb4..207b6cf9d74 100644 +--- a/src/gbm/main/gbm.h ++++ b/src/gbm/main/gbm.h +@@ -266,6 +266,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 +477,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 +diff --git a/src/gbm/main/gbm_abi_check.c b/src/gbm/main/gbm_abi_check.c +index feca0998d9d..0153b5a8754 100644 +--- a/src/gbm/main/gbm_abi_check.c ++++ b/src/gbm/main/gbm_abi_check.c +@@ -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*/ +diff --git a/src/gbm/main/gbm_backend_abi.h b/src/gbm/main/gbm_backend_abi.h +index 222ce3404cb..17f5e0ca808 100644 +--- a/src/gbm/main/gbm_backend_abi.h ++++ b/src/gbm/main/gbm_backend_abi.h +@@ -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; + }; + + /** +-- +2.17.1 + diff --git a/package/mesa3d/0018-gbm-don-t-assert-if-DRI-context-creation-fails.patch b/package/mesa3d/0018-gbm-don-t-assert-if-DRI-context-creation-fails.patch new file mode 100644 index 00000000..89fe0bea --- /dev/null +++ b/package/mesa3d/0018-gbm-don-t-assert-if-DRI-context-creation-fails.patch @@ -0,0 +1,44 @@ +From ec4f98f3c33f8583ab3208d0c1c209a081433627 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 1 Dec 2017 08:31:15 +0000 +Subject: [PATCH 018/168] gbm: don't assert if DRI context creation fails + +If the DRI backend fails to create a DRI context, return an error, +rather than asserting. +--- + src/gbm/backends/dri/gbm_dri.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c +index 6dad8d97d17..53edc1928d8 100644 +--- a/src/gbm/backends/dri/gbm_dri.c ++++ b/src/gbm/backends/dri/gbm_dri.c +@@ -1302,8 +1302,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, +@@ -1431,8 +1434,11 @@ gbm_dri_bo_blit(struct gbm_bo *_dst_bo, struct gbm_bo *_src_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 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, +-- +2.17.1 + diff --git a/package/mesa3d/0019-egl-wayland-add-pbuffer-support.patch b/package/mesa3d/0019-egl-wayland-add-pbuffer-support.patch new file mode 100644 index 00000000..eb9ada26 --- /dev/null +++ b/package/mesa3d/0019-egl-wayland-add-pbuffer-support.patch @@ -0,0 +1,476 @@ +From e396d88e6c6576a0a016429c86da06d04fc3a34a Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 17 Mar 2017 16:23:07 +0000 +Subject: [PATCH 019/168] egl/wayland: add pbuffer support + +The pbuffer code is based on that in the Surfaceless platform code. +--- + src/egl/drivers/dri2/egl_dri2.h | 4 + + src/egl/drivers/dri2/platform_wayland.c | 270 ++++++++++++++++++++---- + 2 files changed, 236 insertions(+), 38 deletions(-) + +diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h +index 40c2a14d8d8..afb2d7297ca 100644 +--- a/src/egl/drivers/dri2/egl_dri2.h ++++ b/src/egl/drivers/dri2/egl_dri2.h +@@ -398,6 +398,10 @@ struct dri2_egl_surface + __DRIimage *front; + unsigned int visual; + ++#ifdef HAVE_WAYLAND_PLATFORM ++ void *swrast_front; ++#endif ++ + int out_fence_fd; + EGLBoolean enable_out_fence; + +diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c +index 8f1c5101441..775909f6138 100644 +--- a/src/egl/drivers/dri2/platform_wayland.c ++++ b/src/egl/drivers/dri2/platform_wayland.c +@@ -787,6 +787,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 +906,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 +918,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 +929,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); +@@ -1091,20 +1190,16 @@ 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, format; + +- image = dri2_surf->back->dri_image; +- + 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->flags = 0; +@@ -1125,12 +1220,28 @@ 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) ++{ + if (dri2_surf->wl_win && + (dri2_surf->base.Width != dri2_surf->wl_win->width || + dri2_surf->base.Height != dri2_surf->wl_win->height)) { +@@ -1176,12 +1287,13 @@ 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) + { + if (dri2_surf->back != NULL) + return 0; + +- return update_buffers(dri2_surf); ++ return update_buffers(dri2_dpy, dri2_surf); + } + + static __DRIbuffer * +@@ -1191,17 +1303,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) < 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], +@@ -1271,12 +1391,30 @@ 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; ++ ++ if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) ++ { ++ if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0) ++ return 0; ++ ++ buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK; ++ buffers->back = dri2_surf->back->dri_image; ++ } ++ ++ 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_BACK; +- buffers->back = dri2_surf->back->dri_image; ++ buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT; ++ buffers->front = dri2_surf->front; ++ } + + return 1; + } +@@ -1524,6 +1662,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"); + +@@ -1549,7 +1690,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) < 0) + return _eglError(EGL_BAD_ALLOC, "dri2_swap_buffers"); + + if (draw->SwapInterval > 0) { +@@ -1630,9 +1771,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) < 0) { + _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age"); + return -1; + } +@@ -1987,6 +2132,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, +@@ -2030,7 +2176,7 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp) + continue; + + 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, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes); + if (dri2_conf) { + if (dri2_conf->base.ConfigID == count + 1) + count++; +@@ -2292,6 +2438,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, +@@ -2423,8 +2586,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) +@@ -2494,7 +2673,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; +@@ -2513,7 +2694,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; +@@ -2551,14 +2736,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; +@@ -2576,7 +2767,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 +@@ -2648,6 +2841,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, +-- +2.17.1 + diff --git a/package/mesa3d/0020-egl-eglBindAPI-workaround-for-dEQP-bug.patch b/package/mesa3d/0020-egl-eglBindAPI-workaround-for-dEQP-bug.patch new file mode 100644 index 00000000..e3a6bc47 --- /dev/null +++ b/package/mesa3d/0020-egl-eglBindAPI-workaround-for-dEQP-bug.patch @@ -0,0 +1,29 @@ +From 87172ae62c79dcd5b384d1a916dc06f81ebc23e2 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 25 Sep 2017 15:58:49 +0100 +Subject: [PATCH 020/168] egl: eglBindAPI workaround for dEQP bug + +dEQP relies on eglBindAPI to only return true if the API can +successfully be used to create contexts, which the spec does not +require. +Until dEQP is fixed, just disable GL on non-X11 platforms. +--- + src/egl/main/eglcurrent.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h +index d813a46d9ab..c03798eaeac 100644 +--- a/src/egl/main/eglcurrent.h ++++ b/src/egl/main/eglcurrent.h +@@ -72,7 +72,7 @@ struct _egl_thread_info + static inline EGLBoolean + _eglIsApiValid(EGLenum api) + { +-#ifdef ANDROID ++#ifndef HAVE_X11_PLATFORM + /* OpenGL is not a valid/supported API on Android */ + return api == EGL_OPENGL_ES_API; + #else +-- +2.17.1 + diff --git a/package/mesa3d/0021-GL_EXT_multi_draw_indirect-entry-points.patch b/package/mesa3d/0021-GL_EXT_multi_draw_indirect-entry-points.patch new file mode 100644 index 00000000..3fca9cb7 --- /dev/null +++ b/package/mesa3d/0021-GL_EXT_multi_draw_indirect-entry-points.patch @@ -0,0 +1,56 @@ +From 40cf908ef114f8c590ee3419153f41b08b208350 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 30 Jan 2018 10:25:11 +0000 +Subject: [PATCH 021/168] GL_EXT_multi_draw_indirect entry points + +--- + src/mapi/glapi/gen/es_EXT.xml | 19 +++++++++++++++++++ + src/mapi/glapi/gen/static_data.py | 2 ++ + 2 files changed, 21 insertions(+) + +diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml +index b59e85d3281..6ff5432e029 100644 +--- a/src/mapi/glapi/gen/es_EXT.xml ++++ b/src/mapi/glapi/gen/es_EXT.xml +@@ -1140,6 +1140,25 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py +index 2255385128c..dd4a802c496 100644 +--- a/src/mapi/glapi/gen/static_data.py ++++ b/src/mapi/glapi/gen/static_data.py +@@ -1715,6 +1715,8 @@ offsets = { + "FramebufferTextureLayerDownsampleIMG" : 1679, + "FramebufferTextureMultiviewOVR" : 1680, + "FramebufferTextureMultisampleMultiviewOVR" : 1681, ++ "MultiDrawArraysIndirectEXT" : 1682, ++ "MultiDrawElementsIndirectEXT" : 1683, + } + + functions = [ +-- +2.17.1 + diff --git a/package/mesa3d/0022-dri-add-support-for-YUV-DRI-config.patch b/package/mesa3d/0022-dri-add-support-for-YUV-DRI-config.patch new file mode 100644 index 00000000..b22a8acb --- /dev/null +++ b/package/mesa3d/0022-dri-add-support-for-YUV-DRI-config.patch @@ -0,0 +1,541 @@ +From 0e502a3fc9d61e6646730b0d77e4e96711bf2d7f Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 22 Dec 2017 17:17:50 +0000 +Subject: [PATCH 022/168] dri: add support for YUV DRI config + +This is prerequisite for adding support for EGL_EXT_yuv_surface. + +This also adds support for NV12 and NV21 EGL configs. +--- + include/GL/internal/dri_interface.h | 48 +++++++++- + src/gallium/frontends/dri/dri_screen.c | 121 +++++++++++++++++++++++- + src/gallium/frontends/dri/dri_util.c | 12 ++- + src/gallium/frontends/pvr/dri_support.h | 5 + + src/gallium/frontends/pvr/pvrutil.c | 34 +++++++ + src/gallium/include/pipe/p_format.h | 4 + + src/mesa/main/format_info.py | 2 +- + src/mesa/main/formats.c | 13 +++ + src/mesa/main/formats.csv | 6 ++ + src/mesa/main/formats.h | 15 +++ + src/mesa/main/glconfig.h | 9 ++ + 11 files changed, 262 insertions(+), 7 deletions(-) + +diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h +index 9f7d805825f..f049fa76431 100644 +--- a/include/GL/internal/dri_interface.h ++++ b/include/GL/internal/dri_interface.h +@@ -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. + * +@@ -1232,6 +1272,12 @@ struct __DRIdri2ExtensionRec { + #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_USE_SHARE 0x0001 + #define __DRI_IMAGE_USE_SCANOUT 0x0002 +diff --git a/src/gallium/frontends/dri/dri_screen.c b/src/gallium/frontends/dri/dri_screen.c +index 27a8cd88efc..d4a61ceffb8 100644 +--- a/src/gallium/frontends/dri/dri_screen.c ++++ b/src/gallium/frontends/dri/dri_screen.c +@@ -137,6 +137,21 @@ 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. +@@ -149,7 +164,8 @@ driCreateConfigs(mesa_format format, + 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; + } + } + } +@@ -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); + } + } +diff --git a/src/gallium/frontends/dri/dri_util.c b/src/gallium/frontends/dri/dri_util.c +index 6c3ce760ab0..32ae2b6fec7 100644 +--- a/src/gallium/frontends/dri/dri_util.c ++++ b/src/gallium/frontends/dri/dri_util.c +@@ -302,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; +@@ -370,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; +diff --git a/src/gallium/frontends/pvr/dri_support.h b/src/gallium/frontends/pvr/dri_support.h +index 955f01cb7d5..3cc8f290d4d 100644 +--- a/src/gallium/frontends/pvr/dri_support.h ++++ b/src/gallium/frontends/pvr/dri_support.h +@@ -92,6 +92,11 @@ typedef enum + #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; + +diff --git a/src/gallium/frontends/pvr/pvrutil.c b/src/gallium/frontends/pvr/pvrutil.c +index e1a1d1cac07..39f0d1e21fe 100644 +--- a/src/gallium/frontends/pvr/pvrutil.c ++++ b/src/gallium/frontends/pvr/pvrutil.c +@@ -113,6 +113,16 @@ PVRDRIMesaFormatToMesaFormat(int pvrdri_mesa_format) + 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; +@@ -171,6 +181,18 @@ PVRDRIFormatToFourCC(int dri_format) + 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; +@@ -229,6 +251,18 @@ PVRDRIFourCCToDRIFormat(int iFourCC) + 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; +diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h +index 3387d3091ab..7a0e19126a7 100644 +--- a/src/gallium/include/pipe/p_format.h ++++ b/src/gallium/include/pipe/p_format.h +@@ -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: +diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py +index 37b46a27c31..9aa1bb9fc63 100644 +--- a/src/mesa/main/format_info.py ++++ b/src/mesa/main/format_info.py +@@ -27,7 +27,7 @@ import sys + def get_gl_base_format(fmat): + if fmat.name == 'MESA_FORMAT_NONE': + return 'GL_NONE' +- elif fmat.name in ['MESA_FORMAT_YCBCR', 'MESA_FORMAT_YCBCR_REV']: ++ elif fmat.name in ['MESA_FORMAT_YCBCR', 'MESA_FORMAT_YCBCR_REV', 'MESA_FORMAT_YUV420_2PLANE', 'MESA_FORMAT_YVU420_2PLANE', 'MESA_FORMAT_YUV420_3PLANE', 'MESA_FORMAT_YVU420_3PLANE', 'MESA_FORMAT_YVYU', 'MESA_FORMAT_VYUY']: + return 'GL_YCBCR_MESA' + elif fmat.has_channel('r'): + if fmat.has_channel('g'): +diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c +index a46572513f0..79402f7fb8c 100644 +--- a/src/mesa/main/formats.c ++++ b/src/mesa/main/formats.c +@@ -1019,6 +1019,8 @@ _mesa_uncompressed_format_to_type_and_comps(mesa_format format, + + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: ++ case MESA_FORMAT_YVYU: ++ case MESA_FORMAT_VYUY: + case MESA_FORMAT_RG_RB_UNORM8: + case MESA_FORMAT_GR_BR_UNORM8: + *datatype = GL_UNSIGNED_SHORT; +@@ -1447,6 +1449,17 @@ _mesa_format_matches_format_and_type(mesa_format mformat, + if (error) + *error = GL_NO_ERROR; + ++ switch (mformat) { ++ case MESA_FORMAT_YUV420_2PLANE: ++ case MESA_FORMAT_YVU420_2PLANE: ++ case MESA_FORMAT_YUV420_3PLANE: ++ case MESA_FORMAT_YVU420_3PLANE: ++ return false; ++ ++ default: ++ break; ++ } ++ + if (_mesa_is_format_compressed(mformat)) { + if (error) + *error = GL_INVALID_ENUM; +diff --git a/src/mesa/main/formats.csv b/src/mesa/main/formats.csv +index 21cdea26e08..d1532b19b06 100644 +--- a/src/mesa/main/formats.csv ++++ b/src/mesa/main/formats.csv +@@ -92,6 +92,12 @@ MESA_FORMAT_A2R10G10B10_UNORM , packed, 1, 1, 1, un2 , un10, un10, u + + MESA_FORMAT_YCBCR , other , 1, 1, 1, x16 , , , , xyzw, yuv + MESA_FORMAT_YCBCR_REV , other , 1, 1, 1, x16 , , , , xyzw, yuv ++MESA_FORMAT_YUV420_2PLANE , other , 1, 1, 1, x8 , , , , y___, yuv ++MESA_FORMAT_YVU420_2PLANE , other , 1, 1, 1, x8 , , , , y___, yuv ++MESA_FORMAT_YUV420_3PLANE , other , 1, 1, 1, x8 , , , , y___, yuv ++MESA_FORMAT_YVU420_3PLANE , other , 1, 1, 1, x8 , , , , y___, yuv ++MESA_FORMAT_YVYU , other , 1, 1, 1, x16 , , , , xyzw, yuv ++MESA_FORMAT_VYUY , other , 1, 1, 1, x16 , , , , xyzw, yuv + + MESA_FORMAT_RG_RB_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb + MESA_FORMAT_GR_BR_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb +diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h +index aee6217621d..6c07281c20e 100644 +--- a/src/mesa/main/formats.h ++++ b/src/mesa/main/formats.h +@@ -617,6 +617,21 @@ typedef enum pipe_format mesa_format; + #define MESA_FORMAT_ATC_RGB PIPE_FORMAT_ATC_RGB + #define MESA_FORMAT_ATC_RGBA_EXPLICIT PIPE_FORMAT_ATC_RGBA_EXPLICIT + #define MESA_FORMAT_ATC_RGBA_INTERPOLATED PIPE_FORMAT_ATC_RGBA_INTERPOLATED ++#define MESA_FORMAT_YVYU PIPE_FORMAT_YVYU ++#define MESA_FORMAT_VYUY PIPE_FORMAT_VYUY ++ ++#define HAVE_MESA_FORMAT_YUV420_2PLANE ++#define MESA_FORMAT_YUV420_2PLANE PIPE_FORMAT_NV12 ++ ++#define HAVE_MESA_FORMAT_YVU420_2PLANE ++#define MESA_FORMAT_YVU420_2PLANE PIPE_FORMAT_NV21 ++ ++#define HAVE_MESA_FORMAT_YUV420_3PLANE ++#define MESA_FORMAT_YUV420_3PLANE PIPE_FORMAT_IYUV ++ ++#define HAVE_MESA_FORMAT_YVU420_3PLANE ++#define MESA_FORMAT_YVU420_3PLANE PIPE_FORMAT_YV12 ++ + #define MESA_FORMAT_COUNT PIPE_FORMAT_COUNT + + /* Packed to array format adapters */ +diff --git a/src/mesa/main/glconfig.h b/src/mesa/main/glconfig.h +index 80414d5d78e..d54a4f75cfd 100644 +--- a/src/mesa/main/glconfig.h ++++ b/src/mesa/main/glconfig.h +@@ -10,6 +10,7 @@ + */ + struct gl_config + { ++ GLboolean rgbMode; + GLboolean floatMode; + GLuint doubleBufferMode; + GLuint stereoMode; +@@ -31,6 +32,14 @@ struct gl_config + + /* EXT_framebuffer_sRGB */ + GLint sRGBCapable; ++ ++ /* EXT_yuv_surface */ ++ GLint YUVOrder; ++ GLint YUVNumberOfPlanes; ++ GLint YUVSubsample; ++ GLint YUVDepthRange; ++ GLint YUVCSCStandard; ++ GLint YUVPlaneBPP; + }; + + +-- +2.17.1 + diff --git a/package/mesa3d/0023-egl-add-support-for-EXT_yuv_surface.patch b/package/mesa3d/0023-egl-add-support-for-EXT_yuv_surface.patch new file mode 100644 index 00000000..57ec217b --- /dev/null +++ b/package/mesa3d/0023-egl-add-support-for-EXT_yuv_surface.patch @@ -0,0 +1,541 @@ +From 76f6b118fe303124dcc5cd4005d3c28f35afbcae Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 20 Dec 2017 17:41:38 +0000 +Subject: [PATCH 023/168] egl: add support for EXT_yuv_surface + +This implements EXT_yuv_surface but doesn't expose it for any platform. +--- + include/GL/internal/dri_interface.h | 1 + + src/egl/drivers/dri2/egl_dri2.c | 83 +++++++++ + src/egl/main/eglapi.c | 1 + + src/egl/main/eglconfig.c | 255 +++++++++++++++++++++++++++- + src/egl/main/eglconfig.h | 12 ++ + src/egl/main/egldisplay.h | 1 + + 6 files changed, 348 insertions(+), 5 deletions(-) + +diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h +index f049fa76431..a62ccc1b41f 100644 +--- a/include/GL/internal/dri_interface.h ++++ b/include/GL/internal/dri_interface.h +@@ -1023,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 { +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index 5ed9898993b..309265dc14b 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -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 * +@@ -442,6 +443,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; +@@ -546,6 +549,73 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, + 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) +@@ -584,6 +654,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; + +@@ -1042,6 +1123,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 +diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c +index 5e69f1cb856..c4dac448b8b 100644 +--- a/src/egl/main/eglapi.c ++++ b/src/egl/main/eglapi.c +@@ -569,6 +569,7 @@ _eglCreateExtensionsString(_EGLDisplay *disp) + _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); + +diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c +index 1c8b01bca8f..86d82851f45 100644 +--- a/src/egl/main/eglconfig.c ++++ b/src/egl/main/eglconfig.c +@@ -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; +diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h +index dcfb11b69a0..0523c8918ef 100644 +--- a/src/egl/main/eglconfig.h ++++ b/src/egl/main/eglconfig.h +@@ -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; +diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h +index b4b2a2fe22b..1b9afdb343a 100644 +--- a/src/egl/main/egldisplay.h ++++ b/src/egl/main/egldisplay.h +@@ -118,6 +118,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 +-- +2.17.1 + diff --git a/package/mesa3d/0024-dri-add-missing-__DRI_IMAGE_COMPONENTS-define-for-EG.patch b/package/mesa3d/0024-dri-add-missing-__DRI_IMAGE_COMPONENTS-define-for-EG.patch new file mode 100644 index 00000000..8fb37fc2 --- /dev/null +++ b/package/mesa3d/0024-dri-add-missing-__DRI_IMAGE_COMPONENTS-define-for-EG.patch @@ -0,0 +1,35 @@ +From 94c3e87ac76f0ea4b84591a45c4853fea8ea93cf Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 2 Feb 2018 16:59:52 +0000 +Subject: [PATCH 024/168] dri: add missing __DRI_IMAGE_COMPONENTS define for + EGL_TEXTURE_EXTERNAL_WL + +The __DRI_IMAGE_COMPONENTS defines have been re-ordered, to make it +less likely that new defines will be added with the same values as +existing ones. +--- + include/GL/internal/dri_interface.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h +index a62ccc1b41f..4b1b691e217 100644 +--- a/include/GL/internal/dri_interface.h ++++ b/include/GL/internal/dri_interface.h +@@ -1331,11 +1331,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 + + + /** +-- +2.17.1 + diff --git a/package/mesa3d/0025-egl-wayland-expose-EXT_yuv_surface-support.patch b/package/mesa3d/0025-egl-wayland-expose-EXT_yuv_surface-support.patch new file mode 100644 index 00000000..eaa270b6 --- /dev/null +++ b/package/mesa3d/0025-egl-wayland-expose-EXT_yuv_surface-support.patch @@ -0,0 +1,74 @@ +From 6bd619dae24da9c94b62a9f7dd68e3ff7f685761 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 11 Jan 2018 09:38:47 +0000 +Subject: [PATCH 025/168] egl/wayland: expose EXT_yuv_surface support + +This adds support for YUYV configs. +--- + src/egl/drivers/dri2/egl_dri2.c | 1 + + src/egl/drivers/dri2/platform_wayland.c | 15 ++++++++++++++- + 2 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index 309265dc14b..d2e7b2b7922 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -2486,6 +2486,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 * +diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c +index 775909f6138..c3fb983c341 100644 +--- a/src/egl/drivers/dri2/platform_wayland.c ++++ b/src/egl/drivers/dri2/platform_wayland.c +@@ -151,6 +151,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 +@@ -1431,6 +1438,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; +@@ -2164,6 +2172,7 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp) + 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++) { +@@ -2175,8 +2184,12 @@ 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; ++ + dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i], +- count + 1, EGL_WINDOW_BIT | EGL_PBUFFER_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++; +-- +2.17.1 + diff --git a/package/mesa3d/0026-gbm-add-some-new-GBM-formats.patch b/package/mesa3d/0026-gbm-add-some-new-GBM-formats.patch new file mode 100644 index 00000000..e99ebbc2 --- /dev/null +++ b/package/mesa3d/0026-gbm-add-some-new-GBM-formats.patch @@ -0,0 +1,134 @@ +From 4f30b27325e00d237f9f6bcd852033cb7ad0981d Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 30 Aug 2018 13:48:53 +0100 +Subject: [PATCH 026/168] gbm: add some new GBM formats + +GBM_FORMAT_ARGB4444 +GBM_FORMAT_BGR888 +GBM_FORMAT_AXBXGXRX106106106106 +GBM_FORMAT_YUYV +GBM_FORMAT_YVU444_PACK10_IMG +--- + include/GL/internal/dri_interface.h | 1 + + src/egl/drivers/dri2/egl_dri2.c | 1 + + src/gbm/backends/dri/gbm_dri.c | 21 +++++++++++++++++++++ + src/gbm/main/gbm.c | 1 + + src/gbm/main/gbm.h | 8 ++++++++ + 5 files changed, 32 insertions(+) + +diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h +index 4b1b691e217..75ced1b9660 100644 +--- a/include/GL/internal/dri_interface.h ++++ b/include/GL/internal/dri_interface.h +@@ -1279,6 +1279,7 @@ struct __DRIdri2ExtensionRec { + #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 +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index d2e7b2b7922..5cfce95aa42 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -2884,6 +2884,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: +diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c +index 53edc1928d8..5b18bdcccbc 100644 +--- a/src/gbm/backends/dri/gbm_dri.c ++++ b/src/gbm/backends/dri/gbm_dri.c +@@ -564,11 +564,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 +629,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 +646,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 +diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c +index 27e9f5bcd03..1b14320ba76 100644 +--- a/src/gbm/main/gbm.c ++++ b/src/gbm/main/gbm.c +@@ -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; + } + } +diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h +index 207b6cf9d74..067d36f16fd 100644 +--- a/src/gbm/main/gbm.h ++++ b/src/gbm/main/gbm.h +@@ -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 +-- +2.17.1 + diff --git a/package/mesa3d/0027-egl-add-null-platform.patch b/package/mesa3d/0027-egl-add-null-platform.patch new file mode 100644 index 00000000..090e62d3 --- /dev/null +++ b/package/mesa3d/0027-egl-add-null-platform.patch @@ -0,0 +1,1485 @@ +From 6eec694571ed99854e69d1b5403cc19c7144fa5d Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Sun, 5 Jun 2016 12:04:40 +0100 +Subject: [PATCH 027/168] egl: add "null" platform + +--- + meson.build | 10 +- + meson_options.txt | 2 +- + src/egl/drivers/dri2/egl_dri2.c | 11 +- + src/egl/drivers/dri2/egl_dri2.h | 59 +- + src/egl/drivers/dri2/platform_null.c | 1179 ++++++++++++++++++++++++++ + src/egl/main/eglapi.c | 5 +- + src/egl/main/egldisplay.c | 1 + + src/egl/main/egldisplay.h | 1 + + src/egl/meson.build | 5 + + 9 files changed, 1264 insertions(+), 9 deletions(-) + create mode 100644 src/egl/drivers/dri2/platform_null.c + +diff --git a/meson.build b/meson.build +index 4d250401a74..9fb6dd81d26 100644 +--- a/meson.build ++++ b/meson.build +@@ -354,7 +354,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()) +@@ -372,6 +372,7 @@ 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') + + with_glx = get_option('glx') + if with_glx == 'auto' +@@ -1003,6 +1004,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', +@@ -1722,7 +1727,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' +diff --git a/meson_options.txt b/meson_options.txt +index c3f0a0f3889..6fd37bbb100 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -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.' + ) +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index 5cfce95aa42..6337cb23aa4 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -1281,6 +1281,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); +@@ -1342,8 +1345,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. +@@ -1369,11 +1370,17 @@ 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; + } + ++ 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. +diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h +index afb2d7297ca..89c48905c95 100644 +--- a/src/egl/drivers/dri2/egl_dri2.h ++++ b/src/egl/drivers/dri2/egl_dri2.h +@@ -78,6 +78,10 @@ struct zwp_linux_dmabuf_feedback_v1; + + #endif /* HAVE_ANDROID_PLATFORM */ + ++#ifdef HAVE_NULL_PLATFORM ++#include ++#endif ++ + #include "eglconfig.h" + #include "eglcontext.h" + #include "egldevice.h" +@@ -95,6 +99,22 @@ struct zwp_linux_dmabuf_feedback_v1; + + struct wl_buffer; + ++#ifdef HAVE_NULL_PLATFORM ++struct display_output { ++ bool in_use; ++ 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; ++}; ++#endif ++ + struct dri2_egl_display_vtbl { + /* mandatory on Wayland, unused otherwise */ + int (*authenticate)(_EGLDisplay *disp, uint32_t id); +@@ -296,6 +316,11 @@ struct dri2_egl_display + char *device_name; + #endif + ++#ifdef HAVE_NULL_PLATFORM ++ bool atomic_enabled; ++ struct display_output output; ++#endif ++ + #ifdef HAVE_ANDROID_PLATFORM + const gralloc_module_t *gralloc; + /* gralloc vendor usage bit for front rendering */ +@@ -340,11 +365,14 @@ 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 +@@ -352,12 +380,15 @@ struct dri2_egl_surface + /* 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,6 +397,9 @@ 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; +@@ -402,6 +436,10 @@ struct dri2_egl_surface + void *swrast_front; + #endif + ++#ifdef HAVE_NULL_PLATFORM ++ uint32_t front_fb_id; ++#endif ++ + int out_fence_fd; + EGLBoolean enable_out_fence; + +@@ -592,6 +630,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 +diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c +new file mode 100644 +index 00000000000..fb03ecc36fd +--- /dev/null ++++ b/src/egl/drivers/dri2/platform_null.c +@@ -0,0 +1,1179 @@ ++/* ++ * Copyright (c) Imagination Technologies Ltd. ++ * ++ * Parts based on platform_wayland, which has: ++ * ++ * Copyright © 2011-2012 Intel Corporation ++ * Copyright © 2012 Collabora, 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 (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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "egl_dri2.h" ++#include "loader.h" ++ ++#define NULL_CARD_MINOR_MAX 63U ++ ++/* ++ * Need at least version 4 for __DRI_IMAGE_ATTRIB_WIDTH and ++ * __DRI_IMAGE_ATTRIB_HEIGHT ++ */ ++#define NULL_IMAGE_EXTENSION_VERSION_MIN 4 ++ ++struct object_property { ++ uint32_t object_id; ++ uint32_t prop_id; ++ uint64_t prop_value; ++}; ++ ++#define object_property_set_named(output, object_type, prop_name, value) \ ++ { \ ++ .object_id = (output)->object_type##_id, \ ++ .prop_id = property_id_get_for_name((output)->object_type##_prop_res, \ ++ prop_name), \ ++ .prop_value = value, \ ++ } ++ ++/* ++ * The index of entries in this table is used as a bitmask in ++ * dri2_dpy->formats, which tracks the formats supported by the display. ++ */ ++static const struct dri2_null_format { ++ uint32_t drm_format; ++ int dri_image_format; ++ int rgba_shifts[4]; ++ unsigned int rgba_sizes[4]; ++} dri2_null_formats[] = { ++ { ++ .drm_format = DRM_FORMAT_XRGB8888, ++ .dri_image_format = __DRI_IMAGE_FORMAT_XRGB8888, ++ .rgba_shifts = { 16, 8, 0, -1 }, ++ .rgba_sizes = { 8, 8, 8, 0 }, ++ }, ++ { ++ .drm_format = DRM_FORMAT_ARGB8888, ++ .dri_image_format = __DRI_IMAGE_FORMAT_ARGB8888, ++ .rgba_shifts = { 16, 8, 0, 24 }, ++ .rgba_sizes = { 8, 8, 8, 8 }, ++ }, ++ { ++ .drm_format = DRM_FORMAT_RGB565, ++ .dri_image_format = __DRI_IMAGE_FORMAT_RGB565, ++ .rgba_shifts = { 11, 5, 0, -1 }, ++ .rgba_sizes = { 5, 6, 5, 0 }, ++ }, ++}; ++ ++ ++static int ++format_idx_get_from_config(struct dri2_egl_display *dri2_dpy, ++ const __DRIconfig *config) ++{ ++ int shifts[4]; ++ unsigned int sizes[4]; ++ ++ dri2_get_shifts_and_sizes(dri2_dpy->core, config, shifts, sizes); ++ ++ for (unsigned int i = 0; i < ARRAY_SIZE(dri2_null_formats); i++) { ++ const struct dri2_null_format *format = &dri2_null_formats[i]; ++ ++ if (shifts[0] == format->rgba_shifts[0] && ++ shifts[1] == format->rgba_shifts[1] && ++ shifts[2] == format->rgba_shifts[2] && ++ shifts[3] == format->rgba_shifts[3] && ++ sizes[0] == format->rgba_sizes[0] && ++ sizes[1] == format->rgba_sizes[1] && ++ sizes[2] == format->rgba_sizes[2] && ++ sizes[3] == format->rgba_sizes[3]) { ++ return i; ++ } ++ } ++ ++ return -1; ++} ++ ++static int ++format_idx_get_from_dri_image_format(uint32_t dri_image_format) ++{ ++ for (unsigned int i = 0; i < ARRAY_SIZE(dri2_null_formats); i++) ++ if (dri2_null_formats[i].dri_image_format == dri_image_format) ++ return i; ++ ++ return -1; ++} ++ ++static int ++format_idx_get_from_drm_format(uint32_t drm_format) ++{ ++ for (unsigned int i = 0; i < ARRAY_SIZE(dri2_null_formats); i++) ++ if (dri2_null_formats[i].drm_format == drm_format) ++ return i; ++ ++ return -1; ++} ++ ++static int ++atomic_state_add_object_properties(drmModeAtomicReq *atomic_state, ++ const struct object_property *props, ++ const unsigned prop_count) ++{ ++ for (unsigned i = 0; i < prop_count; i++) { ++ int err; ++ ++ if (props[i].prop_id == 0) ++ return -EINVAL; ++ ++ err = drmModeAtomicAddProperty(atomic_state, props[i].object_id, ++ props[i].prop_id, props[i].prop_value); ++ if (err < 0) ++ return err; ++ } ++ ++ return 0; ++} ++ ++ ++static uint32_t ++property_id_get_for_name(drmModePropertyRes **prop_res, const char *prop_name) ++{ ++ if (prop_res) ++ for (unsigned i = 0; prop_res[i]; i++) ++ if (!strcmp(prop_res[i]->name, prop_name)) ++ return prop_res[i]->prop_id; ++ ++ return 0; ++} ++ ++static void ++flip_handler(int fd, unsigned int sequence, unsigned int tv_sec, ++ unsigned int tv_usec, void *user_data) ++{ ++ bool *plocked = user_data; ++ ++ if (plocked) ++ *plocked = false; ++} ++ ++static bool ++flip_process(int fd) ++{ ++ static drmEventContext evctx = ++ {.version = 2, .page_flip_handler = flip_handler}; ++ struct pollfd pfd = {.fd = fd, .events = POLLIN}; ++ int ret; ++ ++ do { ++ ret = poll(&pfd, 1, -1); ++ } while (ret > 0 && pfd.revents != pfd.events); ++ ++ if (ret <= 0) ++ return false; ++ ++ drmHandleEvent(fd, &evctx); ++ ++ return true; ++} ++ ++static drmModePropertyRes ** ++object_get_property_resources(int fd, uint32_t object_id, uint32_t object_type) ++{ ++ drmModeObjectProperties *props; ++ drmModePropertyRes **prop_res; ++ ++ props = drmModeObjectGetProperties(fd, object_id, object_type); ++ if (!props) ++ return NULL; ++ ++ prop_res = malloc((props->count_props + 1) * sizeof(*prop_res)); ++ if (prop_res) { ++ prop_res[props->count_props] = NULL; ++ ++ for (unsigned i = 0; i < props->count_props; i++) { ++ prop_res[i] = drmModeGetProperty(fd, props->props[i]); ++ if (!prop_res[i]) { ++ while (i--) { ++ drmModeFreeProperty(prop_res[i]); ++ free(prop_res); ++ prop_res = NULL; ++ } ++ break; ++ } ++ } ++ } ++ ++ drmModeFreeObjectProperties(props); ++ ++ return prop_res; ++} ++ ++static void ++object_free_property_resources(int fd, drmModePropertyRes **prop_res) ++{ ++ for (unsigned i = 0; prop_res[i]; i++) ++ drmModeFreeProperty(prop_res[i]); ++ free(prop_res); ++} ++ ++static bool ++object_property_value_for_name(int fd, uint32_t object_id, uint32_t object_type, ++ const char *prop_name, uint64_t *value_out) ++{ ++ drmModeObjectProperties *plane_props; ++ bool found = false; ++ ++ plane_props = drmModeObjectGetProperties(fd, object_id, object_type); ++ if (!plane_props) ++ return false; ++ ++ for (unsigned i = 0; i < plane_props->count_props; i++) { ++ drmModePropertyRes *prop; ++ ++ prop = drmModeGetProperty(fd, plane_props->props[i]); ++ if (!prop) ++ continue; ++ ++ found = !strcmp(prop->name, prop_name); ++ drmModeFreeProperty(prop); ++ if (found) { ++ *value_out = plane_props->prop_values[i]; ++ break; ++ } ++ } ++ ++ drmModeFreeObjectProperties(plane_props); ++ ++ return found; ++} ++ ++static int ++connector_choose_mode(drmModeConnector *connector) ++{ ++ if (!connector->count_modes) ++ return -1; ++ ++ for (unsigned i = 0; i < connector->count_modes; i++) { ++ if (connector->modes[i].flags & DRM_MODE_FLAG_INTERLACE) ++ continue; ++ ++ if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) ++ return i; ++ } ++ ++ return 0; ++} ++ ++static drmModeConnector * ++connector_get(int fd, drmModeRes *resources) ++{ ++ /* Find the first connected connector */ ++ for (unsigned i = 0; i < resources->count_connectors; i++) { ++ drmModeConnector *connector; ++ ++ connector = drmModeGetConnector(fd, resources->connectors[i]); ++ if (!connector) ++ continue; ++ ++ if (connector->connection == DRM_MODE_CONNECTED) ++ return connector; ++ ++ drmModeFreeConnector(connector); ++ } ++ ++ return NULL; ++} ++ ++static drmModeCrtc * ++crtc_get_for_connector(int fd, drmModeRes *resources, ++ drmModeConnector *connector) ++{ ++ for (unsigned i = 0; i < connector->count_encoders; i++) { ++ drmModeEncoder *encoder; ++ ++ encoder = drmModeGetEncoder(fd, connector->encoders[i]); ++ if (!encoder) ++ continue; ++ ++ for (unsigned j = 0; j < resources->count_crtcs; j++) { ++ if (encoder->possible_crtcs & (1 << j)) { ++ drmModeCrtc *crtc; ++ ++ crtc = drmModeGetCrtc(fd, resources->crtcs[j]); ++ if (crtc) { ++ drmModeFreeEncoder(encoder); ++ return crtc; ++ } ++ } ++ } ++ ++ drmModeFreeEncoder(encoder); ++ } ++ ++ return NULL; ++} ++ ++static drmModePlane * ++primary_plane_get_for_crtc(int fd, drmModeRes *resources, drmModeCrtc *crtc) ++{ ++ drmModePlaneRes *plane_resources; ++ unsigned crtc_idx; ++ ++ plane_resources = drmModeGetPlaneResources(fd); ++ if (!plane_resources) ++ return NULL; ++ ++ for (crtc_idx = 0; crtc_idx < resources->count_crtcs; crtc_idx++) ++ if (resources->crtcs[crtc_idx] == crtc->crtc_id) ++ break; ++ assert(crtc_idx != resources->count_crtcs); ++ ++ for (unsigned i = 0; i < plane_resources->count_planes; i++) { ++ const uint32_t crtc_bit = 1 << crtc_idx; ++ drmModePlane *plane; ++ ++ plane = drmModeGetPlane(fd, plane_resources->planes[i]); ++ if (!plane) ++ continue; ++ ++ if (plane->possible_crtcs & crtc_bit) { ++ uint64_t type; ++ bool res; ++ ++ res = object_property_value_for_name(fd, plane->plane_id, ++ DRM_MODE_OBJECT_PLANE, ++ "type", &type); ++ if (res && type == DRM_PLANE_TYPE_PRIMARY) { ++ drmModeFreePlaneResources(plane_resources); ++ return plane; ++ } ++ } ++ ++ drmModeFreePlane(plane); ++ } ++ ++ drmModeFreePlaneResources(plane_resources); ++ ++ return NULL; ++} ++ ++static bool ++display_output_atomic_init(int fd, struct display_output *output) ++{ ++ drmModePropertyRes **connector_prop_res; ++ drmModePropertyRes **crtc_prop_res; ++ drmModePropertyRes **plane_prop_res; ++ int err; ++ ++ connector_prop_res = object_get_property_resources(fd, output->connector_id, ++ DRM_MODE_OBJECT_CONNECTOR); ++ if (!connector_prop_res) ++ return false; ++ ++ crtc_prop_res = object_get_property_resources(fd, output->crtc_id, ++ DRM_MODE_OBJECT_CRTC); ++ if (!crtc_prop_res) ++ goto err_free_connector_prop_res; ++ ++ plane_prop_res = object_get_property_resources(fd, output->plane_id, ++ DRM_MODE_OBJECT_PLANE); ++ if (!plane_prop_res) ++ goto err_free_crtc_prop_res; ++ ++ err = drmModeCreatePropertyBlob(fd, &output->mode, sizeof(output->mode), ++ &output->mode_blob_id); ++ if (err) ++ goto err_free_plane_prop_res; ++ ++ output->atomic_state = drmModeAtomicAlloc(); ++ if (!output->atomic_state) ++ goto err_destroy_mode_prop_blob; ++ ++ output->connector_prop_res = connector_prop_res; ++ output->crtc_prop_res = crtc_prop_res; ++ output->plane_prop_res = plane_prop_res; ++ ++ return true; ++ ++err_destroy_mode_prop_blob: ++ drmModeDestroyPropertyBlob(fd, output->mode_blob_id); ++err_free_plane_prop_res: ++ object_free_property_resources(fd, plane_prop_res); ++err_free_crtc_prop_res: ++ object_free_property_resources(fd, crtc_prop_res); ++err_free_connector_prop_res: ++ object_free_property_resources(fd, connector_prop_res); ++ return false; ++} ++ ++static int ++display_output_atomic_flip(int fd, struct display_output *output, uint32_t fb_id, ++ uint32_t flags, void *flip_data) ++{ ++ const struct object_property obj_props[] = { ++ object_property_set_named(output, plane, "FB_ID", fb_id), ++ }; ++ int err; ++ ++ /* Reset atomic state */ ++ drmModeAtomicSetCursor(output->atomic_state, 0); ++ ++ err = atomic_state_add_object_properties(output->atomic_state, obj_props, ++ ARRAY_SIZE(obj_props)); ++ if (err) ++ return err; ++ ++ /* ++ * Don't block - like drmModePageFlip, drmModeAtomicCommit will return ++ * -EBUSY if the commit can't be queued in the kernel. ++ */ ++ flags |= DRM_MODE_ATOMIC_NONBLOCK; ++ ++ return drmModeAtomicCommit(fd, output->atomic_state, flags, flip_data); ++} ++ ++static int ++display_output_atomic_modeset(int fd, struct display_output *output, uint32_t fb_id) ++{ ++ /* SRC_W and SRC_H in 16.16 fixed point */ ++ const struct object_property obj_props[] = { ++ object_property_set_named(output, connector, "CRTC_ID", output->crtc_id), ++ object_property_set_named(output, crtc, "ACTIVE", 1), ++ object_property_set_named(output, crtc, "MODE_ID", output->mode_blob_id), ++ object_property_set_named(output, plane, "FB_ID", fb_id), ++ object_property_set_named(output, plane, "CRTC_ID", output->crtc_id), ++ object_property_set_named(output, plane, "CRTC_X", 0), ++ object_property_set_named(output, plane, "CRTC_Y", 0), ++ object_property_set_named(output, plane, "CRTC_W", output->mode.hdisplay), ++ object_property_set_named(output, plane, "CRTC_H", output->mode.vdisplay), ++ object_property_set_named(output, plane, "SRC_X", 0), ++ object_property_set_named(output, plane, "SRC_Y", 0), ++ object_property_set_named(output, plane, "SRC_W", output->mode.hdisplay << 16), ++ object_property_set_named(output, plane, "SRC_H", output->mode.vdisplay << 16), ++ }; ++ int err; ++ ++ /* Reset atomic state */ ++ drmModeAtomicSetCursor(output->atomic_state, 0); ++ ++ err = atomic_state_add_object_properties(output->atomic_state, obj_props, ++ ARRAY_SIZE(obj_props)); ++ if (err) ++ return false; ++ ++ return drmModeAtomicCommit(fd, output->atomic_state, ++ DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); ++} ++ ++static bool ++display_output_init(int fd, struct display_output *output, bool use_atomic) ++{ ++ drmModeRes *resources; ++ drmModeConnector *connector; ++ drmModeCrtc *crtc; ++ drmModePlane *plane; ++ unsigned mode_idx; ++ ++ resources = drmModeGetResources(fd); ++ if (!resources) ++ return false; ++ ++ connector = connector_get(fd, resources); ++ if (!connector) ++ goto err_free_resources; ++ ++ crtc = crtc_get_for_connector(fd, resources, connector); ++ if (!crtc) ++ goto err_free_connector; ++ ++ plane = primary_plane_get_for_crtc(fd, resources, crtc); ++ if (!plane) ++ goto err_free_crtc; ++ ++ mode_idx = connector_choose_mode(connector); ++ if (mode_idx < 0) ++ goto err_free_plane; ++ output->mode = connector->modes[mode_idx]; ++ ++ /* Record the display supported formats */ ++ for (unsigned i = 0; i < plane->count_formats; i++) { ++ int format_idx; ++ ++ format_idx = format_idx_get_from_drm_format(plane->formats[i]); ++ if (format_idx == -1) ++ continue; ++ ++ output->formats |= (1 << format_idx); ++ } ++ if (!output->formats) ++ goto err_free_plane; ++ ++ output->connector_id = connector->connector_id; ++ output->crtc_id = crtc->crtc_id; ++ output->plane_id = plane->plane_id; ++ ++ drmModeFreePlane(plane); ++ drmModeFreeCrtc(crtc); ++ drmModeFreeConnector(connector); ++ drmModeFreeResources(resources); ++ ++ if (use_atomic) { ++ if (!display_output_atomic_init(fd, output)) { ++ _eglLog(_EGL_DEBUG, ++ "failed to initialise atomic support (using legacy mode)"); ++ } ++ } ++ ++ return true; ++ ++err_free_plane: ++ drmModeFreePlane(plane); ++err_free_crtc: ++ drmModeFreeCrtc(crtc); ++err_free_connector: ++ drmModeFreeConnector(connector); ++err_free_resources: ++ drmModeFreeResources(resources); ++ return false; ++} ++ ++static int ++display_output_flip(int fd, struct display_output *output, uint32_t fb_id, ++ uint32_t flags, void *flip_data) ++{ ++ if (output->atomic_state) ++ return display_output_atomic_flip(fd, output, fb_id, flags, flip_data); ++ ++ return drmModePageFlip(fd, output->crtc_id, fb_id, flags, flip_data); ++} ++ ++static int ++display_output_modeset(int fd, struct display_output *output, uint32_t fb_id) ++{ ++ if (output->atomic_state) ++ return display_output_atomic_modeset(fd, output, fb_id); ++ ++ return drmModeSetCrtc(fd, output->crtc_id, fb_id, 0, 0, ++ &output->connector_id, 1, &output->mode); ++} ++ ++static bool ++add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image, ++ uint32_t *fb_id_out) ++{ ++ uint32_t handles[4] = {0}; ++ uint32_t pitches[4] = {0}; ++ uint32_t offsets[4] = {0}; ++ int handle, stride, width, height, format; ++ int format_idx; ++ ++ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HANDLE, &handle); ++ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride); ++ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_WIDTH, &width); ++ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HEIGHT, &height); ++ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format); ++ ++ handles[0] = (uint32_t) handle; ++ pitches[0] = (uint32_t) stride; ++ ++ format_idx = format_idx_get_from_dri_image_format(format); ++ assert(format_idx != -1); ++ ++ return !drmModeAddFB2(dri2_dpy->fd, width, height, ++ dri2_null_formats[format_idx].drm_format, ++ handles, pitches, offsets, fb_id_out, 0); ++} ++ ++static bool ++get_front_bo(struct dri2_egl_surface *dri2_surf) ++{ ++ struct dri2_egl_display *dri2_dpy = ++ dri2_egl_display(dri2_surf->base.Resource.Display); ++ unsigned int use = 0; ++ ++ if (dri2_surf->base.Type == EGL_WINDOW_BIT) ++ use |= __DRI_IMAGE_USE_SCANOUT; ++ ++ dri2_surf->front = dri2_dpy->image->createImage(dri2_dpy->dri_screen, ++ dri2_surf->base.Width, ++ dri2_surf->base.Height, ++ dri2_surf->format, ++ use, ++ NULL); ++ if (!dri2_surf->front) ++ return false; ++ ++ if (dri2_surf->base.Type == EGL_WINDOW_BIT) { ++ if (!add_fb_for_dri_image(dri2_dpy, dri2_surf->front, ++ &dri2_surf->front_fb_id)) { ++ dri2_dpy->image->destroyImage(dri2_surf->front); ++ dri2_surf->front = NULL; ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++static bool ++get_back_bo(struct dri2_egl_surface *dri2_surf) ++{ ++ struct dri2_egl_display *dri2_dpy = ++ dri2_egl_display(dri2_surf->base.Resource.Display); ++ ++ if (!dri2_surf->back) { ++ for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { ++ if (!dri2_surf->color_buffers[i].locked) { ++ dri2_surf->back = &dri2_surf->color_buffers[i]; ++ break; ++ } ++ } ++ if (!dri2_surf->back) ++ return false; ++ } ++ ++ if (!dri2_surf->back->dri_image) { ++ dri2_surf->back->dri_image = ++ dri2_dpy->image->createImage(dri2_dpy->dri_screen, ++ dri2_surf->base.Width, ++ dri2_surf->base.Height, ++ dri2_surf->format, ++ __DRI_IMAGE_USE_SCANOUT, ++ NULL); ++ if (!dri2_surf->back->dri_image) ++ return false; ++ } ++ ++ if (!dri2_surf->back->fb_id) { ++ if (!add_fb_for_dri_image(dri2_dpy, dri2_surf->back->dri_image, ++ &dri2_surf->back->fb_id)) { ++ return false; ++ } ++ } ++ ++ dri2_surf->back->locked = 1; ++ ++ return true; ++} ++ ++static _EGLSurface * ++create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type, ++ const EGLint *attrib_list) ++{ ++ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); ++ struct dri2_egl_config *dri2_config = dri2_egl_config(config); ++ struct dri2_egl_surface *dri2_surf; ++ const __DRIconfig *dri_config; ++ _EGLSurface *surf; ++ int format_idx; ++ ++ dri2_surf = calloc(1, sizeof(*dri2_surf)); ++ if (!dri2_surf) { ++ _eglError(EGL_BAD_ALLOC, "failed to create surface"); ++ return NULL; ++ } ++ surf = &dri2_surf->base; ++ ++ if (!dri2_init_surface(surf, disp, type, config, attrib_list, false, NULL)) ++ goto err_free_surface; ++ ++ dri_config = dri2_get_dri_config(dri2_config, type, ++ dri2_surf->base.GLColorspace); ++ if (!dri_config) { ++ _eglError(EGL_BAD_MATCH, "Unsupported surfacetype/colorspace configuration"); ++ goto err_free_surface; ++ } ++ ++ dri2_surf->dri_drawable = ++ dri2_dpy->image_driver->createNewDrawable(dri2_dpy->dri_screen, ++ dri_config, dri2_surf); ++ if (!dri2_surf->dri_drawable) { ++ _eglError(EGL_BAD_ALLOC, "failed to create drawable"); ++ goto err_free_surface; ++ } ++ ++ format_idx = format_idx_get_from_config(dri2_dpy, dri_config); ++ assert(format_idx != -1); ++ ++ dri2_surf->format = dri2_null_formats[format_idx].dri_image_format; ++ ++ return surf; ++ ++err_free_surface: ++ free(dri2_surf); ++ return NULL; ++} ++ ++static void ++destroy_surface(_EGLSurface *surf) ++{ ++ struct dri2_egl_display *dri2_dpy = dri2_egl_display(surf->Resource.Display); ++ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); ++ ++ dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); ++ dri2_fini_surface(surf); ++ free(surf); ++} ++ ++static EGLBoolean ++dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf); ++ ++static _EGLSurface * ++dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config, ++ void *native_window, const EGLint *attrib_list) ++{ ++ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); ++ struct dri2_egl_surface *dri2_surf; ++ _EGLSurface *surf; ++ int err; ++ ++ if (dri2_dpy->output.in_use) { ++ _eglError(EGL_BAD_NATIVE_WINDOW, "window in use"); ++ return NULL; ++ } ++ ++ surf = create_surface(disp, config, EGL_WINDOW_BIT, attrib_list); ++ if (!surf) ++ return NULL; ++ dri2_surf = dri2_egl_surface(surf); ++ ++ dri2_surf->base.Width = dri2_dpy->output.mode.hdisplay; ++ dri2_surf->base.Height = dri2_dpy->output.mode.vdisplay; ++ ++ if (!get_front_bo(dri2_surf)) { ++ _eglError(EGL_BAD_NATIVE_WINDOW, "window get buffer"); ++ goto err_destroy_surface; ++ } ++ ++ err = display_output_modeset(dri2_dpy->fd, &dri2_dpy->output, ++ dri2_surf->front_fb_id); ++ if (err) { ++ _eglError(EGL_BAD_NATIVE_WINDOW, "window set mode"); ++ goto err_destroy_surface; ++ } ++ ++ dri2_dpy->output.in_use = true; ++ ++ return surf; ++ ++err_destroy_surface: ++ dri2_null_destroy_surface(disp, surf); ++ return NULL; ++} ++ ++static _EGLSurface * ++dri2_null_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *config, ++ const EGLint *attrib_list) ++{ ++ return create_surface(disp, config, EGL_PBUFFER_BIT, attrib_list); ++} ++ ++static EGLBoolean ++dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) ++{ ++ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); ++ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); ++ EGLint type = surf->Type; ++ ++ /* If there's a current surface then a page flip has been performed, so make ++ * sure we process the flip event. ++ */ ++ if (dri2_surf->current) ++ flip_process(dri2_dpy->fd); ++ ++ if (dri2_surf->front) ++ dri2_dpy->image->destroyImage(dri2_surf->front); ++ ++ if (dri2_surf->front_fb_id) ++ drmModeRmFB(dri2_dpy->fd, dri2_surf->front_fb_id); ++ ++ for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { ++ if (dri2_surf->color_buffers[i].fb_id) ++ drmModeRmFB(dri2_dpy->fd, dri2_surf->color_buffers[i].fb_id); ++ if (dri2_surf->color_buffers[i].dri_image) ++ dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image); ++ } ++ ++ destroy_surface(surf); ++ ++ if (type == EGL_WINDOW_BIT) ++ dri2_dpy->output.in_use = false; ++ ++ return EGL_TRUE; ++} ++ ++static EGLBoolean ++dri2_null_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); ++ bool *plocked = NULL; ++ uint32_t flags; ++ int err; ++ ++ if (dri2_surf->base.Type != EGL_WINDOW_BIT) ++ return EGL_TRUE; ++ ++ for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) ++ if (dri2_surf->color_buffers[i].age > 0) ++ dri2_surf->color_buffers[i].age++; ++ ++ /* Make sure we have a back buffer in case we're swapping without ++ * ever rendering. */ ++ if (!get_back_bo(dri2_surf)) { ++ _eglError(EGL_BAD_ALLOC, "dri2_null_swap_buffers"); ++ return EGL_FALSE; ++ } ++ ++ dri2_flush_drawable_for_swapbuffers(disp, draw); ++ dri2_dpy->flush->invalidate(dri2_surf->dri_drawable); ++ ++ if (dri2_surf->current) { ++ /* Wait for the previous flip to happen so the next one can be queued */ ++ if (!flip_process(dri2_dpy->fd)) { ++ _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_null_swap_buffers process"); ++ return EGL_FALSE; ++ } ++ ++ plocked = &dri2_surf->current->locked; ++ } ++ ++ flags = DRM_MODE_PAGE_FLIP_EVENT; ++ if (draw->SwapInterval == 0) ++ flags |= DRM_MODE_PAGE_FLIP_ASYNC; ++ ++ do { ++ err = display_output_flip(dri2_dpy->fd, &dri2_dpy->output, ++ dri2_surf->back->fb_id, flags, plocked); ++ } while (err == -EBUSY); ++ ++ if (err) { ++ _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_null_swap_buffers flip"); ++ dri2_surf->back->locked = false; ++ dri2_surf->back = NULL; ++ return EGL_FALSE; ++ } ++ ++ dri2_surf->back->age = 1; ++ dri2_surf->current = dri2_surf->back; ++ dri2_surf->back = NULL; ++ ++ return EGL_TRUE; ++} ++ ++static EGLint ++dri2_null_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface) ++{ ++ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface); ++ ++ if (!get_back_bo(dri2_surf)) { ++ _eglError(EGL_BAD_ALLOC, "failed to get back buffer to query age"); ++ return -1; ++ } ++ ++ return dri2_surf->back->age; ++} ++ ++static struct dri2_egl_display_vtbl dri2_null_display_vtbl = { ++ .create_window_surface = dri2_null_create_window_surface, ++ .create_pbuffer_surface = dri2_null_create_pbuffer_surface, ++ .destroy_surface = dri2_null_destroy_surface, ++ .create_image = dri2_create_image_khr, ++ .swap_buffers = dri2_null_swap_buffers, ++ .query_buffer_age = dri2_null_query_buffer_age, ++ .get_dri_drawable = dri2_surface_get_dri_drawable, ++}; ++ ++static int ++dri2_null_image_get_buffers(__DRIdrawable *driDrawable, unsigned int format, ++ uint32_t *stamp, void *loaderPrivate, ++ uint32_t buffer_mask, struct __DRIimageList *buffers) ++{ ++ struct dri2_egl_surface *dri2_surf = loaderPrivate; ++ ++ buffers->image_mask = 0; ++ buffers->back = NULL; ++ buffers->front = NULL; ++ ++ if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) ++ if (!get_front_bo(dri2_surf)) ++ return 0; ++ ++ if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) ++ if (!get_back_bo(dri2_surf)) ++ return 0; ++ ++ if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) { ++ buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT; ++ buffers->front = dri2_surf->front; ++ } ++ ++ if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) { ++ buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK; ++ buffers->back = dri2_surf->back->dri_image; ++ } ++ ++ return 1; ++} ++ ++static void ++dri2_null_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) ++{ ++ (void) driDrawable; ++ (void) loaderPrivate; ++} ++ ++static const __DRIimageLoaderExtension image_loader_extension = { ++ .base = { __DRI_IMAGE_LOADER, 1 }, ++ ++ .getBuffers = dri2_null_image_get_buffers, ++ .flushFrontBuffer = dri2_null_flush_front_buffer, ++}; ++ ++static const __DRIextension *image_loader_extensions[] = { ++ &image_loader_extension.base, ++ &image_lookup_extension.base, ++ &use_invalidate.base, ++ NULL, ++}; ++ ++static bool ++dri2_null_device_is_kms(int fd) ++{ ++ drmModeRes *resources; ++ bool is_kms; ++ ++ resources = drmModeGetResources(fd); ++ if (!resources) ++ return false; ++ ++ is_kms = resources->count_crtcs != 0 && ++ resources->count_connectors != 0 && ++ resources->count_encoders != 0; ++ ++ drmModeFreeResources(resources); ++ ++ return is_kms; ++} ++ ++static bool ++dri2_null_probe_device(_EGLDisplay *disp) ++{ ++ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); ++ ++ dri2_dpy->fd = -1; ++ ++ for (unsigned i = 0; i <= NULL_CARD_MINOR_MAX; i++) { ++ char *card_path; ++ ++ if (asprintf(&card_path, DRM_DEV_NAME, DRM_DIR_NAME, i) < 0) ++ continue; ++ ++ dri2_dpy->fd = loader_open_device(card_path); ++ free(card_path); ++ if (dri2_dpy->fd < 0) ++ continue; ++ ++ if (dri2_null_device_is_kms(dri2_dpy->fd)) { ++ dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd); ++ if (dri2_dpy->driver_name) { ++ if (dri2_load_driver_dri3(disp)) { ++ _EGLDevice *dev = _eglAddDevice(dri2_dpy->fd, false); ++ if (!dev) { ++ dlclose(dri2_dpy->driver); ++ _eglLog(_EGL_WARNING, "DRI2: failed to find EGLDevice"); ++ } else { ++ dri2_dpy->loader_extensions = image_loader_extensions; ++ dri2_dpy->own_device = 1; ++ disp->Device = dev; ++ return true; ++ } ++ } ++ free(dri2_dpy->driver_name); ++ dri2_dpy->driver_name = NULL; ++ } ++ } ++ ++ close(dri2_dpy->fd); ++ dri2_dpy->fd = -1; ++ } ++ ++ return false; ++} ++ ++static EGLBoolean ++dri2_null_add_configs_for_formats(_EGLDisplay *disp) ++{ ++ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); ++ unsigned int count = 0; ++ ++ for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) { ++ struct dri2_egl_config *dri2_conf; ++ int format_idx; ++ ++ format_idx = format_idx_get_from_config(dri2_dpy, ++ dri2_dpy->driver_configs[i]); ++ if (format_idx == -1) ++ continue; ++ ++ if (!(dri2_dpy->output.formats & (1 << format_idx))) { ++ _eglLog(_EGL_DEBUG, "unsupported drm format 0x%04x", ++ dri2_null_formats[format_idx].drm_format); ++ continue; ++ } ++ ++ dri2_conf = dri2_add_config(disp, ++ dri2_dpy->driver_configs[i], count + 1, ++ EGL_WINDOW_BIT | EGL_PBUFFER_BIT, ++ NULL, NULL, NULL); ++ if (dri2_conf) ++ count++; ++ } ++ ++ return count != 0; ++} ++ ++EGLBoolean ++dri2_initialize_null(_EGLDisplay *disp) ++{ ++ struct dri2_egl_display *dri2_dpy; ++ uint64_t value; ++ int err; ++ ++ dri2_dpy = calloc(1, sizeof(*dri2_dpy)); ++ if (!dri2_dpy) ++ return _eglError(EGL_BAD_ALLOC, "eglInitialize"); ++ ++ disp->DriverData = (void *) dri2_dpy; ++ ++ if (!dri2_null_probe_device(disp)) { ++ _eglError(EGL_NOT_INITIALIZED, "failed to load driver"); ++ goto cleanup; ++ } ++ ++ /* ++ * Try to use atomic modesetting if available and fallback to legacy kernel ++ * modesetting if not. If this succeeds then universal planes will also have ++ * been enabled. ++ */ ++ err = drmSetClientCap(dri2_dpy->fd, DRM_CLIENT_CAP_ATOMIC, 1); ++ dri2_dpy->atomic_enabled = !err; ++ ++ if (!dri2_dpy->atomic_enabled) { ++ /* ++ * Enable universal planes so that we can get the pixel formats for the ++ * primary plane ++ */ ++ err = drmSetClientCap(dri2_dpy->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); ++ if (err) { ++ _eglError(EGL_NOT_INITIALIZED, "failed to enable universal planes"); ++ goto cleanup; ++ } ++ ++ dri2_dpy->atomic_enabled = false; ++ } ++ ++ if (!dri2_create_screen(disp)) { ++ _eglError(EGL_NOT_INITIALIZED, "failed to create screen"); ++ goto cleanup; ++ } ++ ++ if (!dri2_setup_extensions(disp)) { ++ _eglError(EGL_NOT_INITIALIZED, "failed to find required DRI extensions"); ++ goto cleanup; ++ } ++ ++ dri2_setup_screen(disp); ++ dri2_setup_swap_interval(disp, 1); ++ ++ err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value); ++ if (err || value == 0) ++ dri2_dpy->min_swap_interval = 1; ++ ++ if (dri2_dpy->image->base.version < NULL_IMAGE_EXTENSION_VERSION_MIN) { ++ _eglError(EGL_NOT_INITIALIZED, "image extension version too old"); ++ goto cleanup; ++ } ++ ++ if (!display_output_init(dri2_dpy->fd, &dri2_dpy->output, ++ dri2_dpy->atomic_enabled)) { ++ _eglError(EGL_NOT_INITIALIZED, "failed to create output"); ++ goto cleanup; ++ } ++ ++ if (!dri2_null_add_configs_for_formats(disp)) { ++ _eglError(EGL_NOT_INITIALIZED, "failed to add configs"); ++ goto cleanup; ++ } ++ ++ disp->Extensions.EXT_buffer_age = EGL_TRUE; ++ disp->Extensions.KHR_image_base = EGL_TRUE; ++ ++ /* Fill vtbl last to prevent accidentally calling virtual function during ++ * initialization. ++ */ ++ dri2_dpy->vtbl = &dri2_null_display_vtbl; ++ ++ return EGL_TRUE; ++ ++cleanup: ++ dri2_display_destroy(disp); ++ return EGL_FALSE; ++} ++ ++void ++dri2_teardown_null(struct dri2_egl_display *dri2_dpy) ++{ ++ drmModeAtomicFree(dri2_dpy->output.atomic_state); ++ ++ if (dri2_dpy->output.mode_blob_id) ++ drmModeDestroyPropertyBlob(dri2_dpy->fd, dri2_dpy->output.mode_blob_id); ++ ++ if (dri2_dpy->output.plane_prop_res) { ++ for (unsigned i = 0; dri2_dpy->output.plane_prop_res[i]; i++) ++ drmModeFreeProperty(dri2_dpy->output.plane_prop_res[i]); ++ free(dri2_dpy->output.plane_prop_res); ++ } ++ ++ if (dri2_dpy->output.crtc_prop_res) { ++ for (unsigned i = 0; dri2_dpy->output.crtc_prop_res[i]; i++) ++ drmModeFreeProperty(dri2_dpy->output.crtc_prop_res[i]); ++ free(dri2_dpy->output.crtc_prop_res); ++ } ++ ++ if (dri2_dpy->output.connector_prop_res) { ++ for (unsigned i = 0; dri2_dpy->output.connector_prop_res[i]; i++) ++ drmModeFreeProperty(dri2_dpy->output.connector_prop_res[i]); ++ free(dri2_dpy->output.connector_prop_res); ++ } ++} +diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c +index c4dac448b8b..f8380e139f5 100644 +--- a/src/egl/main/eglapi.c ++++ b/src/egl/main/eglapi.c +@@ -1063,7 +1063,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)) { +diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c +index 39850e34f7c..a0920194153 100644 +--- a/src/egl/main/egldisplay.c ++++ b/src/egl/main/egldisplay.c +@@ -85,6 +85,7 @@ static const struct { + { _EGL_PLATFORM_SURFACELESS, "surfaceless" }, + { _EGL_PLATFORM_DEVICE, "device" }, + { _EGL_PLATFORM_WINDOWS, "windows" }, ++ { _EGL_PLATFORM_NULL, "null" }, + }; + + +diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h +index 1b9afdb343a..cedf3887c9d 100644 +--- a/src/egl/main/egldisplay.h ++++ b/src/egl/main/egldisplay.h +@@ -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 +diff --git a/src/egl/meson.build b/src/egl/meson.build +index a7c6471ceb4..b20d85dc19f 100644 +--- a/src/egl/meson.build ++++ b/src/egl/meson.build +@@ -152,6 +152,11 @@ elif with_platform_windows + incs_for_egl += [inc_wgl, inc_gallium, inc_gallium_aux] + link_for_egl += libgallium_wgl + endif ++if with_platform_null ++ 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' +-- +2.17.1 + diff --git a/package/mesa3d/0028-egl-add-support-for-EXT_image_gl_colorspace.patch b/package/mesa3d/0028-egl-add-support-for-EXT_image_gl_colorspace.patch new file mode 100644 index 00000000..6746cdcb --- /dev/null +++ b/package/mesa3d/0028-egl-add-support-for-EXT_image_gl_colorspace.patch @@ -0,0 +1,205 @@ +From cb9b76162c0d7ca14523b01e803c6d40cb354a91 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 29 Jan 2019 14:36:25 +0000 +Subject: [PATCH 028/168] egl: add support for EXT_image_gl_colorspace + +--- + src/egl/drivers/dri2/egl_dri2.c | 52 +++++++++++++++++++++++++++++++-- + src/egl/main/eglapi.c | 1 + + src/egl/main/egldisplay.h | 1 + + src/egl/main/eglimage.c | 14 +++++++++ + src/egl/main/eglimage.h | 3 ++ + 5 files changed, 69 insertions(+), 2 deletions(-) + +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index 6337cb23aa4..4e39f2e7bdc 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -1109,6 +1109,9 @@ dri2_setup_screen(_EGLDisplay *disp) + 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) +@@ -2516,6 +2519,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) { +@@ -2592,6 +2600,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) { +@@ -2748,6 +2761,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; +@@ -2933,6 +2951,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) +@@ -3090,6 +3125,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; +@@ -3116,6 +3152,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; +@@ -3160,7 +3208,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, +@@ -3172,7 +3220,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, +diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c +index f8380e139f5..b5064a34c67 100644 +--- a/src/egl/main/eglapi.c ++++ b/src/egl/main/eglapi.c +@@ -564,6 +564,7 @@ _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); +diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h +index cedf3887c9d..4b16fb5fd02 100644 +--- a/src/egl/main/egldisplay.h ++++ b/src/egl/main/egldisplay.h +@@ -112,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; +diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c +index 997855f48c0..1011b663b72 100644 +--- a/src/egl/main/eglimage.c ++++ b/src/egl/main/eglimage.c +@@ -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; + +diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h +index 02ad3b8ef10..003955d2b9b 100644 +--- a/src/egl/main/eglimage.h ++++ b/src/egl/main/eglimage.h +@@ -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; + }; + + /** +-- +2.17.1 + diff --git a/package/mesa3d/0029-meson-force-C-2011-for-thread_local.patch b/package/mesa3d/0029-meson-force-C-2011-for-thread_local.patch new file mode 100644 index 00000000..a2c8f5ed --- /dev/null +++ b/package/mesa3d/0029-meson-force-C-2011-for-thread_local.patch @@ -0,0 +1,35 @@ +From a306c154e036cd8d19bc73e93f03e93c2dcc5d81 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 24 Jun 2019 09:35:39 +0100 +Subject: [PATCH 029/168] meson: force C++ 2011 for "thread_local" + +For some combinations of Meson and the GNU C++ compiler, Meson does +not add '-std=c++11' to the command line arguments, resulting in +compilation errors, due to the use of the "thread_local" keyword (a +C++ 2011 feature). If the C++ compiler doesn't understand the +"thread_local" keyword by default, add '-std=c++11' to the compiler +command line arguments. +--- + meson.build | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/meson.build b/meson.build +index 9fb6dd81d26..3bdbb622b42 100644 +--- a/meson.build ++++ b/meson.build +@@ -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' +-- +2.17.1 + diff --git a/package/mesa3d/0030-dri2-add-support-for-swap-intervals-other-than-1.patch b/package/mesa3d/0030-dri2-add-support-for-swap-intervals-other-than-1.patch new file mode 100644 index 00000000..59669fc3 --- /dev/null +++ b/package/mesa3d/0030-dri2-add-support-for-swap-intervals-other-than-1.patch @@ -0,0 +1,787 @@ +From 97d20fbb86135061563ad4c33848a24af719b1b9 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 19 Jun 2019 16:36:06 +0100 +Subject: [PATCH 030/168] dri2: add support for swap intervals other than 1 + +Before this change, the swap interval was fixed at 1, with page flips +scheduled on the next vblank. This change allows any swap interval +between 0 and 10 to be set. + +An additional thread is created, so as not to rely on the application +polling for previously scheduled drm events (be it a flip or a vblank). +Instead, each call to swap buffers made by the application will be +queued, and consumed asynchronously by the additional thread. This +ensures that drm events will be handled as soon as possible, +regardless of the timing of subsequent calls to swap buffers. + +Change-Id: If7c0495df7ddfaa08583a14f820c46e1b97da788 +Signed-off-by: Luigi Santivetti +--- + src/egl/drivers/dri2/egl_dri2.h | 42 ++- + src/egl/drivers/dri2/platform_null.c | 541 +++++++++++++++++++++++---- + 2 files changed, 506 insertions(+), 77 deletions(-) + +diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h +index 89c48905c95..4baff09e80b 100644 +--- a/src/egl/drivers/dri2/egl_dri2.h ++++ b/src/egl/drivers/dri2/egl_dri2.h +@@ -337,6 +337,25 @@ 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; ++}; ++ ++enum { ++ SWAP_IDLE, ++ SWAP_FLIP, ++ SWAP_VBLANK, ++ SWAP_POLL, ++ SWAP_ERROR, ++}; ++#endif ++ + struct dri2_egl_surface + { + _EGLSurface base; +@@ -377,6 +396,19 @@ struct dri2_egl_surface + 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]; + +@@ -403,7 +435,7 @@ struct dri2_egl_surface + #endif + bool locked; + int age; +- } color_buffers[4], *back, *current; ++ } color_buffers[DRI2_SURFACE_NUM_COLOR_BUFFERS], *back, *current; + #endif + + #ifdef HAVE_ANDROID_PLATFORM +@@ -437,7 +469,13 @@ struct dri2_egl_surface + #endif + + #ifdef HAVE_NULL_PLATFORM +- uint32_t front_fb_id; ++ uint32_t front_fb_id; ++ 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 cond_init_unlock_buffer; + #endif + + int out_fence_fd; +diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c +index fb03ecc36fd..5b7c1ec426c 100644 +--- a/src/egl/drivers/dri2/platform_null.c ++++ b/src/egl/drivers/dri2/platform_null.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -58,6 +59,17 @@ struct object_property { + uint64_t prop_value; + }; + ++static inline ++uint32_t get_back_buffer_id(struct dri2_egl_surface *dri2_surf) ++{ ++ uintptr_t offset = ((uintptr_t) dri2_surf->back) - ++ ((uintptr_t) &dri2_surf->color_buffers[0]); ++ ++ assert(dri2_surf->back && !(offset >> 32)); ++ ++ return (uint32_t) (offset / sizeof(dri2_surf->color_buffers[0])); ++} ++ + #define object_property_set_named(output, object_type, prop_name, value) \ + { \ + .object_id = (output)->object_type##_id, \ +@@ -176,36 +188,6 @@ property_id_get_for_name(drmModePropertyRes **prop_res, const char *prop_name) + return 0; + } + +-static void +-flip_handler(int fd, unsigned int sequence, unsigned int tv_sec, +- unsigned int tv_usec, void *user_data) +-{ +- bool *plocked = user_data; +- +- if (plocked) +- *plocked = false; +-} +- +-static bool +-flip_process(int fd) +-{ +- static drmEventContext evctx = +- {.version = 2, .page_flip_handler = flip_handler}; +- struct pollfd pfd = {.fd = fd, .events = POLLIN}; +- int ret; +- +- do { +- ret = poll(&pfd, 1, -1); +- } while (ret > 0 && pfd.revents != pfd.events); +- +- if (ret <= 0) +- return false; +- +- drmHandleEvent(fd, &evctx); +- +- return true; +-} +- + static drmModePropertyRes ** + object_get_property_resources(int fd, uint32_t object_id, uint32_t object_type) + { +@@ -495,6 +477,113 @@ display_output_atomic_modeset(int fd, struct display_output *output, uint32_t fb + DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); + } + ++static void ++swap_enqueue_data(struct dri2_egl_surface *dri2_surf, uint32_t back_id, ++ uint32_t interval) ++{ ++ struct swap_queue_elem *swap_data; ++ ++ pthread_mutex_lock(&dri2_surf->mutex); ++ swap_data = &dri2_surf->swap_queue[dri2_surf->swap_queue_idx_tail]; ++ swap_data->swap_interval = interval; ++ swap_data->fb_id = dri2_surf->back->fb_id; ++ swap_data->back_id = back_id; ++ ++ dri2_surf->swap_queue_idx_tail++; ++ dri2_surf->swap_queue_idx_tail %= ARRAY_SIZE(dri2_surf->swap_queue); ++ ++ /* Notify the swap thread there is new work to do */ ++ pthread_cond_signal(&dri2_surf->swap_queue_cond); ++ pthread_mutex_unlock(&dri2_surf->mutex); ++} ++ ++static void ++swap_dequeue_data_start(struct dri2_egl_surface *dri2_surf) ++{ ++ pthread_mutex_lock(&dri2_surf->mutex); ++ while (dri2_surf->swap_queue_idx_head == dri2_surf->swap_queue_idx_tail) ++ pthread_cond_wait(&dri2_surf->swap_queue_cond, &dri2_surf->mutex); ++ ++ dri2_surf->swap_data = ++ &dri2_surf->swap_queue[dri2_surf->swap_queue_idx_head]; ++ pthread_mutex_unlock(&dri2_surf->mutex); ++} ++ ++static void ++swap_dequeue_data_finish(struct dri2_egl_surface *dri2_surf) ++{ ++ pthread_mutex_lock(&dri2_surf->mutex); ++ ++ if (dri2_surf->current) ++ dri2_surf->current->locked = false; ++ ++ dri2_surf->current = ++ &dri2_surf->color_buffers[dri2_surf->swap_data->back_id]; ++ dri2_surf->swap_state = SWAP_IDLE; ++ ++ dri2_surf->swap_queue_idx_head++; ++ dri2_surf->swap_queue_idx_head %= ARRAY_SIZE(dri2_surf->swap_queue); ++ ++ /* Notify get_back_bo that a buffer has become available */ ++ pthread_cond_signal(&dri2_surf->swap_unlock_buffer_cond); ++ pthread_mutex_unlock(&dri2_surf->mutex); ++} ++ ++static void ++flip_handler(int fd, unsigned int sequence, unsigned int tv_sec, ++ unsigned int tv_usec, void *flip_data) ++{ ++ struct dri2_egl_surface *dri2_surf = flip_data; ++ ++ (void) tv_sec; ++ (void) tv_usec; ++ (void) sequence; ++ ++ /* Ultimate queueing ops */ ++ swap_dequeue_data_finish(dri2_surf); ++} ++ ++static void ++vblank_handler(int fd, unsigned int sequence, unsigned int tv_sec, ++ unsigned int tv_usec, void *vblank_data) ++{ ++ struct dri2_egl_surface *dri2_surf = vblank_data; ++ ++ (void) tv_sec; ++ (void) tv_usec; ++ (void) sequence; ++ ++ dri2_surf->swap_state = SWAP_FLIP; ++} ++ ++static int ++drm_event_process(int fd) ++{ ++ static drmEventContext evctx = { ++ .version = 2, ++ .page_flip_handler = flip_handler, ++ .vblank_handler = vblank_handler ++ }; ++ struct pollfd pfd = {.fd = fd, .events = POLLIN}; ++ int ret; ++ ++ do { ++ ret = poll(&pfd, 1, -1); ++ } while (ret > 0 && pfd.revents != pfd.events); ++ ++ if (ret <= 0) ++ /* Man says: ++ * ++ * On error, -1 is returned, and errno is set to indicate the ++ * cause of the error. ++ */ ++ return -1; ++ ++ drmHandleEvent(fd, &evctx); ++ ++ return 0; ++} ++ + static bool + display_output_init(int fd, struct display_output *output, bool use_atomic) + { +@@ -571,10 +660,46 @@ static int + display_output_flip(int fd, struct display_output *output, uint32_t fb_id, + uint32_t flags, void *flip_data) + { +- if (output->atomic_state) +- return display_output_atomic_flip(fd, output, fb_id, flags, flip_data); ++ int err; ++ ++ do { ++ if (output->atomic_state) ++ err = display_output_atomic_flip(fd, output, fb_id, flags, flip_data); ++ else ++ err = drmModePageFlip(fd, output->crtc_id, fb_id, flags, flip_data); ++ } while (err == -EBUSY); ++ ++ return err; ++} ++ ++static int ++display_request_vblank(int fd, uint32_t target_frame, uint32_t flags, ++ void *vblank_data) ++{ ++ drmVBlank vblank = { ++ .request = { ++ .type = flags, ++ .sequence = target_frame, ++ .signal = (unsigned long)vblank_data, ++ } ++ }; ++ ++ return drmWaitVBlank(fd, &vblank); ++} ++ ++static int ++display_get_vblank_sequence(int fd, uint32_t *current_vblank_out) ++{ ++ drmVBlank vblank = { .request = { .type = DRM_VBLANK_RELATIVE } }; ++ int err; ++ ++ err = drmWaitVBlank(fd, &vblank); ++ if (err) ++ return err; + +- return drmModePageFlip(fd, output->crtc_id, fb_id, flags, flip_data); ++ *current_vblank_out = vblank.reply.sequence; ++ ++ return 0; + } + + static int +@@ -587,6 +712,213 @@ display_output_modeset(int fd, struct display_output *output, uint32_t fb_id) + &output->connector_id, 1, &output->mode); + } + ++static int ++swap_idle_get_target_frame(struct dri2_egl_surface *dri2_surf, ++ uint32_t *current_vblank_out, uint32_t *target_frame_out) ++{ ++ struct dri2_egl_display *dri2_dpy = ++ dri2_egl_display(dri2_surf->base.Resource.Display); ++ int err; ++ ++ /* For intarvals bigger than 1, always update current_vblank. The ++ * spec isn't fully clear, nonetheless page 25 and 26 of the PDF of the ++ * EGL 1.5 spec say: ++ * ++ * "[the parameter interval] indicates the number of swap intervals ++ * that will elapse before a buffer swap takes place after calling ++ * eglSwapBuffers." ++ * ++ * We need to guarantee that the target frame is always ahead of the ++ * current vblank by the number of intervals set at the time swapBuffer ++ * is called. For intervals of 1 or 0, we don't need a target frame. ++ */ ++ err = display_get_vblank_sequence(dri2_dpy->fd, current_vblank_out); ++ if (err) ++ return err; ++ ++ assert(dri2_surf->swap_data->swap_interval > 0); ++ ++ /* -1 accounts for vsync locked flip, so get a vblank one frame earlier */ ++ *target_frame_out = ++ *current_vblank_out + dri2_surf->swap_data->swap_interval - 1; ++ ++ return 0; ++} ++ ++static int ++swap_idle_state_transition(struct dri2_egl_surface *dri2_surf, ++ uint32_t *target_frame_out) ++{ ++ uint32_t current_vblank = 0; ++ uint32_t target_frame = 0; ++ int err; ++ ++ /* update dri2_surf->swap_data */ ++ swap_dequeue_data_start(dri2_surf); ++ ++ /* update next target frame */ ++ if (dri2_surf->swap_data->swap_interval > 1) { ++ err = swap_idle_get_target_frame(dri2_surf, ¤t_vblank, ++ &target_frame); ++ if (err) { ++ dri2_surf->swap_state = SWAP_ERROR; ++ return err; ++ } ++ } ++ ++ dri2_surf->swap_state = ++ target_frame <= current_vblank ? SWAP_FLIP : SWAP_VBLANK; ++ *target_frame_out = target_frame; ++ ++ return 0; ++} ++ ++static int ++swap_vblank_state_transition(struct dri2_egl_surface *dri2_surf, ++ uint32_t target_frame) ++{ ++ struct dri2_egl_display *dri2_dpy = ++ dri2_egl_display(dri2_surf->base.Resource.Display); ++ uint32_t flags = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; ++ int err; ++ ++ err = display_request_vblank(dri2_dpy->fd, target_frame, ++ flags, dri2_surf); ++ if (err) { ++ dri2_surf->swap_state = SWAP_ERROR; ++ return err; ++ } ++ ++ dri2_surf->swap_state = SWAP_POLL; ++ ++ return 0; ++} ++ ++static int ++swap_flip_state_transition(struct dri2_egl_surface *dri2_surf) ++{ ++ struct dri2_egl_display *dri2_dpy = ++ dri2_egl_display(dri2_surf->base.Resource.Display); ++ uint32_t flags; ++ int err; ++ ++ flags = DRM_MODE_PAGE_FLIP_EVENT; ++ if (dri2_surf->swap_data->swap_interval == 0) { ++ assert(!dri2_dpy->atomic_enabled); ++ flags |= DRM_MODE_PAGE_FLIP_ASYNC; ++ } ++ ++ err = display_output_flip(dri2_dpy->fd, &dri2_dpy->output, ++ dri2_surf->swap_data->fb_id, flags, dri2_surf); ++ if (err) { ++ dri2_surf->swap_state = SWAP_ERROR; ++ return err; ++ } ++ ++ dri2_surf->swap_state = SWAP_POLL; ++ ++ return 0; ++} ++ ++static int ++swap_poll_state_transition(struct dri2_egl_surface *dri2_surf) ++{ ++ struct dri2_egl_display *dri2_dpy = ++ dri2_egl_display(dri2_surf->base.Resource.Display); ++ int err; ++ ++ /* dri2_surf->swap_state is being set inside the handler */ ++ err = drm_event_process(dri2_dpy->fd); ++ if (err) { ++ dri2_surf->swap_state = SWAP_ERROR; ++ return err; ++ } ++ ++ return 0; ++} ++ ++static inline void ++swap_error_print_message(const int state, const int err) ++{ ++ switch (state) { ++ case SWAP_IDLE: ++ _eglLog(_EGL_WARNING, ++ "failed to get a target frame (err=%d)", err); ++ break; ++ case SWAP_FLIP: ++ _eglLog(_EGL_WARNING, ++ "failed to schedule a pageflip (err=%d)", err); ++ break; ++ case SWAP_VBLANK: ++ _eglLog(_EGL_WARNING, ++ "failed to request a vblank event (err=%d)", err); ++ break; ++ case SWAP_POLL: ++ _eglLog(_EGL_WARNING, ++ "failed to poll for drm event (err=%d)", err); ++ break; ++ case SWAP_ERROR: ++ _eglLog(_EGL_WARNING, ++ "failed to swap buffers, unknown swap state"); ++ break; ++ default: ++ _eglLog(_EGL_FATAL, ++ "failed to swap buffers (unknown error)"); ++ }; ++} ++ ++static void ++swap_error_state_handler(struct dri2_egl_surface *dri2_surf, ++ int state, int err) ++{ ++ static bool do_log = true; ++ ++ if (do_log) { ++ swap_error_print_message(state, err); ++ do_log = false; ++ } ++ ++ swap_dequeue_data_finish(dri2_surf); ++} ++ ++static void * ++swap_queue_processor_worker(void *data) ++{ ++ struct dri2_egl_surface *dri2_surf = data; ++ int state = SWAP_IDLE, err = SWAP_ERROR; ++ uint32_t target_frame = 0; ++ ++ assert(dri2_surf->swap_state == SWAP_IDLE); ++ ++ while (1) { ++ switch (dri2_surf->swap_state) { ++ case SWAP_IDLE: ++ err = swap_idle_state_transition(dri2_surf, &target_frame); ++ break; ++ case SWAP_VBLANK: ++ err = swap_vblank_state_transition(dri2_surf, target_frame); ++ break; ++ case SWAP_FLIP: ++ err = swap_flip_state_transition(dri2_surf); ++ break; ++ case SWAP_POLL: ++ err = swap_poll_state_transition(dri2_surf); ++ break; ++ case SWAP_ERROR: ++ swap_error_state_handler(dri2_surf, state, err); ++ break; ++ default: ++ dri2_surf->swap_state = SWAP_ERROR; ++ break; ++ } ++ ++ if (!err) ++ state = dri2_surf->swap_state; ++ } ++ ++ return NULL; ++} ++ + static bool + add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image, + uint32_t *fb_id_out) +@@ -651,15 +983,18 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) + struct dri2_egl_display *dri2_dpy = + dri2_egl_display(dri2_surf->base.Resource.Display); + +- if (!dri2_surf->back) { ++ pthread_mutex_lock(&dri2_surf->mutex); ++ while (!dri2_surf->back) { + for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + if (!dri2_surf->color_buffers[i].locked) { + dri2_surf->back = &dri2_surf->color_buffers[i]; + break; + } + } ++ ++ /* Wait for a flip to get a buffer off the screen and unlock it */ + if (!dri2_surf->back) +- return false; ++ pthread_cond_wait(&dri2_surf->swap_unlock_buffer_cond, &dri2_surf->mutex); + } + + if (!dri2_surf->back->dri_image) { +@@ -671,19 +1006,23 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) + __DRI_IMAGE_USE_SCANOUT, + NULL); + if (!dri2_surf->back->dri_image) +- return false; ++ goto err_unlock; + } + + if (!dri2_surf->back->fb_id) { + if (!add_fb_for_dri_image(dri2_dpy, dri2_surf->back->dri_image, +- &dri2_surf->back->fb_id)) { +- return false; +- } ++ &dri2_surf->back->fb_id)) ++ goto err_unlock; + } + + dri2_surf->back->locked = 1; ++ pthread_mutex_unlock(&dri2_surf->mutex); + + return true; ++ ++err_unlock: ++ pthread_mutex_unlock(&dri2_surf->mutex); ++ return false; + } + + static _EGLSurface * +@@ -770,6 +1109,26 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config, + dri2_surf->base.Width = dri2_dpy->output.mode.hdisplay; + dri2_surf->base.Height = dri2_dpy->output.mode.vdisplay; + ++ /* After the dri2_surf is created, init thread's data */ ++ dri2_surf->mutex_init = !pthread_mutex_init(&dri2_surf->mutex, NULL); ++ if (!dri2_surf->mutex_init) { ++ _eglError(EGL_BAD_ALLOC, "failed to init swap thread mutex"); ++ goto err_destroy_surface; ++ } ++ ++ dri2_surf->cond_init = !pthread_cond_init(&dri2_surf->swap_queue_cond, NULL); ++ if (!dri2_surf->cond_init) { ++ _eglError(EGL_BAD_ALLOC, "failed to init swap queue condition"); ++ goto err_destroy_surface; ++ } ++ ++ dri2_surf->cond_init_unlock_buffer = ++ !pthread_cond_init(&dri2_surf->swap_unlock_buffer_cond, NULL); ++ if (!dri2_surf->cond_init_unlock_buffer) { ++ _eglError(EGL_BAD_ALLOC, "failed to init swap buffer unlock condition"); ++ goto err_destroy_surface; ++ } ++ + if (!get_front_bo(dri2_surf)) { + _eglError(EGL_BAD_NATIVE_WINDOW, "window get buffer"); + goto err_destroy_surface; +@@ -783,6 +1142,14 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config, + } + + dri2_dpy->output.in_use = true; ++ dri2_surf->swap_state = SWAP_IDLE; ++ ++ err = pthread_create(&dri2_surf->swap_queue_processor, NULL, ++ swap_queue_processor_worker, dri2_surf); ++ if (err) { ++ _eglError(EGL_BAD_ALLOC, "failed to create swap thread"); ++ goto err_destroy_surface; ++ } + + return surf; + +@@ -808,8 +1175,27 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) + /* If there's a current surface then a page flip has been performed, so make + * sure we process the flip event. + */ +- if (dri2_surf->current) +- flip_process(dri2_dpy->fd); ++ if (dri2_surf->swap_queue_processor) { ++ pthread_mutex_lock(&dri2_surf->mutex); ++ ++ /* Wait for any outstanding swaps to complete */ ++ while (dri2_surf->swap_queue_idx_head != dri2_surf->swap_queue_idx_tail) ++ pthread_cond_wait(&dri2_surf->swap_unlock_buffer_cond, ++ &dri2_surf->mutex); ++ ++ pthread_mutex_unlock(&dri2_surf->mutex); ++ pthread_cancel(dri2_surf->swap_queue_processor); ++ pthread_join(dri2_surf->swap_queue_processor, NULL); ++ } ++ ++ if (dri2_surf->cond_init) ++ pthread_cond_destroy(&dri2_surf->swap_queue_cond); ++ ++ if (dri2_surf->cond_init_unlock_buffer) ++ pthread_cond_destroy(&dri2_surf->swap_unlock_buffer_cond); ++ ++ if (dri2_surf->mutex_init) ++ pthread_mutex_destroy(&dri2_surf->mutex); + + if (dri2_surf->front) + dri2_dpy->image->destroyImage(dri2_surf->front); +@@ -837,9 +1223,7 @@ dri2_null_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); +- bool *plocked = NULL; +- uint32_t flags; +- int err; ++ uint32_t back_id; + + if (dri2_surf->base.Type != EGL_WINDOW_BIT) + return EGL_TRUE; +@@ -858,34 +1242,13 @@ dri2_null_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) + dri2_flush_drawable_for_swapbuffers(disp, draw); + dri2_dpy->flush->invalidate(dri2_surf->dri_drawable); + +- if (dri2_surf->current) { +- /* Wait for the previous flip to happen so the next one can be queued */ +- if (!flip_process(dri2_dpy->fd)) { +- _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_null_swap_buffers process"); +- return EGL_FALSE; +- } ++ back_id = get_back_buffer_id(dri2_surf); ++ assert(dri2_surf->back == &dri2_surf->color_buffers[back_id]); + +- plocked = &dri2_surf->current->locked; +- } +- +- flags = DRM_MODE_PAGE_FLIP_EVENT; +- if (draw->SwapInterval == 0) +- flags |= DRM_MODE_PAGE_FLIP_ASYNC; +- +- do { +- err = display_output_flip(dri2_dpy->fd, &dri2_dpy->output, +- dri2_surf->back->fb_id, flags, plocked); +- } while (err == -EBUSY); +- +- if (err) { +- _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_null_swap_buffers flip"); +- dri2_surf->back->locked = false; +- dri2_surf->back = NULL; +- return EGL_FALSE; +- } ++ swap_enqueue_data(dri2_surf, back_id, draw->SwapInterval); + ++ /* This back buffer is tracked in the swap_data, safe to drop it now */ + dri2_surf->back->age = 1; +- dri2_surf->current = dri2_surf->back; + dri2_surf->back = NULL; + + return EGL_TRUE; +@@ -904,11 +1267,20 @@ dri2_null_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface) + return dri2_surf->back->age; + } + ++static EGLBoolean ++dri2_null_swap_interval(_EGLDisplay *dpy, _EGLSurface *draw, EGLint interval) ++{ ++ _eglLog(_EGL_DEBUG, "DRI2: set swap interval to %d", interval); ++ draw->SwapInterval = interval; ++ return EGL_TRUE; ++} ++ + static struct dri2_egl_display_vtbl dri2_null_display_vtbl = { + .create_window_surface = dri2_null_create_window_surface, + .create_pbuffer_surface = dri2_null_create_pbuffer_surface, + .destroy_surface = dri2_null_destroy_surface, + .create_image = dri2_create_image_khr, ++ .swap_interval = dri2_null_swap_interval, + .swap_buffers = dri2_null_swap_buffers, + .query_buffer_age = dri2_null_query_buffer_age, + .get_dri_drawable = dri2_surface_get_dri_drawable, +@@ -1062,12 +1434,35 @@ dri2_null_add_configs_for_formats(_EGLDisplay *disp) + + return count != 0; + } ++static void ++dri2_null_setup_swap_interval(_EGLDisplay *disp) ++{ ++ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); ++ const int swap_max_interval = 10; /* Arbitrary max value */ ++ uint64_t value; ++ int err; ++ ++ dri2_setup_swap_interval(disp, swap_max_interval); ++ ++ err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value); ++ if (err || value == 0) ++ dri2_dpy->min_swap_interval = 1; ++ ++ /** ++ * drm/atomic: Reject FLIP_ASYNC unconditionally ++ * upstream f2cbda2dba11de868759cae9c0d2bab5b8411406 ++ * ++ * Only allow swap interval 0 for legacy DRM/KMS and let ++ * the app be aware that swap interval is clamped to 1. ++ */ ++ if (dri2_dpy->atomic_enabled) ++ dri2_dpy->min_swap_interval = 1; ++} + + EGLBoolean + dri2_initialize_null(_EGLDisplay *disp) + { + struct dri2_egl_display *dri2_dpy; +- uint64_t value; + int err; + + dri2_dpy = calloc(1, sizeof(*dri2_dpy)); +@@ -1114,11 +1509,7 @@ dri2_initialize_null(_EGLDisplay *disp) + } + + dri2_setup_screen(disp); +- dri2_setup_swap_interval(disp, 1); +- +- err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value); +- if (err || value == 0) +- dri2_dpy->min_swap_interval = 1; ++ dri2_null_setup_swap_interval(disp); + + if (dri2_dpy->image->base.version < NULL_IMAGE_EXTENSION_VERSION_MIN) { + _eglError(EGL_NOT_INITIALIZED, "image extension version too old"); +-- +2.17.1 + diff --git a/package/mesa3d/0031-null_platform-add-support-for-explicit-synchronisati.patch b/package/mesa3d/0031-null_platform-add-support-for-explicit-synchronisati.patch new file mode 100644 index 00000000..bbb99ae2 --- /dev/null +++ b/package/mesa3d/0031-null_platform-add-support-for-explicit-synchronisati.patch @@ -0,0 +1,215 @@ +From 07ba23c3baab75df2ad7928b021cde89d8551c35 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 2 Sep 2019 09:32:01 +0100 +Subject: [PATCH 031/168] null_platform: add support for explicit + synchronisation + +This change adds support for the 'in' fence, the 'out' fence will +potentially be added in subsequent optimisation changes. + +Explicit synchronisation KMS 'in' and 'out' properties have been first +added in Linux kernel 4.10 as an additional feature to the atomic mode +setting. + +9626014258a5957ff120b3987ee72decdbe0c798 - 'in' property +beaf5af48034c9e2ebb8b2b1fb12dc4d8aeba99e - 'out' property + +Unlike many other features - it doesn't have an in kernel capability +flag, so the support for it can be tested in the following way: +KMS creates an additional set of properties when the version of kernel +is new enough to support it ('in' and 'out' fence properties). When +the user-space requests all the properties from the kernel via +drmModeObjectGetProperties it is possible to determine whether the +required property is supported by the kernel or not. + +The explicit synchronisation is used when available, otherwise the +implicit sync model is used instead. If explicit synchronisation is +available but 'in' fence failed to attach in KMS, the system falls +back to the implicit synchronisation model. + +egl_dri2.c already creates the GPU 'out' fence that is then used by +the null_platform as KMS 'in' fence. null_platform takes owenership of +this fence fd during the swap buffers operation, at which point the +fence fd is no longer available to be used outside of null_platform. + +EGL_LOG_LEVEL=debug should give some useful information in case of +explicit synchronisation failure. As mentioned above, this failure +will result in implicit synchronisation being used instead. + +Change-Id: Ib9c4a0bc3ea1b21192ee37909d7580d6b7b366ec +--- + src/egl/drivers/dri2/egl_dri2.h | 2 + + src/egl/drivers/dri2/platform_null.c | 77 +++++++++++++++++++++++++++- + 2 files changed, 77 insertions(+), 2 deletions(-) + +diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h +index 4baff09e80b..9aab57356f7 100644 +--- a/src/egl/drivers/dri2/egl_dri2.h ++++ b/src/egl/drivers/dri2/egl_dri2.h +@@ -102,6 +102,7 @@ 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; +@@ -345,6 +346,7 @@ struct swap_queue_elem + uint32_t swap_interval; + uint32_t back_id; + uint32_t fb_id; ++ int kms_in_fence_fd; + }; + + enum { +diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c +index 5b7c1ec426c..d36dc0ced2a 100644 +--- a/src/egl/drivers/dri2/platform_null.c ++++ b/src/egl/drivers/dri2/platform_null.c +@@ -401,6 +401,9 @@ display_output_atomic_init(int fd, struct display_output *output) + if (!output->atomic_state) + goto err_destroy_mode_prop_blob; + ++ if (property_id_get_for_name(plane_prop_res, "IN_FENCE_FD")) ++ output->in_fence_supported = true; ++ + output->connector_prop_res = connector_prop_res; + output->crtc_prop_res = crtc_prop_res; + output->plane_prop_res = plane_prop_res; +@@ -418,6 +421,53 @@ err_free_connector_prop_res: + return false; + } + ++static void ++display_output_atomic_add_in_fence(struct display_output *output, ++ int kms_in_fence_fd) ++{ ++ const struct object_property obj_sync_props[] = { ++ object_property_set_named(output, plane, "IN_FENCE_FD", kms_in_fence_fd), ++ }; ++ int err; ++ ++ /* Explicit synchronisation is not being used */ ++ if (kms_in_fence_fd < 0) ++ return; ++ ++ err = atomic_state_add_object_properties(output->atomic_state, ++ obj_sync_props, ++ ARRAY_SIZE(obj_sync_props)); ++ if (err) ++ _eglLog(_EGL_DEBUG, "%s: failed to add props ERR = %d", __func__, err); ++} ++ ++static void ++atomic_claim_in_fence_fd(struct dri2_egl_surface *dri2_surf, ++ struct swap_queue_elem *swap_data) ++{ ++ /* Explicit synchronisation is not being used */ ++ if (!dri2_surf->enable_out_fence) ++ return; ++ ++ if (dri2_surf->out_fence_fd < 0) { ++ _eglLog(_EGL_DEBUG, "%s: missing 'in' fence", __func__); ++ return; ++ } ++ ++ /* Take ownership of the fd */ ++ swap_data->kms_in_fence_fd = dri2_surf->out_fence_fd; ++ dri2_surf->out_fence_fd = -1; ++} ++ ++static void ++atomic_relinquish_in_fence_fd(struct dri2_egl_surface *dri2_surf, ++ struct swap_queue_elem *swap_data) ++{ ++ /* KMS is now in control of the fence (post drmModeAtomicCommit) */ ++ close(swap_data->kms_in_fence_fd); ++ swap_data->kms_in_fence_fd = -1; ++} ++ + static int + display_output_atomic_flip(int fd, struct display_output *output, uint32_t fb_id, + uint32_t flags, void *flip_data) +@@ -425,6 +475,8 @@ display_output_atomic_flip(int fd, struct display_output *output, uint32_t fb_id + const struct object_property obj_props[] = { + object_property_set_named(output, plane, "FB_ID", fb_id), + }; ++ struct dri2_egl_surface *dri2_surf = flip_data; ++ struct swap_queue_elem *swap_data = dri2_surf->swap_data; + int err; + + /* Reset atomic state */ +@@ -435,13 +487,19 @@ display_output_atomic_flip(int fd, struct display_output *output, uint32_t fb_id + if (err) + return err; + ++ display_output_atomic_add_in_fence(output, swap_data->kms_in_fence_fd); ++ + /* + * Don't block - like drmModePageFlip, drmModeAtomicCommit will return + * -EBUSY if the commit can't be queued in the kernel. + */ + flags |= DRM_MODE_ATOMIC_NONBLOCK; + +- return drmModeAtomicCommit(fd, output->atomic_state, flags, flip_data); ++ err = drmModeAtomicCommit(fd, output->atomic_state, flags, flip_data); ++ ++ atomic_relinquish_in_fence_fd(dri2_surf, swap_data); ++ ++ return err; + } + + static int +@@ -489,6 +547,8 @@ swap_enqueue_data(struct dri2_egl_surface *dri2_surf, uint32_t back_id, + swap_data->fb_id = dri2_surf->back->fb_id; + swap_data->back_id = back_id; + ++ atomic_claim_in_fence_fd(dri2_surf, swap_data); ++ + dri2_surf->swap_queue_idx_tail++; + dri2_surf->swap_queue_idx_tail %= ARRAY_SIZE(dri2_surf->swap_queue); + +@@ -1025,11 +1085,21 @@ err_unlock: + return false; + } + ++static void surface_swap_queue_init(struct dri2_egl_surface *dri2_surf) ++{ ++ struct swap_queue_elem *swap_queue = &dri2_surf->swap_queue[0]; ++ const int num_el = ARRAY_SIZE(dri2_surf->swap_queue); ++ ++ for (int i = 0; i < num_el; i++) ++ swap_queue[i].kms_in_fence_fd = -1; ++} ++ + static _EGLSurface * + create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type, + const EGLint *attrib_list) + { + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); ++ struct display_output *output = &dri2_dpy->output; + struct dri2_egl_config *dri2_config = dri2_egl_config(config); + struct dri2_egl_surface *dri2_surf; + const __DRIconfig *dri_config; +@@ -1043,7 +1113,8 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type, + } + surf = &dri2_surf->base; + +- if (!dri2_init_surface(surf, disp, type, config, attrib_list, false, NULL)) ++ if (!dri2_init_surface(surf, disp, type, config, attrib_list, ++ output->in_fence_supported, NULL)) + goto err_free_surface; + + dri_config = dri2_get_dri_config(dri2_config, type, +@@ -1066,6 +1137,8 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type, + + dri2_surf->format = dri2_null_formats[format_idx].dri_image_format; + ++ surface_swap_queue_init(dri2_surf); ++ + return surf; + + err_free_surface: +-- +2.17.1 + diff --git a/package/mesa3d/0032-egl-null-add-support-for-DRM-image-format-modifiers.patch b/package/mesa3d/0032-egl-null-add-support-for-DRM-image-format-modifiers.patch new file mode 100644 index 00000000..3c9cc1cf --- /dev/null +++ b/package/mesa3d/0032-egl-null-add-support-for-DRM-image-format-modifiers.patch @@ -0,0 +1,384 @@ +From 08c3f25175eeb21450f1d5e61a0b66c7714bc8a7 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 26 Sep 2019 13:32:15 +0100 +Subject: [PATCH 032/168] egl/null: add support for DRM image format modifiers + +This change introduces support for image modifiers to platform_null. In +order for it to create an image with modifiers, it relies on libdrm to +iterate all formats with associated modifiers supported by the display +for the primary drm plane in use. + +drmModeFormatModifierBlobIterNext() is added to the DRM api in a different +change and it is not upstream at present. + +Internal notes: + [1] IN_FORMATS blobs are available since kernel 4.14: + - db1689aa61bd1efb5ce9b896e7aa860a85b7f1b6 + - https://patchwork.freedesktop.org/patch/168543 + + [2] the dri image->base.version threshold is 14. + - Unlike for platform_wayland, where no details were found regarding + why it's using 15 + - dri_interface.h makes createImageWithModifiers available since + version 14 + - dri/gbm_dri.c as an example checks for minimum version 14. + +Change-Id: I0f7b030f6e1943690692674bf18daabfc153208a +Signed-off-by: Luigi Santivetti +--- + src/egl/drivers/dri2/egl_dri2.h | 3 + + src/egl/drivers/dri2/platform_null.c | 221 +++++++++++++++++++++++---- + 2 files changed, 198 insertions(+), 26 deletions(-) + +diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h +index 9aab57356f7..ee458fdbf61 100644 +--- a/src/egl/drivers/dri2/egl_dri2.h ++++ b/src/egl/drivers/dri2/egl_dri2.h +@@ -113,6 +113,8 @@ struct display_output { + uint32_t mode_blob_id; + unsigned formats; + drmModeAtomicReq *atomic_state; ++ uint32_t in_formats_id; ++ struct u_vector modifiers; + }; + #endif + +@@ -319,6 +321,7 @@ struct dri2_egl_display + + #ifdef HAVE_NULL_PLATFORM + bool atomic_enabled; ++ bool in_formats_enabled; + struct display_output output; + #endif + +diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c +index d36dc0ced2a..2c79199da26 100644 +--- a/src/egl/drivers/dri2/platform_null.c ++++ b/src/egl/drivers/dri2/platform_null.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + #include + + #include "egl_dri2.h" +@@ -156,6 +157,18 @@ format_idx_get_from_drm_format(uint32_t drm_format) + return -1; + } + ++static inline uint32_t ++blob_id_from_property_value(uint64_t prop_value) ++{ ++ /* The KMS properties documetation, 01.org/linuxgraphics, says: ++ * ++ * For all property types except blob properties the value is a 64-bit ++ * unsigned integer. ++ */ ++ assert(!(prop_value >> 32)); ++ return (uint32_t) prop_value; ++} ++ + static int + atomic_state_add_object_properties(drmModeAtomicReq *atomic_state, + const struct object_property *props, +@@ -645,7 +658,66 @@ drm_event_process(int fd) + } + + static bool +-display_output_init(int fd, struct display_output *output, bool use_atomic) ++plane_init_in_formats(int fd, drmModePlane *plane, struct u_vector *modifiers, ++ uint32_t *in_formats_id_out, unsigned *formats_out) ++{ ++ uint32_t blob_id, prev_fmt = DRM_FORMAT_INVALID, count_formats = 0; ++ drmModeFormatModifierIterator drm_iter = {0}; ++ drmModePropertyBlobRes *blob; ++ uint64_t prop_value; ++ int idx, err; ++ ++ assert(plane && in_formats_id_out && formats_out); ++ ++ err = !object_property_value_for_name(fd, plane->plane_id, ++ DRM_MODE_OBJECT_PLANE, ++ "IN_FORMATS", &prop_value); ++ if (err) ++ return false; ++ ++ blob_id = blob_id_from_property_value(prop_value); ++ blob = drmModeGetPropertyBlob(fd, blob_id); ++ ++ while (drmModeFormatModifierBlobIterNext(blob, &drm_iter)) { ++ if (drm_iter.fmt != prev_fmt) { ++ prev_fmt = drm_iter.fmt; ++ count_formats++; ++ ++ idx = format_idx_get_from_drm_format(drm_iter.fmt); ++ if (idx < 0) ++ continue; ++ ++ *formats_out |= (1 << idx); ++ } ++ } ++ ++ drmModeFreePropertyBlob(blob); ++ ++ if (!count_formats) { ++ /* None of the formats in the IN_FORMATS blob has associated modifiers */ ++ _eglLog(_EGL_WARNING, "no format-modifiers found in IN_FORMATS"); ++ return false; ++ } ++ ++ if (plane->count_formats != count_formats) ++ /* Only some of the formats in the IN_FORMATS blob have associated modifiers, ++ * try to use this subset. ++ */ ++ _eglLog(_EGL_WARNING, "discarding formats without modifiers"); ++ ++ /* Allocate space for modifiers, if ENOMEM fallback to plane formats */ ++ if (!u_vector_init(modifiers, sizeof(uint64_t), 64)) { ++ _eglLog(_EGL_WARNING, "failed to allocate modifiers"); ++ return false; ++ } ++ ++ *in_formats_id_out = blob_id; ++ return true; ++} ++ ++static bool ++display_output_init(int fd, struct display_output *output, bool use_atomic, ++ bool prefer_in_formats, bool *in_formats_enabled_out) + { + drmModeRes *resources; + drmModeConnector *connector; +@@ -674,16 +746,34 @@ display_output_init(int fd, struct display_output *output, bool use_atomic) + goto err_free_plane; + output->mode = connector->modes[mode_idx]; + +- /* Record the display supported formats */ +- for (unsigned i = 0; i < plane->count_formats; i++) { +- int format_idx; ++ assert(in_formats_enabled_out && !(*in_formats_enabled_out)); + +- format_idx = format_idx_get_from_drm_format(plane->formats[i]); +- if (format_idx == -1) +- continue; ++ /* Track display supported formats. Look them up from IN_FORMATS blobs ++ * if they are available, otherwise use plane formats. ++ */ ++ if (prefer_in_formats) ++ *in_formats_enabled_out = plane_init_in_formats(fd, plane, ++ &output->modifiers, ++ &output->in_formats_id, ++ &output->formats); + +- output->formats |= (1 << format_idx); ++ if (!*in_formats_enabled_out) { ++ _eglLog(_EGL_WARNING, "fallback to plane formats"); ++ ++ for (unsigned i = 0; i < plane->count_formats; i++) { ++ int format_idx; ++ ++ format_idx = format_idx_get_from_drm_format(plane->formats[i]); ++ if (format_idx == -1) ++ continue; ++ ++ output->formats |= (1 << format_idx); ++ } + } ++ ++ /* At this point we can only shut down if the look up failed and ++ * it is safe to pass NULL to drmModeFreeFormats(). ++ */ + if (!output->formats) + goto err_free_plane; + +@@ -983,10 +1073,12 @@ static bool + add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image, + uint32_t *fb_id_out) + { ++ uint64_t modifiers[4] = {0}; + uint32_t handles[4] = {0}; + uint32_t pitches[4] = {0}; + uint32_t offsets[4] = {0}; +- int handle, stride, width, height, format; ++ uint32_t flags = 0; ++ int handle, stride, width, height, format, l_mod, h_mod; + int format_idx; + + dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HANDLE, &handle); +@@ -1001,9 +1093,47 @@ add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image, + format_idx = format_idx_get_from_dri_image_format(format); + assert(format_idx != -1); + +- return !drmModeAddFB2(dri2_dpy->fd, width, height, +- dri2_null_formats[format_idx].drm_format, +- handles, pitches, offsets, fb_id_out, 0); ++ if (dri2_dpy->in_formats_enabled) { ++ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_MODIFIER_UPPER, &h_mod); ++ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_MODIFIER_LOWER, &l_mod); ++ ++ modifiers[0] = combine_u32_into_u64((uint32_t) h_mod, (uint32_t) l_mod); ++ flags |= DRM_MODE_FB_MODIFIERS; ++ } ++ ++ return !drmModeAddFB2WithModifiers(dri2_dpy->fd, width, height, ++ dri2_null_formats[format_idx].drm_format, ++ handles, pitches, offsets, modifiers, ++ fb_id_out, flags); ++} ++ ++static __DRIimage * ++create_image(struct dri2_egl_surface *dri2_surf, uint32_t flags) ++{ ++ struct dri2_egl_display *dri2_dpy = ++ dri2_egl_display(dri2_surf->base.Resource.Display); ++ uint32_t count_modifiers; ++ uint64_t *modifiers; ++ ++ if (dri2_dpy->in_formats_enabled) { ++ count_modifiers = u_vector_length(&dri2_dpy->output.modifiers); ++ modifiers = u_vector_tail(&dri2_dpy->output.modifiers); ++ ++ return dri2_dpy->image->createImageWithModifiers(dri2_dpy->dri_screen, ++ dri2_surf->base.Width, ++ dri2_surf->base.Height, ++ dri2_surf->format, ++ modifiers, ++ count_modifiers, ++ NULL); ++ } ++ ++ return dri2_dpy->image->createImage(dri2_dpy->dri_screen, ++ dri2_surf->base.Width, ++ dri2_surf->base.Height, ++ dri2_surf->format, ++ flags, ++ NULL); + } + + static bool +@@ -1016,12 +1146,7 @@ get_front_bo(struct dri2_egl_surface *dri2_surf) + if (dri2_surf->base.Type == EGL_WINDOW_BIT) + use |= __DRI_IMAGE_USE_SCANOUT; + +- dri2_surf->front = dri2_dpy->image->createImage(dri2_dpy->dri_screen, +- dri2_surf->base.Width, +- dri2_surf->base.Height, +- dri2_surf->format, +- use, +- NULL); ++ dri2_surf->front = create_image(dri2_surf, use); + if (!dri2_surf->front) + return false; + +@@ -1058,13 +1183,8 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) + } + + if (!dri2_surf->back->dri_image) { +- dri2_surf->back->dri_image = +- dri2_dpy->image->createImage(dri2_dpy->dri_screen, +- dri2_surf->base.Width, +- dri2_surf->base.Height, +- dri2_surf->format, +- __DRI_IMAGE_USE_SCANOUT, +- NULL); ++ dri2_surf->back->dri_image = create_image(dri2_surf, ++ __DRI_IMAGE_USE_SCANOUT); + if (!dri2_surf->back->dri_image) + goto err_unlock; + } +@@ -1094,6 +1214,30 @@ static void surface_swap_queue_init(struct dri2_egl_surface *dri2_surf) + swap_queue[i].kms_in_fence_fd = -1; + } + ++static bool ++in_formats_get_modifiers(const int fd, const uint32_t in_formats_id, ++ const int drm_format, struct u_vector *modifiers) ++{ ++ drmModeFormatModifierIterator drm_iter = {0}; ++ drmModePropertyBlobRes *blob; ++ uint64_t *mod = NULL; ++ ++ blob = drmModeGetPropertyBlob(fd, in_formats_id); ++ ++ while (drmModeFormatModifierBlobIterNext(blob, &drm_iter)) { ++ if (drm_iter.fmt == drm_format) { ++ assert(drm_iter.mod != DRM_FORMAT_MOD_INVALID); ++ ++ mod = u_vector_add(modifiers); ++ *mod = drm_iter.mod; ++ } ++ } ++ ++ drmModeFreePropertyBlob(blob); ++ ++ return mod != NULL; ++} ++ + static _EGLSurface * + create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type, + const EGLint *attrib_list) +@@ -1105,6 +1249,7 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type, + const __DRIconfig *dri_config; + _EGLSurface *surf; + int format_idx; ++ bool ret; + + dri2_surf = calloc(1, sizeof(*dri2_surf)); + if (!dri2_surf) { +@@ -1137,6 +1282,15 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type, + + dri2_surf->format = dri2_null_formats[format_idx].dri_image_format; + ++ if (dri2_dpy->in_formats_enabled) { ++ ret = in_formats_get_modifiers(dri2_dpy->fd, ++ dri2_dpy->output.in_formats_id, ++ dri2_null_formats[format_idx].drm_format, ++ &dri2_dpy->output.modifiers); ++ if (!ret) ++ goto err_free_surface; ++ } ++ + surface_swap_queue_init(dri2_surf); + + return surf; +@@ -1536,6 +1690,8 @@ EGLBoolean + dri2_initialize_null(_EGLDisplay *disp) + { + struct dri2_egl_display *dri2_dpy; ++ bool prefer_in_formats = false; ++ uint64_t value; + int err; + + dri2_dpy = calloc(1, sizeof(*dri2_dpy)); +@@ -1589,8 +1745,19 @@ dri2_initialize_null(_EGLDisplay *disp) + goto cleanup; + } + ++ err = drmGetCap(dri2_dpy->fd_dpy, DRM_CAP_ADDFB2_MODIFIERS, &value); ++ if (!err && value) { ++ /* in_formats could be supported by the platform, however not being ++ * actually enabled, i.e. in_formats init can still fail. ++ */ ++ prefer_in_formats = dri2_dpy->image->base.version >= 14 && ++ dri2_dpy->image->createImageWithModifiers; ++ } ++ + if (!display_output_init(dri2_dpy->fd, &dri2_dpy->output, +- dri2_dpy->atomic_enabled)) { ++ dri2_dpy->atomic_enabled, ++ prefer_in_formats, ++ &dri2_dpy->in_formats_enabled)) { + _eglError(EGL_NOT_INITIALIZED, "failed to create output"); + goto cleanup; + } +@@ -1640,4 +1807,6 @@ dri2_teardown_null(struct dri2_egl_display *dri2_dpy) + drmModeFreeProperty(dri2_dpy->output.connector_prop_res[i]); + free(dri2_dpy->output.connector_prop_res); + } ++ ++ u_vector_finish(&dri2_dpy->output.modifiers); + } +-- +2.17.1 + diff --git a/package/mesa3d/0033-egl-query-the-supported-ES2-context-version.patch b/package/mesa3d/0033-egl-query-the-supported-ES2-context-version.patch new file mode 100644 index 00000000..3f8a280d --- /dev/null +++ b/package/mesa3d/0033-egl-query-the-supported-ES2-context-version.patch @@ -0,0 +1,171 @@ +From f78c8281278608e32defe286cacd555b818acfb8 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 10 Feb 2020 09:23:03 +0000 +Subject: [PATCH 033/168] egl: query the supported ES2 context version + +For OpenGL ES contexts, the EGL specification states that querying +EGL_CONTEXT_CLIENT_VERSION with eglQueryContext may return a version +that differs from that specified at context creation time. For example, +if an OpenGL ES2 context is specified at context creation time, an +OpenGL ES3 context may be created, and so "3" should be returned +when EGL_CONTEXT_CLIENT_VERSION is queried. + +A new EGL driver API function has been added, +QueryContextClientVersion, that is called when the context client +version is queried, allowing EGL drivers to override the default +value (i.e. the version specified at context creation time). If the +function returns zero, the default is used. + +For DRI drivers, QueryContextClientVersion returns zero for all API +contexts other than OpenGL ES2. For OpenGL ES2, the supported context +client version is queried via the Query Renderer driver extension, using +integer query __DRI2_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG. If +the query isn't supported, or the query returns zero, zero is returned +to the caller. + +IMG NOTE: In order to avoid potential name and value clashes, "_IMG" +has been added to the end of the new query name, this should be removed +if an attempt is made to push this patch upstream. The value of the new +query should be adjusted to be the next one in sequence, rather than the +large value it currently has. +--- + include/GL/internal/dri_interface.h | 2 ++ + src/egl/drivers/dri2/egl_dri2.c | 21 +++++++++++++++++++++ + src/egl/drivers/haiku/egl_haiku.cpp | 9 +++++++++ + src/egl/main/eglcontext.c | 14 +++++++++++++- + src/egl/main/egldriver.h | 1 + + 5 files changed, 46 insertions(+), 1 deletion(-) + +diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h +index 75ced1b9660..66a60fd46ad 100644 +--- a/include/GL/internal/dri_interface.h ++++ b/include/GL/internal/dri_interface.h +@@ -1980,6 +1980,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; +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index 4e39f2e7bdc..60cc81ba536 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -2034,6 +2034,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) + { +@@ -4033,6 +4053,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, +diff --git a/src/egl/drivers/haiku/egl_haiku.cpp b/src/egl/drivers/haiku/egl_haiku.cpp +index 18c73c9cd8b..2690a82eb75 100644 +--- a/src/egl/drivers/haiku/egl_haiku.cpp ++++ b/src/egl/drivers/haiku/egl_haiku.cpp +@@ -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, +diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c +index 63b65cc174b..51de016266a 100644 +--- a/src/egl/main/eglcontext.c ++++ b/src/egl/main/eglcontext.c +@@ -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; +diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h +index da2281e76ba..2f4669e0e46 100644 +--- a/src/egl/main/egldriver.h ++++ b/src/egl/main/egldriver.h +@@ -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, +-- +2.17.1 + diff --git a/package/mesa3d/0034-meson-allow-libGL-to-be-built-without-GLX.patch b/package/mesa3d/0034-meson-allow-libGL-to-be-built-without-GLX.patch new file mode 100644 index 00000000..f8f926b4 --- /dev/null +++ b/package/mesa3d/0034-meson-allow-libGL-to-be-built-without-GLX.patch @@ -0,0 +1,153 @@ +From 77a15e42b2362e33380fe48aff48a0b07acdae75 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 11 Jun 2020 12:29:51 +0100 +Subject: [PATCH 034/168] meson: allow libGL to be built without GLX + +If Meson is run with option "glx" set to "null", build the +OpenGL library without GLX. + +The "eglBindAPI workaround for dEQP bug" change to eglcurrent.h +(commit 2d46c91040aeb8ebad486214159c34417fbc87db) has been +modified to use a new EGL_WITH_OPENGL define, which indicates +whether OpenGL is present or not. This allows EGL to be used +with OpenGL on platforms other than X11. +--- + meson.build | 10 +++++++--- + meson_options.txt | 2 +- + src/egl/main/eglcurrent.h | 7 +++---- + src/glx/meson.build | 20 ++++++++++++++++---- + src/meson.build | 2 +- + 5 files changed, 28 insertions(+), 13 deletions(-) + +diff --git a/meson.build b/meson.build +index 3bdbb622b42..3a6de3d5ce8 100644 +--- a/meson.build ++++ b/meson.build +@@ -503,7 +503,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') +@@ -529,6 +529,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 +@@ -580,7 +584,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' +@@ -638,7 +642,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 +diff --git a/meson_options.txt b/meson_options.txt +index 6fd37bbb100..43169974bff 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -299,7 +299,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( +diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h +index c03798eaeac..5e083027da4 100644 +--- a/src/egl/main/eglcurrent.h ++++ b/src/egl/main/eglcurrent.h +@@ -72,11 +72,10 @@ struct _egl_thread_info + static inline EGLBoolean + _eglIsApiValid(EGLenum api) + { +-#ifndef HAVE_X11_PLATFORM +- /* 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 + } + +diff --git a/src/glx/meson.build b/src/glx/meson.build +index 20f04742894..93470d0a9e4 100644 +--- a/src/glx/meson.build ++++ b/src/glx/meson.build +@@ -122,7 +122,15 @@ else + ) + endif + +-libglx = static_library( ++gl_lib_cargs = [ ++ '-D_REENTRANT', ++] ++ ++if with_glx == 'null' ++ libglx_link = [libglapi] ++ libglx_link_whole = [libglapi_static] ++else ++ libglx = static_library( + 'glx', + [files_libglx, glx_generated], + include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_glapi, inc_loader], +@@ -138,13 +146,17 @@ libglx = static_library( + idep_mesautil, idep_xmlconfig, + dep_libdrm, dep_dri2proto, dep_glproto, dep_x11, dep_glvnd, dep_xxf86vm, dep_xshmfence + ], +-) ++ ) ++ ++ libglx_link = [libglapi_static,libglapi] ++ libglx_link_whole = [libglx] ++endif + + libgl = shared_library( + gl_lib_name, + [], +- link_with : [libglapi_static, libglapi], +- link_whole : libglx, ++ link_with : libglx_link, ++ link_whole : libglx_link_whole, + link_args : [ld_args_bsymbolic, ld_args_gc_sections, extra_ld_args_libgl], + dependencies : [ + dep_libdrm, dep_dl, dep_m, dep_thread, dep_x11, dep_xcb_glx, dep_xcb, +diff --git a/src/meson.build b/src/meson.build +index 3c468e86a53..6500312bb29 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -128,7 +128,7 @@ endif + if with_gallium + subdir('mesa') + subdir('gallium') +- if with_glx == 'dri' ++ if with_glx == 'dri' or with_glx == 'null' + subdir('glx') + endif + # This has to be here since it requires libgallium, and subdir cannot +-- +2.17.1 + diff --git a/package/mesa3d/0035-egl-wayland-process-non-resized-window-movement.patch b/package/mesa3d/0035-egl-wayland-process-non-resized-window-movement.patch new file mode 100644 index 00000000..f25ee0fc --- /dev/null +++ b/package/mesa3d/0035-egl-wayland-process-non-resized-window-movement.patch @@ -0,0 +1,38 @@ +From 9671db93a033595b0805088e5ef5728cd99e18a2 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 25 Aug 2020 14:12:32 +0100 +Subject: [PATCH 035/168] egl/wayland: process non-resized window movement + +The dx and dy parameters to the wl_egl_window_resize function were +not being processed unless the window width or height were being +changed. +--- + src/egl/drivers/dri2/platform_wayland.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c +index c3fb983c341..86a9305178d 100644 +--- a/src/egl/drivers/dri2/platform_wayland.c ++++ b/src/egl/drivers/dri2/platform_wayland.c +@@ -392,6 +392,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; +@@ -1255,8 +1258,6 @@ update_buffers(struct dri2_egl_display *dri2_dpy, + + 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) { +-- +2.17.1 + diff --git a/package/mesa3d/0036-Separate-EXT_framebuffer_object-from-ARB-version.patch b/package/mesa3d/0036-Separate-EXT_framebuffer_object-from-ARB-version.patch new file mode 100644 index 00000000..c4dc6d90 --- /dev/null +++ b/package/mesa3d/0036-Separate-EXT_framebuffer_object-from-ARB-version.patch @@ -0,0 +1,372 @@ +From 3922d9a05ebe661eb17dd7e4a75ca40ee2205d6a Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 10 Mar 2014 13:43:45 +0000 +Subject: [PATCH 036/168] Separate EXT_framebuffer_object from ARB version + +This patch separates the EXT_framebuffer_object entry points from the ARB +equivalents. + +Probably not all this separation is necessary; it looks like only + BindRenderbuffer + BindFramebuffer + GetFramebufferAttachmentParameteriv +take advantage of the split. + +Next time this patch is implemented, see if it can be trimmed down to +just the above functions, as it may be more upstreamable. + +We may need to implement the EXT restrictions if we want to upstream. +--- + src/mapi/glapi/gen/EXT_framebuffer_object.xml | 30 +++---- + src/mapi/glapi/gen/static_data.py | 15 ++++ + src/mesa/main/fbobject.c | 83 +++++++++++++++++++ + src/mesa/main/genmipmap.c | 6 ++ + 4 files changed, 119 insertions(+), 15 deletions(-) + +diff --git a/src/mapi/glapi/gen/EXT_framebuffer_object.xml b/src/mapi/glapi/gen/EXT_framebuffer_object.xml +index 6dd90b87971..e2dfa6b25ad 100644 +--- a/src/mapi/glapi/gen/EXT_framebuffer_object.xml ++++ b/src/mapi/glapi/gen/EXT_framebuffer_object.xml +@@ -70,7 +70,7 @@ + + + +- ++ + + + +@@ -81,30 +81,30 @@ + + + +- ++ + + + + +- ++ + + + + +- ++ + + + + + + +- ++ + + + + + +- ++ + + + +@@ -116,22 +116,22 @@ + + + +- ++ + + + + +- ++ + + + + +- ++ + + + + +- ++ + + + +@@ -139,7 +139,7 @@ + + + +- ++ + + + +@@ -147,7 +147,7 @@ + + + +- ++ + + + +@@ -156,21 +156,21 @@ + + + +- ++ + + + + + + +- ++ + + + + + + +- ++ + + + +diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py +index dd4a802c496..c81845d7f0c 100644 +--- a/src/mapi/glapi/gen/static_data.py ++++ b/src/mapi/glapi/gen/static_data.py +@@ -1717,6 +1717,21 @@ offsets = { + "FramebufferTextureMultisampleMultiviewOVR" : 1681, + "MultiDrawArraysIndirectEXT" : 1682, + "MultiDrawElementsIndirectEXT" : 1683, ++ "IsRenderbufferEXT" : 1684, ++ "DeleteRenderbuffersEXT" : 1685, ++ "GenRenderbuffersEXT" : 1686, ++ "RenderbufferStorageEXT" : 1687, ++ "GetRenderbufferParameterivEXT" : 1688, ++ "IsFramebufferEXT" : 1689, ++ "DeleteFramebuffersEXT" : 1690, ++ "GenFramebuffersEXT" : 1691, ++ "CheckFramebufferStatusEXT" : 1692, ++ "FramebufferTexture1DEXT" : 1693, ++ "FramebufferTexture2DEXT" : 1694, ++ "FramebufferTexture3DEXT" : 1695, ++ "FramebufferRenderbufferEXT" : 1696, ++ "GetFramebufferAttachmentParameterivEXT" : 1697, ++ "GenerateMipmapEXT" : 1698, + } + + functions = [ +diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c +index be1d61907a4..74f6e9b3ff6 100644 +--- a/src/mesa/main/fbobject.c ++++ b/src/mesa/main/fbobject.c +@@ -2168,6 +2168,11 @@ _mesa_detach_renderbuffer(struct gl_context *ctx, + return progress; + } + ++GLboolean GLAPIENTRY ++_mesa_IsRenderbufferEXT(GLuint renderbuffer) ++{ ++ return _mesa_IsRenderbuffer(renderbuffer); ++} + + void GLAPIENTRY + _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) +@@ -2895,6 +2900,12 @@ renderbuffer_storage_target(GLenum target, GLenum internalFormat, + } + + ++void GLAPIENTRY ++_mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers) ++{ ++ _mesa_DeleteRenderbuffers(n, renderbuffers); ++} ++ + void GLAPIENTRY + _mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) + { +@@ -2932,6 +2943,11 @@ _mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) + st_egl_image_target_renderbuffer_storage(ctx, rb, image); + } + ++void GLAPIENTRY ++_mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers) ++{ ++ _mesa_GenRenderbuffers(n, renderbuffers); ++} + + /** + * Helper function for _mesa_GetRenderbufferParameteriv() and +@@ -2964,6 +2980,12 @@ _mesa_RenderbufferStorage(GLenum target, GLenum internalFormat, + NO_SAMPLES, 0, "glRenderbufferStorage"); + } + ++void GLAPIENTRY ++_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, ++ GLsizei width, GLsizei height) ++{ ++ _mesa_RenderbufferStorage(target, internalFormat, width, height); ++} + + void GLAPIENTRY + _mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples, +@@ -3144,6 +3166,11 @@ _mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname, + "glGetNamedRenderbufferParameteriv"); + } + ++void GLAPIENTRY ++_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params) ++{ ++ _mesa_GetRenderbufferParameteriv(target, pname, params); ++} + + void GLAPIENTRY + _mesa_GetNamedRenderbufferParameterivEXT(GLuint renderbuffer, GLenum pname, +@@ -3177,6 +3204,11 @@ _mesa_IsFramebuffer(GLuint framebuffer) + return GL_FALSE; + } + ++GLboolean GLAPIENTRY ++_mesa_IsFramebufferEXT(GLuint framebuffer) ++{ ++ return _mesa_IsFramebuffer(framebuffer); ++} + + /** + * Check if any of the attachments of the given framebuffer are textures +@@ -3401,6 +3433,11 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers) + } + } + ++void GLAPIENTRY ++_mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers) ++{ ++ _mesa_DeleteFramebuffers(n, framebuffers); ++} + + /** + * This is the implementation for glGenFramebuffers and glCreateFramebuffers. +@@ -3447,6 +3484,11 @@ create_framebuffers(GLsizei n, GLuint *framebuffers, bool dsa) + _mesa_HashUnlockMutex(ctx->Shared->FrameBuffers); + } + ++void GLAPIENTRY ++_mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers) ++{ ++ _mesa_GenFramebuffers(n, framebuffers); ++} + + void GLAPIENTRY + _mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers) +@@ -3486,6 +3528,11 @@ _mesa_check_framebuffer_status(struct gl_context *ctx, + return buffer->_Status; + } + ++GLenum GLAPIENTRY ++_mesa_CheckFramebufferStatusEXT(GLenum target) ++{ ++ return _mesa_CheckFramebufferStatus(target); ++} + + GLenum GLAPIENTRY + _mesa_CheckFramebufferStatus_no_error(GLenum target) +@@ -4099,6 +4146,12 @@ _mesa_FramebufferTexture1D_no_error(GLenum target, GLenum attachment, + texture, level, 0); + } + ++void GLAPIENTRY ++_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment, ++ GLenum textarget, GLuint texture, GLint level) ++{ ++ _mesa_FramebufferTexture1D(target, attachment, textarget, texture, level); ++} + + void GLAPIENTRY + _mesa_FramebufferTexture1D(GLenum target, GLenum attachment, +@@ -4139,6 +4192,12 @@ _mesa_FramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment, + false); + } + ++void GLAPIENTRY ++_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment, ++ GLenum textarget, GLuint texture, GLint level) ++{ ++ _mesa_FramebufferTexture2D(target, attachment, textarget, texture, level); ++} + + void GLAPIENTRY + _mesa_FramebufferTexture3D_no_error(GLenum target, GLenum attachment, +@@ -4249,6 +4308,15 @@ frame_buffer_texture(GLuint framebuffer, GLenum target, + level, 0, layer, layered); + } + ++void GLAPIENTRY ++_mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment, ++ GLenum textarget, GLuint texture, ++ GLint level, GLint zoffset) ++{ ++ _mesa_FramebufferTexture3D(target, attachment, textarget, texture, ++ level, zoffset); ++} ++ + void GLAPIENTRY + _mesa_FramebufferTextureLayer_no_error(GLenum target, GLenum attachment, + GLuint texture, GLint level, +@@ -4501,6 +4569,15 @@ _mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment, + renderbuffer, "glFramebufferRenderbuffer"); + } + ++void GLAPIENTRY ++_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment, ++ GLenum renderbufferTarget, ++ GLuint renderbuffer) ++{ ++ _mesa_FramebufferRenderbuffer(target, attachment, renderbufferTarget, ++ renderbuffer); ++} ++ + void GLAPIENTRY + _mesa_NamedFramebufferRenderbuffer_no_error(GLuint framebuffer, + GLenum attachment, +@@ -4902,6 +4979,12 @@ invalid_pname_enum: + return; + } + ++void GLAPIENTRY ++_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, ++ GLenum pname, GLint *params) ++{ ++ _mesa_GetFramebufferAttachmentParameteriv(target, attachment, pname, params); ++} + + void GLAPIENTRY + _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, +diff --git a/src/mesa/main/genmipmap.c b/src/mesa/main/genmipmap.c +index 97d0ab36a13..b30cf4f07c4 100644 +--- a/src/mesa/main/genmipmap.c ++++ b/src/mesa/main/genmipmap.c +@@ -286,3 +286,9 @@ _mesa_GenerateMultiTexMipmapEXT(GLenum texunit, GLenum target) + validate_params_and_generate_mipmap(texObj, + "glGenerateMultiTexMipmapEXT"); + } ++ ++void GLAPIENTRY ++_mesa_GenerateMipmapEXT(GLenum target) ++{ ++ _mesa_GenerateMipmap(target); ++} +-- +2.17.1 + diff --git a/package/mesa3d/0037-egl-null-add-support-for-async-flip-with-front-buffe.patch b/package/mesa3d/0037-egl-null-add-support-for-async-flip-with-front-buffe.patch new file mode 100644 index 00000000..0e8e266d --- /dev/null +++ b/package/mesa3d/0037-egl-null-add-support-for-async-flip-with-front-buffe.patch @@ -0,0 +1,321 @@ +From b355302f58881c0bd57b94e2540095c80b20fd43 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 21 Oct 2019 09:21:52 +0100 +Subject: [PATCH 037/168] egl/null: add support for async flip with front + buffer rendering + +This change enables the application to render into the buffer being +scanned out if the display driver doesn't support +DRM_CAP_ASYNC_PAGE_FLIP. + +The egl display now tracks the DRM async flip capabilities, allowing +platform_null to always return the buffer on screen to the application +when the swap interval is set to 0, but the DRM driver doesn't support +async flip. + +platform_null can be in several alternative states by the time +eglSwapInterval() is called, following is a summary of them. + + 1. platform_null was initialised and it has already flipped. In this + case, return to the client API a reference to the buffer on screen + + 2. platform_null was initialised but no back buffer was requested yet + from the client API. In this case, return a reference to the front + buffer + + 3. platform_null was initialised and the client API has already got + a back buffer, but no flip was scheduled. In this case, make sure + to flip and return the buffer on the screen + +Note that this change also refactors the color buffers and front +buffer code. Platform null after this change has a dedicated struct +for storing front buffer DRI data and framebuffer id. + +Also be noted that min_swap_interval is no longer clamped to 1 when +DRM_CAP_ASYNC_PAGE_FLIP isn't supported. This is because, +if min_swap_interval is automatically promoted to 1, Mesa EGL will de +facto prevent the application from requesting any swap interval less +than 1. + +Change-Id: I3930cfcdb30bfb5358166911bcf84a78bdb4548d +Signed-off-by: Luigi Santivetti +--- + src/egl/drivers/dri2/egl_dri2.h | 8 +- + src/egl/drivers/dri2/platform_null.c | 153 +++++++++++++++++++++------ + 2 files changed, 129 insertions(+), 32 deletions(-) + +diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h +index ee458fdbf61..8bef835ef16 100644 +--- a/src/egl/drivers/dri2/egl_dri2.h ++++ b/src/egl/drivers/dri2/egl_dri2.h +@@ -322,6 +322,7 @@ struct dri2_egl_display + #ifdef HAVE_NULL_PLATFORM + bool atomic_enabled; + bool in_formats_enabled; ++ bool async_flip_enabled; + struct display_output output; + #endif + +@@ -440,8 +441,12 @@ struct dri2_egl_surface + #endif + bool locked; + int age; ++#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 + struct ANativeWindow *window; +@@ -474,12 +479,13 @@ struct dri2_egl_surface + #endif + + #ifdef HAVE_NULL_PLATFORM +- uint32_t front_fb_id; + 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 + +diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c +index 2c79199da26..0ce7e60030b 100644 +--- a/src/egl/drivers/dri2/platform_null.c ++++ b/src/egl/drivers/dri2/platform_null.c +@@ -602,6 +602,15 @@ swap_dequeue_data_finish(struct dri2_egl_surface *dri2_surf) + pthread_mutex_unlock(&dri2_surf->mutex); + } + ++static void ++swap_drain_queue_data(struct dri2_egl_surface *dri2_surf) ++{ ++ pthread_mutex_lock(&dri2_surf->mutex); ++ while (dri2_surf->swap_queue_idx_head != dri2_surf->swap_queue_idx_tail) ++ pthread_cond_wait(&dri2_surf->swap_unlock_buffer_cond, &dri2_surf->mutex); ++ pthread_mutex_unlock(&dri2_surf->mutex); ++} ++ + static void + flip_handler(int fd, unsigned int sequence, unsigned int tv_sec, + unsigned int tv_usec, void *flip_data) +@@ -1146,15 +1155,15 @@ get_front_bo(struct dri2_egl_surface *dri2_surf) + if (dri2_surf->base.Type == EGL_WINDOW_BIT) + use |= __DRI_IMAGE_USE_SCANOUT; + +- dri2_surf->front = create_image(dri2_surf, use); +- if (!dri2_surf->front) ++ dri2_surf->front_buffer.dri_image = create_image(dri2_surf, use); ++ if (!dri2_surf->front_buffer.dri_image) + return false; + + if (dri2_surf->base.Type == EGL_WINDOW_BIT) { +- if (!add_fb_for_dri_image(dri2_dpy, dri2_surf->front, +- &dri2_surf->front_fb_id)) { +- dri2_dpy->image->destroyImage(dri2_surf->front); +- dri2_surf->front = NULL; ++ if (!add_fb_for_dri_image(dri2_dpy, dri2_surf->front_buffer.dri_image, ++ &dri2_surf->front_buffer.fb_id)) { ++ dri2_dpy->image->destroyImage(dri2_surf->front_buffer.dri_image); ++ dri2_surf->front_buffer.dri_image = NULL; + return false; + } + } +@@ -1362,7 +1371,7 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config, + } + + err = display_output_modeset(dri2_dpy->fd, &dri2_dpy->output, +- dri2_surf->front_fb_id); ++ dri2_surf->front_buffer.fb_id); + if (err) { + _eglError(EGL_BAD_NATIVE_WINDOW, "window set mode"); + goto err_destroy_surface; +@@ -1392,6 +1401,60 @@ dri2_null_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *config, + return create_surface(disp, config, EGL_PBUFFER_BIT, attrib_list); + } + ++static void ++dri2_null_init_front_buffer_render(_EGLSurface *draw) ++{ ++ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); ++ ++ dri2_surf->front_render_init = true; ++ ++ /* Drain the queue. swap_buffer_unlock_cond signals for the last time ++ * when the last back buffer in the queue went on screen and it's being ++ * tracked as current by then. ++ */ ++ swap_drain_queue_data(dri2_surf); ++ ++ /* If previously flipped, take a reference to the current buffer */ ++ if (dri2_surf->current) { ++ assert(dri2_surf->current->dri_image); ++ dri2_surf->back = dri2_surf->current; ++ ++ for (unsigned i = 0; i < DRI2_SURFACE_NUM_COLOR_BUFFERS; i++) ++ dri2_surf->color_buffers[i].age = 0; ++ ++ return; ++ } ++ ++ /* If the application hasn't yet fetched a back buffer, then it's not too ++ * late to use front buffer's dri_image and fb_id. ++ */ ++ if (!dri2_surf->back) { ++ assert(dri2_surf->front_buffer.dri_image); ++ dri2_surf->back = &dri2_surf->front_buffer; ++ ++ /* Don't need to reset buffer age since no flip was requested yet */ ++ ++ return; ++ } ++ ++ /* In order to initialise one color buffer for front buffer rendering, ++ * one page flip must occur. ++ */ ++ swap_enqueue_data(dri2_surf, get_back_buffer_id(dri2_surf), 1); ++ ++ return dri2_null_init_front_buffer_render(draw); ++} ++ ++static void ++dri2_null_disable_front_buffer_render(_EGLSurface *draw) ++{ ++ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); ++ ++ dri2_surf->front_render_enabled = false; ++ dri2_surf->front_render_init = false; ++ dri2_surf->back = NULL; ++} ++ + static EGLBoolean + dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) + { +@@ -1403,14 +1466,7 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) + * sure we process the flip event. + */ + if (dri2_surf->swap_queue_processor) { +- pthread_mutex_lock(&dri2_surf->mutex); +- +- /* Wait for any outstanding swaps to complete */ +- while (dri2_surf->swap_queue_idx_head != dri2_surf->swap_queue_idx_tail) +- pthread_cond_wait(&dri2_surf->swap_unlock_buffer_cond, +- &dri2_surf->mutex); +- +- pthread_mutex_unlock(&dri2_surf->mutex); ++ swap_drain_queue_data(dri2_surf); + pthread_cancel(dri2_surf->swap_queue_processor); + pthread_join(dri2_surf->swap_queue_processor, NULL); + } +@@ -1424,11 +1480,11 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) + if (dri2_surf->mutex_init) + pthread_mutex_destroy(&dri2_surf->mutex); + +- if (dri2_surf->front) +- dri2_dpy->image->destroyImage(dri2_surf->front); ++ if (dri2_surf->front_buffer.dri_image) ++ dri2_dpy->image->destroyImage(dri2_surf->front_buffer.dri_image); + +- if (dri2_surf->front_fb_id) +- drmModeRmFB(dri2_dpy->fd, dri2_surf->front_fb_id); ++ if (dri2_surf->front_buffer.fb_id) ++ drmModeRmFB(dri2_dpy->fd, dri2_surf->front_buffer.fb_id); + + for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + if (dri2_surf->color_buffers[i].fb_id) +@@ -1455,6 +1511,16 @@ dri2_null_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw) + if (dri2_surf->base.Type != EGL_WINDOW_BIT) + return EGL_TRUE; + ++ /* Flush and early return, no swap takes place */ ++ if (dri2_surf->front_render_enabled) { ++ dri2_flush_drawable_for_swapbuffers(disp, draw); ++ ++ if (!dri2_surf->front_render_init) ++ dri2_null_init_front_buffer_render(draw); ++ ++ return EGL_TRUE; ++ } ++ + for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) + if (dri2_surf->color_buffers[i].age > 0) + dri2_surf->color_buffers[i].age++; +@@ -1497,6 +1563,22 @@ dri2_null_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface) + static EGLBoolean + dri2_null_swap_interval(_EGLDisplay *dpy, _EGLSurface *draw, EGLint interval) + { ++ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); ++ struct dri2_egl_display *dri2_dpy = ++ dri2_egl_display(dri2_surf->base.Resource.Display); ++ ++ /* dri2_dpy tracks whether the display driver is async flip capable. ++ * If it isn't, enable front buffer rendering when swap interval ++ * 0 is passed in from the application. ++ */ ++ if (!interval && !dri2_dpy->async_flip_enabled) { ++ if (!dri2_surf->front_render_enabled) ++ dri2_surf->front_render_enabled = true; ++ } else { ++ if (dri2_surf->front_render_enabled) ++ dri2_null_disable_front_buffer_render(draw); ++ } ++ + _eglLog(_EGL_DEBUG, "DRI2: set swap interval to %d", interval); + draw->SwapInterval = interval; + return EGL_TRUE; +@@ -1534,7 +1616,7 @@ dri2_null_image_get_buffers(__DRIdrawable *driDrawable, unsigned int format, + + if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) { + buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT; +- buffers->front = dri2_surf->front; ++ buffers->front = dri2_surf->front_buffer.dri_image; + } + + if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) { +@@ -1672,18 +1754,27 @@ dri2_null_setup_swap_interval(_EGLDisplay *disp) + dri2_setup_swap_interval(disp, swap_max_interval); + + err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value); +- if (err || value == 0) +- dri2_dpy->min_swap_interval = 1; ++ if (err || value == 0) { + +- /** +- * drm/atomic: Reject FLIP_ASYNC unconditionally +- * upstream f2cbda2dba11de868759cae9c0d2bab5b8411406 +- * +- * Only allow swap interval 0 for legacy DRM/KMS and let +- * the app be aware that swap interval is clamped to 1. +- */ +- if (dri2_dpy->atomic_enabled) +- dri2_dpy->min_swap_interval = 1; ++ /* DRM/KMS does not support async page flip. In order to support ++ * swap interval 0, use front buffer rendering. ++ */ ++ _eglLog(_EGL_DEBUG, ++ "drm async flip not supported, use front buffer"); ++ } else { ++ ++ /* drm/atomic: Reject FLIP_ASYNC unconditionally ++ * upstream f2cbda2dba11de868759cae9c0d2bab5b8411406 ++ * ++ * Legacy DRM/KMS can use DRM_MODE_PAGE_FLIP_ASYNC, for atomic ++ * drivers fallback to front buffer rendering. ++ */ ++ if (dri2_dpy->atomic_enabled) ++ _eglLog(_EGL_DEBUG, ++ "async flip not supported by atomic, use front buffer"); ++ else ++ dri2_dpy->async_flip_enabled = true; ++ } + } + + EGLBoolean +-- +2.17.1 + diff --git a/package/mesa3d/0038-gbm-add-pbuffer-support.patch b/package/mesa3d/0038-gbm-add-pbuffer-support.patch new file mode 100644 index 00000000..cccb96ad --- /dev/null +++ b/package/mesa3d/0038-gbm-add-pbuffer-support.patch @@ -0,0 +1,229 @@ +From 3b52d830ed80131e7fb719a7e3c6b56005e464f1 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 21 Aug 2020 12:13:28 +0100 +Subject: [PATCH 038/168] gbm: add pbuffer support + +The EGL backend GLX provider for XWayland may get the EGL configs it +uses to generate the GLX ones from GBM. That platform doesn't support +pbuffers. When the client tries to match GLX configs with the DRI ones, +a mismatch in the pbuffer attributes will result in the GLX config +being rejected. + +Although support for creating pbuffers has been added, this isn't +required when using the EGL backend GLX provider, as indirect GLX +isn't supported. +--- + src/egl/drivers/dri2/egl_dri2.h | 3 + + src/egl/drivers/dri2/platform_drm.c | 110 +++++++++++++++++++++++++--- + 2 files changed, 103 insertions(+), 10 deletions(-) + +diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h +index 8bef835ef16..29f24f57a63 100644 +--- a/src/egl/drivers/dri2/egl_dri2.h ++++ b/src/egl/drivers/dri2/egl_dri2.h +@@ -473,6 +473,9 @@ 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; +diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c +index 45895a88b6c..4d08851c782 100644 +--- a/src/egl/drivers/dri2/platform_drm.c ++++ b/src/egl/drivers/dri2/platform_drm.c +@@ -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; +@@ -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, +-- +2.17.1 + diff --git a/package/mesa3d/0039-egl-null-expose-EXT_yuv_surface-support.patch b/package/mesa3d/0039-egl-null-expose-EXT_yuv_surface-support.patch new file mode 100644 index 00000000..ea49bcbe --- /dev/null +++ b/package/mesa3d/0039-egl-null-expose-EXT_yuv_surface-support.patch @@ -0,0 +1,376 @@ +From 77ee240cc68da64fed3e5630c0cae6a608403e92 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 2 Sep 2021 22:47:54 +0100 +Subject: [PATCH 039/168] egl/null: expose EXT_yuv_surface support + +--- + src/egl/drivers/dri2/platform_null.c | 247 +++++++++++++++++++++++++-- + 1 file changed, 233 insertions(+), 14 deletions(-) + +diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c +index 0ce7e60030b..c78e1fe0880 100644 +--- a/src/egl/drivers/dri2/platform_null.c ++++ b/src/egl/drivers/dri2/platform_null.c +@@ -79,6 +79,70 @@ uint32_t get_back_buffer_id(struct dri2_egl_surface *dri2_surf) + .prop_value = value, \ + } + ++static const struct dri2_null_yuv_attrib { ++ uint32_t order; ++ uint32_t subsample; ++ uint32_t num_planes; ++ uint32_t plane_bpp; ++} dri2_null_yuv_attribs[] = { ++ { ++ /* __DRI_IMAGE_FORMAT_YUYV */ ++ .order = __DRI_ATTRIB_YUV_ORDER_YUYV_BIT, ++ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT, ++ .num_planes = 1, ++ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT, ++ }, ++ { ++ /* __DRI_IMAGE_FORMAT_NV12 */ ++ .order = __DRI_ATTRIB_YUV_ORDER_YUV_BIT, ++ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT, ++ .num_planes = 2, ++ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT, ++ }, ++ { ++ /* __DRI_IMAGE_FORMAT_NV21 */ ++ .order = __DRI_ATTRIB_YUV_ORDER_YVU_BIT, ++ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT, ++ .num_planes = 2, ++ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT, ++ }, ++ { ++ /* __DRI_IMAGE_FORMAT_YU12 */ ++ .order = __DRI_ATTRIB_YUV_ORDER_YUV_BIT, ++ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT, ++ .num_planes = 3, ++ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT, ++ }, ++ { ++ /* __DRI_IMAGE_FORMAT_YV12 */ ++ .order = __DRI_ATTRIB_YUV_ORDER_YVU_BIT, ++ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT, ++ .num_planes = 3, ++ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT, ++ }, ++ { ++ /* __DRI_IMAGE_FORMAT_UYVY */ ++ .order = __DRI_ATTRIB_YUV_ORDER_UYVY_BIT, ++ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT, ++ .num_planes = 1, ++ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT, ++ }, ++ { ++ /* __DRI_IMAGE_FORMAT_YVYU */ ++ .order = __DRI_ATTRIB_YUV_ORDER_YVYU_BIT, ++ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT, ++ .num_planes = 1, ++ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT, ++ }, ++ { ++ /* __DRI_IMAGE_FORMAT_VYUY */ ++ .order = __DRI_ATTRIB_YUV_ORDER_VYUY_BIT, ++ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT, ++ .num_planes = 1, ++ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT, ++ }, ++}; ++ + /* + * The index of entries in this table is used as a bitmask in + * dri2_dpy->formats, which tracks the formats supported by the display. +@@ -88,24 +152,84 @@ static const struct dri2_null_format { + int dri_image_format; + int rgba_shifts[4]; + unsigned int rgba_sizes[4]; ++ const struct dri2_null_yuv_attrib *yuv; + } dri2_null_formats[] = { + { + .drm_format = DRM_FORMAT_XRGB8888, + .dri_image_format = __DRI_IMAGE_FORMAT_XRGB8888, + .rgba_shifts = { 16, 8, 0, -1 }, + .rgba_sizes = { 8, 8, 8, 0 }, ++ .yuv = NULL, + }, + { + .drm_format = DRM_FORMAT_ARGB8888, + .dri_image_format = __DRI_IMAGE_FORMAT_ARGB8888, + .rgba_shifts = { 16, 8, 0, 24 }, + .rgba_sizes = { 8, 8, 8, 8 }, ++ .yuv = NULL, + }, + { + .drm_format = DRM_FORMAT_RGB565, + .dri_image_format = __DRI_IMAGE_FORMAT_RGB565, + .rgba_shifts = { 11, 5, 0, -1 }, + .rgba_sizes = { 5, 6, 5, 0 }, ++ .yuv = NULL, ++ }, ++ { ++ .drm_format = DRM_FORMAT_YUYV, ++ .dri_image_format = __DRI_IMAGE_FORMAT_YUYV, ++ .rgba_shifts = { -1, -1, -1, -1 }, ++ .rgba_sizes = { 0, 0, 0, 0 }, ++ .yuv = &dri2_null_yuv_attribs[0], ++ }, ++ { ++ .drm_format = DRM_FORMAT_NV12, ++ .dri_image_format = __DRI_IMAGE_FORMAT_NV12, ++ .rgba_shifts = { -1, -1, -1, -1 }, ++ .rgba_sizes = { 0, 0, 0, 0 }, ++ .yuv = &dri2_null_yuv_attribs[1], ++ }, ++ { ++ .drm_format = DRM_FORMAT_NV21, ++ .dri_image_format = __DRI_IMAGE_FORMAT_NV21, ++ .rgba_shifts = { -1, -1, -1, -1 }, ++ .rgba_sizes = { 0, 0, 0, 0 }, ++ .yuv = &dri2_null_yuv_attribs[2], ++ }, ++ { ++ .drm_format = DRM_FORMAT_YUV420, ++ .dri_image_format = __DRI_IMAGE_FORMAT_YU12, ++ .rgba_shifts = { -1, -1, -1, -1 }, ++ .rgba_sizes = { 0, 0, 0, 0 }, ++ .yuv = &dri2_null_yuv_attribs[3], ++ }, ++ { ++ .drm_format = DRM_FORMAT_YVU420, ++ .dri_image_format = __DRI_IMAGE_FORMAT_YV12, ++ .rgba_shifts = { -1, -1, -1, -1 }, ++ .rgba_sizes = { 0, 0, 0, 0 }, ++ .yuv = &dri2_null_yuv_attribs[4], ++ }, ++ { ++ .drm_format = DRM_FORMAT_UYVY, ++ .dri_image_format = __DRI_IMAGE_FORMAT_UYVY, ++ .rgba_shifts = { -1, -1, -1, -1 }, ++ .rgba_sizes = { 0, 0, 0, 0 }, ++ .yuv = &dri2_null_yuv_attribs[5], ++ }, ++ { ++ .drm_format = DRM_FORMAT_YVYU, ++ .dri_image_format = __DRI_IMAGE_FORMAT_YVYU, ++ .rgba_shifts = { -1, -1, -1, -1 }, ++ .rgba_sizes = { 0, 0, 0, 0 }, ++ .yuv = &dri2_null_yuv_attribs[6], ++ }, ++ { ++ .drm_format = DRM_FORMAT_VYUY, ++ .dri_image_format = __DRI_IMAGE_FORMAT_VYUY, ++ .rgba_shifts = { -1, -1, -1, -1 }, ++ .rgba_sizes = { 0, 0, 0, 0 }, ++ .yuv = &dri2_null_yuv_attribs[7], + }, + }; + +@@ -137,6 +261,36 @@ format_idx_get_from_config(struct dri2_egl_display *dri2_dpy, + return -1; + } + ++static int ++yuv_format_idx_get_from_config(struct dri2_egl_display *dri2_dpy, ++ const __DRIconfig *dri_config) ++{ ++ for (unsigned int i = 0; i < ARRAY_SIZE(dri2_null_formats); i++) { ++ const struct dri2_null_yuv_attrib *yuv = dri2_null_formats[i].yuv; ++ unsigned order, subsample, num_planes, plane_bpp; ++ ++ if (!yuv) ++ continue; ++ ++ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_ORDER, ++ &order); ++ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_SUBSAMPLE, ++ &subsample); ++ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_NUMBER_OF_PLANES, ++ &num_planes); ++ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_PLANE_BPP, ++ &plane_bpp); ++ ++ if (order != yuv->order || subsample != yuv->subsample || ++ num_planes != yuv->num_planes || plane_bpp != yuv->plane_bpp) ++ continue; ++ ++ return i; ++ } ++ ++ return -1; ++} ++ + static int + format_idx_get_from_dri_image_format(uint32_t dri_image_format) + { +@@ -1082,23 +1236,21 @@ static bool + add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image, + uint32_t *fb_id_out) + { +- uint64_t modifiers[4] = {0}; ++ int handle, stride, width, height, format, l_mod, h_mod, offset; ++ uint64_t modifier = DRM_FORMAT_MOD_INVALID; ++ uint64_t *modifiers = NULL, mods[4] = {0}; + uint32_t handles[4] = {0}; + uint32_t pitches[4] = {0}; + uint32_t offsets[4] = {0}; ++ __DRIimage *p_image; + uint32_t flags = 0; +- int handle, stride, width, height, format, l_mod, h_mod; + int format_idx; ++ int num_planes; + +- dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HANDLE, &handle); +- dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride); + dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_WIDTH, &width); + dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HEIGHT, &height); + dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format); + +- handles[0] = (uint32_t) handle; +- pitches[0] = (uint32_t) stride; +- + format_idx = format_idx_get_from_dri_image_format(format); + assert(format_idx != -1); + +@@ -1106,10 +1258,44 @@ add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image, + dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_MODIFIER_UPPER, &h_mod); + dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_MODIFIER_LOWER, &l_mod); + +- modifiers[0] = combine_u32_into_u64((uint32_t) h_mod, (uint32_t) l_mod); ++ modifier = combine_u32_into_u64((uint32_t) h_mod, (uint32_t) l_mod); ++ modifiers = mods; ++ + flags |= DRM_MODE_FB_MODIFIERS; + } + ++ dri2_dpy->image->queryImage(image, ++ __DRI_IMAGE_ATTRIB_NUM_PLANES, &num_planes); ++ if (num_planes <= 0) ++ num_planes = 1; ++ ++ for (int i = 0; i < num_planes; i++) { ++ if (dri2_dpy->in_formats_enabled) { ++ assert(modifiers && modifier != DRM_FORMAT_MOD_INVALID); ++ modifiers[i] = modifier; ++ } ++ ++ p_image = dri2_dpy->image->fromPlanar(image, i, NULL); ++ if (!p_image) { ++ assert(i == 0); ++ p_image = image; ++ } ++ ++ dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_STRIDE, ++ &stride); ++ dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_OFFSET, ++ &offset); ++ dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_HANDLE, ++ &handle); ++ ++ if (p_image != image) ++ dri2_dpy->image->destroyImage(p_image); ++ ++ pitches[i] = (uint32_t) stride; ++ offsets[i] = (uint32_t) offset; ++ handles[i] = (uint32_t) handle; ++ } ++ + return !drmModeAddFB2WithModifiers(dri2_dpy->fd, width, height, + dri2_null_formats[format_idx].drm_format, + handles, pitches, offsets, modifiers, +@@ -1256,6 +1442,7 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type, + struct dri2_egl_config *dri2_config = dri2_egl_config(config); + struct dri2_egl_surface *dri2_surf; + const __DRIconfig *dri_config; ++ unsigned int render_type; + _EGLSurface *surf; + int format_idx; + bool ret; +@@ -1286,7 +1473,14 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type, + goto err_free_surface; + } + +- format_idx = format_idx_get_from_config(dri2_dpy, dri_config); ++ if (!dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_RENDER_TYPE, ++ &render_type)) ++ goto err_free_surface; ++ ++ if (render_type & __DRI_ATTRIB_YUV_BIT) ++ format_idx = yuv_format_idx_get_from_config(dri2_dpy, dri_config); ++ else ++ format_idx = format_idx_get_from_config(dri2_dpy, dri_config); + assert(format_idx != -1); + + dri2_surf->format = dri2_null_formats[format_idx].dri_image_format; +@@ -1627,6 +1821,17 @@ dri2_null_image_get_buffers(__DRIdrawable *driDrawable, unsigned int format, + return 1; + } + ++static unsigned ++dri2_null_get_capability(void *loaderPrivate, enum dri_loader_cap cap) ++{ ++ switch (cap) { ++ case DRI_LOADER_CAP_YUV_SURFACE_IMG: ++ return 1; ++ default: ++ return 0; ++ } ++} ++ + static void + dri2_null_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) + { +@@ -1635,10 +1840,11 @@ dri2_null_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) + } + + static const __DRIimageLoaderExtension image_loader_extension = { +- .base = { __DRI_IMAGE_LOADER, 1 }, ++ .base = { __DRI_IMAGE_LOADER, 2 }, + + .getBuffers = dri2_null_image_get_buffers, + .flushFrontBuffer = dri2_null_flush_front_buffer, ++ .getCapability = dri2_null_get_capability, + }; + + static const __DRIextension *image_loader_extensions[] = { +@@ -1720,10 +1926,24 @@ dri2_null_add_configs_for_formats(_EGLDisplay *disp) + + for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) { + struct dri2_egl_config *dri2_conf; ++ EGLint surface_type = EGL_WINDOW_BIT; ++ unsigned int render_type; + int format_idx; + +- format_idx = format_idx_get_from_config(dri2_dpy, +- dri2_dpy->driver_configs[i]); ++ if (!dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i], ++ __DRI_ATTRIB_RENDER_TYPE, ++ &render_type)) ++ continue; ++ ++ if (render_type & __DRI_ATTRIB_YUV_BIT) { ++ format_idx = yuv_format_idx_get_from_config(dri2_dpy, ++ dri2_dpy->driver_configs[i]); ++ } else { ++ format_idx = format_idx_get_from_config(dri2_dpy, ++ dri2_dpy->driver_configs[i]); ++ surface_type |= EGL_PBUFFER_BIT; ++ } ++ + if (format_idx == -1) + continue; + +@@ -1735,8 +1955,7 @@ dri2_null_add_configs_for_formats(_EGLDisplay *disp) + + dri2_conf = dri2_add_config(disp, + dri2_dpy->driver_configs[i], count + 1, +- EGL_WINDOW_BIT | EGL_PBUFFER_BIT, +- NULL, NULL, NULL); ++ surface_type, NULL, NULL, NULL); + if (dri2_conf) + count++; + } +-- +2.17.1 + diff --git a/package/mesa3d/0040-dri-preserve-the-original-FD-for-driver-use.patch b/package/mesa3d/0040-dri-preserve-the-original-FD-for-driver-use.patch new file mode 100644 index 00000000..4b11aa7f --- /dev/null +++ b/package/mesa3d/0040-dri-preserve-the-original-FD-for-driver-use.patch @@ -0,0 +1,442 @@ +From a161ef637586f2fd15f498479a163c441c3e6f94 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 9 Mar 2021 17:15:30 +0000 +Subject: [PATCH 040/168] dri: preserve the original FD for driver use. + +If an application uses a different GPU from the default, allow the +file descriptor (FD) for that original GPU/display to be preserved +for use by drivers. Drivers may wish to use the original FD to +allocate shared surfaces, to ensure the surface properties are +compatible with the original GPU/display (e.g. for X11 or Wayland). + +This feature is only available on platforms that choose to support +it, by implementing the new getDisplayFD function in the DRI image, +and DRI2 loader extensions. + +If the feature is available, drivers can obtain the original FD +by calling the getDisplayFD function in the relevant loader extension. +Drivers should check the FD is valid before use (i.e. not -1). If +the FD is valid, it may be equal to the current GPU FD if a different +GPU is not being used. The FD is owned by the platform, not the +driver, and the platform is responsible for closing it. + +The feature is currently supported by the Wayland, and DRI3 based +X11 EGL and GLX platforms. +--- + include/GL/internal/dri_interface.h | 26 +++++++++++++++++-- + src/egl/drivers/dri2/egl_dri2.c | 12 ++++++++- + src/egl/drivers/dri2/egl_dri2.h | 1 + + src/egl/drivers/dri2/platform_wayland.c | 31 ++++++++++++++++++++-- + src/egl/drivers/dri2/platform_x11.c | 3 +++ + src/egl/drivers/dri2/platform_x11_dri3.c | 27 ++++++++++++++++++- + src/glx/dri3_glx.c | 33 ++++++++++++++++++++++-- + src/glx/dri3_priv.h | 1 + + 8 files changed, 126 insertions(+), 8 deletions(-) + +diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h +index 66a60fd46ad..22c1374af02 100644 +--- a/include/GL/internal/dri_interface.h ++++ b/include/GL/internal/dri_interface.h +@@ -1015,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, +@@ -1096,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); + }; + + /** +@@ -2054,7 +2065,7 @@ struct __DRIimageList { + }; + + #define __DRI_IMAGE_LOADER "DRI_IMAGE_LOADER" +-#define __DRI_IMAGE_LOADER_VERSION 4 ++#define __DRI_IMAGE_LOADER_VERSION 5 + + struct __DRIimageLoaderExtensionRec { + __DRIextension base; +@@ -2122,6 +2133,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); + }; + + /** +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index 60cc81ba536..0bcc5054070 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -1381,6 +1381,16 @@ dri2_display_destroy(_EGLDisplay *disp) + break; + } + ++ switch (disp->Platform) { ++ 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); + +@@ -3596,7 +3606,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) +diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h +index 29f24f57a63..21e77a194e0 100644 +--- a/src/egl/drivers/dri2/egl_dri2.h ++++ b/src/egl/drivers/dri2/egl_dri2.h +@@ -267,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). */ +diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c +index 86a9305178d..7cc6dc0cad6 100644 +--- a/src/egl/drivers/dri2/platform_wayland.c ++++ b/src/egl/drivers/dri2/platform_wayland.c +@@ -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" + +@@ -1448,21 +1449,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 +@@ -2253,12 +2265,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) +@@ -2330,8 +2344,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"); +@@ -2908,6 +2934,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) +diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c +index 15be86dc026..389c1054461 100644 +--- a/src/egl/drivers/dri2/platform_x11.c ++++ b/src/egl/drivers/dri2/platform_x11.c +@@ -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; + +diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c +index c529f426f5e..8fd794bce99 100644 +--- a/src/egl/drivers/dri2/platform_x11_dri3.c ++++ b/src/egl/drivers/dri2/platform_x11_dri3.c +@@ -32,6 +32,7 @@ + + #include + #include "util/macros.h" ++#include "util/os_file.h" + + #include "egl_dri2.h" + #include "platform_x11_dri3.h" +@@ -431,11 +432,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 +566,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 +646,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; + } + +diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c +index e8996dd5e27..f6eb405d130 100644 +--- a/src/glx/dri3_glx.c ++++ b/src/glx/dri3_glx.c +@@ -78,6 +78,7 @@ + #include "loader.h" + #include "loader_dri_helper.h" + #include "dri2.h" ++#include "util/os_file.h" + + static struct dri3_drawable * + loader_drawable_to_dri3_drawable(struct loader_dri3_drawable *draw) { +@@ -537,6 +538,14 @@ dri3_flush_swap_buffers(__DRIdrawable *driDrawable, void *loaderPrivate) + loader_dri3_swapbuffer_barrier(draw); + } + ++static int ++dri3_get_display_fd(void *loaderPrivate) ++{ ++ struct dri3_screen *psc = (struct dri3_screen *)loaderPrivate; ++ ++ return psc->fd_dpy; ++} ++ + static void + dri_set_background_context(void *loaderPrivate) + { +@@ -555,11 +564,12 @@ dri_is_thread_safe(void *loaderPrivate) + /* The image loader extension record for DRI3 + */ + static const __DRIimageLoaderExtension imageLoaderExtension = { +- .base = { __DRI_IMAGE_LOADER, 3 }, ++ .base = { __DRI_IMAGE_LOADER, 5 }, + + .getBuffers = loader_dri3_get_buffers, + .flushFrontBuffer = dri3_flush_front_buffer, + .flushSwapBuffers = dri3_flush_swap_buffers, ++ .getDisplayFD = dri3_get_display_fd, + }; + + const __DRIuseInvalidateExtension dri3UseInvalidate = { +@@ -625,6 +635,10 @@ dri3_destroy_screen(struct glx_screen *base) + loader_dri3_close_screen(psc->driScreen); + (*psc->core->destroyScreen) (psc->driScreen); + driDestroyConfigs(psc->driver_configs); ++ ++ if (psc->fd_dpy != psc->fd) ++ close(psc->fd_dpy); ++ + close(psc->fd); + free(psc); + } +@@ -835,8 +849,9 @@ dri3_create_screen(int screen, struct glx_display * priv) + struct dri3_screen *psc; + __GLXDRIscreen *psp; + struct glx_config *configs = NULL, *visuals = NULL; +- char *driverName, *driverNameDisplayGPU, *tmp; ++ char *driverName = NULL, *driverNameDisplayGPU, *tmp; + int i; ++ int fd_old; + + psc = calloc(1, sizeof *psc); + if (psc == NULL) +@@ -844,6 +859,7 @@ dri3_create_screen(int screen, struct glx_display * priv) + + psc->fd = -1; + psc->fd_display_gpu = -1; ++ psc->fd_dpy = -1; + + if (!glx_screen_init(&psc->base, screen, priv)) { + free(psc); +@@ -864,12 +880,23 @@ dri3_create_screen(int screen, struct glx_display * priv) + return NULL; + } + ++ fd_old = psc->fd; ++ psc->fd_dpy = os_dupfd_cloexec(psc->fd); + psc->fd_display_gpu = fcntl(psc->fd, F_DUPFD_CLOEXEC, 3); + psc->fd = loader_get_user_preferred_fd(psc->fd, &psc->is_different_gpu); + if (!psc->is_different_gpu) { + close(psc->fd_display_gpu); + psc->fd_display_gpu = -1; + } ++ if (psc->fd == fd_old) { ++ if (psc->fd_dpy != -1) ++ close(psc->fd_dpy); ++ ++ psc->fd_dpy = psc->fd; ++ } else if (psc->fd_dpy == -1) { ++ ErrorMessageF("Unable to dup the display FD"); ++ goto handle_error; ++ } + + driverName = loader_get_driver_for_fd(psc->fd); + if (!driverName) { +@@ -1075,6 +1102,8 @@ handle_error: + if (psc->driScreenDisplayGPU) + psc->core->destroyScreen(psc->driScreenDisplayGPU); + psc->driScreenDisplayGPU = NULL; ++ if (psc->fd_dpy >= 0 && psc->fd_dpy != psc->fd) ++ close(psc->fd_dpy); + if (psc->fd >= 0) + close(psc->fd); + if (psc->fd_display_gpu >= 0) +diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h +index 09dcefd6115..bd3073dc4b6 100644 +--- a/src/glx/dri3_priv.h ++++ b/src/glx/dri3_priv.h +@@ -101,6 +101,7 @@ struct dri3_screen { + + void *driver; + int fd; ++ int fd_dpy; + bool is_different_gpu; + bool prefer_back_buffer_reuse; + +-- +2.17.1 + diff --git a/package/mesa3d/0041-egl-wayland-a-linear-buffer-is-not-needed-with-DRM-f.patch b/package/mesa3d/0041-egl-wayland-a-linear-buffer-is-not-needed-with-DRM-f.patch new file mode 100644 index 00000000..58d114dd --- /dev/null +++ b/package/mesa3d/0041-egl-wayland-a-linear-buffer-is-not-needed-with-DRM-f.patch @@ -0,0 +1,131 @@ +From ed92d2bf22f666cbc9bd79e6baf23b83722e78f6 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 28 Apr 2021 10:57:15 +0100 +Subject: [PATCH 041/168] egl/wayland: a linear buffer is not needed with DRM + format modifiers + +If the compositor supports DRM format modifiers, there is no +need for an additional linear buffer, as the client can allocate +buffers with attributes known to the compositor. +--- + src/egl/drivers/dri2/platform_wayland.c | 36 ++++++++++++++----------- + 1 file changed, 21 insertions(+), 15 deletions(-) + +diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c +index 7cc6dc0cad6..3a9f43e6069 100644 +--- a/src/egl/drivers/dri2/platform_wayland.c ++++ b/src/egl/drivers/dri2/platform_wayland.c +@@ -1014,7 +1014,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) + { +@@ -1027,7 +1027,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); +@@ -1071,11 +1071,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) + { +@@ -1107,6 +1109,8 @@ 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 +@@ -1118,6 +1122,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); +@@ -1177,23 +1182,24 @@ 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; ++ } ++ + dri2_surf->back->locked = true; + + return 0; +@@ -1283,7 +1289,7 @@ update_buffers(struct dri2_egl_display *dri2_dpy, + 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; +@@ -1728,7 +1734,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; +@@ -1760,7 +1766,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp, + 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, +-- +2.17.1 + diff --git a/package/mesa3d/0042-dri3-a-linear-buffer-is-not-needed-with-DRM-format-m.patch b/package/mesa3d/0042-dri3-a-linear-buffer-is-not-needed-with-DRM-format-m.patch new file mode 100644 index 00000000..0b509e1f --- /dev/null +++ b/package/mesa3d/0042-dri3-a-linear-buffer-is-not-needed-with-DRM-format-m.patch @@ -0,0 +1,303 @@ +From d4d79415ca824cee38f8c8cdcdfe108179d092c0 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 28 Apr 2021 16:33:42 +0100 +Subject: [PATCH 042/168] dri3: a linear buffer is not needed with DRM format + modifiers + +If the X Server supports DRM format modifiers, there is no need +for an additional linear buffer, as the client can allocate buffers +with attributes known to the Server. +--- + src/egl/drivers/dri2/platform_x11_dri3.c | 7 +- + src/glx/dri3_glx.c | 137 +++++++++++++++-------- + src/loader/loader_dri3_helper.c | 15 +++ + src/loader/loader_dri3_helper.h | 3 + + 4 files changed, 112 insertions(+), 50 deletions(-) + +diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c +index 8fd794bce99..63d3dc589d7 100644 +--- a/src/egl/drivers/dri2/platform_x11_dri3.c ++++ b/src/egl/drivers/dri2/platform_x11_dri3.c +@@ -158,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) { +@@ -165,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; +@@ -190,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, +diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c +index f6eb405d130..6921ed9fcb5 100644 +--- a/src/glx/dri3_glx.c ++++ b/src/glx/dri3_glx.c +@@ -358,6 +358,21 @@ glx_to_loader_dri3_drawable_type(int type) + } + } + ++static bool ++dri3_has_multibuffer(const __DRIimageExtension *image, ++ const struct dri3_display *pdp) ++{ ++#ifdef HAVE_DRI3_MODIFIERS ++ return (image && image->base.version >= 15) && ++ (pdp->dri3Major > 1 || ++ (pdp->dri3Major == 1 && pdp->dri3Minor >= 2)) && ++ (pdp->presentMajor > 1 || ++ (pdp->presentMajor == 1 && pdp->presentMinor >= 2)); ++#else ++ return false; ++#endif ++} ++ + static __GLXDRIdrawable * + dri3_create_drawable(struct glx_screen *base, XID xDrawable, + GLXDrawable drawable, int type, +@@ -366,11 +381,9 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable, + struct dri3_drawable *pdraw; + struct dri3_screen *psc = (struct dri3_screen *) base; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base; +- bool has_multibuffer = false; +-#ifdef HAVE_DRI3_MODIFIERS + const struct dri3_display *const pdp = (struct dri3_display *) + base->display->dri3Display; +-#endif ++ bool has_multibuffer = dri3_has_multibuffer(psc->image, pdp); + + pdraw = calloc(1, sizeof(*pdraw)); + if (!pdraw) +@@ -381,14 +394,6 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable, + pdraw->base.drawable = drawable; + pdraw->base.psc = &psc->base; + +-#ifdef HAVE_DRI3_MODIFIERS +- if ((psc->image && psc->image->base.version >= 15) && +- (pdp->dri3Major > 1 || (pdp->dri3Major == 1 && pdp->dri3Minor >= 2)) && +- (pdp->presentMajor > 1 || +- (pdp->presentMajor == 1 && pdp->presentMinor >= 2))) +- has_multibuffer = true; +-#endif +- + (void) __glXInitialize(psc->base.dpy); + + if (loader_dri3_drawable_init(XGetXCBConnection(base->dpy), +@@ -728,13 +733,14 @@ static const struct glx_context_vtable dri3_context_vtable = { + .interop_flush_objects = dri3_interop_flush_objects + }; + +-/** dri3_bind_extensions ++/** dri3_bind_extensions_part1 + * +- * Enable all of the extensions supported on DRI3 ++ * Enable the extensions supported on DRI3 that don't depend on ++ * whether we are using a different GPU. + */ + static void +-dri3_bind_extensions(struct dri3_screen *psc, struct glx_display * priv, +- const char *driverName) ++dri3_bind_extensions_part1(struct dri3_screen *psc, struct glx_display * priv, ++ const char *driverName) + { + const __DRIextension **extensions; + unsigned mask; +@@ -765,16 +771,6 @@ dri3_bind_extensions(struct dri3_screen *psc, struct glx_display * priv, + } + + for (i = 0; extensions[i]; i++) { +- /* when on a different gpu than the server, the server pixmaps +- * can have a tiling mode we can't read. Thus we can't create +- * a texture from them. +- */ +- if (!psc->is_different_gpu && +- (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) { +- psc->texBuffer = (__DRItexBufferExtension *) extensions[i]; +- __glXEnableDirectExtension(&psc->base, "GLX_EXT_texture_from_pixmap"); +- } +- + if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) { + psc->f = (__DRI2flushExtension *) extensions[i]; + /* internal driver extension, no GL extension exposed */ +@@ -810,6 +806,33 @@ dri3_bind_extensions(struct dri3_screen *psc, struct glx_display * priv, + } + } + ++/** dri3_bind_extensions_part2 ++ * ++ * Enable the extensions supported on DRI3 that depend on whether we ++ * are using a different GPU. ++ */ ++static void ++dri3_bind_extensions_part2(struct dri3_screen *psc, struct glx_display * priv, ++ const char *driverName) ++{ ++ const __DRIextension **extensions; ++ int i; ++ ++ extensions = psc->core->getExtensions(psc->driScreen); ++ ++ for (i = 0; extensions[i]; i++) { ++ /* when on a different gpu than the server, the server pixmaps ++ * can have a tiling mode we can't read. Thus we can't create ++ * a texture from them. ++ */ ++ if (!psc->is_different_gpu && ++ (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) { ++ psc->texBuffer = (__DRItexBufferExtension *) extensions[i]; ++ __glXEnableDirectExtension(&psc->base, "GLX_EXT_texture_from_pixmap"); ++ } ++ } ++} ++ + static char * + dri3_get_driver_name(struct glx_screen *glx_screen) + { +@@ -852,6 +875,8 @@ dri3_create_screen(int screen, struct glx_display * priv) + char *driverName = NULL, *driverNameDisplayGPU, *tmp; + int i; + int fd_old; ++ bool is_different_gpu; ++ bool have_modifiers; + + psc = calloc(1, sizeof *psc); + if (psc == NULL) +@@ -883,8 +908,8 @@ dri3_create_screen(int screen, struct glx_display * priv) + fd_old = psc->fd; + psc->fd_dpy = os_dupfd_cloexec(psc->fd); + psc->fd_display_gpu = fcntl(psc->fd, F_DUPFD_CLOEXEC, 3); +- psc->fd = loader_get_user_preferred_fd(psc->fd, &psc->is_different_gpu); +- if (!psc->is_different_gpu) { ++ psc->fd = loader_get_user_preferred_fd(psc->fd, &is_different_gpu); ++ if (!is_different_gpu) { + close(psc->fd_display_gpu); + psc->fd_display_gpu = -1; + } +@@ -926,27 +951,6 @@ dri3_create_screen(int screen, struct glx_display * priv) + goto handle_error; + } + +- if (psc->is_different_gpu) { +- driverNameDisplayGPU = loader_get_driver_for_fd(psc->fd_display_gpu); +- if (driverNameDisplayGPU) { +- +- /* check if driver name is matching so that non mesa drivers +- * will not crash. Also need this check since image extension +- * pointer from render gpu is shared with display gpu. Image +- * extension pointer is shared because it keeps things simple. +- */ +- if (strcmp(driverName, driverNameDisplayGPU) == 0) { +- psc->driScreenDisplayGPU = +- psc->image_driver->createNewScreen2(screen, psc->fd_display_gpu, +- pdp->loader_extensions, +- extensions, +- &driver_configs, psc); +- } +- +- free(driverNameDisplayGPU); +- } +- } +- + psc->driScreen = + psc->image_driver->createNewScreen2(screen, psc->fd, + pdp->loader_extensions, +@@ -958,7 +962,42 @@ dri3_create_screen(int screen, struct glx_display * priv) + goto handle_error; + } + +- dri3_bind_extensions(psc, priv, driverName); ++ dri3_bind_extensions_part1(psc, priv, driverName); ++ ++ have_modifiers = loader_dri3_has_modifiers(dri3_has_multibuffer(psc->image, ++ pdp), ++ psc->image); ++ ++ if (is_different_gpu) { ++ if (have_modifiers) { ++ close(psc->fd_display_gpu); ++ psc->fd_display_gpu = -1; ++ } else { ++ driverNameDisplayGPU = loader_get_driver_for_fd(psc->fd_display_gpu); ++ if (driverNameDisplayGPU) { ++ ++ /* check if driver name is matching so that non mesa drivers ++ * will not crash. Also need this check since image extension ++ * pointer from render gpu is shared with display gpu. Image ++ * extension pointer is shared because it keeps things simple. ++ */ ++ if (strcmp(driverName, driverNameDisplayGPU) == 0) { ++ psc->driScreenDisplayGPU = ++ psc->image_driver->createNewScreen2(screen, ++ psc->fd_display_gpu, ++ pdp->loader_extensions, ++ extensions, ++ &driver_configs, psc); ++ } ++ ++ free(driverNameDisplayGPU); ++ } ++ } ++ } ++ ++ psc->is_different_gpu = is_different_gpu && !have_modifiers; ++ ++ dri3_bind_extensions_part2(psc, priv, driverName); + + if (!psc->image || psc->image->base.version < 7 || !psc->image->createImageFromFds) { + ErrorMessageF("Version 7 or imageFromFds image extension not found\n"); +diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c +index ad6f0b624b3..2192b20116d 100644 +--- a/src/loader/loader_dri3_helper.c ++++ b/src/loader/loader_dri3_helper.c +@@ -2597,3 +2597,18 @@ dri3_find_back_alloc(struct loader_dri3_drawable *draw) + + return back; + } ++ ++bool ++loader_dri3_has_modifiers(bool multiplanes_available, ++ const __DRIimageExtension *image) ++{ ++#ifdef HAVE_DRI3_MODIFIERS ++ return multiplanes_available && image && ++ image->base.version >= 15 && ++ image->queryDmaBufModifiers && ++ image->createImageWithModifiers && ++ image->createImageFromDmaBufs2; ++#else ++ return false; ++#endif ++} +diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h +index 6d20162c47c..8b39af04e9e 100644 +--- a/src/loader/loader_dri3_helper.h ++++ b/src/loader/loader_dri3_helper.h +@@ -330,5 +330,8 @@ loader_dri3_update_screen_resources(struct loader_dri3_screen_resources *res); + void + loader_dri3_destroy_screen_resources(struct loader_dri3_screen_resources *res); + ++bool ++loader_dri3_has_modifiers(bool multiplanes_available, ++ const __DRIimageExtension *image); + + #endif +-- +2.17.1 + diff --git a/package/mesa3d/0043-egl-drm-add-support-for-DRI_PRIME-GPU-selection.patch b/package/mesa3d/0043-egl-drm-add-support-for-DRI_PRIME-GPU-selection.patch new file mode 100644 index 00000000..60fd2b91 --- /dev/null +++ b/package/mesa3d/0043-egl-drm-add-support-for-DRI_PRIME-GPU-selection.patch @@ -0,0 +1,267 @@ +From 9721fffcf5d7ef752963f682bcc94850935e5f05 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 20 May 2021 14:43:29 +0100 +Subject: [PATCH 043/168] egl/drm: add support for DRI_PRIME GPU selection + +Add support for selecting the GPU to be used for rendering using +the DRI_PRIME environment variable. If a different GPU is selected, +a duplicate of the file descriptor for the original GPU/display is +preserved, which can be obtained by calling the getDisplayFD +function in the image loader extension. + +For server side Wayland, the ability to support PRIME is +determined by checking for the PRIME import and export +capabilities on the driver file descriptor, which may no +longer support them if a different GPU from the default has +been selected. It may be that the driver can still support +PRIME; for example, by making use of the original (default) +file descriptor. The driver can indicate it supports PRIME +via the getCapabilities function in the DRI Image extension. +--- + include/GL/internal/dri_interface.h | 2 ++ + src/egl/drivers/dri2/egl_dri2.c | 10 ++++++++ + src/egl/drivers/dri2/platform_drm.c | 19 ++++++++++----- + src/gbm/backends/dri/gbm_dri.c | 38 +++++++++++++++++++++++++---- + src/gbm/backends/dri/gbm_driint.h | 8 ++++++ + 5 files changed, 66 insertions(+), 11 deletions(-) + +diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h +index 22c1374af02..7d96048688d 100644 +--- a/include/GL/internal/dri_interface.h ++++ b/include/GL/internal/dri_interface.h +@@ -1417,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 + /*@}*/ + + /** +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index 0bcc5054070..485ceeba9b4 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -1382,6 +1382,7 @@ dri2_display_destroy(_EGLDisplay *disp) + } + + switch (disp->Platform) { ++ case _EGL_PLATFORM_DRM: + case _EGL_PLATFORM_WAYLAND: + case _EGL_PLATFORM_X11: + if (dri2_dpy->fd_dpy >= 0 && dri2_dpy->fd_dpy != dri2_dpy->fd) +@@ -3617,6 +3618,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, +diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c +index 4d08851c782..19c50c25128 100644 +--- a/src/egl/drivers/dri2/platform_drm.c ++++ b/src/egl/drivers/dri2/platform_drm.c +@@ -595,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 +@@ -782,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; +@@ -789,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; + } +@@ -810,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"; +@@ -875,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); + +diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c +index 5b18bdcccbc..bfb48769502 100644 +--- a/src/gbm/backends/dri/gbm_dri.c ++++ b/src/gbm/backends/dri/gbm_dri.c +@@ -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; + +@@ -1486,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); + } + +@@ -1507,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; +diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h +index 31f6b67a40f..3f94352185f 100644 +--- a/src/gbm/backends/dri/gbm_driint.h ++++ b/src/gbm/backends/dri/gbm_driint.h +@@ -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 +-- +2.17.1 + diff --git a/package/mesa3d/0044-egl-null-add-support-for-DRI_PRIME-GPU-selection.patch b/package/mesa3d/0044-egl-null-add-support-for-DRI_PRIME-GPU-selection.patch new file mode 100644 index 00000000..3c770992 --- /dev/null +++ b/package/mesa3d/0044-egl-null-add-support-for-DRI_PRIME-GPU-selection.patch @@ -0,0 +1,364 @@ +From 75b1c87bfdba318b06cbef887c415d74b945af88 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 20 May 2021 20:16:18 +0100 +Subject: [PATCH 044/168] egl/null: add support for DRI_PRIME GPU selection + +Add support for selecting the GPU to be used for rendering using +the DRI_PRIME environment variable. If a different GPU is selected, +a duplicate of the file descriptor for the original GPU/display is +preserved, which can be obtained by calling the getDisplayFD +function in the image loader extension. + +This change includes code, in function dri2_null_try_device, to +optionally skip display devices that are not supported by a +particular DRI driver. This can be enabled by setting Meson build +option null-dri-driver-name. This feature is to prevent failure +on PC based test systems, that may have display and GPU hardware +other than that being tested. +--- + meson.build | 4 + + meson_options.txt | 6 ++ + src/egl/drivers/dri2/egl_dri2.c | 1 + + src/egl/drivers/dri2/platform_null.c | 135 +++++++++++++++++++-------- + src/egl/meson.build | 5 + + 5 files changed, 114 insertions(+), 37 deletions(-) + +diff --git a/meson.build b/meson.build +index 3a6de3d5ce8..f4cbae5b0ab 100644 +--- a/meson.build ++++ b/meson.build +@@ -380,6 +380,10 @@ 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' + if with_platform_android +diff --git a/meson_options.txt b/meson_options.txt +index 43169974bff..0607fce2e2f 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -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', +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index 485ceeba9b4..80ba3647a9a 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -1383,6 +1383,7 @@ dri2_display_destroy(_EGLDisplay *disp) + + 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) +diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c +index c78e1fe0880..e2a138367f9 100644 +--- a/src/egl/drivers/dri2/platform_null.c ++++ b/src/egl/drivers/dri2/platform_null.c +@@ -45,6 +45,7 @@ + + #include "egl_dri2.h" + #include "loader.h" ++#include "util/os_file.h" + + #define NULL_CARD_MINOR_MAX 63U + +@@ -1045,7 +1046,7 @@ swap_idle_get_target_frame(struct dri2_egl_surface *dri2_surf, + * current vblank by the number of intervals set at the time swapBuffer + * is called. For intervals of 1 or 0, we don't need a target frame. + */ +- err = display_get_vblank_sequence(dri2_dpy->fd, current_vblank_out); ++ err = display_get_vblank_sequence(dri2_dpy->fd_dpy, current_vblank_out); + if (err) + return err; + +@@ -1095,7 +1096,7 @@ swap_vblank_state_transition(struct dri2_egl_surface *dri2_surf, + uint32_t flags = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT; + int err; + +- err = display_request_vblank(dri2_dpy->fd, target_frame, ++ err = display_request_vblank(dri2_dpy->fd_dpy, target_frame, + flags, dri2_surf); + if (err) { + dri2_surf->swap_state = SWAP_ERROR; +@@ -1121,7 +1122,7 @@ swap_flip_state_transition(struct dri2_egl_surface *dri2_surf) + flags |= DRM_MODE_PAGE_FLIP_ASYNC; + } + +- err = display_output_flip(dri2_dpy->fd, &dri2_dpy->output, ++ err = display_output_flip(dri2_dpy->fd_dpy, &dri2_dpy->output, + dri2_surf->swap_data->fb_id, flags, dri2_surf); + if (err) { + dri2_surf->swap_state = SWAP_ERROR; +@@ -1141,7 +1142,7 @@ swap_poll_state_transition(struct dri2_egl_surface *dri2_surf) + int err; + + /* dri2_surf->swap_state is being set inside the handler */ +- err = drm_event_process(dri2_dpy->fd); ++ err = drm_event_process(dri2_dpy->fd_dpy); + if (err) { + dri2_surf->swap_state = SWAP_ERROR; + return err; +@@ -1296,7 +1297,7 @@ add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image, + handles[i] = (uint32_t) handle; + } + +- return !drmModeAddFB2WithModifiers(dri2_dpy->fd, width, height, ++ return !drmModeAddFB2WithModifiers(dri2_dpy->fd_dpy, width, height, + dri2_null_formats[format_idx].drm_format, + handles, pitches, offsets, modifiers, + fb_id_out, flags); +@@ -1486,7 +1487,7 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type, + dri2_surf->format = dri2_null_formats[format_idx].dri_image_format; + + if (dri2_dpy->in_formats_enabled) { +- ret = in_formats_get_modifiers(dri2_dpy->fd, ++ ret = in_formats_get_modifiers(dri2_dpy->fd_dpy, + dri2_dpy->output.in_formats_id, + dri2_null_formats[format_idx].drm_format, + &dri2_dpy->output.modifiers); +@@ -1564,7 +1565,7 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config, + goto err_destroy_surface; + } + +- err = display_output_modeset(dri2_dpy->fd, &dri2_dpy->output, ++ err = display_output_modeset(dri2_dpy->fd_dpy, &dri2_dpy->output, + dri2_surf->front_buffer.fb_id); + if (err) { + _eglError(EGL_BAD_NATIVE_WINDOW, "window set mode"); +@@ -1678,11 +1679,11 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) + dri2_dpy->image->destroyImage(dri2_surf->front_buffer.dri_image); + + if (dri2_surf->front_buffer.fb_id) +- drmModeRmFB(dri2_dpy->fd, dri2_surf->front_buffer.fb_id); ++ drmModeRmFB(dri2_dpy->fd_dpy, dri2_surf->front_buffer.fb_id); + + for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + if (dri2_surf->color_buffers[i].fb_id) +- drmModeRmFB(dri2_dpy->fd, dri2_surf->color_buffers[i].fb_id); ++ drmModeRmFB(dri2_dpy->fd_dpy, dri2_surf->color_buffers[i].fb_id); + if (dri2_surf->color_buffers[i].dri_image) + dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image); + } +@@ -1839,12 +1840,22 @@ dri2_null_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) + (void) loaderPrivate; + } + ++static int ++dri2_null_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 __DRIimageLoaderExtension image_loader_extension = { +- .base = { __DRI_IMAGE_LOADER, 2 }, ++ .base = { __DRI_IMAGE_LOADER, 5 }, + + .getBuffers = dri2_null_image_get_buffers, + .flushFrontBuffer = dri2_null_flush_front_buffer, + .getCapability = dri2_null_get_capability, ++ .getDisplayFD = dri2_null_get_display_fd, + }; + + static const __DRIextension *image_loader_extensions[] = { +@@ -1873,12 +1884,74 @@ dri2_null_device_is_kms(int fd) + return is_kms; + } + ++static bool ++dri2_null_try_device(_EGLDisplay *disp) ++{ ++ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); ++ ++ if (!dri2_null_device_is_kms(dri2_dpy->fd_dpy)) ++ return false; ++ ++#if defined(NULL_DRI_DRIVER_NAME) ++ /* Skip devices not handled by NULL_DRI_DRIVER_NAME */ ++ { ++ char *driver_name = loader_get_driver_for_fd(dri2_dpy->fd_dpy); ++ bool skip = !driver_name || !!strcmp(driver_name, NULL_DRI_DRIVER_NAME); ++ ++ free(driver_name); ++ ++ if (skip) ++ return false; ++ } ++#endif ++ ++ dri2_dpy->fd = os_dupfd_cloexec(dri2_dpy->fd_dpy); ++ if (dri2_dpy->fd < 0) { ++ _eglLog(_EGL_WARNING, "DRI2: failed to dup display FD"); ++ dri2_dpy->fd = dri2_dpy->fd_dpy; ++ } else { ++ int fd_old; ++ bool is_different_gpu; ++ ++ fd_old = dri2_dpy->fd; ++ dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd, ++ &is_different_gpu); ++ if (dri2_dpy->fd == fd_old) { ++ close (dri2_dpy->fd); ++ dri2_dpy->fd = dri2_dpy->fd_dpy; ++ } ++ } ++ ++ dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd); ++ if (!dri2_dpy->driver_name) ++ return false; ++ ++ if (dri2_load_driver_dri3(disp)) { ++ _EGLDevice *dev = _eglAddDevice(dri2_dpy->fd, false); ++ if (!dev) { ++ dlclose(dri2_dpy->driver); ++ _eglLog(_EGL_WARNING, "DRI2: failed to find EGLDevice"); ++ } else { ++ dri2_dpy->loader_extensions = image_loader_extensions; ++ dri2_dpy->own_device = 1; ++ disp->Device = dev; ++ return true; ++ } ++ } ++ ++ free(dri2_dpy->driver_name); ++ dri2_dpy->driver_name = NULL; ++ ++ return false; ++} ++ + static bool + dri2_null_probe_device(_EGLDisplay *disp) + { + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + + dri2_dpy->fd = -1; ++ dri2_dpy->fd_dpy = -1; + + for (unsigned i = 0; i <= NULL_CARD_MINOR_MAX; i++) { + char *card_path; +@@ -1886,32 +1959,20 @@ dri2_null_probe_device(_EGLDisplay *disp) + if (asprintf(&card_path, DRM_DEV_NAME, DRM_DIR_NAME, i) < 0) + continue; + +- dri2_dpy->fd = loader_open_device(card_path); ++ dri2_dpy->fd_dpy = loader_open_device(card_path); + free(card_path); +- if (dri2_dpy->fd < 0) ++ if (dri2_dpy->fd_dpy < 0) + continue; + +- if (dri2_null_device_is_kms(dri2_dpy->fd)) { +- dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd); +- if (dri2_dpy->driver_name) { +- if (dri2_load_driver_dri3(disp)) { +- _EGLDevice *dev = _eglAddDevice(dri2_dpy->fd, false); +- if (!dev) { +- dlclose(dri2_dpy->driver); +- _eglLog(_EGL_WARNING, "DRI2: failed to find EGLDevice"); +- } else { +- dri2_dpy->loader_extensions = image_loader_extensions; +- dri2_dpy->own_device = 1; +- disp->Device = dev; +- return true; +- } +- } +- free(dri2_dpy->driver_name); +- dri2_dpy->driver_name = NULL; +- } +- } ++ if (dri2_null_try_device(disp)) ++ return true; ++ ++ close(dri2_dpy->fd_dpy); ++ ++ if (dri2_dpy->fd >= 0 && dri2_dpy->fd != dri2_dpy->fd_dpy) ++ close(dri2_dpy->fd); + +- close(dri2_dpy->fd); ++ dri2_dpy->fd_dpy = -1; + dri2_dpy->fd = -1; + } + +@@ -1972,7 +2033,7 @@ dri2_null_setup_swap_interval(_EGLDisplay *disp) + + dri2_setup_swap_interval(disp, swap_max_interval); + +- err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value); ++ err = drmGetCap(dri2_dpy->fd_dpy, DRM_CAP_ASYNC_PAGE_FLIP, &value); + if (err || value == 0) { + + /* DRM/KMS does not support async page flip. In order to support +@@ -2020,7 +2081,7 @@ dri2_initialize_null(_EGLDisplay *disp) + * modesetting if not. If this succeeds then universal planes will also have + * been enabled. + */ +- err = drmSetClientCap(dri2_dpy->fd, DRM_CLIENT_CAP_ATOMIC, 1); ++ err = drmSetClientCap(dri2_dpy->fd_dpy, DRM_CLIENT_CAP_ATOMIC, 1); + dri2_dpy->atomic_enabled = !err; + + if (!dri2_dpy->atomic_enabled) { +@@ -2028,7 +2089,7 @@ dri2_initialize_null(_EGLDisplay *disp) + * Enable universal planes so that we can get the pixel formats for the + * primary plane + */ +- err = drmSetClientCap(dri2_dpy->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); ++ err = drmSetClientCap(dri2_dpy->fd_dpy, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); + if (err) { + _eglError(EGL_NOT_INITIALIZED, "failed to enable universal planes"); + goto cleanup; +@@ -2064,7 +2125,7 @@ dri2_initialize_null(_EGLDisplay *disp) + dri2_dpy->image->createImageWithModifiers; + } + +- if (!display_output_init(dri2_dpy->fd, &dri2_dpy->output, ++ if (!display_output_init(dri2_dpy->fd_dpy, &dri2_dpy->output, + dri2_dpy->atomic_enabled, + prefer_in_formats, + &dri2_dpy->in_formats_enabled)) { +@@ -2098,7 +2159,7 @@ dri2_teardown_null(struct dri2_egl_display *dri2_dpy) + drmModeAtomicFree(dri2_dpy->output.atomic_state); + + if (dri2_dpy->output.mode_blob_id) +- drmModeDestroyPropertyBlob(dri2_dpy->fd, dri2_dpy->output.mode_blob_id); ++ drmModeDestroyPropertyBlob(dri2_dpy->fd_dpy, dri2_dpy->output.mode_blob_id); + + if (dri2_dpy->output.plane_prop_res) { + for (unsigned i = 0; dri2_dpy->output.plane_prop_res[i]; i++) +diff --git a/src/egl/meson.build b/src/egl/meson.build +index b20d85dc19f..88514d7dcb2 100644 +--- a/src/egl/meson.build ++++ b/src/egl/meson.build +@@ -153,6 +153,11 @@ elif with_platform_windows + 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 +-- +2.17.1 + diff --git a/package/mesa3d/0045-egl-null-introduce-NULL_DRM_DISPLAY.patch b/package/mesa3d/0045-egl-null-introduce-NULL_DRM_DISPLAY.patch new file mode 100644 index 00000000..a962d660 --- /dev/null +++ b/package/mesa3d/0045-egl-null-introduce-NULL_DRM_DISPLAY.patch @@ -0,0 +1,120 @@ +From 5ff6d94aeff451aea33268fc13e605981515e605 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 28 Jun 2021 16:36:15 +0100 +Subject: [PATCH 045/168] egl/null: introduce NULL_DRM_DISPLAY + +Introduce the NULL_DRM_DISPLAY environment variable, which allows +a particular DRM display to be selected, rather than the first +suitable DRM device found. + +To select a particular display, NULL_DRM_DISPLAY should be set to +the card number (i.e. minor number) of the DRM device representing +the display. For example, NULL_DRM_DISPLAY=2 will select +/dev/dri/card2. +--- + src/egl/drivers/dri2/platform_null.c | 65 ++++++++++++++++++++-------- + 1 file changed, 46 insertions(+), 19 deletions(-) + +diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c +index e2a138367f9..7e631e0b61d 100644 +--- a/src/egl/drivers/dri2/platform_null.c ++++ b/src/egl/drivers/dri2/platform_null.c +@@ -1889,6 +1889,8 @@ dri2_null_try_device(_EGLDisplay *disp) + { + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + ++ dri2_dpy->fd = -1; ++ + if (!dri2_null_device_is_kms(dri2_dpy->fd_dpy)) + return false; + +@@ -1946,34 +1948,56 @@ dri2_null_try_device(_EGLDisplay *disp) + } + + static bool +-dri2_null_probe_device(_EGLDisplay *disp) ++dri2_null_probe_device(_EGLDisplay *disp, unsigned minor) + { + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); ++ char *card_path; + +- dri2_dpy->fd = -1; +- dri2_dpy->fd_dpy = -1; ++ if (asprintf(&card_path, DRM_DEV_NAME, DRM_DIR_NAME, minor) < 0) ++ goto cleanup; + +- for (unsigned i = 0; i <= NULL_CARD_MINOR_MAX; i++) { +- char *card_path; ++ dri2_dpy->fd_dpy = loader_open_device(card_path); ++ free(card_path); ++ if (dri2_dpy->fd_dpy < 0) ++ goto cleanup; + +- if (asprintf(&card_path, DRM_DEV_NAME, DRM_DIR_NAME, i) < 0) +- continue; ++ if (dri2_null_try_device(disp)) ++ return true; + +- dri2_dpy->fd_dpy = loader_open_device(card_path); +- free(card_path); +- if (dri2_dpy->fd_dpy < 0) +- continue; ++ close(dri2_dpy->fd_dpy); + +- if (dri2_null_try_device(disp)) +- return true; ++ if (dri2_dpy->fd >= 0 && dri2_dpy->fd != dri2_dpy->fd_dpy) ++ close(dri2_dpy->fd); + +- close(dri2_dpy->fd_dpy); ++cleanup: ++ dri2_dpy->fd_dpy = -1; ++ dri2_dpy->fd = -1; + +- if (dri2_dpy->fd >= 0 && dri2_dpy->fd != dri2_dpy->fd_dpy) +- close(dri2_dpy->fd); ++ return false; ++} ++ ++static bool ++dri2_null_probe_devices(_EGLDisplay *disp) ++{ ++ const char *null_drm_display = getenv("NULL_DRM_DISPLAY"); ++ ++ if (null_drm_display) { ++ char *endptr; ++ long val = strtol(null_drm_display, &endptr, 10); + +- dri2_dpy->fd_dpy = -1; +- dri2_dpy->fd = -1; ++ if (endptr != null_drm_display && !*endptr && ++ val >= 0 && val <= NULL_CARD_MINOR_MAX) { ++ if (dri2_null_probe_device(disp, (unsigned)val)) ++ return true; ++ } else { ++ _eglLog(_EGL_FATAL, "NULL_DRM_DISPLAY is invalid: %s", ++ null_drm_display); ++ } ++ } else { ++ for (unsigned i = 0; i <= NULL_CARD_MINOR_MAX; i++) { ++ if (dri2_null_probe_device(disp, i)) ++ return true; ++ } + } + + return false; +@@ -2071,7 +2095,10 @@ dri2_initialize_null(_EGLDisplay *disp) + + disp->DriverData = (void *) dri2_dpy; + +- if (!dri2_null_probe_device(disp)) { ++ dri2_dpy->fd_dpy = -1; ++ dri2_dpy->fd = -1; ++ ++ if (!dri2_null_probe_devices(disp)) { + _eglError(EGL_NOT_INITIALIZED, "failed to load driver"); + goto cleanup; + } +-- +2.17.1 + diff --git a/package/mesa3d/0046-vulkan-wsi-check-the-DRI3-and-Present-XCB-reply-poin.patch b/package/mesa3d/0046-vulkan-wsi-check-the-DRI3-and-Present-XCB-reply-poin.patch new file mode 100644 index 00000000..80fac5f9 --- /dev/null +++ b/package/mesa3d/0046-vulkan-wsi-check-the-DRI3-and-Present-XCB-reply-poin.patch @@ -0,0 +1,28 @@ +From 6189dd1b7120792a131dd214f9383540aafbb45b Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 21 Jun 2021 17:05:17 +0100 +Subject: [PATCH 046/168] vulkan/wsi: check the DRI3 and Present XCB reply + pointers + +Check that the DRI3 and Present version replies are not NULL +before accessing the version fields. +--- + src/vulkan/wsi/wsi_common_x11.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c +index a3c4538366f..535b6d10e0b 100644 +--- a/src/vulkan/wsi/wsi_common_x11.c ++++ b/src/vulkan/wsi/wsi_common_x11.c +@@ -285,7 +285,7 @@ wsi_x11_connection_create(struct wsi_device *wsi_dev, + + ver_cookie = xcb_present_query_version(conn, 1, 2); + ver_reply = xcb_present_query_version_reply(conn, ver_cookie, NULL); +- has_present_v1_2 = ++ has_present_v1_2 = ver_reply != NULL && + (ver_reply->major_version > 1 || ver_reply->minor_version >= 2); + free(ver_reply); + } +-- +2.17.1 + diff --git a/package/mesa3d/0047-vulkan-wsi-make-the-display-FD-available.patch b/package/mesa3d/0047-vulkan-wsi-make-the-display-FD-available.patch new file mode 100644 index 00000000..e73a1723 --- /dev/null +++ b/package/mesa3d/0047-vulkan-wsi-make-the-display-FD-available.patch @@ -0,0 +1,757 @@ +From 4259a670e2c28a13cbc56f6f747156ebcfa0582b Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 17 Jun 2021 17:17:07 +0100 +Subject: [PATCH 047/168] vulkan/wsi: make the display FD available + +Pass the display FD to the Vulkan image create and memory +allocation functions when allocating swapchain images. + +The wl_drm interface code has been partially restored, in order +to obtain the display FD from the compositor. +--- + src/vulkan/wsi/meson.build | 2 + + src/vulkan/wsi/wsi_common.c | 41 +++++++-- + src/vulkan/wsi/wsi_common.h | 14 +++ + src/vulkan/wsi/wsi_common_display.c | 4 +- + src/vulkan/wsi/wsi_common_drm.c | 23 ++++- + src/vulkan/wsi/wsi_common_private.h | 12 ++- + src/vulkan/wsi/wsi_common_wayland.c | 134 +++++++++++++++++++++++++--- + src/vulkan/wsi/wsi_common_win32.c | 4 +- + src/vulkan/wsi/wsi_common_x11.c | 26 +++++- + 9 files changed, 229 insertions(+), 31 deletions(-) + +diff --git a/src/vulkan/wsi/meson.build b/src/vulkan/wsi/meson.build +index a92c7f3e5eb..68d53d51a04 100644 +--- a/src/vulkan/wsi/meson.build ++++ b/src/vulkan/wsi/meson.build +@@ -31,6 +31,8 @@ endif + if with_platform_wayland + files_vulkan_wsi += files('wsi_common_wayland.c') + files_vulkan_wsi += [ ++ wayland_drm_client_protocol_h, ++ wayland_drm_protocol_c, + linux_dmabuf_unstable_v1_client_protocol_h, + linux_dmabuf_unstable_v1_protocol_c, + ] +diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c +index b2974fad7ce..6ca7c767b26 100644 +--- a/src/vulkan/wsi/wsi_common.c ++++ b/src/vulkan/wsi/wsi_common.c +@@ -305,6 +305,7 @@ static VkResult + configure_image(const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const struct wsi_base_image_params *params, ++ UNUSED int display_fd, + struct wsi_image_info *info) + { + switch (params->image_type) { +@@ -317,7 +318,8 @@ configure_image(const struct wsi_swapchain *chain, + case WSI_IMAGE_TYPE_DRM: { + const struct wsi_drm_image_params *drm_params = + container_of(params, const struct wsi_drm_image_params, base); +- return wsi_drm_configure_image(chain, pCreateInfo, drm_params, info); ++ return wsi_drm_configure_image(chain, pCreateInfo, drm_params, ++ display_fd, info); + } + #endif + default: +@@ -331,7 +333,8 @@ wsi_swapchain_init(const struct wsi_device *wsi, + VkDevice _device, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const struct wsi_base_image_params *image_params, +- const VkAllocationCallbacks *pAllocator) ++ const VkAllocationCallbacks *pAllocator, ++ int display_fd) + { + VK_FROM_HANDLE(vk_device, device, _device); + VkResult result; +@@ -377,7 +380,7 @@ wsi_swapchain_init(const struct wsi_device *wsi, + } + + result = configure_image(chain, pCreateInfo, image_params, +- &chain->image_info); ++ display_fd, &chain->image_info); + if (result != VK_SUCCESS) + goto fail; + +@@ -476,6 +479,7 @@ VkResult + wsi_configure_image(const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + VkExternalMemoryHandleTypeFlags handle_types, ++ int display_fd, + struct wsi_image_info *info) + { + memset(info, 0, sizeof(*info)); +@@ -534,6 +538,12 @@ wsi_configure_image(const struct wsi_swapchain *chain, + }; + __vk_append_struct(&info->create, &info->wsi); + ++ info->wsi2 = (struct wsi_image_create_info2) { ++ .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO2_MESA, ++ .display_fd = display_fd, ++ }; ++ __vk_append_struct(&info->create, &info->wsi2); ++ + if (pCreateInfo->flags & VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR) { + info->create.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | + VK_IMAGE_CREATE_EXTENDED_USAGE_BIT; +@@ -599,6 +609,7 @@ wsi_destroy_image_info(const struct wsi_swapchain *chain, + VkResult + wsi_create_image(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, ++ int display_fd, + struct wsi_image *image) + { + const struct wsi_device *wsi = chain->wsi; +@@ -615,7 +626,7 @@ wsi_create_image(const struct wsi_swapchain *chain, + if (result != VK_SUCCESS) + goto fail; + +- result = info->create_mem(chain, info, image); ++ result = info->create_mem(chain, info, display_fd, image); + if (result != VK_SUCCESS) + goto fail; + +@@ -1420,7 +1431,8 @@ wsi_create_buffer_image_mem(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, + struct wsi_image *image, + VkExternalMemoryHandleTypeFlags handle_types, +- bool implicit_sync) ++ bool implicit_sync, ++ int display_fd) + { + const struct wsi_device *wsi = chain->wsi; + VkResult result; +@@ -1484,6 +1496,13 @@ wsi_create_buffer_image_mem(const struct wsi_swapchain *chain, + .handleTypes = handle_types, + }; + __vk_append_struct(&buf_mem_info, &memory_export_info); ++ ++ struct wsi_memory_allocate_info2 memory_wsi_info2 = { ++ .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO2_MESA, ++ .pNext = &memory_wsi_info, ++ .display_fd = display_fd, ++ }; ++ __vk_append_struct(&buf_mem_info, &memory_wsi_info2); + } + + result = wsi->AllocateMemory(chain->device, &buf_mem_info, +@@ -1630,6 +1649,7 @@ VkResult + wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + uint32_t stride_align, uint32_t size_align, ++ int display_fd, + struct wsi_image_info *info) + { + const struct wsi_device *wsi = chain->wsi; +@@ -1638,7 +1658,8 @@ wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain, + assert(util_is_power_of_two_nonzero(size_align)); + + VkResult result = wsi_configure_image(chain, pCreateInfo, +- 0 /* handle_types */, info); ++ 0 /* handle_types */, ++ display_fd, info); + if (result != VK_SUCCESS) + return result; + +@@ -1667,6 +1688,7 @@ wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain, + static VkResult + wsi_create_cpu_linear_image_mem(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, ++ int display_fd, + struct wsi_image *image) + { + const struct wsi_device *wsi = chain->wsi; +@@ -1732,12 +1754,14 @@ wsi_create_cpu_linear_image_mem(const struct wsi_swapchain *chain, + static VkResult + wsi_create_cpu_buffer_image_mem(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, ++ int display_fd, + struct wsi_image *image) + { + VkResult result; + + result = wsi_create_buffer_image_mem(chain, info, image, 0, +- false /* implicit_sync */); ++ false /* implicit_sync */, ++ display_fd); + if (result != VK_SUCCESS) + return result; + +@@ -1778,6 +1802,7 @@ wsi_configure_cpu_image(const struct wsi_swapchain *chain, + VkResult result = wsi_configure_buffer_image(chain, pCreateInfo, + 1 /* stride_align */, + 1 /* size_align */, ++ -1, + info); + if (result != VK_SUCCESS) + return result; +@@ -1787,7 +1812,7 @@ wsi_configure_cpu_image(const struct wsi_swapchain *chain, + info->create_mem = wsi_create_cpu_buffer_image_mem; + } else { + VkResult result = wsi_configure_image(chain, pCreateInfo, +- handle_types, info); ++ handle_types, -1, info); + if (result != VK_SUCCESS) + return result; + +diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h +index 886bac9f800..c8b52339843 100644 +--- a/src/vulkan/wsi/wsi_common.h ++++ b/src/vulkan/wsi/wsi_common.h +@@ -50,6 +50,8 @@ extern const struct vk_device_entrypoint_table wsi_device_entrypoints; + #define VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA (VkStructureType)1000001003 + #define VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA (VkStructureType)1000001005 + #define VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA (VkStructureType)1000001006 ++#define VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO2_MESA (VkStructureType)1000001007 ++#define VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO2_MESA (VkStructureType)1000001008 + + /* This is always chained to VkImageCreateInfo when a wsi image is created. + * It indicates that the image can be transitioned to/from +@@ -86,6 +88,18 @@ struct wsi_memory_signal_submit_info { + VkDeviceMemory memory; + }; + ++struct wsi_image_create_info2 { ++ VkStructureType sType; ++ const void *pNext; ++ int display_fd; ++}; ++ ++struct wsi_memory_allocate_info2 { ++ VkStructureType sType; ++ const void *pNext; ++ int display_fd; ++}; ++ + struct wsi_interface; + + struct driOptionCache; +diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c +index 0e5d27278b1..b9e6f18c8ba 100644 +--- a/src/vulkan/wsi/wsi_common_display.c ++++ b/src/vulkan/wsi/wsi_common_display.c +@@ -1097,7 +1097,7 @@ wsi_display_image_init(VkDevice device_h, + return VK_ERROR_DEVICE_LOST; + + VkResult result = wsi_create_image(&chain->base, &chain->base.image_info, +- &image->base); ++ wsi->fd, &image->base); + if (result != VK_SUCCESS) + return result; + +@@ -1957,7 +1957,7 @@ wsi_display_surface_create_swapchain( + + VkResult result = wsi_swapchain_init(wsi_device, &chain->base, device, + create_info, &image_params.base, +- allocator); ++ allocator, wsi->fd); + if (result != VK_SUCCESS) { + vk_free(allocator, chain); + return result; +diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c +index 728e45152c5..a94be2aeb42 100644 +--- a/src/vulkan/wsi/wsi_common_drm.c ++++ b/src/vulkan/wsi/wsi_common_drm.c +@@ -315,6 +315,7 @@ get_modifier_props(const struct wsi_image_info *info, uint64_t modifier) + static VkResult + wsi_create_native_image_mem(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, ++ int display_fd, + struct wsi_image *image); + + static VkResult +@@ -323,6 +324,7 @@ wsi_configure_native_image(const struct wsi_swapchain *chain, + uint32_t num_modifier_lists, + const uint32_t *num_modifiers, + const uint64_t *const *modifiers, ++ int display_fd, + struct wsi_image_info *info) + { + const struct wsi_device *wsi = chain->wsi; +@@ -330,7 +332,8 @@ wsi_configure_native_image(const struct wsi_swapchain *chain, + VkExternalMemoryHandleTypeFlags handle_type = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; + +- VkResult result = wsi_configure_image(chain, pCreateInfo, handle_type, info); ++ VkResult result = wsi_configure_image(chain, pCreateInfo, handle_type, ++ display_fd, info); + if (result != VK_SUCCESS) + return result; + +@@ -467,6 +470,7 @@ fail_oom: + static VkResult + wsi_create_native_image_mem(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, ++ int display_fd, + struct wsi_image *image) + { + const struct wsi_device *wsi = chain->wsi; +@@ -480,9 +484,14 @@ wsi_create_native_image_mem(const struct wsi_swapchain *chain, + .pNext = NULL, + .implicit_sync = true, + }; ++ const struct wsi_memory_allocate_info2 memory_wsi_info2 = { ++ .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO2_MESA, ++ .pNext = &memory_wsi_info, ++ .display_fd = display_fd, ++ }; + const VkExportMemoryAllocateInfo memory_export_info = { + .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, +- .pNext = &memory_wsi_info, ++ .pNext = &memory_wsi_info2, + .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + }; + const VkMemoryDedicatedAllocateInfo memory_dedicated_info = { +@@ -570,13 +579,14 @@ wsi_create_native_image_mem(const struct wsi_swapchain *chain, + static VkResult + wsi_create_prime_image_mem(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, ++ int display_fd, + struct wsi_image *image) + { + const struct wsi_device *wsi = chain->wsi; + VkResult result = + wsi_create_buffer_image_mem(chain, info, image, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, +- true); ++ true, display_fd); + if (result != VK_SUCCESS) + return result; + +@@ -602,11 +612,13 @@ wsi_configure_prime_image(UNUSED const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + bool use_modifier, + wsi_memory_type_select_cb select_buffer_memory_type, ++ int display_fd, + struct wsi_image_info *info) + { + VkResult result = + wsi_configure_buffer_image(chain, pCreateInfo, + WSI_PRIME_LINEAR_STRIDE_ALIGN, 4096, ++ display_fd, + info); + if (result != VK_SUCCESS) + return result; +@@ -637,6 +649,7 @@ VkResult + wsi_drm_configure_image(const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const struct wsi_drm_image_params *params, ++ int display_fd, + struct wsi_image_info *info) + { + assert(params->base.image_type == WSI_IMAGE_TYPE_DRM); +@@ -647,12 +660,14 @@ wsi_drm_configure_image(const struct wsi_swapchain *chain, + params->same_gpu ? wsi_select_device_memory_type : + prime_select_buffer_memory_type; + return wsi_configure_prime_image(chain, pCreateInfo, use_modifier, +- select_buffer_memory_type, info); ++ select_buffer_memory_type, ++ display_fd, info); + } else { + return wsi_configure_native_image(chain, pCreateInfo, + params->num_modifier_lists, + params->num_modifiers, + params->modifiers, ++ display_fd, + info); + } + } +diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h +index fe3e85556b8..868fdf968e4 100644 +--- a/src/vulkan/wsi/wsi_common_private.h ++++ b/src/vulkan/wsi/wsi_common_private.h +@@ -69,6 +69,7 @@ typedef uint32_t (*wsi_memory_type_select_cb)(const struct wsi_device *wsi, + struct wsi_image_info { + VkImageCreateInfo create; + struct wsi_image_create_info wsi; ++ struct wsi_image_create_info2 wsi2; + VkExternalMemoryImageCreateInfo ext_mem; + VkImageFormatListCreateInfo format_list; + VkImageDrmFormatModifierListCreateInfoEXT drm_mod_list; +@@ -94,6 +95,7 @@ struct wsi_image_info { + + VkResult (*create_mem)(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, ++ int display_fd, + struct wsi_image *image); + + VkResult (*finish_create)(const struct wsi_swapchain *chain, +@@ -178,7 +180,8 @@ wsi_swapchain_init(const struct wsi_device *wsi, + VkDevice device, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const struct wsi_base_image_params *image_params, +- const VkAllocationCallbacks *pAllocator); ++ const VkAllocationCallbacks *pAllocator, ++ int display_fd); + + enum VkPresentModeKHR + wsi_swapchain_get_present_mode(struct wsi_device *wsi, +@@ -203,6 +206,7 @@ VkResult + wsi_drm_configure_image(const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const struct wsi_drm_image_params *params, ++ int display_fd, + struct wsi_image_info *info); + + bool +@@ -220,7 +224,8 @@ wsi_create_buffer_image_mem(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, + struct wsi_image *image, + VkExternalMemoryHandleTypeFlags handle_types, +- bool implicit_sync); ++ bool implicit_sync, ++ int display_fd); + + VkResult + wsi_finish_create_buffer_image(const struct wsi_swapchain *chain, +@@ -231,12 +236,14 @@ VkResult + wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + uint32_t stride_align, uint32_t size_align, ++ int display_fd, + struct wsi_image_info *info); + + VkResult + wsi_configure_image(const struct wsi_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + VkExternalMemoryHandleTypeFlags handle_types, ++ int display_fd, + struct wsi_image_info *info); + void + wsi_destroy_image_info(const struct wsi_swapchain *chain, +@@ -244,6 +251,7 @@ wsi_destroy_image_info(const struct wsi_swapchain *chain, + VkResult + wsi_create_image(const struct wsi_swapchain *chain, + const struct wsi_image_info *info, ++ int display_fd, + struct wsi_image *image); + void + wsi_image_init(struct wsi_image *image); +diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c +index 70b00429972..b1e5ea8bdfd 100644 +--- a/src/vulkan/wsi/wsi_common_wayland.c ++++ b/src/vulkan/wsi/wsi_common_wayland.c +@@ -33,6 +33,8 @@ + #include + #include + #include ++#include ++#include + + #include "drm-uapi/drm_fourcc.h" + +@@ -95,6 +97,7 @@ struct wsi_wl_display { + struct wl_event_queue *queue; + + struct wl_shm *wl_shm; ++ struct wl_drm *wl_drm; + struct zwp_linux_dmabuf_v1 *wl_dmabuf; + struct zwp_linux_dmabuf_feedback_v1 *wl_dmabuf_feedback; + +@@ -104,6 +107,8 @@ struct wsi_wl_display { + + /* Formats populated by zwp_linux_dmabuf_v1 or wl_shm interfaces */ + struct u_vector formats; ++ int fd; ++ bool authenticated; + + bool sw; + +@@ -530,6 +535,79 @@ wl_shm_format_for_vk_format(VkFormat vk_format, bool alpha) + } + } + ++static int ++open_display_device(const char *name) ++{ ++ int fd; ++ ++#ifdef O_CLOEXEC ++ fd = open(name, O_RDWR | O_CLOEXEC); ++ if (fd != -1 || errno != EINVAL) { ++ return fd; ++ } ++#endif ++ ++ fd = open(name, O_RDWR); ++ if (fd != -1) { ++ long flags = fcntl(fd, F_GETFD); ++ ++ if (flags != -1) { ++ if (!fcntl(fd, F_SETFD, flags | FD_CLOEXEC)) ++ return fd; ++ } ++ close (fd); ++ } ++ ++ return -1; ++} ++ ++static void ++drm_handle_device(void *data, struct wl_drm *drm, const char *name) ++{ ++ struct wsi_wl_display *display = data; ++ const int fd = open_display_device(name); ++ ++ if (fd != -1) { ++ if (drmGetNodeTypeFromFd(fd) != DRM_NODE_RENDER) { ++ drm_magic_t magic; ++ ++ if (drmGetMagic(fd, &magic)) { ++ close(fd); ++ return; ++ } ++ wl_drm_authenticate(drm, magic); ++ } else { ++ display->authenticated = true; ++ } ++ display->fd = fd; ++ } ++} ++ ++static void ++drm_handle_format(void *data, struct wl_drm *drm, uint32_t wl_format) ++{ ++} ++ ++static void ++drm_handle_authenticated(void *data, struct wl_drm *drm) ++{ ++ struct wsi_wl_display *display = data; ++ ++ display->authenticated = true; ++} ++ ++static void ++drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t capabilities) ++{ ++} ++ ++static const struct wl_drm_listener drm_listener = { ++ drm_handle_device, ++ drm_handle_format, ++ drm_handle_authenticated, ++ drm_handle_capabilities, ++}; ++ + static void + dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf, + uint32_t format) +@@ -741,6 +819,15 @@ registry_handle_global(void *data, struct wl_registry *registry, + return; + } + ++ if (strcmp(interface, "wl_drm") == 0) { ++ assert(display->wl_drm == NULL); ++ assert(version >= 2); ++ ++ display->wl_drm = ++ wl_registry_bind(registry, name, &wl_drm_interface, 2); ++ wl_drm_add_listener(display->drm.wl_drm, &drm_listener, display); ++ } ++ + if (strcmp(interface, zwp_linux_dmabuf_v1_interface.name) == 0 && version >= 3) { + display->wl_dmabuf = + wl_registry_bind(registry, name, &zwp_linux_dmabuf_v1_interface, +@@ -769,12 +856,17 @@ wsi_wl_display_finish(struct wsi_wl_display *display) + u_vector_finish(&display->formats); + if (display->wl_shm) + wl_shm_destroy(display->wl_shm); ++ if (display->wl_drm) ++ wl_drm_destroy(display->wl_drm); + if (display->wl_dmabuf) + zwp_linux_dmabuf_v1_destroy(display->wl_dmabuf); + if (display->wl_display_wrapper) + wl_proxy_wrapper_destroy(display->wl_display_wrapper); + if (display->queue) + wl_event_queue_destroy(display->queue); ++ ++ if (display->fd != -1) ++ close(display->fd); + } + + static VkResult +@@ -792,6 +884,7 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl, + display->wsi_wl = wsi_wl; + display->wl_display = wl_display; + display->sw = sw; ++ display->fd = -1; + + display->queue = wl_display_create_queue(wl_display); + if (!display->queue) { +@@ -817,17 +910,13 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl, + + wl_registry_add_listener(registry, ®istry_listener, display); + +- /* Round-trip to get wl_shm and zwp_linux_dmabuf_v1 globals */ ++ /* Round-trip to get wl_shm, wl_drm and zwp_linux_dmabuf_v1 globals */ + wl_display_roundtrip_queue(display->wl_display, display->queue); + if (!display->wl_dmabuf && !display->wl_shm) { + result = VK_ERROR_SURFACE_LOST_KHR; + goto fail_registry; + } + +- /* Caller doesn't expect us to query formats/modifiers, so return */ +- if (!get_format_list) +- goto out; +- + /* Default assumption */ + display->same_gpu = true; + +@@ -858,14 +947,38 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl, + } + } + +- /* Round-trip again to get formats and modifiers */ +- wl_display_roundtrip_queue(display->wl_display, display->queue); ++ if (display->wl_dmabuf && !display->wl_drm) { ++ result = VK_ERROR_SURFACE_LOST_KHR; ++ goto fail_registry; ++ } ++ ++ /* Round-trip to get display FD, formats and modifiers */ ++ if (display->wl_drm || get_format_list) ++ wl_display_roundtrip_queue(display->wl_display, display->queue); ++ ++ if (display->wl_drm && display->fd == -1) { ++ result = VK_ERROR_SURFACE_LOST_KHR; ++ goto fail_registry; ++ } ++ ++ if (display->wl_drm) { ++ wl_display_roundtrip_queue(display->wl_display, display->queue); ++ ++ if (!display->authenticated) { ++ result = VK_ERROR_SURFACE_LOST_KHR; ++ goto fail_registry; ++ } ++ } ++ ++ /* Caller doesn't expect us to query formats/modifiers, so return */ ++ if (!get_format_list) ++ goto out; + + if (wsi_wl->wsi->force_bgra8_unorm_first) { + /* Find BGRA8_UNORM in the list and swap it to the first position if we + * can find it. Some apps get confused if SRGB is first in the list. + */ +- struct wsi_wl_format *first_fmt = u_vector_head(&display->formats); ++ struct wsi_wl_format *first_fmt = u_vector_tail(&display->formats); + struct wsi_wl_format *f, tmp_fmt; + f = find_format(&display->formats, VK_FORMAT_B8G8R8A8_UNORM); + if (f) { +@@ -1648,7 +1761,7 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, + VkResult result; + + result = wsi_create_image(&chain->base, &chain->base.image_info, +- &image->base); ++ display->fd, &image->base); + if (result != VK_SUCCESS) + return result; + +@@ -1857,7 +1970,8 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, + } + + result = wsi_swapchain_init(wsi_device, &chain->base, device, +- pCreateInfo, image_params, pAllocator); ++ pCreateInfo, image_params, pAllocator, ++ chain->wsi_wl_surface->display->fd); + if (result != VK_SUCCESS) { + vk_free(pAllocator, chain); + return result; +diff --git a/src/vulkan/wsi/wsi_common_win32.c b/src/vulkan/wsi/wsi_common_win32.c +index bef81028bde..7d16144f3ed 100644 +--- a/src/vulkan/wsi/wsi_common_win32.c ++++ b/src/vulkan/wsi/wsi_common_win32.c +@@ -310,7 +310,7 @@ wsi_win32_image_init(VkDevice device_h, + { + assert(chain->base.use_buffer_blit); + VkResult result = wsi_create_image(&chain->base, &chain->base.image_info, +- &image->base); ++ -1, &image->base); + if (result != VK_SUCCESS) + return result; + +@@ -454,7 +454,7 @@ wsi_win32_surface_create_swapchain( + + VkResult result = wsi_swapchain_init(wsi_device, &chain->base, device, + create_info, &image_params.base, +- allocator); ++ allocator, -1); + if (result != VK_SUCCESS) { + vk_free(allocator, chain); + return result; +diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c +index 535b6d10e0b..2a988b6d2a8 100644 +--- a/src/vulkan/wsi/wsi_common_x11.c ++++ b/src/vulkan/wsi/wsi_common_x11.c +@@ -1660,6 +1660,7 @@ static VkResult + x11_image_init(VkDevice device_h, struct x11_swapchain *chain, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks* pAllocator, ++ int display_fd, + struct x11_image *image) + { + xcb_void_cookie_t cookie; +@@ -1668,7 +1669,7 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, + int fence_fd; + + result = wsi_create_image(&chain->base, &chain->base.image_info, +- &image->base); ++ display_fd, &image->base); + if (result != VK_SUCCESS) + return result; + +@@ -2048,8 +2049,19 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, + image_params = &drm_image_params.base; + } + ++ int display_fd; ++ if (wsi_device->sw) { ++ display_fd = -1; ++ } else { ++ xcb_screen_iterator_t screen_iter = ++ xcb_setup_roots_iterator(xcb_get_setup(conn)); ++ xcb_screen_t *screen = screen_iter.data; ++ ++ display_fd = wsi_dri3_open(conn, screen->root, None); ++ } ++ + result = wsi_swapchain_init(wsi_device, &chain->base, device, pCreateInfo, +- image_params, pAllocator); ++ image_params, pAllocator, display_fd); + + for (int i = 0; i < ARRAY_SIZE(modifiers); i++) + vk_free(pAllocator, modifiers[i]); +@@ -2140,11 +2152,16 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, + uint32_t image = 0; + for (; image < chain->base.image_count; image++) { + result = x11_image_init(device, chain, pCreateInfo, pAllocator, +- &chain->images[image]); ++ display_fd, &chain->images[image]); + if (result != VK_SUCCESS) + goto fail_init_images; + } + ++ if (display_fd >= 0) { ++ close(display_fd); ++ display_fd = -1; ++ } ++ + /* Initialize queues for images in our swapchain. Possible queues are: + * - Present queue: for images sent to the X server but not yet presented. + * - Acquire queue: for images already presented but not yet released by the +@@ -2222,6 +2239,9 @@ fail_register: + fail_alloc: + vk_free(pAllocator, chain); + ++ if (display_fd >= 0) ++ close(display_fd); ++ + return result; + } + +-- +2.17.1 + diff --git a/package/mesa3d/0048-pvr-wsi-add-PowerVR-Vulkan-WSI-library.patch b/package/mesa3d/0048-pvr-wsi-add-PowerVR-Vulkan-WSI-library.patch new file mode 100644 index 00000000..61820dc5 --- /dev/null +++ b/package/mesa3d/0048-pvr-wsi-add-PowerVR-Vulkan-WSI-library.patch @@ -0,0 +1,3239 @@ +From 33fe2f0bc8ff939011f7aedad962a21cf8f7285b Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 18 Mar 2021 13:44:57 +0000 +Subject: [PATCH 048/168] pvr/wsi: add PowerVR Vulkan WSI library + +The old (pre-Mesa 22.0.0) Mesa WSI interface has been restored. +The new interface provides API entry points, ready to be plugged +into a Vulkan dispatch table. The new interface is not useable by +PowerVR Vulkan, as the interface makes assumptions about some Vulkan +data structures which are not valid on the PowerVR side (e.g. +VkPhysicalDevice being a handle to a Mesa vk_physical_device +structure). The new and old interfaces share code. Where an old +interface function has been reintroduced, the corresponding function +in the new interface has become a wrapper around it. + +The original wsi_device_init function has been renamed to +wsi_device_init2, and two parameters added. The first parameter +indicates that Vulkan handles are opaque to Mesa WSI, the +second parameter is an optional pointer to a +vk_device_extension_table structure, containing the supported +Vulkan extensions. If the second parameter is NULL, and Vulkan +handles are not opaque, wsi_device_init2 will use the +vk_device_extension_table structure in the vk_physical_device +structure. The PVR WSI code passes true and NULL for the additional +two parameters. The vk_device_extension_table is used to determine +if the VK_EXT_external_memory_host extension is supported, for the +benefit of software devices. As the PVR GPU is not a software device, +no effort has been made to construct a vk_device_extension_table +structure. + +Wsi_device_init is now a wrapper around wsi_device_init2, +passing false and NULL for the two additional parameters. + +PowerVR Vulkan will load the WSI library, libpvr_mesa_wsi.so, +and lookup the symbol pvr_mesa_wsi_sym_addr, which is a used to +lookup all other symbols required by Vulkan from the library. +The function is used by Vulkan to lookup the library initialisation +function, pvr_mesa_wsi_init. That function is passed the address +of another lookup function, pvr_vk_mesa_wsi_sym_addr, which is used +by the WSI library to lookup symbols in Vulkan. + +The interface between PowerVR Vulkan and Mesa WSI is defined in +pvr_mesa_wsi_interface.h. Most of the functions defined on the WSI +side are wrappers around Mesa WSI functions. +--- + meson.build | 1 + + meson_options.txt | 2 +- + src/meson.build | 3 + + src/pvr/meson.build | 23 ++ + src/pvr/wsi/meson.build | 82 +++++ + src/pvr/wsi/pvr_mesa_wsi_interface.h | 306 +++++++++++++++++ + src/pvr/wsi/pvr_wsi.c | 334 +++++++++++++++++++ + src/pvr/wsi/pvr_wsi.h | 78 +++++ + src/pvr/wsi/pvr_wsi_display.c | 293 ++++++++++++++++ + src/pvr/wsi/pvr_wsi_wayland.c | 45 +++ + src/pvr/wsi/pvr_wsi_x11.c | 62 ++++ + src/vulkan/wsi/wsi_common.c | 308 +++++++++++++---- + src/vulkan/wsi/wsi_common.h | 71 ++++ + src/vulkan/wsi/wsi_common_display.c | 479 +++++++++++++++++++++------ + src/vulkan/wsi/wsi_common_display.h | 126 +++++++ + src/vulkan/wsi/wsi_common_wayland.c | 57 +++- + src/vulkan/wsi/wsi_common_wayland.h | 35 ++ + src/vulkan/wsi/wsi_common_x11.c | 88 +++-- + src/vulkan/wsi/wsi_common_x11.h | 41 +++ + 19 files changed, 2218 insertions(+), 216 deletions(-) + create mode 100644 src/pvr/meson.build + create mode 100644 src/pvr/wsi/meson.build + create mode 100644 src/pvr/wsi/pvr_mesa_wsi_interface.h + create mode 100644 src/pvr/wsi/pvr_wsi.c + create mode 100644 src/pvr/wsi/pvr_wsi.h + create mode 100644 src/pvr/wsi/pvr_wsi_display.c + create mode 100644 src/pvr/wsi/pvr_wsi_wayland.c + create mode 100644 src/pvr/wsi/pvr_wsi_x11.c + create mode 100644 src/vulkan/wsi/wsi_common_wayland.h + create mode 100644 src/vulkan/wsi/wsi_common_x11.h + +diff --git a/meson.build b/meson.build +index f4cbae5b0ab..ee142c5b4b5 100644 +--- a/meson.build ++++ b/meson.build +@@ -306,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 +diff --git a/meson_options.txt b/meson_options.txt +index 0607fce2e2f..1597664e904 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -197,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( +diff --git a/src/meson.build b/src/meson.build +index 6500312bb29..9569a10df7d 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -104,6 +104,9 @@ endif + if with_gallium_panfrost or with_gallium_lima or with_panfrost_vk or with_tools.contains('panfrost') + subdir('panfrost') + endif ++if with_pvr_vk ++ subdir('pvr') ++endif + if with_gallium_virgl or with_virtio_vk + subdir('virtio') + endif +diff --git a/src/pvr/meson.build b/src/pvr/meson.build +new file mode 100644 +index 00000000000..09a6986a4c9 +--- /dev/null ++++ b/src/pvr/meson.build +@@ -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. ++ ++if with_pvr_vk ++ subdir('wsi') ++endif +diff --git a/src/pvr/wsi/meson.build b/src/pvr/wsi/meson.build +new file mode 100644 +index 00000000000..f843cebeeeb +--- /dev/null ++++ b/src/pvr/wsi/meson.build +@@ -0,0 +1,82 @@ ++# 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. ++ ++pvr_wsi_args = [] ++ ++pvr_wsi_depends = [ ++ dep_libdrm, ++ idep_vulkan_util, ++ idep_xmlconfig, ++ idep_vulkan_wsi, ++ idep_vulkan_runtime_headers, ++ idep_vulkan_runtime, ++ idep_nir ++] ++ ++pvr_wsi_includes = [ ++ inc_include, ++ inc_src, ++ inc_vulkan_util ++] ++ ++pvr_wsi_src = [ 'pvr_wsi.c' ] ++ ++if with_platform_wayland ++ pvr_wsi_args += '-DVK_USE_PLATFORM_WAYLAND_KHR' ++ ++ pvr_wsi_depends += dep_wayland_client ++ ++ pvr_wsi_src += 'pvr_wsi_wayland.c' ++endif ++ ++if with_platform_x11 ++ pvr_wsi_args += [ ++ '-DVK_USE_PLATFORM_XCB_KHR', ++ '-DVK_USE_PLATFORM_XLIB_KHR', ++ ] ++ ++ pvr_wsi_depends += dep_xcb_dri2 ++ ++ pvr_wsi_src += 'pvr_wsi_x11.c' ++endif ++ ++if system_has_kms_drm and not with_platform_android ++ pvr_wsi_args += '-DVK_USE_PLATFORM_DISPLAY_KHR' ++ ++ pvr_wsi_src += 'pvr_wsi_display.c' ++endif ++ ++if with_xlib_lease ++ pvr_wsi_args += '-DVK_USE_PLATFORM_XLIB_XRANDR_EXT' ++ ++ pvr_wsi_depends += dep_xlib_xrandr ++endif ++ ++libpvr_mesa_wsi = shared_library( ++ 'pvr_mesa_wsi', ++ pvr_wsi_src, ++ include_directories : pvr_wsi_includes, ++ dependencies : pvr_wsi_depends, ++ c_args : pvr_wsi_args, ++ link_with: libvulkan_wsi, ++ gnu_symbol_visibility : 'hidden', ++ build_by_default : true, ++ install : true ++) +diff --git a/src/pvr/wsi/pvr_mesa_wsi_interface.h b/src/pvr/wsi/pvr_mesa_wsi_interface.h +new file mode 100644 +index 00000000000..b4b1bcb0c9d +--- /dev/null ++++ b/src/pvr/wsi/pvr_mesa_wsi_interface.h +@@ -0,0 +1,306 @@ ++/*************************************************************************/ /*! ++@File ++@Title PVR interface to the Vulkan WSI layer in Mesa ++@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 PVR_MESA_WSI_INTERFACE_H ++#define PVR_MESA_WSI_INTERFACE_H ++ ++#include ++#include ++ ++#include ++ ++/* ++ * The pvr_mesa_wsi structure holds the Mesa WSI state, and is opaque to ++ * the PowerVK DDK. ++ */ ++struct pvr_mesa_wsi; ++ ++/* ++ * Functions defined in Mesa for use by the PowerVR DDK. ++ * All functions have a "pvr_mesa_wsi" prefix. ++ */ ++ ++void * ++pvr_mesa_wsi_sym_addr(struct pvr_mesa_wsi *mwsi, ++ const char *name); ++ ++VkResult ++pvr_mesa_wsi_init(struct pvr_mesa_wsi **mwsi, ++ VkPhysicalDevice physicalDevice, ++ PFN_vkVoidFunction (VKAPI_PTR *pvr_vk_mesa_wsi_sym_addr) ++ (VkPhysicalDevice physicalDevice, const char *), ++ const VkAllocationCallbacks *alloc, ++ int fd, ++ bool sw); ++ ++void ++pvr_mesa_wsi_finish(struct pvr_mesa_wsi *mwsi, ++ const VkAllocationCallbacks *alloc); ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_support(struct pvr_mesa_wsi *mwsi, ++ uint32_t queueFamilyIndex, ++ VkSurfaceKHR surface, ++ VkBool32 *pSupported); ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_capabilities(struct pvr_mesa_wsi *mwsi, ++ VkSurfaceKHR surface, ++ VkSurfaceCapabilitiesKHR *pSurfaceCapabilities); ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_capabilities2(struct pvr_mesa_wsi *mwsi, ++ const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, ++ VkSurfaceCapabilities2KHR *pSurfaceCapabilities); ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_capabilities2ext(struct pvr_mesa_wsi *mwsi, ++ VkSurfaceKHR surface, ++ VkSurfaceCapabilities2EXT *pSurfaceCapabilities); ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_formats(struct pvr_mesa_wsi *mwsi, ++ VkSurfaceKHR surface, ++ uint32_t *pSurfaceFormatCount, ++ VkSurfaceFormatKHR *pSurfaceFormats); ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_formats2(struct pvr_mesa_wsi *mwsi, ++ const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, ++ uint32_t *pSurfaceFormatCount, ++ VkSurfaceFormat2KHR *pSurfaceFormats); ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_present_modes(struct pvr_mesa_wsi *mwsi, ++ VkSurfaceKHR surface, ++ uint32_t *pPresentModeCount, ++ VkPresentModeKHR *pPresentModes); ++ ++VkResult ++pvr_mesa_wsi_common_create_swapchain(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ const VkSwapchainCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *pAllocator, ++ VkSwapchainKHR *pSwapchain); ++void ++pvr_mesa_wsi_common_destroy_swapchain(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ VkSwapchainKHR swapchain, ++ const VkAllocationCallbacks *pAllocator); ++ ++VkResult ++pvr_mesa_wsi_common_get_images(struct pvr_mesa_wsi *mwsi, ++ VkSwapchainKHR swapchain, ++ uint32_t *pSwapchainImageCount, ++ VkImage *pSwapchainImages); ++ ++VkResult ++pvr_mesa_wsi_common_acquire_next_image2(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ const VkAcquireNextImageInfoKHR *pAcquireInfo, ++ uint32_t *pImageIndex); ++ ++VkResult ++pvr_mesa_wsi_common_queue_present(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ VkQueue queue, ++ int queue_family_index, ++ const VkPresentInfoKHR *pPresentInfo); ++ ++VkResult ++pvr_mesa_wsi_common_get_present_rectangles(struct pvr_mesa_wsi *mwsi, ++ VkSurfaceKHR surface, ++ uint32_t* pRectCount, ++ VkRect2D* pRects); ++ ++#if defined(VK_USE_PLATFORM_WAYLAND_KHR) ++VkBool32 ++pvr_mesa_wsi_get_physical_device_wayland_presentation_support(struct pvr_mesa_wsi *mwsi, ++ uint32_t queueFamilyIndex, ++ void *display); ++ ++VkResult ++pvr_mesa_wsi_create_wayland_surface(struct pvr_mesa_wsi *mwsi, ++ const VkAllocationCallbacks *pAllocator, ++ const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface); ++#endif ++ ++#if defined(VK_USE_PLATFORM_XCB_KHR) ++VkBool32 ++pvr_mesa_wsi_get_physical_device_xcb_presentation_support(struct pvr_mesa_wsi *mwsi, ++ uint32_t queueFamilyIndex, ++ void *connection, ++ uint32_t visualId); ++VkResult ++pvr_mesa_wsi_create_xcb_surface(struct pvr_mesa_wsi *mwsi, ++ const VkAllocationCallbacks *pAllocator, ++ const VkXcbSurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface); ++#endif ++ ++#if defined(VK_USE_PLATFORM_XLIB_KHR) ++VkResult ++pvr_mesa_wsi_create_xlib_surface(struct pvr_mesa_wsi *mwsi, ++ const VkAllocationCallbacks *pAllocator, ++ const VkXlibSurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface); ++#endif ++ ++VkResult ++pvr_mesa_wsi_display_get_physical_device_display_properties(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ uint32_t *pPropertyCount, ++ VkDisplayPropertiesKHR *pProperties); ++ ++VkResult ++pvr_mesa_wsi_display_get_physical_device_display_properties2(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ uint32_t *pPropertyCount, ++ VkDisplayProperties2KHR *pProperties); ++ ++VkResult ++pvr_mesa_wsi_display_get_physical_device_display_plane_properties(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ uint32_t *pPropertyCount, ++ VkDisplayPlanePropertiesKHR *pProperties); ++ ++VkResult ++pvr_mesa_wsi_display_get_physical_device_display_plane_properties2(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ uint32_t *pPropertyCount, ++ VkDisplayPlaneProperties2KHR *pProperties); ++ ++VkResult ++pvr_mesa_wsi_display_get_display_plane_supported_displays(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ uint32_t planeIndex, ++ uint32_t *pDisplayCount, ++ VkDisplayKHR *pDisplays); ++ ++VkResult ++pvr_mesa_wsi_display_get_display_mode_properties(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ VkDisplayKHR display, ++ uint32_t *pPropertyCount, ++ VkDisplayModePropertiesKHR *pProperties); ++ ++VkResult ++pvr_mesa_wsi_display_get_display_mode_properties2(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ VkDisplayKHR display, ++ uint32_t *pPropertyCount, ++ VkDisplayModeProperties2KHR *pProperties); ++ ++VkResult ++pvr_mesa_wsi_display_create_display_mode(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ VkDisplayKHR display, ++ const VkDisplayModeCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *pAllocator, ++ VkDisplayModeKHR *pMode); ++ ++VkResult ++pvr_mesa_wsi_get_display_plane_capabilities(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ VkDisplayModeKHR modeKhr, ++ uint32_t planeIndex, ++ VkDisplayPlaneCapabilitiesKHR *pCapabilities); ++ ++VkResult ++pvr_mesa_wsi_get_display_plane_capabilities2(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo, ++ VkDisplayPlaneCapabilities2KHR *pCapabilities); ++ ++VkResult ++pvr_mesa_wsi_create_display_surface(struct pvr_mesa_wsi *mwsi, ++ VkInstance instance, ++ const VkAllocationCallbacks *pAllocator, ++ const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface); ++ ++VkResult ++pvr_mesa_wsi_release_display(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ VkDisplayKHR display); ++ ++#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) ++VkResult ++pvr_mesa_wsi_acquire_xlib_display(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ void *dpy, ++ VkDisplayKHR display); ++ ++VkResult ++pvr_mesa_wsi_get_randr_output_display(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ void *dpy, ++ uint32_t output, ++ VkDisplayKHR *pDisplay); ++ ++#endif ++ ++VkResult ++pvr_mesa_wsi_display_power_control(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ VkDisplayKHR display, ++ const VkDisplayPowerInfoEXT *pDisplayPowerInfo); ++ ++VkResult ++pvr_mesa_wsi_register_device_event(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ const VkDeviceEventInfoEXT *pDeviceEventInfo, ++ const VkAllocationCallbacks *pAllocator, ++ void **pFence, ++ int syncFd); ++ ++VkResult ++pvr_mesa_wsi_register_display_event(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ VkDisplayKHR display, ++ const VkDisplayEventInfoEXT *pDisplayEventInfo, ++ const VkAllocationCallbacks *pAllocator, ++ void **pFence, ++ int syncFd); ++ ++VkResult ++pvr_mesa_wsi_get_swapchain_counter(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ VkSwapchainKHR swapchain, ++ VkSurfaceCounterFlagBitsEXT flagBits, ++ uint64_t *pValue); ++ ++/* ++ * Functions defined in the PowerVR DDK for use by Mesa. ++ * All functions have a "pvr_vk_mesa_wsi" prefix. ++ */ ++VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL ++pvr_vk_mesa_wsi_sym_addr(VkPhysicalDevice physicalDevice, ++ const char *name); ++ ++#endif /* PVR_MESA_WSI_INTERFACE_H */ +diff --git a/src/pvr/wsi/pvr_wsi.c b/src/pvr/wsi/pvr_wsi.c +new file mode 100644 +index 00000000000..f1e4bc594c8 +--- /dev/null ++++ b/src/pvr/wsi/pvr_wsi.c +@@ -0,0 +1,334 @@ ++/* ++ * Copyright © 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 ++ ++#include "pvr_wsi.h" ++#include "pvr_mesa_wsi_interface.h" ++ ++VkResult ++pvr_mesa_wsi_init(struct pvr_mesa_wsi **pmwsi, ++ VkPhysicalDevice physicalDevice, ++ PFN_vkVoidFunction (VKAPI_PTR *pvr_vk_mesa_wsi_sym_addr) ++ (VkPhysicalDevice physicalDevice, const char *), ++ const VkAllocationCallbacks *alloc, ++ int fd, ++ bool sw) ++{ ++ struct pvr_mesa_wsi *mwsi; ++ VkResult result; ++ ++ mwsi = vk_zalloc(alloc, sizeof(*mwsi), 8, ++ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); ++ if (!mwsi) ++ return VK_ERROR_OUT_OF_HOST_MEMORY; ++ ++ mwsi->symtab.pvr_vk_mesa_wsi_sym_addr = pvr_vk_mesa_wsi_sym_addr; ++ mwsi->physicalDevice = physicalDevice; ++ ++ result = wsi_device_init2(&mwsi->wsi, ++ physicalDevice, ++ pvr_vk_mesa_wsi_sym_addr, ++ alloc, ++ fd, NULL, sw, ++ true, NULL); ++ if (result != VK_SUCCESS) { ++ vk_free(alloc, mwsi); ++ return result; ++ } ++ ++ if (!sw) ++ mwsi->wsi.supports_modifiers = true; ++ ++ *pmwsi = mwsi; ++ ++ return VK_SUCCESS; ++} ++ ++void ++pvr_mesa_wsi_finish(struct pvr_mesa_wsi *mwsi, ++ const VkAllocationCallbacks *alloc) ++{ ++ wsi_device_finish(&mwsi->wsi, alloc); ++ ++ vk_free(alloc, mwsi); ++} ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_support(struct pvr_mesa_wsi *mwsi, ++ uint32_t queueFamilyIndex, ++ VkSurfaceKHR surface, ++ VkBool32 *pSupported) ++{ ++ return wsi_common_get_surface_support(&mwsi->wsi, ++ queueFamilyIndex, ++ surface, ++ pSupported); ++} ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_capabilities(struct pvr_mesa_wsi *mwsi, ++ VkSurfaceKHR surface, ++ VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) ++{ ++ return wsi_common_get_surface_capabilities(&mwsi->wsi, ++ surface, ++ pSurfaceCapabilities); ++} ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_capabilities2(struct pvr_mesa_wsi *mwsi, ++ const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, ++ VkSurfaceCapabilities2KHR *pSurfaceCapabilities) ++{ ++ return wsi_common_get_surface_capabilities2(&mwsi->wsi, ++ pSurfaceInfo, ++ pSurfaceCapabilities); ++} ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_capabilities2ext(struct pvr_mesa_wsi *mwsi, ++ VkSurfaceKHR surface, ++ VkSurfaceCapabilities2EXT *pSurfaceCapabilities) ++{ ++ return wsi_common_get_surface_capabilities2ext(&mwsi->wsi, ++ surface, ++ pSurfaceCapabilities); ++} ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_formats(struct pvr_mesa_wsi *mwsi, ++ VkSurfaceKHR surface, ++ uint32_t *pSurfaceFormatCount, ++ VkSurfaceFormatKHR *pSurfaceFormats) ++{ ++ return wsi_common_get_surface_formats(&mwsi->wsi, ++ surface, ++ pSurfaceFormatCount, ++ pSurfaceFormats); ++} ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_formats2(struct pvr_mesa_wsi *mwsi, ++ const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, ++ uint32_t *pSurfaceFormatCount, ++ VkSurfaceFormat2KHR *pSurfaceFormats) ++{ ++ return wsi_common_get_surface_formats2(&mwsi->wsi, ++ pSurfaceInfo, ++ pSurfaceFormatCount, ++ pSurfaceFormats); ++} ++ ++VkResult ++pvr_mesa_wsi_common_get_surface_present_modes(struct pvr_mesa_wsi *mwsi, ++ VkSurfaceKHR surface, ++ uint32_t *pPresentModeCount, ++ VkPresentModeKHR *pPresentModes) ++{ ++ return wsi_common_get_surface_present_modes(&mwsi->wsi, ++ surface, ++ pPresentModeCount, ++ pPresentModes); ++} ++ ++VkResult ++pvr_mesa_wsi_common_create_swapchain(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ const VkSwapchainCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *pAllocator, ++ VkSwapchainKHR *pSwapchain) ++{ ++ return wsi_common_create_swapchain(&mwsi->wsi, ++ device, ++ pCreateInfo, ++ pAllocator, ++ pSwapchain); ++} ++ ++void ++pvr_mesa_wsi_common_destroy_swapchain(UNUSED struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ VkSwapchainKHR swapchain, ++ const VkAllocationCallbacks *pAllocator) ++{ ++ return wsi_common_destroy_swapchain(device, ++ swapchain, ++ pAllocator); ++} ++ ++VkResult ++pvr_mesa_wsi_common_get_images(UNUSED struct pvr_mesa_wsi *mwsi, ++ VkSwapchainKHR swapchain, ++ uint32_t *pSwapchainImageCount, ++ VkImage *pSwapchainImages) ++{ ++ return wsi_common_get_images(swapchain, ++ pSwapchainImageCount, ++ pSwapchainImages); ++} ++ ++VkResult ++pvr_mesa_wsi_common_acquire_next_image2(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ const VkAcquireNextImageInfoKHR *pAcquireInfo, ++ uint32_t *pImageIndex) ++{ ++ return wsi_common_acquire_next_image2(&mwsi->wsi, ++ device, ++ pAcquireInfo, ++ pImageIndex); ++} ++ ++VkResult ++pvr_mesa_wsi_common_queue_present(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ VkQueue queue, ++ int queue_family_index, ++ const VkPresentInfoKHR *pPresentInfo) ++{ ++ return wsi_common_queue_present(&mwsi->wsi, ++ device, ++ queue, ++ queue_family_index, ++ pPresentInfo); ++} ++ ++VkResult ++pvr_mesa_wsi_common_get_present_rectangles(struct pvr_mesa_wsi *mwsi, ++ VkSurfaceKHR surface, ++ uint32_t* pRectCount, ++ VkRect2D* pRects) ++{ ++ return wsi_common_get_present_rectangles(&mwsi->wsi, ++ surface, ++ pRectCount, ++ pRects); ++} ++ ++/* ++ * The mwsi parameter is currently unused. Note that it is invalid for ++ * pvr_mesa_wsi_init, which is responsible for allocating it. ++*/ ++PUBLIC void * ++pvr_mesa_wsi_sym_addr(UNUSED struct pvr_mesa_wsi *mwsi, const char *name) ++{ ++ static const struct { ++ char *name; ++ void *addr; ++ } lookup[] = { ++ { "pvr_mesa_wsi_init", ++ pvr_mesa_wsi_init }, ++ { "pvr_mesa_wsi_finish", ++ pvr_mesa_wsi_finish }, ++ { "pvr_mesa_wsi_common_get_surface_support", ++ pvr_mesa_wsi_common_get_surface_support }, ++ { "pvr_mesa_wsi_common_get_surface_capabilities", ++ pvr_mesa_wsi_common_get_surface_capabilities }, ++ { "pvr_mesa_wsi_common_get_surface_capabilities2", ++ pvr_mesa_wsi_common_get_surface_capabilities2 }, ++ { "pvr_mesa_wsi_common_get_surface_capabilities2ext", ++ pvr_mesa_wsi_common_get_surface_capabilities2ext }, ++ { "pvr_mesa_wsi_common_get_surface_formats", ++ pvr_mesa_wsi_common_get_surface_formats }, ++ { "pvr_mesa_wsi_common_get_surface_formats2", ++ pvr_mesa_wsi_common_get_surface_formats2 }, ++ { "pvr_mesa_wsi_common_get_surface_present_modes", ++ pvr_mesa_wsi_common_get_surface_present_modes }, ++ { "pvr_mesa_wsi_common_create_swapchain", ++ pvr_mesa_wsi_common_create_swapchain }, ++ { "pvr_mesa_wsi_common_destroy_swapchain", ++ pvr_mesa_wsi_common_destroy_swapchain }, ++ { "pvr_mesa_wsi_common_get_images", ++ pvr_mesa_wsi_common_get_images }, ++ { "pvr_mesa_wsi_common_acquire_next_image2", ++ pvr_mesa_wsi_common_acquire_next_image2 }, ++ { "pvr_mesa_wsi_common_queue_present", ++ pvr_mesa_wsi_common_queue_present }, ++ { "pvr_mesa_wsi_common_get_present_rectangles", ++ pvr_mesa_wsi_common_get_present_rectangles }, ++#if defined(VK_USE_PLATFORM_WAYLAND_KHR) ++ { "pvr_mesa_wsi_get_physical_device_wayland_presentation_support", ++ pvr_mesa_wsi_get_physical_device_wayland_presentation_support }, ++ { "pvr_mesa_wsi_create_wayland_surface", ++ pvr_mesa_wsi_create_wayland_surface }, ++#endif ++#if defined(VK_USE_PLATFORM_XCB_KHR) ++ { "pvr_mesa_wsi_get_physical_device_xcb_presentation_support", ++ pvr_mesa_wsi_get_physical_device_xcb_presentation_support }, ++ { "pvr_mesa_wsi_create_xcb_surface", ++ pvr_mesa_wsi_create_xcb_surface }, ++#endif ++#if defined(VK_USE_PLATFORM_XLIB_KHR) ++ { "pvr_mesa_wsi_create_xlib_surface", ++ pvr_mesa_wsi_create_xlib_surface }, ++#endif ++ { "pvr_mesa_wsi_display_get_physical_device_display_properties", ++ pvr_mesa_wsi_display_get_physical_device_display_properties }, ++ { "pvr_mesa_wsi_display_get_physical_device_display_properties2", ++ pvr_mesa_wsi_display_get_physical_device_display_properties2 }, ++ { "pvr_mesa_wsi_display_get_physical_device_display_plane_properties", ++ pvr_mesa_wsi_display_get_physical_device_display_plane_properties }, ++ { "pvr_mesa_wsi_display_get_physical_device_display_plane_properties2", ++ pvr_mesa_wsi_display_get_physical_device_display_plane_properties2 }, ++ { "pvr_mesa_wsi_display_get_display_plane_supported_displays", ++ pvr_mesa_wsi_display_get_display_plane_supported_displays }, ++ { "pvr_mesa_wsi_display_get_display_mode_properties", ++ pvr_mesa_wsi_display_get_display_mode_properties }, ++ { "pvr_mesa_wsi_display_get_display_mode_properties2", ++ pvr_mesa_wsi_display_get_display_mode_properties2 }, ++ { "pvr_mesa_wsi_display_create_display_mode", ++ pvr_mesa_wsi_display_create_display_mode }, ++ { "pvr_mesa_wsi_get_display_plane_capabilities", ++ pvr_mesa_wsi_get_display_plane_capabilities }, ++ { "pvr_mesa_wsi_get_display_plane_capabilities2", ++ pvr_mesa_wsi_get_display_plane_capabilities2 }, ++ { "pvr_mesa_wsi_create_display_surface", ++ pvr_mesa_wsi_create_display_surface }, ++ { "pvr_mesa_wsi_release_display", ++ pvr_mesa_wsi_release_display }, ++#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) ++ { "pvr_mesa_wsi_acquire_xlib_display", ++ pvr_mesa_wsi_acquire_xlib_display }, ++ { "pvr_mesa_wsi_get_randr_output_display", ++ pvr_mesa_wsi_get_randr_output_display }, ++#endif ++ { "pvr_mesa_wsi_display_power_control", ++ pvr_mesa_wsi_display_power_control }, ++ { "pvr_mesa_wsi_register_device_event", ++ pvr_mesa_wsi_register_device_event }, ++ { "pvr_mesa_wsi_register_display_event", ++ pvr_mesa_wsi_register_display_event }, ++ { "pvr_mesa_wsi_get_swapchain_counter", ++ pvr_mesa_wsi_get_swapchain_counter }, ++ }; ++ unsigned i; ++ ++ for (i = 0; i < ARRAY_SIZE(lookup); i++) { ++ if (!strcmp(name, lookup[i].name)) ++ return lookup[i].addr; ++ } ++ ++ return NULL; ++} +diff --git a/src/pvr/wsi/pvr_wsi.h b/src/pvr/wsi/pvr_wsi.h +new file mode 100644 +index 00000000000..142358db3de +--- /dev/null ++++ b/src/pvr/wsi/pvr_wsi.h +@@ -0,0 +1,78 @@ ++/* ++ * Copyright © 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 PVR_WSI_H ++#define PVR_WSI_H ++ ++#include "util/macros.h" ++#include "util/u_memory.h" ++#include "util/u_atomic.h" ++ ++#include "wsi_common.h" ++ ++#define Container(p, s, m) ((s *) ((uintptr_t)(p) - Offset(s, m))) ++ ++#define _MAKE_STRING(x) # x ++#define MAKE_STRING(x) _MAKE_STRING(x) ++ ++#define LOOKUP_DDK(mwsi, sym) \ ++ mwsi->symtab.pvr_vk_mesa_wsi_sym_addr(MAKE_STRING(sym)) ++ ++#define JUMP_DDK(mwsi, sym, ...) \ ++ do { \ ++ void *_entry = p_atomic_read(&mwsi->symtab.sym); \ ++ \ ++ if (!_entry) { \ ++ _entry = LOOKUP_DDK(mwsi, sym); \ ++ \ ++ if (_entry) \ ++ p_atomic_set(&mwsi->symtab.sym, _entry); \ ++ } \ ++ \ ++ if (_entry) { \ ++ __typeof__(mwsi->symtab.sym) _func = _entry; \ ++ \ ++ return _func(__VA_ARGS__); \ ++ } \ ++ } while(0) ++ ++struct pvr_vk_mesa_wsi_sym_tab ++{ ++ PFN_vkVoidFunction (VKAPI_PTR *pvr_vk_mesa_wsi_sym_addr) ++ (VkPhysicalDevice physicalDevice, const char *); ++}; ++ ++struct pvr_mesa_wsi ++{ ++ struct wsi_device wsi; ++ struct pvr_vk_mesa_wsi_sym_tab symtab; ++ VkPhysicalDevice physicalDevice; ++}; ++ ++static inline struct pvr_mesa_wsi *pvr_mesa_wsi(struct wsi_device *wsi_ptr) ++{ ++ return Container(wsi_ptr, struct pvr_mesa_wsi, wsi); ++} ++ ++#endif +diff --git a/src/pvr/wsi/pvr_wsi_display.c b/src/pvr/wsi/pvr_wsi_display.c +new file mode 100644 +index 00000000000..8ee13896ee9 +--- /dev/null ++++ b/src/pvr/wsi/pvr_wsi_display.c +@@ -0,0 +1,293 @@ ++/* ++ * Copyright © 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 "wsi_common_display.h" ++ ++#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) ++#include "wsi_common_x11.h" ++#endif ++ ++#include "pvr_wsi.h" ++#include "pvr_mesa_wsi_interface.h" ++ ++VkResult ++pvr_mesa_wsi_display_get_physical_device_display_properties(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ uint32_t *pPropertyCount, ++ VkDisplayPropertiesKHR *pProperties) ++{ ++ return wsi_display_get_physical_device_display_properties(physicalDevice, ++ &mwsi->wsi, ++ pPropertyCount, ++ pProperties); ++} ++ ++VkResult ++pvr_mesa_wsi_display_get_physical_device_display_properties2(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ uint32_t *pPropertyCount, ++ VkDisplayProperties2KHR *pProperties) ++{ ++ return wsi_display_get_physical_device_display_properties2(physicalDevice, ++ &mwsi->wsi, ++ pPropertyCount, ++ pProperties); ++} ++ ++VkResult ++pvr_mesa_wsi_display_get_physical_device_display_plane_properties(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ uint32_t *pPropertyCount, ++ VkDisplayPlanePropertiesKHR *pProperties) ++{ ++ return wsi_display_get_physical_device_display_plane_properties(physicalDevice, ++ &mwsi->wsi, ++ pPropertyCount, ++ pProperties); ++} ++ ++VkResult ++pvr_mesa_wsi_display_get_physical_device_display_plane_properties2(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ uint32_t *pPropertyCount, ++ VkDisplayPlaneProperties2KHR *pProperties) ++{ ++ return wsi_display_get_physical_device_display_plane_properties2(physicalDevice, ++ &mwsi->wsi, ++ pPropertyCount, ++ pProperties); ++} ++ ++VkResult ++pvr_mesa_wsi_display_get_display_plane_supported_displays(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ uint32_t planeIndex, ++ uint32_t *pDisplayCount, ++ VkDisplayKHR *pDisplays) ++{ ++ return wsi_display_get_display_plane_supported_displays(physicalDevice, ++ &mwsi->wsi, ++ planeIndex, ++ pDisplayCount, ++ pDisplays); ++ ++} ++ ++VkResult ++pvr_mesa_wsi_display_get_display_mode_properties(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ VkDisplayKHR display, ++ uint32_t *pPropertyCount, ++ VkDisplayModePropertiesKHR *pProperties) ++{ ++ return wsi_display_get_display_mode_properties(physicalDevice, ++ &mwsi->wsi, ++ display, ++ pPropertyCount, ++ pProperties); ++} ++ ++VkResult ++pvr_mesa_wsi_display_get_display_mode_properties2(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ VkDisplayKHR display, ++ uint32_t *pPropertyCount, ++ VkDisplayModeProperties2KHR *pProperties) ++{ ++ return wsi_display_get_display_mode_properties2(physicalDevice, ++ &mwsi->wsi, ++ display, ++ pPropertyCount, ++ pProperties); ++} ++ ++VkResult ++pvr_mesa_wsi_display_create_display_mode(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ VkDisplayKHR display, ++ const VkDisplayModeCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *pAllocator, ++ VkDisplayModeKHR *pMode) ++{ ++ return wsi_display_create_display_mode(physicalDevice, ++ &mwsi->wsi, ++ display, ++ pCreateInfo, ++ pAllocator, ++ pMode); ++} ++ ++VkResult ++pvr_mesa_wsi_get_display_plane_capabilities(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ VkDisplayModeKHR modeKhr, ++ uint32_t planeIndex, ++ VkDisplayPlaneCapabilitiesKHR *pCapabilities) ++{ ++ return wsi_get_display_plane_capabilities(physicalDevice, ++ &mwsi->wsi, ++ modeKhr, ++ planeIndex, ++ pCapabilities); ++} ++ ++VkResult ++pvr_mesa_wsi_get_display_plane_capabilities2(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo, ++ VkDisplayPlaneCapabilities2KHR *pCapabilities) ++{ ++ return wsi_get_display_plane_capabilities2(physicalDevice, ++ &mwsi->wsi, ++ pDisplayPlaneInfo, ++ pCapabilities); ++} ++ ++VkResult ++pvr_mesa_wsi_create_display_surface(UNUSED struct pvr_mesa_wsi *mwsi, ++ VkInstance instance, ++ const VkAllocationCallbacks *pAllocator, ++ const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface) ++{ ++ return wsi_create_display_surface(instance, ++ pAllocator, ++ pCreateInfo, ++ pSurface); ++} ++ ++VkResult ++pvr_mesa_wsi_release_display(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ VkDisplayKHR display) ++{ ++ return wsi_release_display(physicalDevice, ++ &mwsi->wsi, ++ display); ++} ++ ++#if defined(VK_USE_PLATFORM_XLIB_XRANDR_EXT) ++VkResult ++pvr_mesa_wsi_acquire_xlib_display(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ void *dpy, ++ VkDisplayKHR display) ++{ ++ return wsi_acquire_xlib_display(physicalDevice, ++ &mwsi->wsi, ++ dpy, ++ display); ++} ++ ++VkResult ++pvr_mesa_wsi_get_randr_output_display(struct pvr_mesa_wsi *mwsi, ++ VkPhysicalDevice physicalDevice, ++ void *dpy, ++ uint32_t output, ++ VkDisplayKHR *pDisplay) ++{ ++ return wsi_get_randr_output_display(physicalDevice, ++ &mwsi->wsi, ++ dpy, ++ output, ++ pDisplay); ++} ++#endif ++ ++VkResult ++pvr_mesa_wsi_display_power_control(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ VkDisplayKHR display, ++ const VkDisplayPowerInfoEXT *pDisplayPowerInfo) ++{ ++ return wsi_display_power_control(device, ++ &mwsi->wsi, ++ display, ++ pDisplayPowerInfo); ++} ++ ++VkResult ++pvr_mesa_wsi_register_device_event(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ const VkDeviceEventInfoEXT *pDeviceEventInfo, ++ const VkAllocationCallbacks *pAllocator, ++ void **pFence, ++ int syncFd) ++{ ++ struct vk_sync *fence; ++ VkResult ret; ++ ++ ret = wsi_register_device_event(device, ++ &mwsi->wsi, ++ pDeviceEventInfo, ++ pAllocator, ++ pFence ? &fence : NULL, ++ syncFd); ++ ++ if (ret == VK_SUCCESS && pFence != NULL) ++ *pFence = fence; ++ ++ return ret; ++} ++ ++VkResult ++pvr_mesa_wsi_register_display_event(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ VkDisplayKHR display, ++ const VkDisplayEventInfoEXT *pDisplayEventInfo, ++ const VkAllocationCallbacks *pAllocator, ++ void **pFence, ++ int syncFd) ++{ ++ struct vk_sync *fence; ++ VkResult ret; ++ ++ ret = wsi_register_display_event(device, ++ &mwsi->wsi, ++ display, ++ pDisplayEventInfo, ++ pAllocator, ++ pFence ? &fence : NULL, ++ syncFd); ++ ++ if (ret == VK_SUCCESS && pFence != NULL) ++ *pFence = fence; ++ ++ return ret; ++} ++ ++VkResult ++pvr_mesa_wsi_get_swapchain_counter(struct pvr_mesa_wsi *mwsi, ++ VkDevice device, ++ VkSwapchainKHR swapchain, ++ VkSurfaceCounterFlagBitsEXT flagBits, ++ uint64_t *pValue) ++{ ++ return wsi_get_swapchain_counter(device, ++ &mwsi->wsi, ++ swapchain, ++ flagBits, ++ pValue); ++} ++ +diff --git a/src/pvr/wsi/pvr_wsi_wayland.c b/src/pvr/wsi/pvr_wsi_wayland.c +new file mode 100644 +index 00000000000..5b052667ac9 +--- /dev/null ++++ b/src/pvr/wsi/pvr_wsi_wayland.c +@@ -0,0 +1,45 @@ ++/* ++ * Copyright © 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 "wsi_common_wayland.h" ++ ++#include "pvr_wsi.h" ++#include "pvr_mesa_wsi_interface.h" ++ ++VkBool32 ++pvr_mesa_wsi_get_physical_device_wayland_presentation_support(struct pvr_mesa_wsi *mwsi, ++ uint32_t queueFamilyIndex, ++ void *display) ++{ ++ return wsi_wl_get_presentation_support(&mwsi->wsi, display); ++} ++ ++VkResult ++pvr_mesa_wsi_create_wayland_surface(UNUSED struct pvr_mesa_wsi *mwsi, ++ const VkAllocationCallbacks *pAllocator, ++ const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface) ++{ ++ return wsi_create_wl_surface(pAllocator, pCreateInfo, pSurface); ++} +diff --git a/src/pvr/wsi/pvr_wsi_x11.c b/src/pvr/wsi/pvr_wsi_x11.c +new file mode 100644 +index 00000000000..0a69e92ac9e +--- /dev/null ++++ b/src/pvr/wsi/pvr_wsi_x11.c +@@ -0,0 +1,62 @@ ++/* ++ * Copyright © 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 "wsi_common_x11.h" ++ ++#include "pvr_wsi.h" ++#include "pvr_mesa_wsi_interface.h" ++ ++VkBool32 ++pvr_mesa_wsi_get_physical_device_xcb_presentation_support(struct pvr_mesa_wsi *mwsi, ++ uint32_t queueFamilyIndex, ++ void *connection, ++ uint32_t visual_id) ++{ ++ return wsi_get_physical_device_xcb_presentation_support(&mwsi->wsi, ++ queueFamilyIndex, ++ connection, ++ visual_id); ++} ++ ++VkResult ++pvr_mesa_wsi_create_xcb_surface(UNUSED struct pvr_mesa_wsi *mwsi, ++ const VkAllocationCallbacks *pAllocator, ++ const VkXcbSurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface) ++{ ++ return wsi_create_xcb_surface(pAllocator, ++ pCreateInfo, ++ pSurface); ++} ++ ++VkResult ++pvr_mesa_wsi_create_xlib_surface(UNUSED struct pvr_mesa_wsi *mwsi, ++ const VkAllocationCallbacks *pAllocator, ++ const VkXlibSurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface) ++{ ++ return wsi_create_xlib_surface(pAllocator, ++ pCreateInfo, ++ pSurface); ++} +diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c +index 6ca7c767b26..815ecc07c09 100644 +--- a/src/vulkan/wsi/wsi_common.c ++++ b/src/vulkan/wsi/wsi_common.c +@@ -57,13 +57,15 @@ static const struct debug_control debug_control[] = { + }; + + VkResult +-wsi_device_init(struct wsi_device *wsi, +- VkPhysicalDevice pdevice, +- WSI_FN_GetPhysicalDeviceProcAddr proc_addr, +- const VkAllocationCallbacks *alloc, +- int display_fd, +- const struct driOptionCache *dri_options, +- bool sw_device) ++wsi_device_init2(struct wsi_device *wsi, ++ VkPhysicalDevice pdevice, ++ WSI_FN_GetPhysicalDeviceProcAddr proc_addr, ++ const VkAllocationCallbacks *alloc, ++ int display_fd, ++ const struct driOptionCache *dri_options, ++ bool sw_device, ++ bool opaque_vk_handles, ++ const struct vk_device_extension_table *device_extensions) + { + const char *present_mode; + UNUSED VkResult result; +@@ -79,6 +81,7 @@ wsi_device_init(struct wsi_device *wsi, + wsi->supports_scanout = true; + wsi->sw = sw_device || (WSI_DEBUG & WSI_DEBUG_SW); + wsi->wants_linear = (WSI_DEBUG & WSI_DEBUG_LINEAR) != 0; ++ wsi->opaque_vk_handles = opaque_vk_handles; + #define WSI_GET_CB(func) \ + PFN_vk##func func = (PFN_vk##func)proc_addr(pdevice, "vk" #func) + WSI_GET_CB(GetPhysicalDeviceExternalSemaphoreProperties); +@@ -124,10 +127,19 @@ wsi_device_init(struct wsi_device *wsi, + wsi->semaphore_export_handle_types |= handle_type; + } + +- const struct vk_device_extension_table *supported_extensions = +- &vk_physical_device_from_handle(pdevice)->supported_extensions; +- wsi->has_import_memory_host = +- supported_extensions->EXT_external_memory_host; ++ const struct vk_device_extension_table *supported_extensions; ++ ++ if (device_extensions) ++ supported_extensions = device_extensions; ++ else if (!opaque_vk_handles) ++ supported_extensions = ++ &vk_physical_device_from_handle(pdevice)->supported_extensions; ++ else ++ supported_extensions = NULL; ++ ++ if (supported_extensions) ++ wsi->has_import_memory_host = ++ supported_extensions->EXT_external_memory_host; + + list_inithead(&wsi->hotplug_fences); + +@@ -231,6 +243,26 @@ fail: + #endif + } + ++VkResult ++wsi_device_init(struct wsi_device *wsi, ++ VkPhysicalDevice pdevice, ++ WSI_FN_GetPhysicalDeviceProcAddr proc_addr, ++ const VkAllocationCallbacks *alloc, ++ int display_fd, ++ const struct driOptionCache *dri_options, ++ bool sw_device) ++{ ++ return wsi_device_init2(wsi, ++ pdevice, ++ proc_addr, ++ alloc, ++ display_fd, ++ dri_options, ++ sw_device, ++ false, ++ NULL); ++} ++ + void + wsi_device_finish(struct wsi_device *wsi, + const VkAllocationCallbacks *alloc) +@@ -336,12 +368,17 @@ wsi_swapchain_init(const struct wsi_device *wsi, + const VkAllocationCallbacks *pAllocator, + int display_fd) + { +- VK_FROM_HANDLE(vk_device, device, _device); + VkResult result; + + memset(chain, 0, sizeof(*chain)); + +- vk_object_base_init(device, &chain->base, VK_OBJECT_TYPE_SWAPCHAIN_KHR); ++ if (wsi->opaque_vk_handles) { ++ vk_object_base_init(NULL, &chain->base, VK_OBJECT_TYPE_SWAPCHAIN_KHR); ++ } else { ++ VK_FROM_HANDLE(vk_device, device, _device); ++ ++ vk_object_base_init(device, &chain->base, VK_OBJECT_TYPE_SWAPCHAIN_KHR); ++ } + + chain->wsi = wsi; + chain->device = _device; +@@ -681,6 +718,19 @@ wsi_destroy_image(const struct wsi_swapchain *chain, + wsi->DestroyBuffer(chain->device, image->buffer.buffer, &chain->alloc); + } + ++VkResult ++wsi_common_get_surface_support(struct wsi_device *wsi_device, ++ uint32_t queueFamilyIndex, ++ VkSurfaceKHR _surface, ++ VkBool32 *pSupported) ++{ ++ ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); ++ struct wsi_interface *iface = wsi_device->wsi[surface->platform]; ++ ++ return iface->get_support(surface, wsi_device, ++ queueFamilyIndex, pSupported); ++} ++ + VKAPI_ATTR VkResult VKAPI_CALL + wsi_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, +@@ -688,23 +738,20 @@ wsi_GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, + VkBool32 *pSupported) + { + VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); +- ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); + struct wsi_device *wsi_device = device->wsi_device; +- struct wsi_interface *iface = wsi_device->wsi[surface->platform]; + +- return iface->get_support(surface, wsi_device, +- queueFamilyIndex, pSupported); ++ return wsi_common_get_surface_support(wsi_device, ++ queueFamilyIndex, ++ _surface, ++ pSupported); + } + +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetPhysicalDeviceSurfaceCapabilitiesKHR( +- VkPhysicalDevice physicalDevice, +- VkSurfaceKHR _surface, +- VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) ++VkResult ++wsi_common_get_surface_capabilities(struct wsi_device *wsi_device, ++ VkSurfaceKHR _surface, ++ VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) + { +- VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); + ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); +- struct wsi_device *wsi_device = device->wsi_device; + struct wsi_interface *iface = wsi_device->wsi[surface->platform]; + + VkSurfaceCapabilities2KHR caps2 = { +@@ -720,14 +767,26 @@ wsi_GetPhysicalDeviceSurfaceCapabilitiesKHR( + } + + VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetPhysicalDeviceSurfaceCapabilities2KHR( ++wsi_GetPhysicalDeviceSurfaceCapabilitiesKHR( + VkPhysicalDevice physicalDevice, ++ VkSurfaceKHR _surface, ++ VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) ++{ ++ VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); ++ struct wsi_device *wsi_device = device->wsi_device; ++ ++ return wsi_common_get_surface_capabilities(wsi_device, ++ _surface, ++ pSurfaceCapabilities); ++} ++ ++VkResult ++wsi_common_get_surface_capabilities2( ++ struct wsi_device *wsi_device, + const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, + VkSurfaceCapabilities2KHR *pSurfaceCapabilities) + { +- VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); + ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface); +- struct wsi_device *wsi_device = device->wsi_device; + struct wsi_interface *iface = wsi_device->wsi[surface->platform]; + + return iface->get_capabilities2(surface, wsi_device, pSurfaceInfo->pNext, +@@ -735,14 +794,26 @@ wsi_GetPhysicalDeviceSurfaceCapabilities2KHR( + } + + VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetPhysicalDeviceSurfaceCapabilities2EXT( ++wsi_GetPhysicalDeviceSurfaceCapabilities2KHR( + VkPhysicalDevice physicalDevice, ++ const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, ++ VkSurfaceCapabilities2KHR *pSurfaceCapabilities) ++{ ++ VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); ++ struct wsi_device *wsi_device = device->wsi_device; ++ ++ return wsi_common_get_surface_capabilities2(wsi_device, ++ pSurfaceInfo, ++ pSurfaceCapabilities); ++} ++ ++VkResult ++wsi_common_get_surface_capabilities2ext( ++ struct wsi_device *wsi_device, + VkSurfaceKHR _surface, + VkSurfaceCapabilities2EXT *pSurfaceCapabilities) + { +- VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); + ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); +- struct wsi_device *wsi_device = device->wsi_device; + struct wsi_interface *iface = wsi_device->wsi[surface->platform]; + + assert(pSurfaceCapabilities->sType == +@@ -781,6 +852,33 @@ wsi_GetPhysicalDeviceSurfaceCapabilities2EXT( + return result; + } + ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_GetPhysicalDeviceSurfaceCapabilities2EXT( ++ VkPhysicalDevice physicalDevice, ++ VkSurfaceKHR _surface, ++ VkSurfaceCapabilities2EXT *pSurfaceCapabilities) ++{ ++ VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); ++ struct wsi_device *wsi_device = device->wsi_device; ++ ++ return wsi_common_get_surface_capabilities2ext(wsi_device, ++ _surface, ++ pSurfaceCapabilities); ++} ++ ++VkResult ++wsi_common_get_surface_formats(struct wsi_device *wsi_device, ++ VkSurfaceKHR _surface, ++ uint32_t *pSurfaceFormatCount, ++ VkSurfaceFormatKHR *pSurfaceFormats) ++{ ++ ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); ++ struct wsi_interface *iface = wsi_device->wsi[surface->platform]; ++ ++ return iface->get_formats(surface, wsi_device, ++ pSurfaceFormatCount, pSurfaceFormats); ++} ++ + VKAPI_ATTR VkResult VKAPI_CALL + wsi_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, + VkSurfaceKHR _surface, +@@ -788,12 +886,25 @@ wsi_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, + VkSurfaceFormatKHR *pSurfaceFormats) + { + VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); +- ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); + struct wsi_device *wsi_device = device->wsi_device; ++ ++ return wsi_common_get_surface_formats(wsi_device, ++ _surface, ++ pSurfaceFormatCount, ++ pSurfaceFormats); ++} ++ ++VkResult ++wsi_common_get_surface_formats2(struct wsi_device *wsi_device, ++ const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, ++ uint32_t *pSurfaceFormatCount, ++ VkSurfaceFormat2KHR *pSurfaceFormats) ++{ ++ ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface); + struct wsi_interface *iface = wsi_device->wsi[surface->platform]; + +- return iface->get_formats(surface, wsi_device, +- pSurfaceFormatCount, pSurfaceFormats); ++ return iface->get_formats2(surface, wsi_device, pSurfaceInfo->pNext, ++ pSurfaceFormatCount, pSurfaceFormats); + } + + VKAPI_ATTR VkResult VKAPI_CALL +@@ -803,12 +914,25 @@ wsi_GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, + VkSurfaceFormat2KHR *pSurfaceFormats) + { + VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); +- ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pSurfaceInfo->surface); + struct wsi_device *wsi_device = device->wsi_device; ++ ++ return wsi_common_get_surface_formats2(wsi_device, ++ pSurfaceInfo, ++ pSurfaceFormatCount, ++ pSurfaceFormats); ++} ++ ++VkResult ++wsi_common_get_surface_present_modes(struct wsi_device *wsi_device, ++ VkSurfaceKHR _surface, ++ uint32_t *pPresentModeCount, ++ VkPresentModeKHR *pPresentModes) ++{ ++ ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); + struct wsi_interface *iface = wsi_device->wsi[surface->platform]; + +- return iface->get_formats2(surface, wsi_device, pSurfaceInfo->pNext, +- pSurfaceFormatCount, pSurfaceFormats); ++ return iface->get_present_modes(surface, pPresentModeCount, ++ pPresentModes); + } + + VKAPI_ATTR VkResult VKAPI_CALL +@@ -818,12 +942,25 @@ wsi_GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, + VkPresentModeKHR *pPresentModes) + { + VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); +- ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); + struct wsi_device *wsi_device = device->wsi_device; ++ ++ return wsi_common_get_surface_present_modes(wsi_device, ++ _surface, ++ pPresentModeCount, ++ pPresentModes); ++} ++ ++VkResult ++wsi_common_get_present_rectangles(struct wsi_device *wsi_device, ++ VkSurfaceKHR _surface, ++ uint32_t* pRectCount, ++ VkRect2D* pRects) ++{ ++ ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); + struct wsi_interface *iface = wsi_device->wsi[surface->platform]; + +- return iface->get_present_modes(surface, pPresentModeCount, +- pPresentModes); ++ return iface->get_present_rectangles(surface, wsi_device, ++ pRectCount, pRects); + } + + VKAPI_ATTR VkResult VKAPI_CALL +@@ -833,55 +970,47 @@ wsi_GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice, + VkRect2D *pRects) + { + VK_FROM_HANDLE(vk_physical_device, device, physicalDevice); +- ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); + struct wsi_device *wsi_device = device->wsi_device; +- struct wsi_interface *iface = wsi_device->wsi[surface->platform]; + +- return iface->get_present_rectangles(surface, wsi_device, +- pRectCount, pRects); ++ return wsi_common_get_present_rectangles(wsi_device, ++ _surface, ++ pRectCount, ++ pRects); + } + +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_CreateSwapchainKHR(VkDevice _device, +- const VkSwapchainCreateInfoKHR *pCreateInfo, +- const VkAllocationCallbacks *pAllocator, +- VkSwapchainKHR *pSwapchain) ++VkResult ++wsi_common_create_swapchain(struct wsi_device *wsi_device, ++ VkDevice _device, ++ const VkSwapchainCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *allocator, ++ VkSwapchainKHR *pSwapchain) + { +- MESA_TRACE_FUNC(); +- VK_FROM_HANDLE(vk_device, device, _device); + ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, pCreateInfo->surface); +- struct wsi_device *wsi_device = device->physical->wsi_device; + struct wsi_interface *iface = wsi_device->wsi[surface->platform]; +- const VkAllocationCallbacks *alloc; + struct wsi_swapchain *swapchain; + +- if (pAllocator) +- alloc = pAllocator; +- else +- alloc = &device->alloc; +- + VkResult result = iface->create_swapchain(surface, _device, wsi_device, +- pCreateInfo, alloc, ++ pCreateInfo, allocator, + &swapchain); + if (result != VK_SUCCESS) + return result; + +- swapchain->fences = vk_zalloc(alloc, ++ swapchain->fences = vk_zalloc(allocator, + sizeof (*swapchain->fences) * swapchain->image_count, + sizeof (*swapchain->fences), + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!swapchain->fences) { +- swapchain->destroy(swapchain, alloc); ++ swapchain->destroy(swapchain, allocator); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + if (swapchain->buffer_blit_queue != VK_NULL_HANDLE) { +- swapchain->buffer_blit_semaphores = vk_zalloc(alloc, ++ swapchain->buffer_blit_semaphores = vk_zalloc(allocator, + sizeof (*swapchain->buffer_blit_semaphores) * swapchain->image_count, + sizeof (*swapchain->buffer_blit_semaphores), + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!swapchain->buffer_blit_semaphores) { +- swapchain->destroy(swapchain, alloc); ++ swapchain->destroy(swapchain, allocator); + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + } +@@ -891,25 +1020,57 @@ wsi_CreateSwapchainKHR(VkDevice _device, + return VK_SUCCESS; + } + +-VKAPI_ATTR void VKAPI_CALL +-wsi_DestroySwapchainKHR(VkDevice _device, +- VkSwapchainKHR _swapchain, +- const VkAllocationCallbacks *pAllocator) ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_CreateSwapchainKHR(VkDevice _device, ++ const VkSwapchainCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *pAllocator, ++ VkSwapchainKHR *pSwapchain) + { + MESA_TRACE_FUNC(); + VK_FROM_HANDLE(vk_device, device, _device); ++ struct wsi_device *wsi_device = device->physical->wsi_device; ++ const VkAllocationCallbacks *allocator; ++ ++ if (pAllocator) ++ allocator = pAllocator; ++ else ++ allocator = &device->alloc; ++ ++ return wsi_common_create_swapchain(wsi_device, ++ _device, ++ pCreateInfo, ++ allocator, ++ pSwapchain); ++} ++ ++void ++wsi_common_destroy_swapchain(VkDevice _device, ++ VkSwapchainKHR _swapchain, ++ const VkAllocationCallbacks *allocator) ++{ + VK_FROM_HANDLE(wsi_swapchain, swapchain, _swapchain); +- const VkAllocationCallbacks *alloc; + + if (!swapchain) + return; + ++ swapchain->destroy(swapchain, allocator); ++} ++ ++VKAPI_ATTR void VKAPI_CALL ++wsi_DestroySwapchainKHR(VkDevice _device, ++ VkSwapchainKHR _swapchain, ++ const VkAllocationCallbacks *pAllocator) ++{ ++ MESA_TRACE_FUNC(); ++ VK_FROM_HANDLE(vk_device, device, _device); ++ const VkAllocationCallbacks *allocator; ++ + if (pAllocator) +- alloc = pAllocator; ++ allocator = pAllocator; + else +- alloc = &device->alloc; ++ allocator = &device->alloc; + +- swapchain->destroy(swapchain, alloc); ++ wsi_common_destroy_swapchain(_device, _swapchain, allocator); + } + + VkResult +@@ -1044,7 +1205,6 @@ wsi_common_acquire_next_image2(const struct wsi_device *wsi, + uint32_t *pImageIndex) + { + VK_FROM_HANDLE(wsi_swapchain, swapchain, pAcquireInfo->swapchain); +- VK_FROM_HANDLE(vk_device, device, _device); + + VkResult result = swapchain->acquire_next_image(swapchain, pAcquireInfo, + pImageIndex); +@@ -1053,7 +1213,8 @@ wsi_common_acquire_next_image2(const struct wsi_device *wsi, + struct wsi_image *image = + swapchain->get_wsi_image(swapchain, *pImageIndex); + +- if (pAcquireInfo->semaphore != VK_NULL_HANDLE) { ++ if (pAcquireInfo->semaphore != VK_NULL_HANDLE && !wsi->opaque_vk_handles) { ++ VK_FROM_HANDLE(vk_device, device, _device); + VkResult signal_result = + wsi_signal_semaphore_for_image(device, swapchain, image, + pAcquireInfo->semaphore); +@@ -1061,7 +1222,8 @@ wsi_common_acquire_next_image2(const struct wsi_device *wsi, + return signal_result; + } + +- if (pAcquireInfo->fence != VK_NULL_HANDLE) { ++ if (pAcquireInfo->fence != VK_NULL_HANDLE && !wsi->opaque_vk_handles) { ++ VK_FROM_HANDLE(vk_device, device, _device); + VkResult signal_result = + wsi_signal_fence_for_image(device, swapchain, image, + pAcquireInfo->fence); +diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h +index c8b52339843..0f5790b2213 100644 +--- a/src/vulkan/wsi/wsi_common.h ++++ b/src/vulkan/wsi/wsi_common.h +@@ -136,6 +136,10 @@ struct wsi_device { + * available. Not all window systems might support this. */ + bool enable_adaptive_sync; + ++ /* Handles, such as VKDevice, cannot be converted to Mesa data ++ * structures using VK_FROM_HANDLE. */ ++ bool opaque_vk_handles; ++ + /* List of fences to signal when hotplug event happens. */ + struct list_head hotplug_fences; + +@@ -250,6 +254,17 @@ struct wsi_device { + + typedef PFN_vkVoidFunction (VKAPI_PTR *WSI_FN_GetPhysicalDeviceProcAddr)(VkPhysicalDevice physicalDevice, const char* pName); + ++VkResult ++wsi_device_init2(struct wsi_device *wsi, ++ VkPhysicalDevice pdevice, ++ WSI_FN_GetPhysicalDeviceProcAddr proc_addr, ++ const VkAllocationCallbacks *alloc, ++ int display_fd, ++ const struct driOptionCache *dri_options, ++ bool sw_device, ++ bool opaque_vk_handles, ++ const struct vk_device_extension_table *device_extensions); ++ + VkResult + wsi_device_init(struct wsi_device *wsi, + VkPhysicalDevice pdevice, +@@ -287,6 +302,51 @@ wsi_device_setup_syncobj_fd(struct wsi_device *wsi_device, + + ICD_DEFINE_NONDISP_HANDLE_CASTS(VkIcdSurfaceBase, VkSurfaceKHR) + ++VkResult ++wsi_common_get_surface_support(struct wsi_device *wsi_device, ++ uint32_t queueFamilyIndex, ++ VkSurfaceKHR surface, ++ VkBool32 *pSupported); ++ ++VkResult ++wsi_common_get_surface_capabilities(struct wsi_device *wsi_device, ++ VkSurfaceKHR surface, ++ VkSurfaceCapabilitiesKHR *pSurfaceCapabilities); ++ ++VkResult ++wsi_common_get_surface_capabilities2(struct wsi_device *wsi_device, ++ const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, ++ VkSurfaceCapabilities2KHR *pSurfaceCapabilities); ++ ++VkResult ++wsi_common_get_surface_formats(struct wsi_device *wsi_device, ++ VkSurfaceKHR surface, ++ uint32_t *pSurfaceFormatCount, ++ VkSurfaceFormatKHR *pSurfaceFormats); ++ ++VkResult ++wsi_common_get_surface_formats2(struct wsi_device *wsi_device, ++ const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, ++ uint32_t *pSurfaceFormatCount, ++ VkSurfaceFormat2KHR *pSurfaceFormats); ++ ++VkResult ++wsi_common_get_surface_present_modes(struct wsi_device *wsi_device, ++ VkSurfaceKHR surface, ++ uint32_t *pPresentModeCount, ++ VkPresentModeKHR *pPresentModes); ++ ++VkResult ++wsi_common_get_present_rectangles(struct wsi_device *wsi_device, ++ VkSurfaceKHR surface, ++ uint32_t* pRectCount, ++ VkRect2D* pRects); ++ ++VkResult ++wsi_common_get_surface_capabilities2ext(struct wsi_device *wsi_device, ++ VkSurfaceKHR surface, ++ VkSurfaceCapabilities2EXT *pSurfaceCapabilities); ++ + VkResult + wsi_common_get_images(VkSwapchainKHR _swapchain, + uint32_t *pSwapchainImageCount, +@@ -301,6 +361,17 @@ wsi_common_acquire_next_image2(const struct wsi_device *wsi, + const VkAcquireNextImageInfoKHR *pAcquireInfo, + uint32_t *pImageIndex); + ++VkResult ++wsi_common_create_swapchain(struct wsi_device *wsi, ++ VkDevice device, ++ const VkSwapchainCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *pAllocator, ++ VkSwapchainKHR *pSwapchain); ++void ++wsi_common_destroy_swapchain(VkDevice device, ++ VkSwapchainKHR swapchain, ++ const VkAllocationCallbacks *pAllocator); ++ + VkResult + wsi_common_queue_present(const struct wsi_device *wsi, + VkDevice device_h, +diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c +index b9e6f18c8ba..7dd6af7c287 100644 +--- a/src/vulkan/wsi/wsi_common_display.c ++++ b/src/vulkan/wsi/wsi_common_display.c +@@ -434,20 +434,19 @@ wsi_display_fill_in_display_properties(struct wsi_device *wsi_device, + properties->persistentContent = VK_FALSE; + } + +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, +- uint32_t *pPropertyCount, +- VkDisplayPropertiesKHR *pProperties) ++VkResult ++wsi_display_get_physical_device_display_properties( ++ VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ uint32_t *pPropertyCount, ++ VkDisplayPropertiesKHR *pProperties) + { +- VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); +- struct wsi_device *wsi_device = pdevice->wsi_device; + struct wsi_display *wsi = + (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + + if (pProperties == NULL) { +- return wsi_GetPhysicalDeviceDisplayProperties2KHR(physicalDevice, +- pPropertyCount, +- NULL); ++ return wsi_display_get_physical_device_display_properties2( ++ physicalDevice, wsi_device, pPropertyCount, NULL); + } else { + /* If we're actually returning properties, allocate a temporary array of + * VkDisplayProperties2KHR structs, call properties2 to fill them out, +@@ -465,9 +464,8 @@ wsi_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, + for (uint32_t i = 0; i < *pPropertyCount; i++) + props2[i].sType = VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR; + +- VkResult result = +- wsi_GetPhysicalDeviceDisplayProperties2KHR(physicalDevice, +- pPropertyCount, props2); ++ VkResult result = wsi_display_get_physical_device_display_properties2( ++ physicalDevice, wsi_device, pPropertyCount, props2); + + if (result == VK_SUCCESS || result == VK_INCOMPLETE) { + for (uint32_t i = 0; i < *pPropertyCount; i++) +@@ -480,14 +478,23 @@ wsi_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, + } + } + +-static VkResult +-wsi_get_connectors(VkPhysicalDevice physicalDevice) ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, ++ uint32_t *pPropertyCount, ++ VkDisplayPropertiesKHR *pProperties) + { + VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); + struct wsi_device *wsi_device = pdevice->wsi_device; +- struct wsi_display *wsi = +- (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + ++ return wsi_display_get_physical_device_display_properties(physicalDevice, ++ wsi_device, ++ pPropertyCount, ++ pProperties); ++} ++ ++static VkResult ++wsi_get_connectors(struct wsi_device *wsi_device, struct wsi_display *wsi) ++{ + if (wsi->fd < 0) + return VK_SUCCESS; + +@@ -511,18 +518,18 @@ wsi_get_connectors(VkPhysicalDevice physicalDevice) + return VK_SUCCESS; + } + +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice, +- uint32_t *pPropertyCount, +- VkDisplayProperties2KHR *pProperties) ++VkResult ++wsi_display_get_physical_device_display_properties2( ++ VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ uint32_t *pPropertyCount, ++ VkDisplayProperties2KHR *pProperties) + { +- VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); +- struct wsi_device *wsi_device = pdevice->wsi_device; + struct wsi_display *wsi = + (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + + /* Get current information */ +- VkResult result = wsi_get_connectors(physicalDevice); ++ VkResult result = wsi_get_connectors(wsi_device, wsi); + if (result != VK_SUCCESS) + goto bail; + +@@ -546,6 +553,20 @@ bail: + return result; + } + ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_GetPhysicalDeviceDisplayProperties2KHR(VkPhysicalDevice physicalDevice, ++ uint32_t *pPropertyCount, ++ VkDisplayProperties2KHR *pProperties) ++{ ++ VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); ++ struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_display_get_physical_device_display_properties2(physicalDevice, ++ wsi_device, ++ pPropertyCount, ++ pProperties); ++} ++ + /* + * Implement vkGetPhysicalDeviceDisplayPlanePropertiesKHR (VK_KHR_display + */ +@@ -567,17 +588,17 @@ wsi_display_fill_in_display_plane_properties( + } + } + +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, +- uint32_t *pPropertyCount, +- VkDisplayPlanePropertiesKHR *pProperties) ++VkResult ++wsi_display_get_physical_device_display_plane_properties( ++ VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ uint32_t *pPropertyCount, ++ VkDisplayPlanePropertiesKHR *pProperties) + { +- VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); +- struct wsi_device *wsi_device = pdevice->wsi_device; + struct wsi_display *wsi = + (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + +- VkResult result = wsi_get_connectors(physicalDevice); ++ VkResult result = wsi_get_connectors(wsi_device, wsi); + if (result != VK_SUCCESS) + goto bail; + +@@ -602,17 +623,32 @@ bail: + } + + VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice, +- uint32_t *pPropertyCount, +- VkDisplayPlaneProperties2KHR *pProperties) ++wsi_GetPhysicalDeviceDisplayPlanePropertiesKHR(VkPhysicalDevice physicalDevice, ++ uint32_t *pPropertyCount, ++ VkDisplayPlanePropertiesKHR *pProperties) + { + VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); + struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_display_get_physical_device_display_plane_properties( ++ physicalDevice, ++ wsi_device, ++ pPropertyCount, ++ pProperties); ++} ++ ++VkResult ++wsi_display_get_physical_device_display_plane_properties2( ++ VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ uint32_t *pPropertyCount, ++ VkDisplayPlaneProperties2KHR *pProperties) ++{ + struct wsi_display *wsi = + (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + + /* Get current information */ +- VkResult result = wsi_get_connectors(physicalDevice); ++ VkResult result = wsi_get_connectors(wsi_device, wsi); + if (result != VK_SUCCESS) + goto bail; + +@@ -632,18 +668,34 @@ bail: + return result; + } + ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_GetPhysicalDeviceDisplayPlaneProperties2KHR(VkPhysicalDevice physicalDevice, ++ uint32_t *pPropertyCount, ++ VkDisplayPlaneProperties2KHR *pProperties) ++{ ++ VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); ++ struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_display_get_physical_device_display_plane_properties2( ++ physicalDevice, ++ wsi_device, ++ pPropertyCount, ++ pProperties); ++} ++ ++ + /* + * Implement vkGetDisplayPlaneSupportedDisplaysKHR (VK_KHR_display) + */ + +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, +- uint32_t planeIndex, +- uint32_t *pDisplayCount, +- VkDisplayKHR *pDisplays) ++VkResult ++wsi_display_get_display_plane_supported_displays( ++ VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ uint32_t planeIndex, ++ uint32_t *pDisplayCount, ++ VkDisplayKHR *pDisplays) + { +- VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); +- struct wsi_device *wsi_device = pdevice->wsi_device; + struct wsi_display *wsi = + (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + +@@ -662,6 +714,22 @@ wsi_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, + return vk_outarray_status(&conn); + } + ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, ++ uint32_t planeIndex, ++ uint32_t *pDisplayCount, ++ VkDisplayKHR *pDisplays) ++{ ++ VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); ++ struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_display_get_display_plane_supported_displays(physicalDevice, ++ wsi_device, ++ planeIndex, ++ pDisplayCount, ++ pDisplays); ++} ++ + /* + * Implement vkGetDisplayModePropertiesKHR (VK_KHR_display) + */ +@@ -682,14 +750,13 @@ wsi_display_fill_in_display_mode_properties( + (uint32_t) (wsi_display_mode_refresh(display_mode) * 1000 + 0.5); + } + +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, +- VkDisplayKHR display, +- uint32_t *pPropertyCount, +- VkDisplayModePropertiesKHR *pProperties) ++VkResult ++wsi_display_get_display_mode_properties(VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ VkDisplayKHR display, ++ uint32_t *pPropertyCount, ++ VkDisplayModePropertiesKHR *pProperties) + { +- VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); +- struct wsi_device *wsi_device = pdevice->wsi_device; + struct wsi_display_connector *connector = + wsi_display_connector_from_handle(display); + +@@ -713,13 +780,28 @@ wsi_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, + } + + VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, +- VkDisplayKHR display, +- uint32_t *pPropertyCount, +- VkDisplayModeProperties2KHR *pProperties) ++wsi_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, ++ VkDisplayKHR display, ++ uint32_t *pPropertyCount, ++ VkDisplayModePropertiesKHR *pProperties) + { + VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); + struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_display_get_display_mode_properties(physicalDevice, ++ wsi_device, ++ display, ++ pPropertyCount, ++ pProperties); ++} ++ ++VkResult ++wsi_display_get_display_mode_properties2(VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ VkDisplayKHR display, ++ uint32_t *pPropertyCount, ++ VkDisplayModeProperties2KHR *pProperties) ++{ + struct wsi_display_connector *connector = + wsi_display_connector_from_handle(display); + +@@ -738,6 +820,22 @@ wsi_GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, + return vk_outarray_status(&conn); + } + ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_GetDisplayModeProperties2KHR(VkPhysicalDevice physicalDevice, ++ VkDisplayKHR display, ++ uint32_t *pPropertyCount, ++ VkDisplayModeProperties2KHR *pProperties) ++{ ++ VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); ++ struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_display_get_display_mode_properties2(physicalDevice, ++ wsi_device, ++ display, ++ pPropertyCount, ++ pProperties); ++} ++ + static bool + wsi_display_mode_matches_vk(wsi_display_mode *wsi, + const VkDisplayModeParametersKHR *vk) +@@ -750,12 +848,13 @@ wsi_display_mode_matches_vk(wsi_display_mode *wsi, + /* + * Implement vkCreateDisplayModeKHR (VK_KHR_display) + */ +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, +- VkDisplayKHR display, +- const VkDisplayModeCreateInfoKHR *pCreateInfo, +- const VkAllocationCallbacks *pAllocator, +- VkDisplayModeKHR *pMode) ++VkResult ++wsi_display_create_display_mode(VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ VkDisplayKHR display, ++ const VkDisplayModeCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *pAllocator, ++ VkDisplayModeKHR *pMode) + { + struct wsi_display_connector *connector = + wsi_display_connector_from_handle(display); +@@ -779,11 +878,31 @@ wsi_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, + return VK_ERROR_INITIALIZATION_FAILED; + } + ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_CreateDisplayModeKHR(VkPhysicalDevice physicalDevice, ++ VkDisplayKHR display, ++ const VkDisplayModeCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *pAllocator, ++ VkDisplayModeKHR *pMode) ++{ ++ VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); ++ struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_display_create_display_mode(physicalDevice, ++ wsi_device, ++ display, ++ pCreateInfo, ++ pAllocator, ++ pMode); ++} ++ ++ + /* + * Implement vkGetDisplayPlaneCapabilities + */ +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, ++VkResult ++wsi_get_display_plane_capabilities(VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, + VkDisplayModeKHR _mode, + uint32_t planeIndex, + VkDisplayPlaneCapabilitiesKHR *pCapabilities) +@@ -812,15 +931,33 @@ wsi_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, + } + + VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice, +- const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo, +- VkDisplayPlaneCapabilities2KHR *pCapabilities) ++wsi_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice, ++ VkDisplayModeKHR _mode, ++ uint32_t planeIndex, ++ VkDisplayPlaneCapabilitiesKHR *pCapabilities) ++{ ++ VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); ++ struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_get_display_plane_capabilities(physicalDevice, ++ wsi_device, ++ _mode, ++ planeIndex, ++ pCapabilities); ++} ++ ++VkResult ++wsi_get_display_plane_capabilities2( ++ VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo, ++ VkDisplayPlaneCapabilities2KHR *pCapabilities) + { + assert(pCapabilities->sType == + VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR); + + VkResult result = +- wsi_GetDisplayPlaneCapabilitiesKHR(physicalDevice, ++ wsi_get_display_plane_capabilities(physicalDevice, wsi_device, + pDisplayPlaneInfo->mode, + pDisplayPlaneInfo->planeIndex, + &pCapabilities->capabilities); +@@ -843,18 +980,31 @@ wsi_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice, + } + + VKAPI_ATTR VkResult VKAPI_CALL +-wsi_CreateDisplayPlaneSurfaceKHR(VkInstance _instance, +- const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, +- const VkAllocationCallbacks *pAllocator, +- VkSurfaceKHR *pSurface) ++wsi_GetDisplayPlaneCapabilities2KHR(VkPhysicalDevice physicalDevice, ++ const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo, ++ VkDisplayPlaneCapabilities2KHR *pCapabilities) ++{ ++ VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); ++ struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_get_display_plane_capabilities2(physicalDevice, ++ wsi_device, ++ pDisplayPlaneInfo, ++ pCapabilities); ++} ++ ++VkResult ++wsi_create_display_surface(VkInstance instance, ++ const VkAllocationCallbacks *allocator, ++ const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface) + { +- VK_FROM_HANDLE(vk_instance, instance, _instance); + VkIcdSurfaceDisplay *surface; + + assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR); + +- surface = vk_zalloc2(&instance->alloc, pAllocator, sizeof(*surface), 8, +- VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); ++ surface = vk_zalloc(allocator, sizeof(*surface), 8, ++ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (surface == NULL) + return VK_ERROR_OUT_OF_HOST_MEMORY; + +@@ -873,6 +1023,27 @@ wsi_CreateDisplayPlaneSurfaceKHR(VkInstance _instance, + return VK_SUCCESS; + } + ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_CreateDisplayPlaneSurfaceKHR(VkInstance _instance, ++ const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *pAllocator, ++ VkSurfaceKHR *pSurface) ++{ ++ VK_FROM_HANDLE(vk_instance, instance, _instance); ++ const VkAllocationCallbacks *allocator; ++ ++ if (pAllocator) ++ allocator = pAllocator; ++ else ++ allocator = &instance->alloc; ++ ++ return wsi_create_display_surface(_instance, ++ allocator, ++ pCreateInfo, ++ pSurface); ++} ++ ++ + static VkResult + wsi_display_surface_get_support(VkIcdSurfaceBase *surface, + struct wsi_device *wsi_device, +@@ -2224,12 +2395,11 @@ wsi_display_finish_wsi(struct wsi_device *wsi_device, + /* + * Implement vkReleaseDisplay + */ +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, +- VkDisplayKHR display) ++VkResult ++wsi_release_display(VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ VkDisplayKHR display) + { +- VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); +- struct wsi_device *wsi_device = pdevice->wsi_device; + struct wsi_display *wsi = + (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + +@@ -2646,12 +2816,23 @@ wsi_display_find_crtc_for_output(xcb_connection_t *connection, + } + + VKAPI_ATTR VkResult VKAPI_CALL +-wsi_AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, +- Display *dpy, +- VkDisplayKHR display) ++wsi_ReleaseDisplayEXT(VkPhysicalDevice physicalDevice, ++ VkDisplayKHR display) + { + VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); + struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_release_display(physicalDevice, ++ wsi_device, ++ display); ++} ++ ++VkResult ++wsi_acquire_xlib_display(VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ Display *dpy, ++ VkDisplayKHR display) ++{ + struct wsi_display *wsi = + (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + xcb_connection_t *connection = XGetXCBConnection(dpy); +@@ -2710,13 +2891,26 @@ wsi_AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, + } + + VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, ++wsi_AcquireXlibDisplayEXT(VkPhysicalDevice physicalDevice, ++ Display *dpy, ++ VkDisplayKHR display) ++{ ++ VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); ++ struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_acquire_xlib_display(physicalDevice, ++ wsi_device, ++ dpy, ++ display); ++} ++ ++VkResult ++wsi_get_randr_output_display(VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, + Display *dpy, + RROutput rrOutput, + VkDisplayKHR *pDisplay) + { +- VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); +- struct wsi_device *wsi_device = pdevice->wsi_device; + xcb_connection_t *connection = XGetXCBConnection(dpy); + struct wsi_display_connector *connector = + wsi_display_get_output(wsi_device, connection, +@@ -2729,16 +2923,31 @@ wsi_GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, + return VK_SUCCESS; + } + ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_GetRandROutputDisplayEXT(VkPhysicalDevice physicalDevice, ++ Display *dpy, ++ RROutput rrOutput, ++ VkDisplayKHR *pDisplay) ++{ ++ VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); ++ struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_get_randr_output_display(physicalDevice, ++ wsi_device, ++ dpy, ++ rrOutput, ++ pDisplay); ++} ++ + #endif + + /* VK_EXT_display_control */ +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_DisplayPowerControlEXT(VkDevice _device, +- VkDisplayKHR display, +- const VkDisplayPowerInfoEXT *pDisplayPowerInfo) ++VkResult ++wsi_display_power_control(VkDevice _device, ++ struct wsi_device *wsi_device, ++ VkDisplayKHR display, ++ const VkDisplayPowerInfoEXT *pDisplayPowerInfo) + { +- VK_FROM_HANDLE(vk_device, device, _device); +- struct wsi_device *wsi_device = device->physical->wsi_device; + struct wsi_display *wsi = + (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + struct wsi_display_connector *connector = +@@ -2766,6 +2975,20 @@ wsi_DisplayPowerControlEXT(VkDevice _device, + return VK_SUCCESS; + } + ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_DisplayPowerControlEXT(VkDevice _device, ++ VkDisplayKHR display, ++ const VkDisplayPowerInfoEXT *pDisplayPowerInfo) ++{ ++ VK_FROM_HANDLE(vk_device, device, _device); ++ struct wsi_device *wsi_device = device->physical->wsi_device; ++ ++ return wsi_display_power_control(_device, ++ wsi_device, ++ display, ++ pDisplayPowerInfo); ++} ++ + VkResult + wsi_register_device_event(VkDevice _device, + struct wsi_device *wsi_device, +@@ -2774,7 +2997,6 @@ wsi_register_device_event(VkDevice _device, + struct vk_sync **sync_out, + int sync_fd) + { +- VK_FROM_HANDLE(vk_device, device, _device); + struct wsi_display *wsi = + (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + VkResult ret = VK_SUCCESS; +@@ -2808,6 +3030,8 @@ wsi_register_device_event(VkDevice _device, + mtx_unlock(&wsi->wait_mutex); + + if (sync_out) { ++ VK_FROM_HANDLE(vk_device, device, _device); ++ + ret = wsi_display_sync_create(device, fence, sync_out); + if (ret != VK_SUCCESS) + wsi_display_fence_destroy(fence); +@@ -2856,7 +3080,6 @@ wsi_register_display_event(VkDevice _device, + struct vk_sync **sync_out, + int sync_fd) + { +- VK_FROM_HANDLE(vk_device, device, _device); + struct wsi_display *wsi = + (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + struct wsi_display_fence *fence; +@@ -2875,6 +3098,8 @@ wsi_register_display_event(VkDevice _device, + + if (ret == VK_SUCCESS) { + if (sync_out) { ++ VK_FROM_HANDLE(vk_device, device, _device); ++ + ret = wsi_display_sync_create(device, fence, sync_out); + if (ret != VK_SUCCESS) + wsi_display_fence_destroy(fence); +@@ -2933,14 +3158,13 @@ wsi_display_setup_syncobj_fd(struct wsi_device *wsi_device, + wsi->syncobj_fd = fd; + } + +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetSwapchainCounterEXT(VkDevice _device, +- VkSwapchainKHR _swapchain, +- VkSurfaceCounterFlagBitsEXT counter, +- uint64_t *pCounterValue) ++VkResult ++wsi_get_swapchain_counter(VkDevice _device, ++ struct wsi_device *wsi_device, ++ VkSwapchainKHR _swapchain, ++ VkSurfaceCounterFlagBitsEXT counter, ++ uint64_t *pCounterValue) + { +- VK_FROM_HANDLE(vk_device, device, _device); +- struct wsi_device *wsi_device = device->physical->wsi_device; + struct wsi_display *wsi = + (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + struct wsi_display_swapchain *swapchain = +@@ -2965,13 +3189,27 @@ wsi_GetSwapchainCounterEXT(VkDevice _device, + } + + VKAPI_ATTR VkResult VKAPI_CALL +-wsi_AcquireDrmDisplayEXT(VkPhysicalDevice physicalDevice, +- int32_t drmFd, +- VkDisplayKHR display) ++wsi_GetSwapchainCounterEXT(VkDevice _device, ++ VkSwapchainKHR _swapchain, ++ VkSurfaceCounterFlagBitsEXT counter, ++ uint64_t *pCounterValue) + { +- VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); +- struct wsi_device *wsi_device = pdevice->wsi_device; ++ VK_FROM_HANDLE(vk_device, device, _device); ++ struct wsi_device *wsi_device = device->physical->wsi_device; + ++ return wsi_get_swapchain_counter(_device, ++ wsi_device, ++ _swapchain, ++ counter, ++ pCounterValue); ++} ++ ++VkResult ++wsi_acquire_drm_display(VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ int drmFd, ++ VkDisplayKHR display) ++{ + if (!wsi_device_matches_drm_fd(wsi_device, drmFd)) + return VK_ERROR_UNKNOWN; + +@@ -2998,14 +3236,26 @@ wsi_AcquireDrmDisplayEXT(VkPhysicalDevice physicalDevice, + } + + VKAPI_ATTR VkResult VKAPI_CALL +-wsi_GetDrmDisplayEXT(VkPhysicalDevice physicalDevice, +- int32_t drmFd, +- uint32_t connectorId, +- VkDisplayKHR *pDisplay) ++wsi_AcquireDrmDisplayEXT(VkPhysicalDevice physicalDevice, ++ int32_t drmFd, ++ VkDisplayKHR display) + { + VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); + struct wsi_device *wsi_device = pdevice->wsi_device; + ++ return wsi_acquire_drm_display(physicalDevice, ++ wsi_device, ++ drmFd, ++ display); ++} ++ ++VkResult ++wsi_get_drm_display(VkPhysicalDevice physicalDevice, ++ struct wsi_device *wsi_device, ++ int drmFd, ++ int connectorId, ++ VkDisplayKHR *pDisplay) ++{ + if (!wsi_device_matches_drm_fd(wsi_device, drmFd)) + return VK_ERROR_UNKNOWN; + +@@ -3020,3 +3270,20 @@ wsi_GetDrmDisplayEXT(VkPhysicalDevice physicalDevice, + *pDisplay = wsi_display_connector_to_handle(connector); + return VK_SUCCESS; + } ++ ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_GetDrmDisplayEXT(VkPhysicalDevice physicalDevice, ++ int32_t drmFd, ++ uint32_t connectorId, ++ VkDisplayKHR *pDisplay) ++{ ++ VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); ++ struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_get_drm_display(physicalDevice, ++ wsi_device, ++ drmFd, ++ connectorId, ++ pDisplay); ++} ++ +diff --git a/src/vulkan/wsi/wsi_common_display.h b/src/vulkan/wsi/wsi_common_display.h +index dd54b9b775f..cdfbda50107 100644 +--- a/src/vulkan/wsi/wsi_common_display.h ++++ b/src/vulkan/wsi/wsi_common_display.h +@@ -29,7 +29,112 @@ + + struct vk_sync; + ++VkResult ++wsi_display_get_physical_device_display_properties( ++ VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ uint32_t *property_count, ++ VkDisplayPropertiesKHR *properties); ++ ++VkResult ++wsi_display_get_physical_device_display_properties2( ++ VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ uint32_t *pPropertyCount, ++ VkDisplayProperties2KHR *pProperties); ++ ++VkResult ++wsi_display_get_physical_device_display_plane_properties( ++ VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ uint32_t *property_count, ++ VkDisplayPlanePropertiesKHR *properties); ++ ++VkResult ++wsi_display_get_physical_device_display_plane_properties2( ++ VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ uint32_t *property_count, ++ VkDisplayPlaneProperties2KHR *properties); ++ ++VkResult ++wsi_display_get_display_plane_supported_displays( ++ VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ uint32_t plane_index, ++ uint32_t *display_count, ++ VkDisplayKHR *displays); ++ ++VkResult ++wsi_display_get_display_mode_properties(VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ VkDisplayKHR display, ++ uint32_t *property_count, ++ VkDisplayModePropertiesKHR *properties); ++ ++VkResult ++wsi_display_get_display_mode_properties2(VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ VkDisplayKHR display, ++ uint32_t *property_count, ++ VkDisplayModeProperties2KHR *properties); ++ ++VkResult ++wsi_display_create_display_mode(VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ VkDisplayKHR display, ++ const VkDisplayModeCreateInfoKHR *create_info, ++ const VkAllocationCallbacks *allocator, ++ VkDisplayModeKHR *mode); ++ ++VkResult ++wsi_get_display_plane_capabilities(VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ VkDisplayModeKHR mode_khr, ++ uint32_t plane_index, ++ VkDisplayPlaneCapabilitiesKHR *capabilities); ++ ++VkResult ++wsi_get_display_plane_capabilities2(VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ const VkDisplayPlaneInfo2KHR *pDisplayPlaneInfo, ++ VkDisplayPlaneCapabilities2KHR *capabilities); ++ ++VkResult ++wsi_create_display_surface(VkInstance instance, ++ const VkAllocationCallbacks *pAllocator, ++ const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface); ++ ++VkResult ++wsi_release_display(VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ VkDisplayKHR display); ++ ++ ++#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT ++VkResult ++wsi_acquire_xlib_display(VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ Display *dpy, ++ VkDisplayKHR display); ++ ++VkResult ++wsi_get_randr_output_display(VkPhysicalDevice physical_device, ++ struct wsi_device *wsi_device, ++ Display *dpy, ++ RROutput output, ++ VkDisplayKHR *display); ++ ++#endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */ ++ + /* VK_EXT_display_control */ ++VkResult ++wsi_display_power_control(VkDevice device, ++ struct wsi_device *wsi_device, ++ VkDisplayKHR display, ++ const VkDisplayPowerInfoEXT *display_power_info); ++ + VkResult + wsi_register_device_event(VkDevice device, + struct wsi_device *wsi_device, +@@ -47,4 +152,25 @@ wsi_register_display_event(VkDevice device, + struct vk_sync **sync, + int sync_fd); + ++VkResult ++wsi_get_swapchain_counter(VkDevice device, ++ struct wsi_device *wsi_device, ++ VkSwapchainKHR swapchain, ++ VkSurfaceCounterFlagBitsEXT flag_bits, ++ uint64_t *value); ++ ++/* VK_EXT_acquire_drm_display */ ++VkResult ++wsi_acquire_drm_display(VkPhysicalDevice pDevice, ++ struct wsi_device *wsi_device, ++ int drmFd, ++ VkDisplayKHR display); ++ ++VkResult ++wsi_get_drm_display(VkPhysicalDevice pDevice, ++ struct wsi_device *wsi_device, ++ int drmFd, ++ int connectorId, ++ VkDisplayKHR *display); ++ + #endif +diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c +index b1e5ea8bdfd..bffc52da13f 100644 +--- a/src/vulkan/wsi/wsi_common_wayland.c ++++ b/src/vulkan/wsi/wsi_common_wayland.c +@@ -43,6 +43,8 @@ + #include "vk_util.h" + #include "wsi_common_entrypoints.h" + #include "wsi_common_private.h" ++#include "wsi_common_wayland.h" ++#include "wayland-drm-client-protocol.h" + #include "linux-dmabuf-unstable-v1-client-protocol.h" + + #include +@@ -825,7 +827,7 @@ registry_handle_global(void *data, struct wl_registry *registry, + + display->wl_drm = + wl_registry_bind(registry, name, &wl_drm_interface, 2); +- wl_drm_add_listener(display->drm.wl_drm, &drm_listener, display); ++ wl_drm_add_listener(display->wl_drm, &drm_listener, display); + } + + if (strcmp(interface, zwp_linux_dmabuf_v1_interface.name) == 0 && version >= 3) { +@@ -1041,13 +1043,10 @@ wsi_wl_display_destroy(struct wsi_wl_display *display) + vk_free(wsi->alloc, display); + } + +-VKAPI_ATTR VkBool32 VKAPI_CALL +-wsi_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, +- uint32_t queueFamilyIndex, +- struct wl_display *wl_display) ++VkBool32 ++wsi_wl_get_presentation_support(struct wsi_device *wsi_device, ++ struct wl_display *wl_display) + { +- VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); +- struct wsi_device *wsi_device = pdevice->wsi_device; + struct wsi_wayland *wsi = + (struct wsi_wayland *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND]; + +@@ -1060,6 +1059,18 @@ wsi_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevi + return ret == VK_SUCCESS; + } + ++VKAPI_ATTR VkBool32 VKAPI_CALL ++wsi_GetPhysicalDeviceWaylandPresentationSupportKHR(VkPhysicalDevice physicalDevice, ++ uint32_t queueFamilyIndex, ++ struct wl_display *wl_display) ++{ ++ VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); ++ struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_wl_get_presentation_support(wsi_device, ++ wl_display); ++} ++ + static VkResult + wsi_wl_surface_get_support(VkIcdSurfaceBase *surface, + struct wsi_device *wsi_device, +@@ -1536,20 +1547,17 @@ fail: + return result; + } + +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_CreateWaylandSurfaceKHR(VkInstance _instance, +- const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, +- const VkAllocationCallbacks *pAllocator, +- VkSurfaceKHR *pSurface) ++VkResult wsi_create_wl_surface(const VkAllocationCallbacks *allocator, ++ const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface) + { +- VK_FROM_HANDLE(vk_instance, instance, _instance); + struct wsi_wl_surface *wsi_wl_surface; + VkIcdSurfaceWayland *surface; + + assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR); + +- wsi_wl_surface = vk_zalloc2(&instance->alloc, pAllocator, sizeof *wsi_wl_surface, +- 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); ++ wsi_wl_surface = vk_zalloc(allocator, sizeof *wsi_wl_surface, 8, ++ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (wsi_wl_surface == NULL) + return VK_ERROR_OUT_OF_HOST_MEMORY; + +@@ -1564,6 +1572,25 @@ wsi_CreateWaylandSurfaceKHR(VkInstance _instance, + return VK_SUCCESS; + } + ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_CreateWaylandSurfaceKHR(VkInstance _instance, ++ const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *pAllocator, ++ VkSurfaceKHR *pSurface) ++{ ++ VK_FROM_HANDLE(vk_instance, instance, _instance); ++ const VkAllocationCallbacks *allocator; ++ ++ if (pAllocator) ++ allocator = pAllocator; ++ else ++ allocator = &instance->alloc; ++ ++ return wsi_create_wl_surface(allocator, ++ pCreateInfo, ++ pSurface); ++} ++ + static struct wsi_image * + wsi_wl_swapchain_get_wsi_image(struct wsi_swapchain *wsi_chain, + uint32_t image_index) +diff --git a/src/vulkan/wsi/wsi_common_wayland.h b/src/vulkan/wsi/wsi_common_wayland.h +new file mode 100644 +index 00000000000..effba0ebba4 +--- /dev/null ++++ b/src/vulkan/wsi/wsi_common_wayland.h +@@ -0,0 +1,35 @@ ++/* ++ * Copyright © 2015 Intel Corporation ++ * ++ * 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. ++ */ ++#ifndef WSI_COMMON_WAYLAND_H ++#define WSI_COMMON_WAYLAND_H ++ ++#include "wsi_common.h" ++ ++VkBool32 ++wsi_wl_get_presentation_support(struct wsi_device *wsi_device, ++ struct wl_display *wl_display); ++ ++VkResult wsi_create_wl_surface(const VkAllocationCallbacks *pAllocator, ++ const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface); ++#endif +diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c +index 2a988b6d2a8..95336222550 100644 +--- a/src/vulkan/wsi/wsi_common_x11.c ++++ b/src/vulkan/wsi/wsi_common_x11.c +@@ -52,6 +52,7 @@ + #include "vk_enum_to_str.h" + #include "wsi_common_entrypoints.h" + #include "wsi_common_private.h" ++#include "wsi_common_x11.h" + #include "wsi_common_queue.h" + + #ifdef HAVE_SYS_SHM_H +@@ -543,14 +544,12 @@ visual_supported(xcb_visualtype_t *visual) + visual->_class == XCB_VISUAL_CLASS_DIRECT_COLOR; + } + +-VKAPI_ATTR VkBool32 VKAPI_CALL +-wsi_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, +- uint32_t queueFamilyIndex, +- xcb_connection_t *connection, +- xcb_visualid_t visual_id) ++VkBool32 wsi_get_physical_device_xcb_presentation_support( ++ struct wsi_device *wsi_device, ++ uint32_t queueFamilyIndex, ++ xcb_connection_t *connection, ++ xcb_visualid_t visual_id) + { +- VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); +- struct wsi_device *wsi_device = pdevice->wsi_device; + struct wsi_x11_connection *wsi_conn = + wsi_x11_get_connection(wsi_device, connection); + +@@ -568,6 +567,21 @@ wsi_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, + return true; + } + ++VKAPI_ATTR VkBool32 VKAPI_CALL ++wsi_GetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, ++ uint32_t queueFamilyIndex, ++ xcb_connection_t *connection, ++ xcb_visualid_t visual_id) ++{ ++ VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); ++ struct wsi_device *wsi_device = pdevice->wsi_device; ++ ++ return wsi_get_physical_device_xcb_presentation_support(wsi_device, ++ queueFamilyIndex, ++ connection, ++ visual_id); ++} ++ + VKAPI_ATTR VkBool32 VKAPI_CALL + wsi_GetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, +@@ -876,19 +890,16 @@ x11_surface_get_present_rectangles(VkIcdSurfaceBase *icd_surface, + return vk_outarray_status(&out); + } + +-VKAPI_ATTR VkResult VKAPI_CALL +-wsi_CreateXcbSurfaceKHR(VkInstance _instance, +- const VkXcbSurfaceCreateInfoKHR *pCreateInfo, +- const VkAllocationCallbacks *pAllocator, +- VkSurfaceKHR *pSurface) ++VkResult wsi_create_xcb_surface(const VkAllocationCallbacks *allocator, ++ const VkXcbSurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface) + { +- VK_FROM_HANDLE(vk_instance, instance, _instance); + VkIcdSurfaceXcb *surface; + + assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR); + +- surface = vk_alloc2(&instance->alloc, pAllocator, sizeof *surface, 8, +- VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); ++ surface = vk_alloc(allocator, sizeof *surface, 8, ++ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (surface == NULL) + return VK_ERROR_OUT_OF_HOST_MEMORY; + +@@ -901,18 +912,34 @@ wsi_CreateXcbSurfaceKHR(VkInstance _instance, + } + + VKAPI_ATTR VkResult VKAPI_CALL +-wsi_CreateXlibSurfaceKHR(VkInstance _instance, +- const VkXlibSurfaceCreateInfoKHR *pCreateInfo, +- const VkAllocationCallbacks *pAllocator, +- VkSurfaceKHR *pSurface) ++wsi_CreateXcbSurfaceKHR(VkInstance _instance, ++ const VkXcbSurfaceCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *pAllocator, ++ VkSurfaceKHR *pSurface) + { + VK_FROM_HANDLE(vk_instance, instance, _instance); ++ const VkAllocationCallbacks *allocator; ++ ++ if (pAllocator) ++ allocator = pAllocator; ++ else ++ allocator = &instance->alloc; ++ ++ return wsi_create_xcb_surface(allocator, ++ pCreateInfo, ++ pSurface); ++} ++ ++VkResult wsi_create_xlib_surface(const VkAllocationCallbacks *allocator, ++ const VkXlibSurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface) ++{ + VkIcdSurfaceXlib *surface; + + assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR); + +- surface = vk_alloc2(&instance->alloc, pAllocator, sizeof *surface, 8, +- VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); ++ surface = vk_alloc(allocator, sizeof *surface, 8, ++ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (surface == NULL) + return VK_ERROR_OUT_OF_HOST_MEMORY; + +@@ -939,6 +966,25 @@ struct x11_image { + uint8_t * shmaddr; + }; + ++VKAPI_ATTR VkResult VKAPI_CALL ++wsi_CreateXlibSurfaceKHR(VkInstance _instance, ++ const VkXlibSurfaceCreateInfoKHR *pCreateInfo, ++ const VkAllocationCallbacks *pAllocator, ++ VkSurfaceKHR *pSurface) ++{ ++ VK_FROM_HANDLE(vk_instance, instance, _instance); ++ const VkAllocationCallbacks *allocator; ++ ++ if (pAllocator) ++ allocator = pAllocator; ++ else ++ allocator = &instance->alloc; ++ ++ return wsi_create_xlib_surface(allocator, ++ pCreateInfo, ++ pSurface); ++} ++ + struct x11_swapchain { + struct wsi_swapchain base; + +diff --git a/src/vulkan/wsi/wsi_common_x11.h b/src/vulkan/wsi/wsi_common_x11.h +new file mode 100644 +index 00000000000..e4b1e94a8c8 +--- /dev/null ++++ b/src/vulkan/wsi/wsi_common_x11.h +@@ -0,0 +1,41 @@ ++/* ++ * Copyright © 2015 Intel Corporation ++ * ++ * 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. ++ */ ++#ifndef WSI_COMMON_X11_H ++#define WSI_COMMON_X11_H ++ ++#include "wsi_common.h" ++ ++VkBool32 wsi_get_physical_device_xcb_presentation_support( ++ struct wsi_device *wsi_device, ++ uint32_t queueFamilyIndex, ++ xcb_connection_t* connection, ++ xcb_visualid_t visual_id); ++ ++VkResult wsi_create_xcb_surface(const VkAllocationCallbacks *pAllocator, ++ const VkXcbSurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface); ++ ++VkResult wsi_create_xlib_surface(const VkAllocationCallbacks *pAllocator, ++ const VkXlibSurfaceCreateInfoKHR *pCreateInfo, ++ VkSurfaceKHR *pSurface); ++#endif +-- +2.17.1 + diff --git a/package/mesa3d/0049-vulkan-wsi-Disable-use-of-VK_EXT_pci_bus_info.patch b/package/mesa3d/0049-vulkan-wsi-Disable-use-of-VK_EXT_pci_bus_info.patch new file mode 100644 index 00000000..3613675a --- /dev/null +++ b/package/mesa3d/0049-vulkan-wsi-Disable-use-of-VK_EXT_pci_bus_info.patch @@ -0,0 +1,80 @@ +From eefa4483028dab0bd5b4e21b4179b151696ca4da Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 30 Jul 2021 15:34:13 +0100 +Subject: [PATCH 049/168] vulkan/wsi: Disable use of VK_EXT_pci_bus_info + +The VK_EXT_pci_bus_info related code has been wrapped in +VULKAN_WSI_USE_PCI_BUS_INFO, effectively disabling it. + +Not all platforms support the VK_EXT_pci_bus_info extension. +A better fix might be to pass another parameter to wsi_device_init, +to indicate that the device is a PCI one. +--- + src/vulkan/wsi/wsi_common.c | 6 ++++++ + src/vulkan/wsi/wsi_common.h | 3 +++ + src/vulkan/wsi/wsi_common_drm.c | 4 ++++ + 3 files changed, 13 insertions(+) + +diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c +index 815ecc07c09..65049bd5f06 100644 +--- a/src/vulkan/wsi/wsi_common.c ++++ b/src/vulkan/wsi/wsi_common.c +@@ -92,12 +92,18 @@ wsi_device_init2(struct wsi_device *wsi, + + wsi->drm_info.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT; ++#if defined(VULKAN_WSI_USE_PCI_BUS_INFO) + wsi->pci_bus_info.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT; + wsi->pci_bus_info.pNext = &wsi->drm_info; ++#endif + VkPhysicalDeviceProperties2 pdp2 = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, ++#if defined(VULKAN_WSI_USE_PCI_BUS_INFO) + .pNext = &wsi->pci_bus_info, ++#else ++ .pNext = &wsi->drm_info, ++#endif + }; + GetPhysicalDeviceProperties2(pdevice, &pdp2); + +diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h +index 0f5790b2213..aec1021113e 100644 +--- a/src/vulkan/wsi/wsi_common.h ++++ b/src/vulkan/wsi/wsi_common.h +@@ -115,7 +115,10 @@ struct wsi_device { + uint32_t queue_family_count; + + VkPhysicalDeviceDrmPropertiesEXT drm_info; ++ ++#if defined(VULKAN_WSI_USE_PCI_BUS_INFO) + VkPhysicalDevicePCIBusInfoPropertiesEXT pci_bus_info; ++#endif + + VkExternalSemaphoreHandleTypeFlags semaphore_export_handle_types; + +diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c +index a94be2aeb42..0a7887368fc 100644 +--- a/src/vulkan/wsi/wsi_common_drm.c ++++ b/src/vulkan/wsi/wsi_common_drm.c +@@ -275,6 +275,7 @@ wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd) + if (ret) + return false; + ++#if defined(VULKAN_WSI_USE_PCI_BUS_INFO) + bool match = false; + switch (fd_device->bustype) { + case DRM_BUS_PCI: +@@ -287,6 +288,9 @@ wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd) + default: + break; + } ++#else ++ const bool match = true; ++#endif + + drmFreeDevice(&fd_device); + +-- +2.17.1 + diff --git a/package/mesa3d/0050-vulkan-wsi-default-to-force_bgra8_unorm_first-true.patch b/package/mesa3d/0050-vulkan-wsi-default-to-force_bgra8_unorm_first-true.patch new file mode 100644 index 00000000..59d43536 --- /dev/null +++ b/package/mesa3d/0050-vulkan-wsi-default-to-force_bgra8_unorm_first-true.patch @@ -0,0 +1,34 @@ +From 367580365944010cb0b605a03d750dcfc0dd7223 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 2 Aug 2021 16:29:36 +0100 +Subject: [PATCH 050/168] vulkan/wsi: default to force_bgra8_unorm_first true + +If VULKAN_WSI_BGRA8_SNORM_FIRST is not defined, default to +force_bgra8_unorm_first true. + +This brings Mesa WSI into line with IMG WSI with regards to the +VK_FORMAT_B8G8R8A8_UNORM and VK_FORMAT_B8G8R8A8_SRGB formats. +With this change, the IMG Vulkan unit test, vkbonjour, will default +to VK_FORMAT_B8G8R8A8_UNORM rather than VK_FORMAT_B8G8R8A8_SRGB. +--- + src/vulkan/wsi/wsi_common.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c +index 65049bd5f06..389117ceb2e 100644 +--- a/src/vulkan/wsi/wsi_common.c ++++ b/src/vulkan/wsi/wsi_common.c +@@ -237,6 +237,10 @@ wsi_device_init2(struct wsi_device *wsi, + driQueryOptionb(dri_options, "vk_wsi_force_bgra8_unorm_first"); + } + } ++#if !defined(VULKAN_WSI_BGRA8_SNORM_FIRST) ++ else ++ wsi->force_bgra8_unorm_first = true; ++#endif + + return VK_SUCCESS; + #if defined(VK_USE_PLATFORM_XCB_KHR) || \ +-- +2.17.1 + diff --git a/package/mesa3d/0051-vulkan-wsi-enable-additional-formats-for-Display.patch b/package/mesa3d/0051-vulkan-wsi-enable-additional-formats-for-Display.patch new file mode 100644 index 00000000..ee164684 --- /dev/null +++ b/package/mesa3d/0051-vulkan-wsi-enable-additional-formats-for-Display.patch @@ -0,0 +1,27 @@ +From ce0bc276a1674ea1573df4b522ac3b70154c7c92 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 3 Aug 2021 15:44:57 +0100 +Subject: [PATCH 051/168] vulkan/wsi: enable additional formats for Display + +Add VK_FORMAT_R5G6B5_UNORM_PACK16. + +This is for compatibility with IMG WSI. +--- + src/vulkan/wsi/wsi_common_display.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c +index 7dd6af7c287..e0232e08e1d 100644 +--- a/src/vulkan/wsi/wsi_common_display.c ++++ b/src/vulkan/wsi/wsi_common_display.c +@@ -1134,6 +1134,7 @@ static const struct { + } available_surface_formats[] = { + { .format = VK_FORMAT_B8G8R8A8_SRGB, .drm_format = DRM_FORMAT_XRGB8888 }, + { .format = VK_FORMAT_B8G8R8A8_UNORM, .drm_format = DRM_FORMAT_XRGB8888 }, ++ { .format = VK_FORMAT_R5G6B5_UNORM_PACK16, .drm_format = DRM_FORMAT_RGB565 }, + }; + + static void +-- +2.17.1 + diff --git a/package/mesa3d/0052-mesa-partially-revert-pbuffer-attribute-removal.patch b/package/mesa3d/0052-mesa-partially-revert-pbuffer-attribute-removal.patch new file mode 100644 index 00000000..8df51011 --- /dev/null +++ b/package/mesa3d/0052-mesa-partially-revert-pbuffer-attribute-removal.patch @@ -0,0 +1,51 @@ +From 505efe31a09ed9ad8291976b95ac77db9397fdcf Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 16 Sep 2021 17:46:28 +0100 +Subject: [PATCH 052/168] mesa: partially revert pbuffer attribute removal + +This partially reverts commit 5ffd1ebe6b3c8c7dd316dd47fac088044222e6ef +("mesa: Remove misc pbuffer attributes from struct gl_config"). + +The IMG PowerVR driver sets meaningful values for the maximum +pbuffer width, height and pixels. +--- + src/gallium/frontends/dri/dri_util.c | 6 +++--- + src/mesa/main/glconfig.h | 5 +++++ + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/src/gallium/frontends/dri/dri_util.c b/src/gallium/frontends/dri/dri_util.c +index 32ae2b6fec7..ca2655ec536 100644 +--- a/src/gallium/frontends/dri/dri_util.c ++++ b/src/gallium/frontends/dri/dri_util.c +@@ -338,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: +diff --git a/src/mesa/main/glconfig.h b/src/mesa/main/glconfig.h +index d54a4f75cfd..f9aa5a06940 100644 +--- a/src/mesa/main/glconfig.h ++++ b/src/mesa/main/glconfig.h +@@ -27,6 +27,11 @@ struct gl_config + /* ARB_multisample / SGIS_multisample */ + GLuint samples; + ++ /* GLX 1.3 */ ++ GLint maxPbufferWidth; ++ GLint maxPbufferHeight; ++ GLint maxPbufferPixels; ++ + /* OML_swap_method */ + GLint swapMethod; + +-- +2.17.1 + diff --git a/package/mesa3d/0053-egl_dri2-set-pbuffer-config-attribs-to-0-for-non-pbu.patch b/package/mesa3d/0053-egl_dri2-set-pbuffer-config-attribs-to-0-for-non-pbu.patch new file mode 100644 index 00000000..bf4250db --- /dev/null +++ b/package/mesa3d/0053-egl_dri2-set-pbuffer-config-attribs-to-0-for-non-pbu.patch @@ -0,0 +1,66 @@ +From 6aed2a165b43231f487a3c0cf2c7835541fe91bf Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jun 2014 13:43:03 +0100 +Subject: [PATCH 053/168] egl_dri2: set pbuffer config attribs to 0 for + non-pbuffer configs + +If the EGL_PBUFFER_BIT isn't set in the surface type, don't set the +EGL_MAX_PBUFFER_WIDTH, EGL_MAX_PBUFFER_HEIGHT and +EGL_MAX_PBUFFER_PIXELS attributes to non-zero values when adding an +EGL config. If the EGL_PBUFFER_BIT is set, don't override non-zero +values from the DRI config. +--- + src/egl/drivers/dri2/egl_dri2.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c +index 80ba3647a9a..4c52c9aac1a 100644 +--- a/src/egl/drivers/dri2/egl_dri2.c ++++ b/src/egl/drivers/dri2/egl_dri2.c +@@ -417,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 }; +@@ -540,11 +541,17 @@ 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; +@@ -624,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]); +-- +2.17.1 + diff --git a/package/mesa3d/0054-GL_ARB_geometry_shader4-entry-points.patch b/package/mesa3d/0054-GL_ARB_geometry_shader4-entry-points.patch new file mode 100644 index 00000000..77f70471 --- /dev/null +++ b/package/mesa3d/0054-GL_ARB_geometry_shader4-entry-points.patch @@ -0,0 +1,146 @@ +From 16f7e804e0f4625c17b86fe5247df7257bac7370 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 11 Nov 2021 12:09:38 +0000 +Subject: [PATCH 054/168] GL_ARB_geometry_shader4 entry points. + +--- + src/mapi/glapi/gen/ARB_geometry_shader4.xml | 97 +++++++++++++++++++++ + src/mapi/glapi/gen/gl_API.xml | 2 +- + src/mapi/glapi/gen/static_data.py | 4 + + 3 files changed, 102 insertions(+), 1 deletion(-) + create mode 100644 src/mapi/glapi/gen/ARB_geometry_shader4.xml + +diff --git a/src/mapi/glapi/gen/ARB_geometry_shader4.xml b/src/mapi/glapi/gen/ARB_geometry_shader4.xml +new file mode 100644 +index 00000000000..d92dc577b17 +--- /dev/null ++++ b/src/mapi/glapi/gen/ARB_geometry_shader4.xml +@@ -0,0 +1,97 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml +index 2526770fe35..0e30eb109ed 100644 +--- a/src/mapi/glapi/gen/gl_API.xml ++++ b/src/mapi/glapi/gen/gl_API.xml +@@ -8068,7 +8068,7 @@ + + + +- ++ + + + +diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py +index c81845d7f0c..c906125ba75 100644 +--- a/src/mapi/glapi/gen/static_data.py ++++ b/src/mapi/glapi/gen/static_data.py +@@ -1732,6 +1732,10 @@ offsets = { + "FramebufferRenderbufferEXT" : 1696, + "GetFramebufferAttachmentParameterivEXT" : 1697, + "GenerateMipmapEXT" : 1698, ++ "ProgramParameteriARB" : 1699, ++ "FramebufferTextureARB" : 1700, ++ "FramebufferTextureLayerARB" : 1701, ++ "FramebufferTextureFaceARB" : 1702, + } + + functions = [ +-- +2.17.1 + diff --git a/package/mesa3d/0055-egl-wayland-add-EGL_BUFFER_PRESERVED-support.patch b/package/mesa3d/0055-egl-wayland-add-EGL_BUFFER_PRESERVED-support.patch new file mode 100644 index 00000000..58a663fa --- /dev/null +++ b/package/mesa3d/0055-egl-wayland-add-EGL_BUFFER_PRESERVED-support.patch @@ -0,0 +1,285 @@ +From 84039ed0796602a560fd22cec6313ec81daa4044 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 9 Sep 2021 17:55:13 +0100 +Subject: [PATCH 055/168] egl/wayland: add EGL_BUFFER_PRESERVED support + +When the next back buffer is obtained, and the swap method is +EGL_BUFFER_PRESERVED, the current buffer contents are preserved with +a blit, unless the DRI driver is using the image loader extension, +and the DRI driver requests the current buffer contents +(__DRI_IMAGE_BUFFER_PREV) as well as the back buffer. This allows the +blit to be avoided for GPUs that can support EGL_BUFFER_PRESERVED +directly. + +Querying the age of a back buffer may force a blit, but outside of EGL +conformance testing, this would be an odd thing to do, as the buffer +age can always be assumed to be 1 with EGL_BUFFER_PRESERVED. + +Any received dmabuf feedback may also force a blit. + +The IMG PVR driver does not support the DRI2 loader extension, which +is why the buffer preserved support for the extension is less optimal, +with the current buffer always being preserved with a blit. + +EGL_BUFFER_PRESERVED support has not been added for the Mesa software +rasteriser. +--- + include/GL/internal/dri_interface.h | 4 ++ + src/egl/drivers/dri2/platform_wayland.c | 94 +++++++++++++++++++++---- + 2 files changed, 83 insertions(+), 15 deletions(-) + +diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h +index 7d96048688d..f2138437bd5 100644 +--- a/include/GL/internal/dri_interface.h ++++ b/include/GL/internal/dri_interface.h +@@ -2058,12 +2058,16 @@ 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" +diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c +index 3a9f43e6069..8124697fc90 100644 +--- a/src/egl/drivers/dri2/platform_wayland.c ++++ b/src/egl/drivers/dri2/platform_wayland.c +@@ -962,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; +@@ -992,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 +@@ -1114,7 +1127,8 @@ create_dri_image(struct dri2_egl_surface *dri2_surf, + } + + 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); +@@ -1200,6 +1214,28 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) + 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; +@@ -1257,8 +1293,12 @@ front_bo_to_dri_buffer(struct dri2_egl_display *dri2_dpy, + + static int + update_buffers(struct dri2_egl_display *dri2_dpy, +- struct dri2_egl_surface *dri2_surf) ++ 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 || + dri2_surf->base.Height != dri2_surf->wl_win->height)) { +@@ -1268,12 +1308,20 @@ update_buffers(struct dri2_egl_display *dri2_dpy, + } + + 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; + } +@@ -1303,12 +1351,13 @@ update_buffers(struct dri2_egl_display *dri2_dpy, + + static int + update_buffers_if_needed(struct dri2_egl_display *dri2_dpy, +- struct dri2_egl_surface *dri2_surf) ++ struct dri2_egl_surface *dri2_surf, ++ bool allow_preserve) + { + if (dri2_surf->back != NULL) + return 0; + +- return update_buffers(dri2_dpy, dri2_surf); ++ return update_buffers(dri2_dpy, dri2_surf, allow_preserve); + } + + static __DRIbuffer * +@@ -1327,7 +1376,7 @@ dri2_wl_get_buffers_with_format(__DRIdrawable * driDrawable, + + switch (attachments[i]) { + case __DRI_BUFFER_BACK_LEFT: +- if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0) ++ 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]); +@@ -1412,14 +1461,25 @@ image_get_buffers(__DRIdrawable *driDrawable, + buffers->image_mask = 0; + buffers->front = NULL; + buffers->back = NULL; ++ buffers->prev = NULL; + + if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) + { +- if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0) ++ 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) +@@ -1717,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_dpy, 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) { +@@ -1804,7 +1864,7 @@ dri2_wl_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface) + if (surface->Type != EGL_WINDOW_BIT) + return 0; + +- if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0) { ++ if (update_buffers_if_needed(dri2_dpy, dri2_surf, true) < 0) { + _eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age"); + return -1; + } +@@ -2186,7 +2246,7 @@ 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 }; +@@ -2207,6 +2267,10 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp) + 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, surface_type, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes); + if (dri2_conf) { +@@ -2443,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; + } +@@ -2555,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; +@@ -3002,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; + } +-- +2.17.1 + diff --git a/package/mesa3d/0056-glapi-restore-exec-dynamic.patch b/package/mesa3d/0056-glapi-restore-exec-dynamic.patch new file mode 100644 index 00000000..3e80a15f --- /dev/null +++ b/package/mesa3d/0056-glapi-restore-exec-dynamic.patch @@ -0,0 +1,28 @@ +From 462716a04a43d23ff35aa0eb147f58fa336eff1c Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 23 Mar 2022 12:57:01 +0000 +Subject: [PATCH 056/168] glapi: restore exec="dynamic" + +This is needed for the dispatch table entry points used by the IMG +Rogue DDK driver, which have no implementation in Mesa. Using +exec="dynamic" avoids the need to create stubs in Mesa for the +unimplemented functions. +--- + src/mapi/glapi/gen/api_exec_init.py | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/mapi/glapi/gen/api_exec_init.py b/src/mapi/glapi/gen/api_exec_init.py +index 3f862287768..28b2395ce47 100644 +--- a/src/mapi/glapi/gen/api_exec_init.py ++++ b/src/mapi/glapi/gen/api_exec_init.py +@@ -34,6 +34,7 @@ import apiexec + + exec_flavor_map = { + 'beginend': None, ++ 'dynamic': None, + 'dlist': '_mesa_', + 'mesa': '_mesa_', + 'skip': None, +-- +2.17.1 + diff --git a/package/mesa3d/0057-Revert-meson-check-mtls-if-has_exe_wrapper.patch b/package/mesa3d/0057-Revert-meson-check-mtls-if-has_exe_wrapper.patch new file mode 100644 index 00000000..93a1ab9d --- /dev/null +++ b/package/mesa3d/0057-Revert-meson-check-mtls-if-has_exe_wrapper.patch @@ -0,0 +1,42 @@ +From 00f9320539178cacf9dd75104f61f07a303b9960 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 29 Apr 2022 14:48:06 +0100 +Subject: [PATCH 057/168] Revert "meson: check -mtls if has_exe_wrapper" + +This reverts commit 558bc2227ed00fc6a29c2a10c0b99719cd445c6c. + +The change breaks 32 bit x86 cross compilation on x86_64 systems, as +meson.has_exe_wrapper returns true, but Meson fails with: + + Build machine cpu family: x86_64 + Build machine cpu: x86_64 + Host machine cpu family: x86 + Host machine cpu: i686 + Target machine cpu family: x86 + Target machine cpu: i686 + Checking if "thread_local" compiles: YES + + meson.build:555:4: ERROR: Can not run test applications in this + cross environment. + +See also https://github.com/mesonbuild/meson/issues/9845 +--- + meson.build | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/meson.build b/meson.build +index ee142c5b4b5..53019fc2e3f 100644 +--- a/meson.build ++++ b/meson.build +@@ -566,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 +-- +2.17.1 + diff --git a/package/mesa3d/0058-vulkan-wsi-extend-PVR-WSI-library-to-destroy-surface.patch b/package/mesa3d/0058-vulkan-wsi-extend-PVR-WSI-library-to-destroy-surface.patch new file mode 100644 index 00000000..741e8eda --- /dev/null +++ b/package/mesa3d/0058-vulkan-wsi-extend-PVR-WSI-library-to-destroy-surface.patch @@ -0,0 +1,271 @@ +From b5785681453f05818e2c077a2304427774c82b11 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 24 Jan 2023 21:41:48 +0000 +Subject: [PATCH 058/168] vulkan/wsi: extend PVR WSI library to destroy + surfaces + +Up until now, the Rogue DDK has destroyed surfaces without using the +library, by simply freeing the surface. Changes to surface allocation +for Wayland mean that this is no longer possible, as additional +cleanup is required. +--- + src/pvr/wsi/pvr_mesa_wsi_interface.h | 24 ++++++++++++++++++++ + src/pvr/wsi/pvr_wsi.c | 34 ++++++++++++++++++++++++++++ + src/pvr/wsi/pvr_wsi.h | 5 +++- + src/vulkan/wsi/wsi_common.c | 28 +++++++++++++++++------ + src/vulkan/wsi/wsi_common.h | 4 ++++ + src/vulkan/wsi/wsi_common_private.h | 2 +- + src/vulkan/wsi/wsi_common_wayland.c | 5 ++-- + 7 files changed, 90 insertions(+), 12 deletions(-) + +diff --git a/src/pvr/wsi/pvr_mesa_wsi_interface.h b/src/pvr/wsi/pvr_mesa_wsi_interface.h +index b4b1bcb0c9d..46430b56c63 100644 +--- a/src/pvr/wsi/pvr_mesa_wsi_interface.h ++++ b/src/pvr/wsi/pvr_mesa_wsi_interface.h +@@ -42,6 +42,8 @@ struct pvr_mesa_wsi; + /* + * Functions defined in Mesa for use by the PowerVR DDK. + * All functions have a "pvr_mesa_wsi" prefix. ++ * Since the introduction of version 1 of the interface, the following ++ * functions are now regarded as forming version 0 of the interface. + */ + + void * +@@ -295,12 +297,34 @@ pvr_mesa_wsi_get_swapchain_counter(struct pvr_mesa_wsi *mwsi, + VkSurfaceCounterFlagBitsEXT flagBits, + uint64_t *pValue); + ++/* ++ * The following are available in version 1 of the interface. ++ * Version 1 also supports the version 0 interface. ++ */ ++ ++uint32_t ++pvr_mesa_wsi_get_version(struct pvr_mesa_wsi *mwsi); ++ ++void ++pvr_mesa_wsi_surface_destroy(struct pvr_mesa_wsi *mwsi, ++ VkSurfaceKHR surface, ++ const VkAllocationCallbacks *pAllocator); ++ + /* + * Functions defined in the PowerVR DDK for use by Mesa. + * All functions have a "pvr_vk_mesa_wsi" prefix. ++ * Since the introduction of version 1 of the interface, the following ++ * function is now regarded as forming version 0 of the interface. + */ + VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL + pvr_vk_mesa_wsi_sym_addr(VkPhysicalDevice physicalDevice, + const char *name); + ++/* ++ * The following is available in version 1 of the interface. ++ * Version 1 also supports the version 0 interface. ++ */ ++uint32_t ++pvr_vk_mesa_wsi_get_version(VkPhysicalDevice physicalDevice); ++ + #endif /* PVR_MESA_WSI_INTERFACE_H */ +diff --git a/src/pvr/wsi/pvr_wsi.c b/src/pvr/wsi/pvr_wsi.c +index f1e4bc594c8..cbf2b7a086f 100644 +--- a/src/pvr/wsi/pvr_wsi.c ++++ b/src/pvr/wsi/pvr_wsi.c +@@ -27,6 +27,16 @@ + #include "pvr_wsi.h" + #include "pvr_mesa_wsi_interface.h" + ++static inline uint32_t ++pvr_vk_wsi_get_version(struct pvr_mesa_wsi *mwsi) ++{ ++ JUMP_DDK(mwsi, pvr_vk_mesa_wsi_get_version, ++ mwsi->physicalDevice); ++ ++ return 0; ++} ++ ++ + VkResult + pvr_mesa_wsi_init(struct pvr_mesa_wsi **pmwsi, + VkPhysicalDevice physicalDevice, +@@ -47,6 +57,12 @@ pvr_mesa_wsi_init(struct pvr_mesa_wsi **pmwsi, + mwsi->symtab.pvr_vk_mesa_wsi_sym_addr = pvr_vk_mesa_wsi_sym_addr; + mwsi->physicalDevice = physicalDevice; + ++ mwsi->pvr_vk_wsi_version = pvr_vk_wsi_get_version(mwsi); ++ if (mwsi->pvr_vk_wsi_version < 1) { ++ vk_free(alloc, mwsi); ++ return VK_ERROR_FEATURE_NOT_PRESENT; ++ } ++ + result = wsi_device_init2(&mwsi->wsi, + physicalDevice, + pvr_vk_mesa_wsi_sym_addr, +@@ -227,6 +243,20 @@ pvr_mesa_wsi_common_get_present_rectangles(struct pvr_mesa_wsi *mwsi, + pRects); + } + ++uint32_t ++pvr_mesa_wsi_get_version(UNUSED struct pvr_mesa_wsi *mwsi) ++{ ++ return 1; ++} ++ ++void ++pvr_mesa_wsi_surface_destroy(UNUSED struct pvr_mesa_wsi *mwsi, ++ VkSurfaceKHR surface, ++ const VkAllocationCallbacks *pAllocator) ++{ ++ wsi_surface_destroy(surface, pAllocator); ++} ++ + /* + * The mwsi parameter is currently unused. Note that it is invalid for + * pvr_mesa_wsi_init, which is responsible for allocating it. +@@ -322,6 +352,10 @@ pvr_mesa_wsi_sym_addr(UNUSED struct pvr_mesa_wsi *mwsi, const char *name) + pvr_mesa_wsi_register_display_event }, + { "pvr_mesa_wsi_get_swapchain_counter", + pvr_mesa_wsi_get_swapchain_counter }, ++ { "pvr_mesa_wsi_get_version", ++ pvr_mesa_wsi_get_version }, ++ { "pvr_mesa_wsi_surface_destroy", ++ pvr_mesa_wsi_surface_destroy }, + }; + unsigned i; + +diff --git a/src/pvr/wsi/pvr_wsi.h b/src/pvr/wsi/pvr_wsi.h +index 142358db3de..0c734fdb1f5 100644 +--- a/src/pvr/wsi/pvr_wsi.h ++++ b/src/pvr/wsi/pvr_wsi.h +@@ -37,7 +37,7 @@ + #define MAKE_STRING(x) _MAKE_STRING(x) + + #define LOOKUP_DDK(mwsi, sym) \ +- mwsi->symtab.pvr_vk_mesa_wsi_sym_addr(MAKE_STRING(sym)) ++ mwsi->symtab.pvr_vk_mesa_wsi_sym_addr(mwsi->physicalDevice, MAKE_STRING(sym)) + + #define JUMP_DDK(mwsi, sym, ...) \ + do { \ +@@ -61,6 +61,8 @@ struct pvr_vk_mesa_wsi_sym_tab + { + PFN_vkVoidFunction (VKAPI_PTR *pvr_vk_mesa_wsi_sym_addr) + (VkPhysicalDevice physicalDevice, const char *); ++ ++ uint32_t (*pvr_vk_mesa_wsi_get_version)(VkPhysicalDevice physicalDevice); + }; + + struct pvr_mesa_wsi +@@ -68,6 +70,7 @@ struct pvr_mesa_wsi + struct wsi_device wsi; + struct pvr_vk_mesa_wsi_sym_tab symtab; + VkPhysicalDevice physicalDevice; ++ uint32_t pvr_vk_wsi_version; + }; + + static inline struct pvr_mesa_wsi *pvr_mesa_wsi(struct wsi_device *wsi_ptr) +diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c +index 389117ceb2e..8067781c459 100644 +--- a/src/vulkan/wsi/wsi_common.c ++++ b/src/vulkan/wsi/wsi_common.c +@@ -291,12 +291,10 @@ wsi_device_finish(struct wsi_device *wsi, + #endif + } + +-VKAPI_ATTR void VKAPI_CALL +-wsi_DestroySurfaceKHR(VkInstance _instance, +- VkSurfaceKHR _surface, +- const VkAllocationCallbacks *pAllocator) ++void ++wsi_surface_destroy(VkSurfaceKHR _surface, ++ const VkAllocationCallbacks *pAllocator) + { +- VK_FROM_HANDLE(vk_instance, instance, _instance); + ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); + + if (!surface) +@@ -304,12 +302,28 @@ wsi_DestroySurfaceKHR(VkInstance _instance, + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + if (surface->platform == VK_ICD_WSI_PLATFORM_WAYLAND) { +- wsi_wl_surface_destroy(surface, _instance, pAllocator); ++ wsi_wl_surface_destroy(surface, pAllocator); + return; + } + #endif + +- vk_free2(&instance->alloc, pAllocator, surface); ++ vk_free(pAllocator, surface); ++} ++ ++VKAPI_ATTR void VKAPI_CALL ++wsi_DestroySurfaceKHR(VkInstance _instance, ++ VkSurfaceKHR _surface, ++ const VkAllocationCallbacks *pAllocator) ++{ ++ VK_FROM_HANDLE(vk_instance, instance, _instance); ++ const VkAllocationCallbacks *allocator; ++ ++ if (pAllocator) ++ allocator = pAllocator; ++ else ++ allocator = &instance->alloc; ++ ++ wsi_surface_destroy(_surface, allocator); + } + + void +diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h +index aec1021113e..3a47be66859 100644 +--- a/src/vulkan/wsi/wsi_common.h ++++ b/src/vulkan/wsi/wsi_common.h +@@ -393,6 +393,10 @@ wsi_common_bind_swapchain_image(const struct wsi_device *wsi, + VkSwapchainKHR _swapchain, + uint32_t image_idx); + ++void ++wsi_surface_destroy(VkSurfaceKHR _surface, ++ const VkAllocationCallbacks *pAllocator); ++ + #ifdef __cplusplus + } + #endif +diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h +index 868fdf968e4..631ea93e3d6 100644 +--- a/src/vulkan/wsi/wsi_common_private.h ++++ b/src/vulkan/wsi/wsi_common_private.h +@@ -171,7 +171,7 @@ bool + wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd); + + void +-wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface, VkInstance _instance, ++wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface, + const VkAllocationCallbacks *pAllocator); + + VkResult +diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c +index bffc52da13f..da3575fc584 100644 +--- a/src/vulkan/wsi/wsi_common_wayland.c ++++ b/src/vulkan/wsi/wsi_common_wayland.c +@@ -1273,10 +1273,9 @@ wsi_wl_surface_get_present_rectangles(VkIcdSurfaceBase *surface, + } + + void +-wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface, VkInstance _instance, ++wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface, + const VkAllocationCallbacks *pAllocator) + { +- VK_FROM_HANDLE(vk_instance, instance, _instance); + struct wsi_wl_surface *wsi_wl_surface = + wl_container_of((VkIcdSurfaceWayland *)icd_surface, wsi_wl_surface, base); + +@@ -1292,7 +1291,7 @@ wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface, VkInstance _instance, + dmabuf_feedback_fini(&wsi_wl_surface->pending_dmabuf_feedback); + } + +- vk_free2(&instance->alloc, pAllocator, wsi_wl_surface); ++ vk_free(pAllocator, wsi_wl_surface); + } + + static struct wsi_wl_format * +-- +2.17.1 + diff --git a/package/mesa3d/0059-vulkan-wsi-dEQP-wayland.swapchain.simulate_oom.min_i.patch b/package/mesa3d/0059-vulkan-wsi-dEQP-wayland.swapchain.simulate_oom.min_i.patch new file mode 100644 index 00000000..bdd07dda --- /dev/null +++ b/package/mesa3d/0059-vulkan-wsi-dEQP-wayland.swapchain.simulate_oom.min_i.patch @@ -0,0 +1,45 @@ +From 8cbccbc6182f92a6256ef73bfb1a74eec0ccc5f6 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 17 Jan 2023 19:24:13 +0000 +Subject: [PATCH 059/168] vulkan/wsi: dEQP + wayland.swapchain.simulate_oom.min_image_count fix + +Fix for segfault with dEQP test case +dEQP-VK.wsi.wayland.swapchain.simulate_oom.min_image_count. + +In wsi_wl_surface_create_swapchain, if wsi_wl_surface_init failed, +wsi_wl_swapchain_chain_free was called without wsi_swapchain_init +having been called, resulting in a segfault in wsi_swapchain_finish, +due to chain->wsi having never been initialised. +--- + src/vulkan/wsi/wsi_common_wayland.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c +index da3575fc584..e292ec4c70f 100644 +--- a/src/vulkan/wsi/wsi_common_wayland.c ++++ b/src/vulkan/wsi/wsi_common_wayland.c +@@ -1940,8 +1940,10 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, + wsi_wl_surface->chain = chain; + + result = wsi_wl_surface_init(wsi_wl_surface, wsi_device); +- if (result != VK_SUCCESS) +- goto fail; ++ if (result != VK_SUCCESS) { ++ vk_free(pAllocator, chain); ++ return result; ++ } + + enum wsi_wl_buffer_type buffer_type; + struct wsi_base_image_params *image_params = NULL; +@@ -2039,7 +2041,6 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, + fail_image_init: + wsi_wl_swapchain_images_free(chain); + +-fail: + wsi_wl_swapchain_chain_free(chain, pAllocator); + + return result; +-- +2.17.1 + diff --git a/package/mesa3d/0060-vulkan-wsi-wayland-allocate-memory-for-swapchain-mod.patch b/package/mesa3d/0060-vulkan-wsi-wayland-allocate-memory-for-swapchain-mod.patch new file mode 100644 index 00000000..cf8c226d --- /dev/null +++ b/package/mesa3d/0060-vulkan-wsi-wayland-allocate-memory-for-swapchain-mod.patch @@ -0,0 +1,64 @@ +From 1bc869491d51631c3fe0c6b2f2373e7b0c4fca84 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 26 Jan 2023 16:23:27 +0000 +Subject: [PATCH 060/168] vulkan/wsi/wayland: allocate memory for swapchain + modifier array + +A pointer to the array of DRM format modifiers is stored in the +swapchain. If the pointer is derived from dmabuf feedback, it may +become invalid when new feedback is received, making the comparison +done by surface_dmabuf_feedback_tranche_done unreliable. +--- + src/vulkan/wsi/wsi_common_wayland.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c +index e292ec4c70f..bf242e19c16 100644 +--- a/src/vulkan/wsi/wsi_common_wayland.c ++++ b/src/vulkan/wsi/wsi_common_wayland.c +@@ -1884,6 +1884,8 @@ wsi_wl_swapchain_chain_free(struct wsi_wl_swapchain *chain, + + wsi_swapchain_finish(&chain->base); + ++ vk_free(pAllocator, (void *)chain->drm_modifiers); ++ + vk_free(pAllocator, chain); + } + +@@ -2022,8 +2024,24 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, + } else { + chain->shm_format = wl_shm_format_for_vk_format(chain->vk_format, alpha); + } ++ + chain->num_drm_modifiers = num_drm_modifiers; +- chain->drm_modifiers = drm_modifiers; ++ if (num_drm_modifiers > 0) { ++ uint64_t *modifiers; ++ ++ modifiers = vk_alloc(pAllocator, sizeof(*modifiers) * num_drm_modifiers, ++ 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); ++ if (!modifiers) { ++ result = VK_ERROR_OUT_OF_HOST_MEMORY; ++ goto fail_modifiers_alloc; ++ } ++ ++ for (uint32_t i = 0; i < num_drm_modifiers; i++) ++ modifiers[i] = drm_modifiers[i]; ++ ++ chain->drm_modifiers = modifiers; ++ } ++ + chain->fifo_ready = true; + + for (uint32_t i = 0; i < chain->base.image_count; i++) { +@@ -2041,6 +2059,7 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, + fail_image_init: + wsi_wl_swapchain_images_free(chain); + ++fail_modifiers_alloc: + wsi_wl_swapchain_chain_free(chain, pAllocator); + + return result; +-- +2.17.1 + diff --git a/package/mesa3d/0061-zink-remove-descriptor-mode-selection-infrastructure.patch b/package/mesa3d/0061-zink-remove-descriptor-mode-selection-infrastructure.patch new file mode 100644 index 00000000..17ae1f6b --- /dev/null +++ b/package/mesa3d/0061-zink-remove-descriptor-mode-selection-infrastructure.patch @@ -0,0 +1,108 @@ +From 9c388aa5a84373b65859ed680b785c1cc50249a9 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 11 Nov 2022 10:35:40 +0100 +Subject: [PATCH 061/168] zink: remove descriptor-mode selection infrastructure + +We only support lazy descriptors these days, so having the +infrastructure around to support automatic selection of that one mode is +kinda silly. + +And it's not like setting an environment variable that is never read is +going to cause any issues, so we don't even need this to avoid breaking +existing setups. + +Let's just rip it out. We can reintroduce it again on the off-chance +that someone has a new clever descriptor mode they want to experiment +with. + +Reviewed-by: Hoe Hao Cheng +Part-of: +--- + docs/drivers/zink.rst | 13 ------------- + src/gallium/drivers/zink/zink_screen.c | 15 --------------- + src/gallium/drivers/zink/zink_types.h | 5 ----- + 3 files changed, 33 deletions(-) + +diff --git a/docs/drivers/zink.rst b/docs/drivers/zink.rst +index 157ecc82e4a..7bf397796f6 100644 +--- a/docs/drivers/zink.rst ++++ b/docs/drivers/zink.rst +@@ -247,19 +247,6 @@ are required to be supported + + * `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 ("auto") +- +-``auto`` +- Automatically detect best mode. This is the default. +-``lazy`` +- Attempt to use the least amount of CPU by binding descriptors opportunistically. +- + Debugging + --------- + +diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c +index 3427b68cd8c..79d85ce1899 100644 +--- a/src/gallium/drivers/zink/zink_screen.c ++++ b/src/gallium/drivers/zink/zink_screen.c +@@ -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) + { +@@ -2451,7 +2440,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 +2548,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; +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index b05ad12ed18..7968e44aad2 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -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, +-- +2.17.1 + diff --git a/package/mesa3d/0062-aux-draw-vectorize-aaline-computations.patch b/package/mesa3d/0062-aux-draw-vectorize-aaline-computations.patch new file mode 100644 index 00000000..46eefb2f --- /dev/null +++ b/package/mesa3d/0062-aux-draw-vectorize-aaline-computations.patch @@ -0,0 +1,37 @@ +From fdad4f15f39f0f202c956dae599397e7c0b20e43 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 21 Nov 2022 13:53:04 +0100 +Subject: [PATCH 062/168] aux/draw: vectorize aaline computations + +This makes it a bit more similar to the TGSI version, which makes +modifying them easier to review. + +Reviewed-by: Roland Scheidegger +Part-of: +--- + src/gallium/auxiliary/nir/nir_draw_helpers.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/gallium/auxiliary/nir/nir_draw_helpers.c b/src/gallium/auxiliary/nir/nir_draw_helpers.c +index daa1fcb260b..098b83b194b 100644 +--- a/src/gallium/auxiliary/nir/nir_draw_helpers.c ++++ b/src/gallium/auxiliary/nir/nir_draw_helpers.c +@@ -174,12 +174,10 @@ nir_lower_aaline_block(nir_block *block, + 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_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))))); + +- tmp = nir_fmul(b, tmp, tmp1); ++ tmp = nir_fmul(b, nir_channel(b, tmp, 0), nir_channel(b, tmp, 1)); + tmp = nir_fmul(b, nir_channel(b, out_input, 3), tmp); + + nir_ssa_def *out = nir_vec4(b, nir_channel(b, out_input, 0), +-- +2.17.1 + diff --git a/package/mesa3d/0063-gallium-draw-properly-fix-short-aalines.patch b/package/mesa3d/0063-gallium-draw-properly-fix-short-aalines.patch new file mode 100644 index 00000000..e546a52b --- /dev/null +++ b/package/mesa3d/0063-gallium-draw-properly-fix-short-aalines.patch @@ -0,0 +1,175 @@ +From f0e7e3a87363ecbc386ce8438734fe172ae290df Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 21 Nov 2022 13:28:00 +0100 +Subject: [PATCH 063/168] gallium/draw: properly fix short aalines + +The fix we used to have for short smooth lines were incorrect, and +here's the real fix: + +For lines shorter than one pixel, we need to clamp the length-wise +coverage to the line-length. That produces results that are consistent +with our approximation for longer lines. + +Because we pass (length / 2) + 0.5 to the fragment shader instead of +the unmodified length, we need to spend a few instructions to +reconstruct the original width. + +Reviewed-by: Roland Scheidegger +Part-of: +--- + src/gallium/auxiliary/draw/draw_pipe_aaline.c | 61 ++++++++++++------- + src/gallium/auxiliary/nir/nir_draw_helpers.c | 5 +- + .../drivers/llvmpipe/ci/traces-llvmpipe.yml | 4 +- + 3 files changed, 44 insertions(+), 26 deletions(-) + +diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c +index 7dac4078559..edbbc7d5451 100644 +--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c ++++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c +@@ -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) +@@ -390,29 +427,7 @@ aaline_line(struct draw_stage *stage, struct prim_header *header) + 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; +diff --git a/src/gallium/auxiliary/nir/nir_draw_helpers.c b/src/gallium/auxiliary/nir/nir_draw_helpers.c +index 098b83b194b..4588b56f461 100644 +--- a/src/gallium/auxiliary/nir/nir_draw_helpers.c ++++ b/src/gallium/auxiliary/nir/nir_draw_helpers.c +@@ -174,10 +174,13 @@ nir_lower_aaline_block(nir_block *block, + 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))))); + +- tmp = nir_fmul(b, nir_channel(b, tmp, 0), nir_channel(b, tmp, 1)); ++ tmp = nir_fmul(b, nir_channel(b, tmp, 0), ++ nir_fmin(b, nir_channel(b, tmp, 1), len)); + tmp = nir_fmul(b, nir_channel(b, out_input, 3), tmp); + + nir_ssa_def *out = nir_vec4(b, nir_channel(b, out_input, 0), +diff --git a/src/gallium/drivers/llvmpipe/ci/traces-llvmpipe.yml b/src/gallium/drivers/llvmpipe/ci/traces-llvmpipe.yml +index 32fe5e45562..2ff2689cdd5 100644 +--- a/src/gallium/drivers/llvmpipe/ci/traces-llvmpipe.yml ++++ b/src/gallium/drivers/llvmpipe/ci/traces-llvmpipe.yml +@@ -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 +-- +2.17.1 + diff --git a/package/mesa3d/0064-gallium-draw-do-not-use-trig-to-compute-tangent.patch b/package/mesa3d/0064-gallium-draw-do-not-use-trig-to-compute-tangent.patch new file mode 100644 index 00000000..eded15d1 --- /dev/null +++ b/package/mesa3d/0064-gallium-draw-do-not-use-trig-to-compute-tangent.patch @@ -0,0 +1,38 @@ +From 12da2f975bc767faf71dfd147e9fe1363f7600d7 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 22 Nov 2022 09:40:12 +0100 +Subject: [PATCH 064/168] gallium/draw: do not use trig to compute tangent + +We've already done the expensive part of computing this without +trigenometry, e.g computing the length. So let's finish it off. + +Reviewed-by: Roland Scheidegger +Part-of: +--- + src/gallium/auxiliary/draw/draw_pipe_aaline.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c +index edbbc7d5451..464f9c3dd96 100644 +--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c ++++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c +@@ -420,13 +420,12 @@ 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); + half_length = half_length + 0.5f; + + t_w = half_width; +-- +2.17.1 + diff --git a/package/mesa3d/0065-mesa-support-dummy-queries-for-ARB_pipeline_statisti.patch b/package/mesa3d/0065-mesa-support-dummy-queries-for-ARB_pipeline_statisti.patch new file mode 100644 index 00000000..02e29460 --- /dev/null +++ b/package/mesa3d/0065-mesa-support-dummy-queries-for-ARB_pipeline_statisti.patch @@ -0,0 +1,117 @@ +From 99bc9d22f15b0506dc276f21e1b0afbe806bf694 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 15 Nov 2022 13:18:16 +0100 +Subject: [PATCH 065/168] mesa: support dummy queries for + ARB_pipeline_statistics_query +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Similar to ARB_occlusion_query / ARB_occlusion_query2, this extension +allows zero bits for the queries, meaning there's no actual hardware +requirements here. + +So let's just report zero bits if the driver doesn't support the CAP, +and treat these queries as dummies like we already do for occlusion +queries. + +We still don't expose the extension, this is just to make it possible to +allow the core OpenGL functionality without exposing the extension. + +Reviewed-by: Soroush Kashani +Reviewed-by: Christian Gmeiner +Reviewed-by: Marek Olšák +Part-of: +--- + src/mesa/main/queryobj.c | 41 +++++++++++++++++++++-------- + src/mesa/state_tracker/st_context.c | 2 ++ + src/mesa/state_tracker/st_context.h | 1 + + 3 files changed, 33 insertions(+), 11 deletions(-) + +diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c +index a5385aaf456..9b75d69f0e4 100644 +--- a/src/mesa/main/queryobj.c ++++ b/src/mesa/main/queryobj.c +@@ -133,6 +133,10 @@ query_type_is_dummy(struct gl_context *ctx, unsigned type) + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: + return !st->has_occlusion_query; ++ case PIPE_QUERY_PIPELINE_STATISTICS: ++ return !st->has_pipeline_stat; ++ case PIPE_QUERY_PIPELINE_STATISTICS_SINGLE: ++ return !st->has_single_pipe_stat; + default: + break; + } +@@ -1353,17 +1357,32 @@ _mesa_init_queryobj(struct gl_context *ctx) + ctx->Const.QueryCounterBits.PrimitivesGenerated = 64; + ctx->Const.QueryCounterBits.PrimitivesWritten = 64; + +- ctx->Const.QueryCounterBits.VerticesSubmitted = 64; +- ctx->Const.QueryCounterBits.PrimitivesSubmitted = 64; +- ctx->Const.QueryCounterBits.VsInvocations = 64; +- ctx->Const.QueryCounterBits.TessPatches = 64; +- ctx->Const.QueryCounterBits.TessInvocations = 64; +- ctx->Const.QueryCounterBits.GsInvocations = 64; +- ctx->Const.QueryCounterBits.GsPrimitives = 64; +- ctx->Const.QueryCounterBits.FsInvocations = 64; +- ctx->Const.QueryCounterBits.ComputeInvocations = 64; +- ctx->Const.QueryCounterBits.ClInPrimitives = 64; +- ctx->Const.QueryCounterBits.ClOutPrimitives = 64; ++ if (screen->get_param(screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS) || ++ screen->get_param(screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE)) { ++ ctx->Const.QueryCounterBits.VerticesSubmitted = 64; ++ ctx->Const.QueryCounterBits.PrimitivesSubmitted = 64; ++ ctx->Const.QueryCounterBits.VsInvocations = 64; ++ ctx->Const.QueryCounterBits.TessPatches = 64; ++ ctx->Const.QueryCounterBits.TessInvocations = 64; ++ ctx->Const.QueryCounterBits.GsInvocations = 64; ++ ctx->Const.QueryCounterBits.GsPrimitives = 64; ++ ctx->Const.QueryCounterBits.FsInvocations = 64; ++ ctx->Const.QueryCounterBits.ComputeInvocations = 64; ++ ctx->Const.QueryCounterBits.ClInPrimitives = 64; ++ ctx->Const.QueryCounterBits.ClOutPrimitives = 64; ++ } else { ++ ctx->Const.QueryCounterBits.VerticesSubmitted = 0; ++ ctx->Const.QueryCounterBits.PrimitivesSubmitted = 0; ++ ctx->Const.QueryCounterBits.VsInvocations = 0; ++ ctx->Const.QueryCounterBits.TessPatches = 0; ++ ctx->Const.QueryCounterBits.TessInvocations = 0; ++ ctx->Const.QueryCounterBits.GsInvocations = 0; ++ ctx->Const.QueryCounterBits.GsPrimitives = 0; ++ ctx->Const.QueryCounterBits.FsInvocations = 0; ++ ctx->Const.QueryCounterBits.ComputeInvocations = 0; ++ ctx->Const.QueryCounterBits.ClInPrimitives = 0; ++ ctx->Const.QueryCounterBits.ClOutPrimitives = 0; ++ } + } + + +diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c +index 9573b5f8679..d711bd1750c 100644 +--- a/src/mesa/state_tracker/st_context.c ++++ b/src/mesa/state_tracker/st_context.c +@@ -629,6 +629,8 @@ st_create_context_priv(struct gl_context *ctx, struct pipe_context *pipe, + screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY); + st->has_single_pipe_stat = + screen->get_param(screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE); ++ st->has_pipeline_stat = ++ screen->get_param(screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS); + st->has_indep_blend_func = + screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC); + st->needs_rgb_dst_alpha_override = +diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h +index 11937cbc532..7f5c5dc65b9 100644 +--- a/src/mesa/state_tracker/st_context.h ++++ b/src/mesa/state_tracker/st_context.h +@@ -158,6 +158,7 @@ struct st_context + boolean has_indirect_partial_stride; + boolean has_occlusion_query; + boolean has_single_pipe_stat; ++ boolean has_pipeline_stat; + boolean has_indep_blend_func; + boolean needs_rgb_dst_alpha_override; + boolean can_dither; +-- +2.17.1 + diff --git a/package/mesa3d/0066-mesa-do-not-require-optional-queries.patch b/package/mesa3d/0066-mesa-do-not-require-optional-queries.patch new file mode 100644 index 00000000..927ba904 --- /dev/null +++ b/package/mesa3d/0066-mesa-do-not-require-optional-queries.patch @@ -0,0 +1,127 @@ +From 5855b83fe6fd6217cc94fc03ab3b785e192d0ad9 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 22 Nov 2022 12:43:24 +0100 +Subject: [PATCH 066/168] mesa: do not require optional queries +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The OpenGL specifications explicitly calls out these queries as allowing +zero bits, so these features aren't actually required to bump the OpenGL +version. + +While we could in theory also enable the corresponding extensions +unconditionally, this risks breaking applications that assume that the +presence of the extensions are sufficient to use meaningfully use them, +like is the case with most other OpenGL extensions. + +However, blocking more recent GL versions due to this seems like a bit +of an overreaction. So let's allow new OpenGL versions, but not the +extensions themselves. + +Reviewed-by: Marek Olšák +Reviewed-by: Soroush Kashani +Part-of: +--- + src/mesa/main/context.h | 23 +++++++++++++++++++++++ + src/mesa/main/queryobj.c | 8 +++----- + src/mesa/main/version.c | 5 +---- + 3 files changed, 27 insertions(+), 9 deletions(-) + +diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h +index a2c8a308403..fbfdd2ddbf8 100644 +--- a/src/mesa/main/context.h ++++ b/src/mesa/main/context.h +@@ -416,6 +416,29 @@ _mesa_hw_select_enabled(const struct gl_context *ctx) + ctx->Const.HardwareAcceleratedSelect; + } + ++static inline bool ++_mesa_has_occlusion_query(const struct gl_context *ctx) ++{ ++ return _mesa_has_ARB_occlusion_query(ctx) || ++ _mesa_has_ARB_occlusion_query2(ctx) || ++ (_mesa_is_desktop_gl(ctx) && ctx->Version >= 15); ++} ++ ++static inline bool ++_mesa_has_occlusion_query_boolean(const struct gl_context *ctx) ++{ ++ return _mesa_has_ARB_occlusion_query2(ctx) || ++ _mesa_has_EXT_occlusion_query_boolean(ctx) || ++ (_mesa_is_desktop_gl(ctx) && ctx->Version >= 33); ++} ++ ++static inline bool ++_mesa_has_pipeline_statistics(const struct gl_context *ctx) ++{ ++ return _mesa_has_ARB_pipeline_statistics_query(ctx) || ++ (_mesa_is_desktop_gl(ctx) && ctx->Version >= 46); ++} ++ + #ifdef __cplusplus + } + #endif +diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c +index 9b75d69f0e4..a524a6c951c 100644 +--- a/src/mesa/main/queryobj.c ++++ b/src/mesa/main/queryobj.c +@@ -471,7 +471,7 @@ get_pipe_stats_binding_point(struct gl_context *ctx, + const int which = target - GL_VERTICES_SUBMITTED; + assert(which < MAX_PIPELINE_STATISTICS); + +- if (!_mesa_has_ARB_pipeline_statistics_query(ctx)) ++ if (!_mesa_has_pipeline_statistics(ctx)) + return NULL; + + return &ctx->Query.pipeline_stats[which]; +@@ -487,14 +487,12 @@ get_query_binding_point(struct gl_context *ctx, GLenum target, GLuint index) + { + switch (target) { + case GL_SAMPLES_PASSED: +- if (_mesa_has_ARB_occlusion_query(ctx) || +- _mesa_has_ARB_occlusion_query2(ctx)) ++ if (_mesa_has_occlusion_query(ctx)) + return &ctx->Query.CurrentOcclusionObject; + else + return NULL; + case GL_ANY_SAMPLES_PASSED: +- if (_mesa_has_ARB_occlusion_query2(ctx) || +- _mesa_has_EXT_occlusion_query_boolean(ctx)) ++ if (_mesa_has_occlusion_query_boolean(ctx)) + return &ctx->Query.CurrentOcclusionObject; + else + return NULL; +diff --git a/src/mesa/main/version.c b/src/mesa/main/version.c +index a564b8cf1f9..d60724b2c91 100644 +--- a/src/mesa/main/version.c ++++ b/src/mesa/main/version.c +@@ -252,8 +252,7 @@ compute_version(const struct gl_extensions *extensions, + GLuint major, minor, version; + + const bool ver_1_4 = (extensions->ARB_shadow); +- const bool ver_1_5 = (ver_1_4 && +- extensions->ARB_occlusion_query); ++ const bool ver_1_5 = ver_1_4; + const bool ver_2_0 = (ver_1_5 && + extensions->ARB_vertex_shader && + extensions->ARB_fragment_shader && +@@ -313,7 +312,6 @@ compute_version(const struct gl_extensions *extensions, + extensions->ARB_blend_func_extended && + extensions->ARB_explicit_attrib_location && + extensions->ARB_instanced_arrays && +- extensions->ARB_occlusion_query2 && + extensions->ARB_shader_bit_encoding && + extensions->ARB_texture_rgb10_a2ui && + extensions->ARB_timer_query && +@@ -395,7 +393,6 @@ compute_version(const struct gl_extensions *extensions, + extensions->ARB_gl_spirv && + extensions->ARB_spirv_extensions && + extensions->ARB_indirect_parameters && +- extensions->ARB_pipeline_statistics_query && + extensions->ARB_polygon_offset_clamp && + extensions->ARB_shader_atomic_counter_ops && + extensions->ARB_shader_draw_parameters && +-- +2.17.1 + diff --git a/package/mesa3d/0067-docs-zink-update-query-requirements.patch b/package/mesa3d/0067-docs-zink-update-query-requirements.patch new file mode 100644 index 00000000..9be74dbb --- /dev/null +++ b/package/mesa3d/0067-docs-zink-update-query-requirements.patch @@ -0,0 +1,62 @@ +From 60228a19edf4424c15f9e837f3f2c3cc25175f6f Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 15 Nov 2022 16:04:29 +0100 +Subject: [PATCH 067/168] docs/zink: update query requirements +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These features are no longer required. + +Reviewed-by: Soroush Kashani +Reviewed-by: Christian Gmeiner +Reviewed-by: Marek Olšák +Part-of: +--- + docs/drivers/zink.rst | 2 -- + src/gallium/drivers/zink/VP_ZINK_requirements.json | 2 -- + 2 files changed, 4 deletions(-) + +diff --git a/docs/drivers/zink.rst b/docs/drivers/zink.rst +index 7bf397796f6..84508158459 100644 +--- a/docs/drivers/zink.rst ++++ b/docs/drivers/zink.rst +@@ -117,7 +117,6 @@ supported, although some of these might not actually get verified: + + * ``VkPhysicalDeviceFeatures``: + +- * ``occlusionQueryPrecise`` + * ``dualSrcBlend`` + + * Device extensions: +@@ -240,7 +239,6 @@ are required to be supported + * ``VkPhysicalDeviceFeatures``: + + * ``samplerAnisotropy`` +- * ``pipelineStatisticsQuery`` + * ``depthBiasClamp`` + + * Device extensions: +diff --git a/src/gallium/drivers/zink/VP_ZINK_requirements.json b/src/gallium/drivers/zink/VP_ZINK_requirements.json +index f42f4c8d7a9..262a690993d 100644 +--- a/src/gallium/drivers/zink/VP_ZINK_requirements.json ++++ b/src/gallium/drivers/zink/VP_ZINK_requirements.json +@@ -105,7 +105,6 @@ + }, + "features": { + "VkPhysicalDeviceFeatures": { +- "occlusionQueryPrecise": true, + "dualSrcBlend": true + } + } +@@ -298,7 +297,6 @@ + "features": { + "VkPhysicalDeviceFeatures": { + "samplerAnisotropy": true, +- "pipelineStatisticsQuery": true, + "depthBiasClamp": true + } + } +-- +2.17.1 + diff --git a/package/mesa3d/0068-nir-Add-helper-to-create-passthrough-GS-shader.patch b/package/mesa3d/0068-nir-Add-helper-to-create-passthrough-GS-shader.patch new file mode 100644 index 00000000..a962f793 --- /dev/null +++ b/package/mesa3d/0068-nir-Add-helper-to-create-passthrough-GS-shader.patch @@ -0,0 +1,162 @@ +From 13f76fae0e22593829d1ac7145cb1b6acd1f594e Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 29 Aug 2022 14:36:09 +0200 +Subject: [PATCH 068/168] nir: Add helper to create passthrough GS shader + +Based on nir_create_passthrough_tcs and d3d12_make_passthrough_gs, this +creates a passthrough geometry shader that can be used by drivers that +needs to emulate some graphics features in the geometry shader. + +Reviewed-by: Rob Clark +Part-of: +--- + src/compiler/nir/meson.build | 1 + + src/compiler/nir/nir.h | 4 + + src/compiler/nir/nir_passthrough_gs.c | 108 ++++++++++++++++++++++++++ + 3 files changed, 113 insertions(+) + create mode 100644 src/compiler/nir/nir_passthrough_gs.c + +diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build +index f1a1879f6d2..133e64a39e1 100644 +--- a/src/compiler/nir/meson.build ++++ b/src/compiler/nir/meson.build +@@ -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', +diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h +index 42583435556..851a9934b1b 100644 +--- a/src/compiler/nir/nir.h ++++ b/src/compiler/nir/nir.h +@@ -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); +diff --git a/src/compiler/nir/nir_passthrough_gs.c b/src/compiler/nir/nir_passthrough_gs.c +new file mode 100644 +index 00000000000..b13b8909484 +--- /dev/null ++++ b/src/compiler/nir/nir_passthrough_gs.c +@@ -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; ++} +-- +2.17.1 + diff --git a/package/mesa3d/0069-zink-setup-driver-workaround-for-missing-linestipple.patch b/package/mesa3d/0069-zink-setup-driver-workaround-for-missing-linestipple.patch new file mode 100644 index 00000000..3a5a108c --- /dev/null +++ b/package/mesa3d/0069-zink-setup-driver-workaround-for-missing-linestipple.patch @@ -0,0 +1,97 @@ +From 029c0c28de05dc744d98dce9ea543d04993abd13 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 27 Sep 2022 12:53:03 +0200 +Subject: [PATCH 069/168] zink: setup driver-workaround for missing linestipple + +This is not ideal, but at least it should work. In the long run, we +might want to store a bit per mode we're missing, so we can do this +conditionally. But that's quite a bit more complicated, so let's go with +this for now. + +The line-stippling logic needs non-optimal shader-keys. So let's drop +some perf on the floor here. + +Part-of: +--- + src/gallium/drivers/zink/zink_draw.cpp | 2 +- + src/gallium/drivers/zink/zink_pipeline.c | 2 +- + src/gallium/drivers/zink/zink_screen.c | 17 ++++++++++++++++- + src/gallium/drivers/zink/zink_types.h | 1 + + 4 files changed, 19 insertions(+), 3 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp +index 21884073e3f..e414f9e7901 100644 +--- a/src/gallium/drivers/zink/zink_draw.cpp ++++ b/src/gallium/drivers/zink/zink_draw.cpp +@@ -670,7 +670,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) { +diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c +index 12869a7ccc6..b78c5df3408 100644 +--- a/src/gallium/drivers/zink/zink_pipeline.c ++++ b/src/gallium/drivers/zink/zink_pipeline.c +@@ -681,7 +681,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)); + +diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c +index 79d85ce1899..e2f65c7a348 100644 +--- a/src/gallium/drivers/zink/zink_screen.c ++++ b/src/gallium/drivers/zink/zink_screen.c +@@ -2343,6 +2343,18 @@ 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_AMD_OPEN_SOURCE || + screen->info.driver_props.driverID == VK_DRIVER_ID_AMD_PROPRIETARY || + screen->info.driver_props.driverID == VK_DRIVER_ID_NVIDIA_PROPRIETARY || +@@ -2710,7 +2722,10 @@ 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; + if (!screen->optimal_keys) + screen->info.have_EXT_graphics_pipeline_library = false; + +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index 7968e44aad2..b1d41bfc0cf 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -1279,6 +1279,7 @@ struct zink_screen { + bool always_feedback_loop_zs; + bool needs_sanitised_layer; + bool track_renderpasses; ++ bool no_linestipple; + unsigned z16_unscaled_bias; + unsigned z24_unscaled_bias; + } driver_workarounds; +-- +2.17.1 + diff --git a/package/mesa3d/0070-zink-add-line-stippling-lowering-passes.patch b/package/mesa3d/0070-zink-add-line-stippling-lowering-passes.patch new file mode 100644 index 00000000..1406763e --- /dev/null +++ b/package/mesa3d/0070-zink-add-line-stippling-lowering-passes.patch @@ -0,0 +1,255 @@ +From ee610e98b8287fcabd16a2f707f0eb52467347b7 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 27 Sep 2022 09:35:54 +0200 +Subject: [PATCH 070/168] zink: add line-stippling lowering passes + +There's two notable limitations here: +- This will viewport-map to viewport #0 only. This is because we need + the viewport-scale factors, which we'll be uploading using + push-constants. And we don't want to waste too many of those... +- It's missing a "global" stipple-counter. It doesn't seem like there's + a portable way of implementing this, so this is going to require a VK + extension that can be implemented in a hardware-specific way in the + long run. For now, let's just ignore the global stipple counter. + +These two limitations don't seem viable to overcome for now, so but this +is better than nothing. + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 182 +++++++++++++++++++++++ + src/gallium/drivers/zink/zink_types.h | 4 + + 2 files changed, 186 insertions(+) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 3deaed03f53..9661c4564b9 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -32,6 +32,7 @@ + + #include "nir.h" + #include "compiler/nir/nir_builder.h" ++#include "compiler/nir/nir_builtin_builder.h" + + #include "nir/tgsi_to_nir.h" + #include "tgsi/tgsi_dump.h" +@@ -64,6 +65,8 @@ fields[member_idx].offset = offsetof(struct zink_gfx_push_constant, field); + PUSHCONST_MEMBER(ZINK_GFX_PUSHCONST_FRAMEBUFFER_IS_LAYERED, framebuffer_is_layered); + PUSHCONST_MEMBER(ZINK_GFX_PUSHCONST_DEFAULT_INNER_LEVEL, default_inner_level); + PUSHCONST_MEMBER(ZINK_GFX_PUSHCONST_DEFAULT_OUTER_LEVEL, default_outer_level); ++ PUSHCONST_MEMBER(ZINK_GFX_PUSHCONST_LINE_STIPPLE_PATTERN, line_stipple_pattern); ++ PUSHCONST_MEMBER(ZINK_GFX_PUSHCONST_VIEWPORT_SCALE, viewport_scale); + + pushconst = nir_variable_create(nir, nir_var_mem_push_const, + glsl_struct_type(fields, ZINK_GFX_PUSHCONST_MAX, "struct", false), +@@ -270,6 +273,185 @@ lower_drawid(nir_shader *shader) + return nir_shader_instructions_pass(shader, lower_drawid_instr, nir_metadata_dominance, NULL); + } + ++struct lower_line_stipple_state { ++ nir_variable *pos_out; ++ nir_variable *stipple_out; ++ nir_variable *prev_pos; ++ nir_variable *pos_counter; ++ nir_variable *stipple_counter; ++}; ++ ++static nir_ssa_def * ++viewport_map(nir_builder *b, nir_ssa_def *vert, ++ nir_ssa_def *scale) ++{ ++ nir_ssa_def *w_recip = nir_frcp(b, nir_channel(b, vert, 3)); ++ nir_ssa_def *ndc_point = nir_fmul(b, nir_channels(b, vert, 0x3), ++ w_recip); ++ return nir_fmul(b, ndc_point, scale); ++} ++ ++static bool ++lower_line_stipple_gs_instr(nir_builder *b, nir_instr *instr, void *data) ++{ ++ struct lower_line_stipple_state *state = data; ++ if (instr->type != nir_instr_type_intrinsic) ++ return false; ++ ++ nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); ++ if (intrin->intrinsic != nir_intrinsic_emit_vertex_with_counter && ++ intrin->intrinsic != nir_intrinsic_emit_vertex) ++ return false; ++ ++ b->cursor = nir_before_instr(instr); ++ ++ nir_push_if(b, nir_ine_imm(b, nir_load_var(b, state->pos_counter), 0)); ++ // viewport-map endpoints ++ nir_ssa_def *vp_scale = nir_load_push_constant(b, 2, 32, ++ nir_imm_int(b, ZINK_GFX_PUSHCONST_VIEWPORT_SCALE), ++ .base = 1, ++ .range = 2); ++ nir_ssa_def *prev = nir_load_var(b, state->prev_pos); ++ nir_ssa_def *curr = nir_load_var(b, state->pos_out); ++ prev = viewport_map(b, prev, vp_scale); ++ curr = viewport_map(b, curr, vp_scale); ++ ++ // calculate length of line ++ nir_ssa_def *len = nir_fast_distance(b, prev, curr); ++ // update stipple_counter ++ nir_store_var(b, state->stipple_counter, ++ nir_fadd(b, nir_load_var(b, state->stipple_counter), ++ len), 1); ++ nir_pop_if(b, NULL); ++ // emit stipple out ++ nir_copy_var(b, state->stipple_out, state->stipple_counter); ++ nir_copy_var(b, state->prev_pos, state->pos_out); ++ ++ // update prev_pos and pos_counter for next vertex ++ b->cursor = nir_after_instr(instr); ++ nir_store_var(b, state->pos_counter, ++ nir_iadd_imm(b, nir_load_var(b, state->pos_counter), ++ 1), 1); ++ ++ return true; ++} ++ ++static bool ++lower_line_stipple_gs(nir_shader *shader) ++{ ++ nir_builder b; ++ struct lower_line_stipple_state state; ++ ++ state.pos_out = ++ nir_find_variable_with_location(shader, nir_var_shader_out, ++ VARYING_SLOT_POS); ++ ++ // if position isn't written, we have nothing to do ++ if (!state.pos_out) ++ return false; ++ ++ state.stipple_out = nir_variable_create(shader, nir_var_shader_out, ++ glsl_float_type(), ++ "__stipple"); ++ state.stipple_out->data.interpolation = INTERP_MODE_NOPERSPECTIVE; ++ state.stipple_out->data.driver_location = shader->num_outputs++; ++ state.stipple_out->data.location = MIN2(util_last_bit64(shader->info.outputs_written) + 1, VARYING_SLOT_VAR0); ++ shader->info.outputs_written |= BITFIELD64_BIT(state.stipple_out->data.location); ++ ++ // create temp variables ++ state.prev_pos = nir_variable_create(shader, nir_var_shader_temp, ++ glsl_vec4_type(), ++ "__prev_pos"); ++ state.pos_counter = nir_variable_create(shader, nir_var_shader_temp, ++ glsl_uint_type(), ++ "__pos_counter"); ++ state.stipple_counter = nir_variable_create(shader, nir_var_shader_temp, ++ glsl_float_type(), ++ "__stipple_counter"); ++ ++ // initialize pos_counter and stipple_counter ++ nir_function_impl *entry = nir_shader_get_entrypoint(shader); ++ nir_builder_init(&b, entry); ++ b.cursor = nir_before_cf_list(&entry->body); ++ nir_store_var(&b, state.pos_counter, nir_imm_int(&b, 0), 1); ++ nir_store_var(&b, state.stipple_counter, nir_imm_float(&b, 0), 1); ++ ++ return nir_shader_instructions_pass(shader, lower_line_stipple_gs_instr, ++ nir_metadata_dominance, &state); ++} ++ ++static bool ++lower_line_stipple_fs(nir_shader *shader) ++{ ++ nir_builder b; ++ nir_function_impl *entry = nir_shader_get_entrypoint(shader); ++ nir_builder_init(&b, entry); ++ ++ // create stipple counter ++ nir_variable *stipple = nir_variable_create(shader, nir_var_shader_in, ++ glsl_float_type(), ++ "__stipple"); ++ stipple->data.interpolation = INTERP_MODE_NOPERSPECTIVE; ++ stipple->data.driver_location = shader->num_inputs++; ++ stipple->data.location = MIN2(util_last_bit64(shader->info.inputs_read) + 1, VARYING_SLOT_VAR0); ++ shader->info.inputs_read |= BITFIELD64_BIT(stipple->data.location); ++ ++ nir_variable *sample_mask_out = ++ nir_find_variable_with_location(shader, nir_var_shader_out, ++ FRAG_RESULT_SAMPLE_MASK); ++ if (!sample_mask_out) { ++ sample_mask_out = nir_variable_create(shader, nir_var_shader_out, ++ glsl_uint_type(), "sample_mask"); ++ sample_mask_out->data.driver_location = shader->num_outputs++; ++ sample_mask_out->data.location = FRAG_RESULT_SAMPLE_MASK; ++ } ++ ++ b.cursor = nir_after_cf_list(&entry->body); ++ ++ nir_ssa_def *pattern = nir_load_push_constant(&b, 1, 32, ++ nir_imm_int(&b, ZINK_GFX_PUSHCONST_LINE_STIPPLE_PATTERN), ++ .base = 1); ++ nir_ssa_def *factor = nir_i2f32(&b, nir_ishr_imm(&b, pattern, 16)); ++ pattern = nir_iand_imm(&b, pattern, 0xffff); ++ ++ nir_ssa_def *sample_mask_in = nir_load_sample_mask_in(&b); ++ nir_variable *v = nir_local_variable_create(entry, glsl_uint_type(), NULL); ++ nir_variable *sample_mask = nir_local_variable_create(entry, glsl_uint_type(), NULL); ++ nir_store_var(&b, v, sample_mask_in, 1); ++ nir_store_var(&b, sample_mask, sample_mask_in, 1); ++ nir_push_loop(&b); ++ { ++ nir_ssa_def *value = nir_load_var(&b, v); ++ nir_ssa_def *index = nir_ufind_msb(&b, value); ++ nir_ssa_def *index_mask = nir_ishl(&b, nir_imm_int(&b, 1), index); ++ nir_ssa_def *new_value = nir_ixor(&b, value, index_mask); ++ nir_store_var(&b, v, new_value, 1); ++ nir_push_if(&b, nir_ieq_imm(&b, value, 0)); ++ nir_jump(&b, nir_jump_break); ++ nir_pop_if(&b, NULL); ++ ++ nir_ssa_def *stipple_pos = ++ nir_interp_deref_at_sample(&b, 1, 32, ++ &nir_build_deref_var(&b, stipple)->dest.ssa, index); ++ stipple_pos = nir_fmod(&b, nir_fdiv(&b, stipple_pos, factor), ++ nir_imm_float(&b, 16.0)); ++ stipple_pos = nir_f2i32(&b, stipple_pos); ++ nir_ssa_def *bit = ++ nir_iand_imm(&b, nir_ishr(&b, pattern, stipple_pos), 1); ++ nir_push_if(&b, nir_ieq_imm(&b, bit, 0)); ++ { ++ nir_ssa_def *value = nir_load_var(&b, sample_mask); ++ value = nir_ixor(&b, value, index_mask); ++ nir_store_var(&b, sample_mask, value, 1); ++ } ++ nir_pop_if(&b, NULL); ++ } ++ nir_pop_loop(&b, NULL); ++ nir_store_var(&b, sample_mask_out, nir_load_var(&b, sample_mask), 1); ++ ++ return true; ++} ++ + static bool + lower_dual_blend(nir_shader *shader) + { +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index b1d41bfc0cf..329cddf2e93 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -805,6 +805,8 @@ 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]; + }; + + /* The order of the enums MUST match the order of the zink_gfx_push_constant +@@ -816,6 +818,8 @@ 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_MAX + }; + +-- +2.17.1 + diff --git a/package/mesa3d/0071-zink-emit-vars-with-nir_var_shader_temp-mode.patch b/package/mesa3d/0071-zink-emit-vars-with-nir_var_shader_temp-mode.patch new file mode 100644 index 00000000..c7553ae1 --- /dev/null +++ b/package/mesa3d/0071-zink-emit-vars-with-nir_var_shader_temp-mode.patch @@ -0,0 +1,53 @@ +From dbdd2514d5a0a02408a806d46c90da3471cab174 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 26 Oct 2022 15:38:03 +0200 +Subject: [PATCH 071/168] zink: emit vars with nir_var_shader_temp mode + +Part-of: +--- + .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 22 +++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +index 5166eb92aae..c9a496509b8 100644 +--- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c ++++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +@@ -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) + { +@@ -4741,6 +4760,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); + +-- +2.17.1 + diff --git a/package/mesa3d/0072-zink-give-gs-its-own-shader-key.patch b/package/mesa3d/0072-zink-give-gs-its-own-shader-key.patch new file mode 100644 index 00000000..9dbb3ec4 --- /dev/null +++ b/package/mesa3d/0072-zink-give-gs-its-own-shader-key.patch @@ -0,0 +1,104 @@ +From 7ed47b85cb1e372270350df4aa3dc8cbf2c38f82 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 27 Sep 2022 09:43:11 +0200 +Subject: [PATCH 072/168] zink: give gs its own shader-key + +Line-stipple lowering is going to need some geometry-shader specific +lowering, so lets give the GS its own shader-key struct. + +The GS variant only needs a non-optimal variant, so let's assert that to +be sure. + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 2 +- + src/gallium/drivers/zink/zink_program.h | 14 ++++++++++++++ + src/gallium/drivers/zink/zink_shader_keys.h | 17 ++++++++++++++++- + 3 files changed, 31 insertions(+), 2 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 7c8cec2d973..07194fd2965 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -4843,7 +4843,7 @@ 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); + } + _mesa_hash_table_init(&ctx->framebuffer_cache, ctx, hash_framebuffer_imageless, equals_framebuffer_imageless); +diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h +index 12658458ef3..ad94b7e7845 100644 +--- a/src/gallium/drivers/zink/zink_program.h ++++ b/src/gallium/drivers/zink/zink_program.h +@@ -257,6 +257,20 @@ zink_get_fs_key(struct zink_context *ctx) + &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 + zink_set_tcs_key_patches(struct zink_context *ctx, uint8_t patch_vertices) + { +diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h +index fab6fb403cb..72fee81b641 100644 +--- a/src/gallium/drivers/zink/zink_shader_keys.h ++++ b/src/gallium/drivers/zink/zink_shader_keys.h +@@ -56,6 +56,13 @@ struct zink_vs_key { + unsigned size; + }; + ++struct zink_gs_key { ++ struct zink_vs_key_base base; ++ uint8_t pad; ++ // not hashed ++ unsigned size; ++}; ++ + struct zink_fs_key { + bool point_coord_yinvert : 1; + bool samples : 1; +@@ -82,10 +89,11 @@ 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; + } key; + struct zink_shader_key_base base; +@@ -140,6 +148,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) + { +-- +2.17.1 + diff --git a/package/mesa3d/0073-zink-process-non-optimal-key-passes-first.patch b/package/mesa3d/0073-zink-process-non-optimal-key-passes-first.patch new file mode 100644 index 00000000..b5046577 --- /dev/null +++ b/package/mesa3d/0073-zink-process-non-optimal-key-passes-first.patch @@ -0,0 +1,58 @@ +From 7addbf0fd40e778b3fce996196768b3435482b6f Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 17 Nov 2022 12:15:54 +0100 +Subject: [PATCH 073/168] zink: process non-optimal-key passes first + +Right now, it's only the vertex-shader that needs special handling for +non-optimal keys. That makes it possible to use fallthrough to always +end up in the last-vertex-stage conditional. + +But we're about to add special handling for the geometry stage as well, +so let's prepare by splitting the switch-statement in two; one that only +happens for non-optimal keys, and does all the needed processing there, +and one that deals with the rest. + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 9661c4564b9..3dc9d19e740 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2435,9 +2435,10 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + } + + /* TODO: use a separate mem ctx here for ralloc */ +- switch (zs->nir->info.stage) { +- case MESA_SHADER_VERTEX: { +- if (!screen->optimal_keys) { ++ ++ if (!screen->optimal_keys) { ++ switch (zs->nir->info.stage) { ++ case MESA_SHADER_VERTEX: { + uint32_t decomposed_attrs = 0, decomposed_attrs_without_w = 0; + const struct zink_vs_key *vs_key = zink_vs_key(key); + switch (vs_key->size) { +@@ -2457,9 +2458,16 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + } + if (decomposed_attrs || decomposed_attrs_without_w) + NIR_PASS_V(nir, decompose_attribs, decomposed_attrs, decomposed_attrs_without_w); ++ break; ++ } ++ ++ default: ++ break; + } +- FALLTHROUGH; + } ++ ++ switch (zs->nir->info.stage) { ++ case MESA_SHADER_VERTEX: + case MESA_SHADER_TESS_EVAL: + case MESA_SHADER_GEOMETRY: + if (zink_vs_key_base(key)->last_vertex_stage) { +-- +2.17.1 + diff --git a/package/mesa3d/0074-zink-allow-to-generate-any-vertex-shader-stage.patch b/package/mesa3d/0074-zink-allow-to-generate-any-vertex-shader-stage.patch new file mode 100644 index 00000000..dd87fc2a --- /dev/null +++ b/package/mesa3d/0074-zink-allow-to-generate-any-vertex-shader-stage.patch @@ -0,0 +1,237 @@ +From 5a9d09f2514cc04ef1101bb6cb5cc662e826f2f9 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 3 Nov 2022 12:45:47 +0100 +Subject: [PATCH 074/168] zink: allow to generate any vertex shader stage + +There's times when it's going to be useful to generate geometry shaders +as well, so let's generalize the infrastructure for generated shader +stages a bit. + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 18 +++++++------- + src/gallium/drivers/zink/zink_draw.cpp | 2 +- + src/gallium/drivers/zink/zink_program.c | 24 +++++++++---------- + .../drivers/zink/zink_program_state.hpp | 2 +- + src/gallium/drivers/zink/zink_types.h | 8 +++---- + 5 files changed, 26 insertions(+), 28 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 3dc9d19e740..af5a9d6abbf 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2564,7 +2564,7 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + ralloc_free(nir); + + /* TODO: determine if there's any reason to cache spirv output? */ +- if (zs->nir->info.stage == MESA_SHADER_TESS_CTRL && zs->tcs.is_generated) ++ if (zs->nir->info.stage == MESA_SHADER_TESS_CTRL && zs->non_fs.is_generated) + zs->spirv = spirv; + else + ralloc_free(spirv); +@@ -3846,10 +3846,10 @@ zink_shader_free(struct zink_screen *screen, struct zink_shader *shader) + gl_shader_stage stage = shader->nir->info.stage; + assert(stage < ZINK_GFX_SHADER_COUNT); + if (!prog->base.removed && prog->stages_present == prog->stages_remaining && +- (stage != MESA_SHADER_TESS_CTRL || !shader->tcs.is_generated)) { ++ (stage == MESA_SHADER_FRAGMENT || !shader->non_fs.is_generated)) { + unsigned stages_present = prog->stages_present; + if (prog->shaders[MESA_SHADER_TESS_CTRL] && +- prog->shaders[MESA_SHADER_TESS_CTRL]->tcs.is_generated) ++ prog->shaders[MESA_SHADER_TESS_CTRL]->non_fs.is_generated) + stages_present &= ~BITFIELD_BIT(MESA_SHADER_TESS_CTRL); + unsigned idx = zink_program_cache_stages(stages_present); + struct hash_table *ht = &prog->ctx->program_cache[idx]; +@@ -3861,20 +3861,20 @@ zink_shader_free(struct zink_screen *screen, struct zink_shader *shader) + simple_mtx_unlock(&prog->ctx->program_lock[idx]); + util_queue_fence_wait(&prog->base.cache_fence); + } +- if (stage != MESA_SHADER_TESS_CTRL || !shader->tcs.is_generated) { ++ if (stage == MESA_SHADER_FRAGMENT || !shader->non_fs.is_generated) { + prog->shaders[stage] = NULL; + prog->stages_remaining &= ~BITFIELD_BIT(stage); + } + /* only remove generated tcs during parent tes destruction */ +- if (stage == MESA_SHADER_TESS_EVAL && shader->tes.generated) ++ if (stage == MESA_SHADER_TESS_EVAL && shader->non_fs.generated_tcs) + prog->shaders[MESA_SHADER_TESS_CTRL] = NULL; + zink_gfx_program_reference(screen, &prog, NULL); + } + if (shader->nir->info.stage == MESA_SHADER_TESS_EVAL && +- shader->tes.generated) { ++ shader->non_fs.generated_tcs) { + /* automatically destroy generated tcs shaders when tes is destroyed */ +- zink_shader_free(screen, shader->tes.generated); +- shader->tes.generated = NULL; ++ zink_shader_free(screen, shader->non_fs.generated_tcs); ++ shader->non_fs.generated_tcs = NULL; + } + _mesa_set_destroy(shader->programs, NULL); + ralloc_free(shader->nir); +@@ -3993,7 +3993,7 @@ zink_shader_tcs_create(struct zink_screen *screen, struct zink_shader *vs, unsig + NIR_PASS_V(nir, nir_convert_from_ssa, true); + + ret->nir = nir; +- ret->tcs.is_generated = true; ++ ret->non_fs.is_generated = true; + return ret; + } + +diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp +index e414f9e7901..3b057b5c9cd 100644 +--- a/src/gallium/drivers/zink/zink_draw.cpp ++++ b/src/gallium/drivers/zink/zink_draw.cpp +@@ -787,7 +787,7 @@ 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]); +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 95348153c9b..615ffbf8205 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -129,13 +129,13 @@ 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; ++ const bool is_nongenerated_tcs = stage == MESA_SHADER_TESS_CTRL && !zs->non_fs.is_generated; + zm = malloc(sizeof(struct zink_shader_module) + key->size + (!has_nonseamless ? nonseamless_size : 0) + inline_size * sizeof(uint32_t)); + 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 { +@@ -161,7 +161,7 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr + 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); +@@ -183,7 +183,7 @@ 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; + + 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 *); +@@ -224,7 +224,7 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr + 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) { ++ } else if (stage == MESA_SHADER_TESS_CTRL && zs->non_fs.is_generated) { + key = (uint16_t*)&state->shader_keys_optimal.key.tcs; + } else { + key = NULL; +@@ -234,7 +234,7 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr + 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); +@@ -247,7 +247,7 @@ 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; +@@ -266,14 +266,14 @@ 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; + 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) { ++ } 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; +@@ -647,7 +647,7 @@ update_gfx_program_optimal(struct zink_context *ctx, struct zink_gfx_program *pr + update_gfx_shader_module_optimal(ctx, prog, MESA_SHADER_FRAGMENT); + ctx->gfx_pipeline_state.modules_changed = true; + } +- 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; +@@ -897,7 +897,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); +@@ -1521,7 +1521,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; + } + } +diff --git a/src/gallium/drivers/zink/zink_program_state.hpp b/src/gallium/drivers/zink/zink_program_state.hpp +index d1832f4a413..4711047b04f 100644 +--- a/src/gallium/drivers/zink/zink_program_state.hpp ++++ b/src/gallium/drivers/zink/zink_program_state.hpp +@@ -395,7 +395,7 @@ get_gfx_pipeline_stage_eq_func(struct zink_gfx_program *prog, bool optimal_keys) + { + 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)) { +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index 329cddf2e93..76dd9bd4990 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -684,12 +684,10 @@ 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 { + nir_variable *fbfetch; //for fs output +-- +2.17.1 + diff --git a/package/mesa3d/0075-zink-lower-line-stipple.patch b/package/mesa3d/0075-zink-lower-line-stipple.patch new file mode 100644 index 00000000..b99462a8 --- /dev/null +++ b/package/mesa3d/0075-zink-lower-line-stipple.patch @@ -0,0 +1,288 @@ +From 2851ea6c01e58814aed0c8cff53c66911db0b04b Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 27 Sep 2022 13:23:04 +0200 +Subject: [PATCH 075/168] zink: lower line stipple + +This lowers line-stippling to a combination of geometry and fragment +shaders: + +- The geometry shader computes the length of each line-segment, and + outputs a varying that produces the stipple position. +- The fragment shader looks up the stipple position in the + stipple-pattern once per sample, and updates the sample mask + accordingly. + +In case there's no geometry shader in place, we create a new +pass-through shader. + +We should probably not declare the the push-constants in the pipeline +layout unless they're actually needed. But we already do this +unconditionally for the vertex shader and tesselation push-constants, so +let's do it unconditionally for these as well for now. + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 18 +++++++ + src/gallium/drivers/zink/zink_draw.cpp | 30 +++++++++++ + src/gallium/drivers/zink/zink_program.c | 59 ++++++++++++++++++++- + src/gallium/drivers/zink/zink_program.h | 3 ++ + src/gallium/drivers/zink/zink_shader_keys.h | 4 +- + src/gallium/drivers/zink/zink_state.c | 5 +- + 6 files changed, 115 insertions(+), 4 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index af5a9d6abbf..249143e2304 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2461,6 +2461,14 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + break; + } + ++ case MESA_SHADER_GEOMETRY: ++ if (zink_gs_key(key)->lower_line_stipple) { ++ NIR_PASS_V(nir, lower_line_stipple_gs); ++ NIR_PASS_V(nir, nir_lower_var_copies); ++ need_optimize = true; ++ } ++ break; ++ + default: + break; + } +@@ -2483,6 +2491,8 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + } + break; + case MESA_SHADER_FRAGMENT: ++ if (zink_fs_key(key)->lower_line_stipple) ++ NIR_PASS_V(nir, lower_line_stipple_fs); + if (!zink_fs_key(key)->samples && + nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)) { + /* VK will always use gl_SampleMask[] values even if sample count is 0, +@@ -3868,6 +3878,8 @@ zink_shader_free(struct zink_screen *screen, struct zink_shader *shader) + /* only remove generated tcs during parent tes destruction */ + if (stage == MESA_SHADER_TESS_EVAL && shader->non_fs.generated_tcs) + prog->shaders[MESA_SHADER_TESS_CTRL] = NULL; ++ if (stage != MESA_SHADER_FRAGMENT && shader->non_fs.generated_gs) ++ prog->shaders[MESA_SHADER_GEOMETRY] = NULL; + zink_gfx_program_reference(screen, &prog, NULL); + } + if (shader->nir->info.stage == MESA_SHADER_TESS_EVAL && +@@ -3876,6 +3888,12 @@ zink_shader_free(struct zink_screen *screen, struct zink_shader *shader) + zink_shader_free(screen, shader->non_fs.generated_tcs); + shader->non_fs.generated_tcs = NULL; + } ++ if (shader->nir->info.stage != MESA_SHADER_FRAGMENT && ++ shader->non_fs.generated_gs) { ++ /* automatically destroy generated gs shaders when owner is destroyed */ ++ zink_shader_free(screen, shader->non_fs.generated_gs); ++ shader->non_fs.generated_gs = NULL; ++ } + _mesa_set_destroy(shader->programs, NULL); + ralloc_free(shader->nir); + ralloc_free(shader->spirv); +diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp +index 3b057b5c9cd..f1c70aa906b 100644 +--- a/src/gallium/drivers/zink/zink_draw.cpp ++++ b/src/gallium/drivers/zink/zink_draw.cpp +@@ -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 (lines_changed || rast_state_changed || ++ ctx->gfx_pipeline_state.modules_changed) ++ zink_set_line_stipple_keys(ctx); ++ + if (index_size) { + const VkIndexType index_type[3] = { + VK_INDEX_TYPE_UINT8_EXT, +@@ -792,6 +801,27 @@ zink_draw(struct pipe_context *pctx, + offsetof(struct zink_gfx_push_constant, default_inner_level), sizeof(float) * 6, + &ctx->tess_levels[0]); + } ++ if (zink_get_fs_key(ctx)->lower_line_stipple) { ++ assert(zink_get_gs_key(ctx)->lower_line_stipple); ++ ++ 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 (have_streamout) { + for (unsigned i = 0; i < ctx->num_so_targets; i++) { +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 615ffbf8205..7812e81e30e 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -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 +@@ -1306,7 +1307,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 +1315,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; +@@ -1851,3 +1862,47 @@ 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_line_stipple_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; ++ } ++ ++ if (lower_line_stipple) { ++ 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, ++ SHADER_PRIM_LINE_STRIP, 2); ++ NIR_PASS_V(nir, nir_lower_gs_intrinsics, nir_lower_gs_intrinsics_per_stream); ++ ++ 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); ++} +diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h +index ad94b7e7845..75a855936ac 100644 +--- a/src/gallium/drivers/zink/zink_program.h ++++ b/src/gallium/drivers/zink/zink_program.h +@@ -340,6 +340,9 @@ zink_set_fs_point_coord_key(struct zink_context *ctx) + } + } + ++void ++zink_set_line_stipple_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) + { +diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h +index 72fee81b641..013892bff2d 100644 +--- a/src/gallium/drivers/zink/zink_shader_keys.h ++++ b/src/gallium/drivers/zink/zink_shader_keys.h +@@ -59,6 +59,7 @@ struct zink_vs_key { + struct zink_gs_key { + struct zink_vs_key_base base; + uint8_t pad; ++ bool lower_line_stipple : 1; + // not hashed + unsigned size; + }; +@@ -69,7 +70,8 @@ struct zink_fs_key { + bool force_dual_color_blend : 1; + bool force_persample_interp : 1; + bool fbfetch_ms : 1; +- uint8_t pad : 3; ++ bool lower_line_stipple : 1; ++ uint8_t pad : 2; + uint8_t coord_replace_bits; + }; + +diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c +index c38a06e3032..eba2cc8dfb8 100644 +--- a/src/gallium/drivers/zink/zink_state.c ++++ b/src/gallium/drivers/zink/zink_state.c +@@ -564,7 +564,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; +-- +2.17.1 + diff --git a/package/mesa3d/0076-zink-do-not-complain-about-missing-line-stipple-supp.patch b/package/mesa3d/0076-zink-do-not-complain-about-missing-line-stipple-supp.patch new file mode 100644 index 00000000..20406d9a --- /dev/null +++ b/package/mesa3d/0076-zink-do-not-complain-about-missing-line-stipple-supp.patch @@ -0,0 +1,37 @@ +From a10ce655fdd83be18a445e3bc4cdd060063c8965 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 27 Sep 2022 09:57:10 +0200 +Subject: [PATCH 076/168] zink: do not complain about missing line-stipple + support + +We can lower this now, so let's not complain about it... + +Part-of: +--- + src/gallium/drivers/zink/zink_pipeline.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c +index b78c5df3408..0af7fd4b34f 100644 +--- a/src/gallium/drivers/zink/zink_pipeline.c ++++ b/src/gallium/drivers/zink/zink_pipeline.c +@@ -294,7 +294,15 @@ 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; ++ else ++ warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][0]); ++ } else + warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][hw_rast_state->line_stipple_enable]); + } + +-- +2.17.1 + diff --git a/package/mesa3d/0077-util-dynarray-Add-an-append_array-helper.patch b/package/mesa3d/0077-util-dynarray-Add-an-append_array-helper.patch new file mode 100644 index 00000000..c09d818e --- /dev/null +++ b/package/mesa3d/0077-util-dynarray-Add-an-append_array-helper.patch @@ -0,0 +1,35 @@ +From 7d5a0fa22f939891195da7193f2f092425663275 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 15 Sep 2022 18:31:06 -0500 +Subject: [PATCH 077/168] util/dynarray: Add an append_array helper + +Reviewed-by: Caio Oliveira +Part-of: +--- + src/util/u_dynarray.h | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/util/u_dynarray.h b/src/util/u_dynarray.h +index 6f91b820892..b41b0d4b032 100644 +--- a/src/util/u_dynarray.h ++++ b/src/util/u_dynarray.h +@@ -168,6 +168,16 @@ util_dynarray_trim(struct util_dynarray *buf) + } + } + ++static inline void ++util_dynarray_append_dynarray(struct util_dynarray *buf, ++ const struct util_dynarray *other) ++{ ++ if (other->size > 0) { ++ void *p = util_dynarray_grow_bytes(buf, 1, other->size); ++ memcpy(p, other->data, other->size); ++ } ++} ++ + #define util_dynarray_append(buf, type, v) do {type __v = (v); memcpy(util_dynarray_grow_bytes((buf), 1, sizeof(type)), &__v, sizeof(type));} while(0) + /* Returns a pointer to the space of the first new element (in case of growth) or NULL on failure. */ + #define util_dynarray_resize(buf, type, nelts) util_dynarray_resize_bytes(buf, (nelts), sizeof(type)) +-- +2.17.1 + diff --git a/package/mesa3d/0078-zink-do-not-lower-gs-intrinsics.patch b/package/mesa3d/0078-zink-do-not-lower-gs-intrinsics.patch new file mode 100644 index 00000000..08e0ee35 --- /dev/null +++ b/package/mesa3d/0078-zink-do-not-lower-gs-intrinsics.patch @@ -0,0 +1,66 @@ +From 8a8a7f37aba0af97035dfba45917350a182ee6b2 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 5 Dec 2022 15:25:55 +0100 +Subject: [PATCH 078/168] zink: do not lower gs-intrinsics + +We don't use the counters for anything useful, so let's drop this +lowering pass. + +Part-of: +--- + src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c | 8 ++------ + src/gallium/drivers/zink/zink_compiler.c | 5 ++--- + 2 files changed, 4 insertions(+), 9 deletions(-) + +diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +index c9a496509b8..f385830f5ad 100644 +--- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c ++++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +@@ -3305,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 + */ +@@ -3316,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; +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 249143e2304..1adb464a50d 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -1611,7 +1611,8 @@ clamp_layer_output_instr(nir_builder *b, nir_instr *instr, void *data) + switch (instr->type) { + case nir_instr_type_intrinsic: { + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); +- if (intr->intrinsic != nir_intrinsic_emit_vertex_with_counter) ++ if (intr->intrinsic != nir_intrinsic_emit_vertex_with_counter && ++ intr->intrinsic != nir_intrinsic_emit_vertex) + return false; + b->cursor = nir_before_instr(instr); + clamp_layer_output_emit(b, state); +@@ -3837,8 +3838,6 @@ zink_shader_finalize(struct pipe_screen *pscreen, void *nirptr) + if (!screen->info.feats.features.shaderImageGatherExtended) + tex_opts.lower_tg4_offsets = true; + NIR_PASS_V(nir, nir_lower_tex, &tex_opts); +- if (nir->info.stage == MESA_SHADER_GEOMETRY) +- NIR_PASS_V(nir, nir_lower_gs_intrinsics, nir_lower_gs_intrinsics_per_stream); + optimize_nir(nir, NULL); + nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); + if (screen->driconf.inline_uniforms) +-- +2.17.1 + diff --git a/package/mesa3d/0079-zink-do-not-lower-gs-intrinscs-take-two.patch b/package/mesa3d/0079-zink-do-not-lower-gs-intrinscs-take-two.patch new file mode 100644 index 00000000..e3891c7c --- /dev/null +++ b/package/mesa3d/0079-zink-do-not-lower-gs-intrinscs-take-two.patch @@ -0,0 +1,28 @@ +From 9639375be33219e5efe3e5a325cb68d5f9c12d03 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 6 Dec 2022 08:52:44 +0100 +Subject: [PATCH 079/168] zink: do not lower gs-intrinscs, take two + +Whoops, I missed a spot! + +Fixes: ad26d29adcc ("zink: do not lower gs-intrinsics") +Part-of: +--- + src/gallium/drivers/zink/zink_program.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 7812e81e30e..5524bf659c8 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -1892,7 +1892,6 @@ zink_set_line_stipple_keys(struct zink_context *ctx) + &screen->nir_options, + ctx->gfx_stages[prev_vertex_stage]->nir, + SHADER_PRIM_LINE_STRIP, 2); +- NIR_PASS_V(nir, nir_lower_gs_intrinsics, nir_lower_gs_intrinsics_per_stream); + + struct zink_shader *shader = zink_shader_create(screen, nir, NULL); + ctx->gfx_stages[prev_vertex_stage]->non_fs.generated_gs = shader; +-- +2.17.1 + diff --git a/package/mesa3d/0080-zink-add-gl_point-lowering-pass.patch b/package/mesa3d/0080-zink-add-gl_point-lowering-pass.patch new file mode 100644 index 00000000..5ef86f3f --- /dev/null +++ b/package/mesa3d/0080-zink-add-gl_point-lowering-pass.patch @@ -0,0 +1,135 @@ +From 62462e63b65440decde30333f5b82ee8d6f10565 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 1 Dec 2022 09:41:48 -0300 +Subject: [PATCH 080/168] zink: add gl_point lowering pass + +This lowering pass is intended for hardwares/drivers that can't honor +the gl_PointSize when GL_PROGRAM_POINT_SIZE is enabled. + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 108 +++++++++++++++++++++++ + 1 file changed, 108 insertions(+) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 1adb464a50d..d78846b1858 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -273,6 +273,114 @@ lower_drawid(nir_shader *shader) + return nir_shader_instructions_pass(shader, lower_drawid_instr, nir_metadata_dominance, NULL); + } + ++struct lower_gl_point_state { ++ nir_variable *gl_pos_out; ++ nir_variable *gl_point_size; ++}; ++ ++static bool ++lower_gl_point_gs_instr(nir_builder *b, nir_instr *instr, void *data) ++{ ++ struct lower_gl_point_state *state = data; ++ nir_ssa_def *vp_scale, *pos; ++ ++ if (instr->type != nir_instr_type_intrinsic) ++ return false; ++ ++ nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); ++ if (intrin->intrinsic != nir_intrinsic_emit_vertex_with_counter && ++ intrin->intrinsic != nir_intrinsic_emit_vertex) ++ return false; ++ ++ if (nir_intrinsic_stream_id(intrin) != 0) ++ return false; ++ ++ if (intrin->intrinsic == nir_intrinsic_end_primitive_with_counter || ++ intrin->intrinsic == nir_intrinsic_end_primitive) { ++ nir_instr_remove(&intrin->instr); ++ return true; ++ } ++ ++ b->cursor = nir_before_instr(instr); ++ ++ // viewport-map endpoints ++ nir_ssa_def *vp_const_pos = nir_imm_int(b, ZINK_GFX_PUSHCONST_VIEWPORT_SCALE); ++ vp_scale = nir_load_push_constant(b, 2, 32, vp_const_pos, .base = 1, .range = 2); ++ ++ // Load point info values ++ nir_ssa_def *point_size = nir_load_var(b, state->gl_point_size); ++ nir_ssa_def *point_pos = nir_load_var(b, state->gl_pos_out); ++ ++ // w_delta = gl_point_size / width_viewport_size_scale * gl_Position.w ++ nir_ssa_def *w_delta = nir_fdiv(b, point_size, nir_channel(b, vp_scale, 0)); ++ w_delta = nir_fmul(b, w_delta, nir_channel(b, point_pos, 3)); ++ // halt_w_delta = w_delta / 2 ++ nir_ssa_def *half_w_delta = nir_fmul(b, w_delta, nir_imm_float(b, 0.5)); ++ ++ // h_delta = gl_point_size / height_viewport_size_scale * gl_Position.w ++ nir_ssa_def *h_delta = nir_fdiv(b, point_size, nir_channel(b, vp_scale, 1)); ++ h_delta = nir_fmul(b, h_delta, nir_channel(b, point_pos, 3)); ++ // halt_h_delta = h_delta / 2 ++ nir_ssa_def *half_h_delta = nir_fmul(b, h_delta, nir_imm_float(b, 0.5)); ++ ++ nir_ssa_def *point_dir[4][2] = { ++ { nir_imm_float(b, -1), nir_imm_float(b, -1) }, ++ { nir_imm_float(b, -1), nir_imm_float(b, 1) }, ++ { nir_imm_float(b, 1), nir_imm_float(b, -1) }, ++ { nir_imm_float(b, 1), nir_imm_float(b, 1) } ++ }; ++ ++ nir_ssa_def *point_pos_x = nir_channel(b, point_pos, 0); ++ nir_ssa_def *point_pos_y = nir_channel(b, point_pos, 1); ++ ++ for (size_t i = 0; i < 4; i++) { ++ pos = nir_vec4(b, ++ nir_ffma(b, half_w_delta, point_dir[i][0], point_pos_x), ++ nir_ffma(b, half_h_delta, point_dir[i][1], point_pos_y), ++ nir_channel(b, point_pos, 2), ++ nir_channel(b, point_pos, 3)); ++ ++ nir_store_var(b, state->gl_pos_out, pos, 0xf); ++ ++ nir_emit_vertex(b); ++ } ++ ++ nir_end_primitive(b); ++ ++ nir_instr_remove(&intrin->instr); ++ ++ return true; ++} ++ ++static bool ++lower_gl_point_gs(nir_shader *shader) ++{ ++ struct lower_gl_point_state state; ++ nir_builder b; ++ ++ shader->info.gs.output_primitive = SHADER_PRIM_TRIANGLE_STRIP; ++ shader->info.gs.vertices_out *= 4; ++ ++ // Gets the gl_Position in and out ++ state.gl_pos_out = ++ nir_find_variable_with_location(shader, nir_var_shader_out, ++ VARYING_SLOT_POS); ++ state.gl_point_size = ++ nir_find_variable_with_location(shader, nir_var_shader_out, ++ VARYING_SLOT_PSIZ); ++ ++ // if position in or gl_PointSize aren't written, we have nothing to do ++ if (!state.gl_pos_out || !state.gl_point_size) ++ return false; ++ ++ nir_function_impl *entry = nir_shader_get_entrypoint(shader); ++ nir_builder_init(&b, entry); ++ b.cursor = nir_before_cf_list(&entry->body); ++ ++ return nir_shader_instructions_pass(shader, lower_gl_point_gs_instr, ++ nir_metadata_dominance, &state); ++} ++ + struct lower_line_stipple_state { + nir_variable *pos_out; + nir_variable *stipple_out; +-- +2.17.1 + diff --git a/package/mesa3d/0081-zink-rename-zink_set_line_stipple_keys.patch b/package/mesa3d/0081-zink-rename-zink_set_line_stipple_keys.patch new file mode 100644 index 00000000..3758d124 --- /dev/null +++ b/package/mesa3d/0081-zink-rename-zink_set_line_stipple_keys.patch @@ -0,0 +1,57 @@ +From 8808e80bd95faa2b67e0b681c48bce2f687698f1 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 29 Nov 2022 11:40:50 -0300 +Subject: [PATCH 081/168] zink: rename `zink_set_line_stipple_keys` + +This function will be used by another primitive emulation and +a more generic name will be needed. + +Part-of: +--- + src/gallium/drivers/zink/zink_draw.cpp | 2 +- + src/gallium/drivers/zink/zink_program.c | 2 +- + src/gallium/drivers/zink/zink_program.h | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp +index f1c70aa906b..303ad32bd51 100644 +--- a/src/gallium/drivers/zink/zink_draw.cpp ++++ b/src/gallium/drivers/zink/zink_draw.cpp +@@ -550,7 +550,7 @@ zink_draw(struct pipe_context *pctx, + + if (lines_changed || rast_state_changed || + ctx->gfx_pipeline_state.modules_changed) +- zink_set_line_stipple_keys(ctx); ++ zink_set_primitive_emulation_keys(ctx); + + if (index_size) { + const VkIndexType index_type[3] = { +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 5524bf659c8..3085177e9f1 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -1864,7 +1864,7 @@ zink_driver_thread_add_job(struct pipe_screen *pscreen, void *data, + } + + void +-zink_set_line_stipple_keys(struct zink_context *ctx) ++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 && +diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h +index 75a855936ac..322f10155b6 100644 +--- a/src/gallium/drivers/zink/zink_program.h ++++ b/src/gallium/drivers/zink/zink_program.h +@@ -341,7 +341,7 @@ zink_set_fs_point_coord_key(struct zink_context *ctx) + } + + void +-zink_set_line_stipple_keys(struct zink_context *ctx); ++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) +-- +2.17.1 + diff --git a/package/mesa3d/0082-zink-add-driver-workaround-for-missing-gl_point_size.patch b/package/mesa3d/0082-zink-add-driver-workaround-for-missing-gl_point_size.patch new file mode 100644 index 00000000..deca80db --- /dev/null +++ b/package/mesa3d/0082-zink-add-driver-workaround-for-missing-gl_point_size.patch @@ -0,0 +1,171 @@ +From 8b14d44cf23da63cc9610374cfb1dc6ef314ebf6 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 29 Nov 2022 10:50:56 -0300 +Subject: [PATCH 082/168] zink: add driver-workaround for missing gl_point_size + +Add code to support gl_point lowering. + +In this commit the target of this lowering will be only the +imagination proprietary driver. + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 4 ++++ + src/gallium/drivers/zink/zink_draw.cpp | 5 +++-- + src/gallium/drivers/zink/zink_program.c | 6 ++++-- + src/gallium/drivers/zink/zink_screen.c | 16 +++++++++++++++- + src/gallium/drivers/zink/zink_shader_keys.h | 1 + + src/gallium/drivers/zink/zink_state.c | 16 ++++++++++++++-- + src/gallium/drivers/zink/zink_types.h | 1 + + 7 files changed, 42 insertions(+), 7 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index d78846b1858..babb69b68c2 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2576,6 +2576,10 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + NIR_PASS_V(nir, nir_lower_var_copies); + need_optimize = true; + } ++ if (zink_gs_key(key)->lower_gl_point) { ++ NIR_PASS_V(nir, lower_gl_point_gs); ++ need_optimize = true; ++ } + break; + + default: +diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp +index 303ad32bd51..b8b5b9fbe67 100644 +--- a/src/gallium/drivers/zink/zink_draw.cpp ++++ b/src/gallium/drivers/zink/zink_draw.cpp +@@ -801,8 +801,9 @@ zink_draw(struct pipe_context *pctx, + offsetof(struct zink_gfx_push_constant, default_inner_level), sizeof(float) * 6, + &ctx->tess_levels[0]); + } +- if (zink_get_fs_key(ctx)->lower_line_stipple) { +- assert(zink_get_gs_key(ctx)->lower_line_stipple); ++ if (zink_get_fs_key(ctx)->lower_line_stipple || ++ zink_get_gs_key(ctx)->lower_gl_point) { ++ assert(zink_get_fs_key(ctx)->lower_line_stipple == zink_get_gs_key(ctx)->lower_line_stipple); + + float viewport_scale[2] = { + ctx->vp_state.viewport_states[0].scale[0], +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 3085177e9f1..9843ce13582 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -1879,7 +1879,7 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx) + zink_set_gs_key(ctx)->lower_line_stipple = lower_line_stipple; + } + +- if (lower_line_stipple) { ++ if (lower_line_stipple || 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; +@@ -1891,7 +1891,9 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx) + nir_shader *nir = nir_create_passthrough_gs( + &screen->nir_options, + ctx->gfx_stages[prev_vertex_stage]->nir, +- SHADER_PRIM_LINE_STRIP, 2); ++ lower_line_stipple ? SHADER_PRIM_LINE_STRIP : SHADER_PRIM_POINTS, ++ lower_line_stipple ? 2 : 1); ++ NIR_PASS_V(nir, nir_lower_gs_intrinsics, nir_lower_gs_intrinsics_per_stream); + + struct zink_shader *shader = zink_shader_create(screen, nir, NULL); + ctx->gfx_stages[prev_vertex_stage]->non_fs.generated_gs = shader; +diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c +index e2f65c7a348..a200244a07d 100644 +--- a/src/gallium/drivers/zink/zink_screen.c ++++ b/src/gallium/drivers/zink/zink_screen.c +@@ -2355,6 +2355,19 @@ init_driver_workarounds(struct zink_screen *screen) + screen->driver_workarounds.no_linestipple = 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 || +@@ -2725,7 +2738,8 @@ zink_internal_create_screen(const struct pipe_screen_config *config) + 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_linestipple && ++ !screen->driver_workarounds.no_hw_gl_point; + if (!screen->optimal_keys) + screen->info.have_EXT_graphics_pipeline_library = false; + +diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h +index 013892bff2d..afdf10a1177 100644 +--- a/src/gallium/drivers/zink/zink_shader_keys.h ++++ b/src/gallium/drivers/zink/zink_shader_keys.h +@@ -60,6 +60,7 @@ struct zink_gs_key { + struct zink_vs_key_base base; + uint8_t pad; + bool lower_line_stipple : 1; ++ bool lower_gl_point : 1; + // not hashed + unsigned size; + }; +diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c +index eba2cc8dfb8..92b0b0ed483 100644 +--- a/src/gallium/drivers/zink/zink_state.c ++++ b/src/gallium/drivers/zink/zink_state.c +@@ -578,8 +578,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 : +@@ -651,6 +658,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; +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index 76dd9bd4990..a62b71f352b 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -1282,6 +1282,7 @@ struct zink_screen { + bool needs_sanitised_layer; + bool track_renderpasses; + bool no_linestipple; ++ bool no_hw_gl_point; + unsigned z16_unscaled_bias; + unsigned z24_unscaled_bias; + } driver_workarounds; +-- +2.17.1 + diff --git a/package/mesa3d/0083-zink-fix-rebase-mistake.patch b/package/mesa3d/0083-zink-fix-rebase-mistake.patch new file mode 100644 index 00000000..7872eafc --- /dev/null +++ b/package/mesa3d/0083-zink-fix-rebase-mistake.patch @@ -0,0 +1,29 @@ +From a687fef70621b9383a02c83e85937aa8845d7aef Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 7 Dec 2022 09:27:28 +0100 +Subject: [PATCH 083/168] zink: fix rebase-mistake + +This should not have re-introduced this lowering, effectively reverting +dcf3ae72abf78e8959c5b5a94ef332c0b7396ab2. + +Fixes: 16971cd667b ("zink: add driver-workaround for missing gl_point_size") +Part-of: +--- + src/gallium/drivers/zink/zink_program.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 9843ce13582..a90e13e202a 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -1893,7 +1893,6 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx) + ctx->gfx_stages[prev_vertex_stage]->nir, + lower_line_stipple ? SHADER_PRIM_LINE_STRIP : SHADER_PRIM_POINTS, + lower_line_stipple ? 2 : 1); +- NIR_PASS_V(nir, nir_lower_gs_intrinsics, nir_lower_gs_intrinsics_per_stream); + + struct zink_shader *shader = zink_shader_create(screen, nir, NULL); + ctx->gfx_stages[prev_vertex_stage]->non_fs.generated_gs = shader; +-- +2.17.1 + diff --git a/package/mesa3d/0084-zink-do-not-leave-needless-shader-temps-around.patch b/package/mesa3d/0084-zink-do-not-leave-needless-shader-temps-around.patch new file mode 100644 index 00000000..d5d1ff9e --- /dev/null +++ b/package/mesa3d/0084-zink-do-not-leave-needless-shader-temps-around.patch @@ -0,0 +1,38 @@ +From 041bb56b8981a2b9fa7685f49f8f3ceeb9fe28be Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 8 Dec 2022 13:13:33 +0100 +Subject: [PATCH 084/168] zink: do not leave needless shader temps around +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This used to not matter, but since we started emitting shader-temps +properly, this causes issues where we end up with samplers and images as +shader-temps. That causes asserts while emitting them. + +So let's remove the unused vars as well. + +This fixes a piglit regression that somehow went unnoticed on CI. + +Fixes: 85964945e7c ("zink: emit vars with nir_var_shader_temp mode") +Tested-by: Martin Roukala (né Peres) +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index babb69b68c2..40337e47956 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2496,6 +2496,7 @@ prune_io(nir_shader *nir) + if (!find_var_deref(nir, var)) + var->data.mode = nir_var_shader_temp; + } ++ NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_shader_temp, NULL); + } + + static bool +-- +2.17.1 + diff --git a/package/mesa3d/0085-zink-Don-t-set-dynamic-color-attachment-state-for-0-.patch b/package/mesa3d/0085-zink-Don-t-set-dynamic-color-attachment-state-for-0-.patch new file mode 100644 index 00000000..27d062e9 --- /dev/null +++ b/package/mesa3d/0085-zink-Don-t-set-dynamic-color-attachment-state-for-0-.patch @@ -0,0 +1,49 @@ +From f1651d848b6df82c8b97702ea8870d1ee0cb2b2e Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 6 Dec 2022 09:46:25 -0800 +Subject: [PATCH 085/168] zink: Don't set dynamic color attachment state for 0 + attachments. + +Fixes some validation failures like: + +VUID-vkCmdSetColorBlendEquationEXT-attachmentCount-arraylength(ERROR / SPEC): msgNum: -175001922 - Validation Error: [ VUID-vkCmdSetColorBlendEquationEXT-attachmentCount-arraylength ] Object 0: handle = 0xaaaae7632fa0, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xf591aebe | vkCmdSetColorBlendEquationEXT: parameter attachmentCount must be greater than 0. The Vulkan spec states: attachmentCount must be greater than 0 (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdSetColorBlendEquationEXT-attachmentCount-arraylength) + +However, we still have some around dynamic color attachment state: + + Objects: 1 + [0] 0xaaaafcab4150, type: 6, name: NULL +VUID_Undefined(ERROR / SPEC): msgNum: 2044605652 - Validation Error: [ VUID_Undefined ] Object 0: handle = 0xaaaafcab4150, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x79de34d4 | VkCommandBuffer 0xaaaafcab4150[]: Dynamic color blend enable state not set for this command buffer. + Objects: 1 + [0] 0xaaaafcab4150, type: 6, name: NULL +VUID_Undefined(ERROR / SPEC): msgNum: 2044605652 - Validation Error: [ VUID_Undefined ] Object 0: handle = 0xaaaafcab4150, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x79de34d4 | VkCommandBuffer 0xaaaafcab4150[]: Dynamic color blend equation state not set for this command buffer. + Objects: 1 + [0] 0xaaaafcab4150, type: 6, name: NULL +VUID_Undefined(ERROR / SPEC): msgNum: 2044605652 - Validation Error: [ VUID_Undefined ] Object 0: handle = 0xaaaafcab4150, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x79de34d4 | VkCommandBuffer 0xaaaafcab4150[]: Dynamic color write mask state not set for this command buffer. + +Part-of: +--- + src/gallium/drivers/zink/zink_draw.cpp | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp +index b8b5b9fbe67..72f6c404766 100644 +--- a/src/gallium/drivers/zink/zink_draw.cpp ++++ b/src/gallium/drivers/zink/zink_draw.cpp +@@ -704,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); + } +-- +2.17.1 + diff --git a/package/mesa3d/0086-zink-fix-line-stipple-varying-allocation.patch b/package/mesa3d/0086-zink-fix-line-stipple-varying-allocation.patch new file mode 100644 index 00000000..2ac9cf7e --- /dev/null +++ b/package/mesa3d/0086-zink-fix-line-stipple-varying-allocation.patch @@ -0,0 +1,41 @@ +From 7a6a6620875299bbd82a4e558ddc6b50c3433c6e Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 1 Dec 2022 22:17:42 +0100 +Subject: [PATCH 086/168] zink: fix line-stipple varying allocation + +This was really derpy. There's two things wrong; first of all, we should +pick at LEAST VARYING_SLOT_VAR0, second, util_last_bit64 returns one +more than the index of the bit already, so we don't want to add twice +here. + +Fixes: 4b17c099ca4 ("zink: add line-stippling lowering passes") +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 40337e47956..ee05cf7aa6d 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -463,7 +463,7 @@ lower_line_stipple_gs(nir_shader *shader) + "__stipple"); + state.stipple_out->data.interpolation = INTERP_MODE_NOPERSPECTIVE; + state.stipple_out->data.driver_location = shader->num_outputs++; +- state.stipple_out->data.location = MIN2(util_last_bit64(shader->info.outputs_written) + 1, VARYING_SLOT_VAR0); ++ state.stipple_out->data.location = MAX2(util_last_bit64(shader->info.outputs_written), VARYING_SLOT_VAR0); + shader->info.outputs_written |= BITFIELD64_BIT(state.stipple_out->data.location); + + // create temp variables +@@ -501,7 +501,7 @@ lower_line_stipple_fs(nir_shader *shader) + "__stipple"); + stipple->data.interpolation = INTERP_MODE_NOPERSPECTIVE; + stipple->data.driver_location = shader->num_inputs++; +- stipple->data.location = MIN2(util_last_bit64(shader->info.inputs_read) + 1, VARYING_SLOT_VAR0); ++ stipple->data.location = MAX2(util_last_bit64(shader->info.inputs_read), VARYING_SLOT_VAR0); + shader->info.inputs_read |= BITFIELD64_BIT(stipple->data.location); + + nir_variable *sample_mask_out = +-- +2.17.1 + diff --git a/package/mesa3d/0087-zink-add-line-smooth-lowering-passes.patch b/package/mesa3d/0087-zink-add-line-smooth-lowering-passes.patch new file mode 100644 index 00000000..830983e7 --- /dev/null +++ b/package/mesa3d/0087-zink-add-line-smooth-lowering-passes.patch @@ -0,0 +1,311 @@ +From 66144d816bc24a52c899e9f11e4ba46a11b5ac86 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 16 Nov 2022 16:28:06 +0100 +Subject: [PATCH 087/168] zink: add line-smooth lowering passes + +These passes implements basically the same logic as draw_pipe_aaline.c +does, but using geometry shaders instead of doing it CPU-side. + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 249 +++++++++++++++++++++++ + src/gallium/drivers/zink/zink_types.h | 2 + + 2 files changed, 251 insertions(+) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index ee05cf7aa6d..6a783a78d26 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -31,6 +31,7 @@ + #include "pipe/p_state.h" + + #include "nir.h" ++#include "nir/nir_draw_helpers.h" + #include "compiler/nir/nir_builder.h" + #include "compiler/nir/nir_builtin_builder.h" + +@@ -67,6 +68,7 @@ fields[member_idx].offset = offsetof(struct zink_gfx_push_constant, field); + PUSHCONST_MEMBER(ZINK_GFX_PUSHCONST_DEFAULT_OUTER_LEVEL, default_outer_level); + PUSHCONST_MEMBER(ZINK_GFX_PUSHCONST_LINE_STIPPLE_PATTERN, line_stipple_pattern); + PUSHCONST_MEMBER(ZINK_GFX_PUSHCONST_VIEWPORT_SCALE, viewport_scale); ++ PUSHCONST_MEMBER(ZINK_GFX_PUSHCONST_LINE_WIDTH, line_width); + + pushconst = nir_variable_create(nir, nir_var_mem_push_const, + glsl_struct_type(fields, ZINK_GFX_PUSHCONST_MAX, "struct", false), +@@ -560,6 +562,253 @@ lower_line_stipple_fs(nir_shader *shader) + return true; + } + ++struct lower_line_smooth_state { ++ nir_variable *pos_out; ++ nir_variable *line_coord_out; ++ nir_variable *prev_pos; ++ nir_variable *pos_counter; ++ nir_variable *prev_varyings[VARYING_SLOT_MAX], ++ *varyings[VARYING_SLOT_MAX]; ++}; ++ ++static bool ++lower_line_smooth_gs_store(nir_builder *b, ++ nir_intrinsic_instr *intrin, ++ struct lower_line_smooth_state *state) ++{ ++ b->cursor = nir_before_instr(&intrin->instr); ++ nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]); ++ if (nir_deref_mode_is(deref, nir_var_shader_out)) { ++ nir_variable *var = nir_deref_instr_get_variable(deref); ++ ++ // we take care of position elsewhere ++ gl_varying_slot location = var->data.location; ++ if (location != VARYING_SLOT_POS) { ++ assert(state->varyings[location]); ++ assert(intrin->src[1].is_ssa); ++ nir_store_var(b, state->varyings[location], ++ intrin->src[1].ssa, ++ nir_intrinsic_write_mask(intrin)); ++ nir_instr_remove(&intrin->instr); ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++static bool ++lower_line_smooth_gs_emit_vertex(nir_builder *b, ++ nir_intrinsic_instr *intrin, ++ struct lower_line_smooth_state *state) ++{ ++ b->cursor = nir_before_instr(&intrin->instr); ++ ++ nir_push_if(b, nir_ine_imm(b, nir_load_var(b, state->pos_counter), 0)); ++ nir_ssa_def *vp_scale = nir_load_push_constant(b, 2, 32, ++ nir_imm_int(b, ZINK_GFX_PUSHCONST_VIEWPORT_SCALE), ++ .base = 1, ++ .range = 2); ++ nir_ssa_def *prev = nir_load_var(b, state->prev_pos); ++ nir_ssa_def *curr = nir_load_var(b, state->pos_out); ++ nir_ssa_def *prev_vp = viewport_map(b, prev, vp_scale); ++ nir_ssa_def *curr_vp = viewport_map(b, curr, vp_scale); ++ ++ nir_ssa_def *width = nir_load_push_constant(b, 1, 32, ++ nir_imm_int(b, ZINK_GFX_PUSHCONST_LINE_WIDTH), ++ .base = 1); ++ nir_ssa_def *half_width = nir_fadd_imm(b, nir_fmul_imm(b, width, 0.5), 0.5); ++ ++ const unsigned yx[2] = { 1, 0 }; ++ nir_ssa_def *vec = nir_fsub(b, curr_vp, prev_vp); ++ nir_ssa_def *len = nir_fast_length(b, vec); ++ nir_ssa_def *dir = nir_normalize(b, vec); ++ nir_ssa_def *half_length = nir_fmul_imm(b, len, 0.5); ++ half_length = nir_fadd_imm(b, half_length, 0.5); ++ ++ nir_ssa_def *vp_scale_rcp = nir_frcp(b, vp_scale); ++ nir_ssa_def *tangent = ++ nir_fmul(b, ++ nir_fmul(b, ++ nir_swizzle(b, dir, yx, 2), ++ nir_imm_vec2(b, 1.0, -1.0)), ++ vp_scale_rcp); ++ tangent = nir_fmul(b, tangent, half_width); ++ tangent = nir_pad_vector_imm_int(b, tangent, 0, 4); ++ dir = nir_fmul_imm(b, nir_fmul(b, dir, vp_scale_rcp), 0.5); ++ ++ nir_ssa_def *line_offets[4] = { ++ nir_fadd(b, tangent, nir_fneg(b, dir)), ++ nir_fadd(b, nir_fneg(b, tangent), nir_fneg(b, dir)), ++ nir_fadd(b, tangent, dir), ++ nir_fadd(b, nir_fneg(b, tangent), dir), ++ }; ++ nir_ssa_def *line_coord = ++ nir_vec4(b, half_width, half_width, half_length, half_length); ++ nir_ssa_def *line_coords[4] = { ++ nir_fmul(b, line_coord, nir_imm_vec4(b, -1, 1, -1, 1)), ++ nir_fmul(b, line_coord, nir_imm_vec4(b, 1, 1, -1, 1)), ++ nir_fmul(b, line_coord, nir_imm_vec4(b, -1, 1, 1, 1)), ++ nir_fmul(b, line_coord, nir_imm_vec4(b, 1, 1, 1, 1)), ++ }; ++ ++ /* emit first two vertices */ ++ for (int i = 0; i < 2; ++i) { ++ nir_foreach_variable_with_modes(var, b->shader, nir_var_shader_out) { ++ gl_varying_slot location = var->data.location; ++ if (state->prev_varyings[location]) ++ nir_copy_var(b, var, state->prev_varyings[location]); ++ } ++ nir_store_var(b, state->pos_out, ++ nir_fadd(b, prev, nir_fmul(b, line_offets[i], ++ nir_channel(b, prev, 3))), 0xf); ++ nir_store_var(b, state->line_coord_out, line_coords[i], 0xf); ++ nir_emit_vertex(b); ++ } ++ ++ /* emit last two vertices */ ++ for (int i = 2; i < 4; ++i) { ++ nir_foreach_variable_with_modes(var, b->shader, nir_var_shader_out) { ++ gl_varying_slot location = var->data.location; ++ if (state->varyings[location]) ++ nir_copy_var(b, var, state->varyings[location]); ++ } ++ nir_store_var(b, state->pos_out, ++ nir_fadd(b, curr, nir_fmul(b, line_offets[i], ++ nir_channel(b, curr, 3))), 0xf); ++ nir_store_var(b, state->line_coord_out, line_coords[i], 0xf); ++ nir_emit_vertex(b); ++ } ++ nir_end_primitive(b); ++ ++ nir_pop_if(b, NULL); ++ ++ nir_copy_var(b, state->prev_pos, state->pos_out); ++ nir_foreach_variable_with_modes(var, b->shader, nir_var_shader_out) { ++ gl_varying_slot location = var->data.location; ++ if (state->varyings[location]) ++ nir_copy_var(b, state->prev_varyings[location], state->varyings[location]); ++ } ++ ++ // update prev_pos and pos_counter for next vertex ++ b->cursor = nir_after_instr(&intrin->instr); ++ nir_store_var(b, state->pos_counter, ++ nir_iadd_imm(b, nir_load_var(b, state->pos_counter), ++ 1), 1); ++ ++ nir_instr_remove(&intrin->instr); ++ return true; ++} ++ ++static bool ++lower_line_smooth_gs_end_primitive(nir_builder *b, ++ nir_intrinsic_instr *intrin, ++ struct lower_line_smooth_state *state) ++{ ++ b->cursor = nir_before_instr(&intrin->instr); ++ ++ // reset line counter ++ nir_store_var(b, state->pos_counter, nir_imm_int(b, 0), 1); ++ ++ nir_instr_remove(&intrin->instr); ++ return true; ++} ++ ++static bool ++lower_line_smooth_gs_instr(nir_builder *b, nir_instr *instr, void *data) ++{ ++ if (instr->type != nir_instr_type_intrinsic) ++ return false; ++ ++ struct lower_line_smooth_state *state = data; ++ nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); ++ ++ switch (intrin->intrinsic) { ++ case nir_intrinsic_store_deref: ++ return lower_line_smooth_gs_store(b, intrin, state); ++ case nir_intrinsic_copy_deref: ++ unreachable("should be lowered"); ++ case nir_intrinsic_emit_vertex_with_counter: ++ case nir_intrinsic_emit_vertex: ++ return lower_line_smooth_gs_emit_vertex(b, intrin, state); ++ case nir_intrinsic_end_primitive: ++ case nir_intrinsic_end_primitive_with_counter: ++ return lower_line_smooth_gs_end_primitive(b, intrin, state); ++ default: ++ return false; ++ } ++} ++ ++static bool ++lower_line_smooth_gs(nir_shader *shader) ++{ ++ nir_builder b; ++ struct lower_line_smooth_state state; ++ ++ memset(state.varyings, 0, sizeof(state.varyings)); ++ memset(state.prev_varyings, 0, sizeof(state.prev_varyings)); ++ nir_foreach_variable_with_modes(var, shader, nir_var_shader_out) { ++ gl_varying_slot location = var->data.location; ++ if (location == VARYING_SLOT_POS) ++ continue; ++ ++ char name[100]; ++ snprintf(name, sizeof(name), "__tmp_%d", location); ++ state.varyings[location] = ++ nir_variable_create(shader, nir_var_shader_temp, ++ var->type, name); ++ ++ snprintf(name, sizeof(name), "__tmp_prev_%d", location); ++ state.prev_varyings[location] = ++ nir_variable_create(shader, nir_var_shader_temp, ++ var->type, name); ++ } ++ ++ state.pos_out = ++ nir_find_variable_with_location(shader, nir_var_shader_out, ++ VARYING_SLOT_POS); ++ ++ // if position isn't written, we have nothing to do ++ if (!state.pos_out) ++ return false; ++ ++ state.line_coord_out = ++ nir_variable_create(shader, nir_var_shader_out, glsl_vec4_type(), ++ "__line_coord"); ++ state.line_coord_out->data.interpolation = INTERP_MODE_NOPERSPECTIVE; ++ state.line_coord_out->data.driver_location = shader->num_outputs++; ++ state.line_coord_out->data.location = MAX2(util_last_bit64(shader->info.outputs_written), VARYING_SLOT_VAR0); ++ shader->info.outputs_written |= BITFIELD64_BIT(state.line_coord_out->data.location); ++ ++ // create temp variables ++ state.prev_pos = nir_variable_create(shader, nir_var_shader_temp, ++ glsl_vec4_type(), ++ "__prev_pos"); ++ state.pos_counter = nir_variable_create(shader, nir_var_shader_temp, ++ glsl_uint_type(), ++ "__pos_counter"); ++ ++ // initialize pos_counter ++ nir_function_impl *entry = nir_shader_get_entrypoint(shader); ++ nir_builder_init(&b, entry); ++ b.cursor = nir_before_cf_list(&entry->body); ++ nir_store_var(&b, state.pos_counter, nir_imm_int(&b, 0), 1); ++ ++ shader->info.gs.vertices_out = 2 * shader->info.gs.vertices_out; ++ shader->info.gs.output_primitive = SHADER_PRIM_TRIANGLE_STRIP; ++ ++ return nir_shader_instructions_pass(shader, lower_line_smooth_gs_instr, ++ nir_metadata_dominance, &state); ++} ++ ++static bool ++lower_line_smooth_fs(nir_shader *shader) ++{ ++ int dummy; ++ nir_lower_aaline_fs(shader, &dummy); ++ return true; ++} ++ + static bool + lower_dual_blend(nir_shader *shader) + { +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index a62b71f352b..64b79e30396 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -805,6 +805,7 @@ struct zink_gfx_push_constant { + 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 +@@ -818,6 +819,7 @@ enum zink_gfx_push_constant_member { + 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 + }; + +-- +2.17.1 + diff --git a/package/mesa3d/0088-zink-lower-smooth-lines-if-not-supported.patch b/package/mesa3d/0088-zink-lower-smooth-lines-if-not-supported.patch new file mode 100644 index 00000000..47d86544 --- /dev/null +++ b/package/mesa3d/0088-zink-lower-smooth-lines-if-not-supported.patch @@ -0,0 +1,215 @@ +From 17b509cee23cad5e104a02274cfbeeacc24123f7 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 6 Dec 2022 08:54:34 +0100 +Subject: [PATCH 088/168] zink: lower smooth-lines if not supported + +This implements line-smoothing the same way as the draw-module does, +except using a geometry shader instead of a CPU pass. + +Ideally, this should be enabled either by checking for the various +smooth-line caps, or by a DRIconf setting. + +Unfortunately, RADV doesn't support he smooth-lines features, and we +don't want to force it down a pessimistic shader-key code-path. So that +plan is out the window for now. + +While DRIconf is also neat, it's a bit of work to wire up, and we don't +really know of any real-world applications who would need this yet. So, +for now, let's just unconditionally enable is on the IMG proprietary +driver, which is going to need this for sure. + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 13 +++++++++++++ + src/gallium/drivers/zink/zink_draw.cpp | 19 +++++++++++++++++-- + src/gallium/drivers/zink/zink_pipeline.c | 3 ++- + src/gallium/drivers/zink/zink_program.c | 14 +++++++++++++- + src/gallium/drivers/zink/zink_screen.c | 7 +++++++ + src/gallium/drivers/zink/zink_shader_keys.h | 4 +++- + src/gallium/drivers/zink/zink_state.c | 3 ++- + src/gallium/drivers/zink/zink_types.h | 1 + + 8 files changed, 58 insertions(+), 6 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 6a783a78d26..3a635259ee5 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2826,6 +2826,13 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + NIR_PASS_V(nir, nir_lower_var_copies); + need_optimize = true; + } ++ ++ if (zink_gs_key(key)->lower_line_smooth) { ++ NIR_PASS_V(nir, lower_line_smooth_gs); ++ NIR_PASS_V(nir, nir_lower_var_copies); ++ need_optimize = true; ++ } ++ + if (zink_gs_key(key)->lower_gl_point) { + NIR_PASS_V(nir, lower_gl_point_gs); + need_optimize = true; +@@ -2856,6 +2863,12 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + case MESA_SHADER_FRAGMENT: + if (zink_fs_key(key)->lower_line_stipple) + NIR_PASS_V(nir, lower_line_stipple_fs); ++ ++ if (zink_fs_key(key)->lower_line_smooth) { ++ NIR_PASS_V(nir, lower_line_smooth_fs); ++ need_optimize = true; ++ } ++ + if (!zink_fs_key(key)->samples && + nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)) { + /* VK will always use gl_SampleMask[] values even if sample count is 0, +diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp +index 72f6c404766..aea345d379b 100644 +--- a/src/gallium/drivers/zink/zink_draw.cpp ++++ b/src/gallium/drivers/zink/zink_draw.cpp +@@ -804,8 +804,14 @@ zink_draw(struct pipe_context *pctx, + &ctx->tess_levels[0]); + } + if (zink_get_fs_key(ctx)->lower_line_stipple || +- zink_get_gs_key(ctx)->lower_gl_point) { +- assert(zink_get_fs_key(ctx)->lower_line_stipple == zink_get_gs_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], +@@ -824,6 +830,15 @@ zink_draw(struct pipe_context *pctx, + 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) { +diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c +index 0af7fd4b34f..731288a83f9 100644 +--- a/src/gallium/drivers/zink/zink_pipeline.c ++++ b/src/gallium/drivers/zink/zink_pipeline.c +@@ -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; +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index a90e13e202a..60865ca5462 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -1879,7 +1879,19 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx) + zink_set_gs_key(ctx)->lower_line_stipple = lower_line_stipple; + } + +- if (lower_line_stipple || zink_get_gs_key(ctx)->lower_gl_point) { ++ 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; +diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c +index a200244a07d..c0ba0861fe1 100644 +--- a/src/gallium/drivers/zink/zink_screen.c ++++ b/src/gallium/drivers/zink/zink_screen.c +@@ -2355,6 +2355,12 @@ init_driver_workarounds(struct zink_screen *screen) + 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. +@@ -2739,6 +2745,7 @@ zink_internal_create_screen(const struct pipe_screen_config *config) + 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; + if (!screen->optimal_keys) + screen->info.have_EXT_graphics_pipeline_library = false; +diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h +index afdf10a1177..6c6a18aadda 100644 +--- a/src/gallium/drivers/zink/zink_shader_keys.h ++++ b/src/gallium/drivers/zink/zink_shader_keys.h +@@ -60,6 +60,7 @@ 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; +@@ -72,7 +73,8 @@ struct zink_fs_key { + bool force_persample_interp : 1; + bool fbfetch_ms : 1; + bool lower_line_stipple : 1; +- uint8_t pad : 2; ++ bool lower_line_smooth : 1; ++ uint8_t pad : 1; + uint8_t coord_replace_bits; + }; + +diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c +index 92b0b0ed483..e5b82bda278 100644 +--- a/src/gallium/drivers/zink/zink_state.c ++++ b/src/gallium/drivers/zink/zink_state.c +@@ -594,7 +594,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; +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index 64b79e30396..4b6a0100396 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -1284,6 +1284,7 @@ struct zink_screen { + bool needs_sanitised_layer; + bool track_renderpasses; + bool no_linestipple; ++ bool no_linesmooth; + bool no_hw_gl_point; + unsigned z16_unscaled_bias; + unsigned z24_unscaled_bias; +-- +2.17.1 + diff --git a/package/mesa3d/0089-zink-fix-line-smooth-interpolation.patch b/package/mesa3d/0089-zink-fix-line-smooth-interpolation.patch new file mode 100644 index 00000000..d7c9f595 --- /dev/null +++ b/package/mesa3d/0089-zink-fix-line-smooth-interpolation.patch @@ -0,0 +1,82 @@ +From f7d94afbe86c44f6a1ef6d7b86805b50587ed3c5 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 5 Dec 2022 16:16:43 +0100 +Subject: [PATCH 089/168] zink: fix line-smooth interpolation + +Extending the lines by half a pixel in each direction without doing +anything about the varyings makes the varyings interpolate over a +distance than intended. While this can be negligeble for long lines, +it can lead to big error for short lines. + +Let's instead add extra geometry for each of the line-caps, so we can +make sure the varyings stay constant for the whole cap, and interpolate +over the intended distance instead. + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 3a635259ee5..7366ae80a87 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -637,23 +637,31 @@ lower_line_smooth_gs_emit_vertex(nir_builder *b, + tangent = nir_pad_vector_imm_int(b, tangent, 0, 4); + dir = nir_fmul_imm(b, nir_fmul(b, dir, vp_scale_rcp), 0.5); + +- nir_ssa_def *line_offets[4] = { ++ nir_ssa_def *line_offets[8] = { + nir_fadd(b, tangent, nir_fneg(b, dir)), + nir_fadd(b, nir_fneg(b, tangent), nir_fneg(b, dir)), ++ tangent, ++ nir_fneg(b, tangent), ++ tangent, ++ nir_fneg(b, tangent), + nir_fadd(b, tangent, dir), + nir_fadd(b, nir_fneg(b, tangent), dir), + }; + nir_ssa_def *line_coord = + nir_vec4(b, half_width, half_width, half_length, half_length); +- nir_ssa_def *line_coords[4] = { ++ nir_ssa_def *line_coords[8] = { + nir_fmul(b, line_coord, nir_imm_vec4(b, -1, 1, -1, 1)), + nir_fmul(b, line_coord, nir_imm_vec4(b, 1, 1, -1, 1)), ++ nir_fmul(b, line_coord, nir_imm_vec4(b, -1, 1, 0, 1)), ++ nir_fmul(b, line_coord, nir_imm_vec4(b, 1, 1, 0, 1)), ++ nir_fmul(b, line_coord, nir_imm_vec4(b, -1, 1, 0, 1)), ++ nir_fmul(b, line_coord, nir_imm_vec4(b, 1, 1, 0, 1)), + nir_fmul(b, line_coord, nir_imm_vec4(b, -1, 1, 1, 1)), + nir_fmul(b, line_coord, nir_imm_vec4(b, 1, 1, 1, 1)), + }; + +- /* emit first two vertices */ +- for (int i = 0; i < 2; ++i) { ++ /* emit first end-cap, and start line */ ++ for (int i = 0; i < 4; ++i) { + nir_foreach_variable_with_modes(var, b->shader, nir_var_shader_out) { + gl_varying_slot location = var->data.location; + if (state->prev_varyings[location]) +@@ -666,8 +674,8 @@ lower_line_smooth_gs_emit_vertex(nir_builder *b, + nir_emit_vertex(b); + } + +- /* emit last two vertices */ +- for (int i = 2; i < 4; ++i) { ++ /* finish line and emit last end-cap */ ++ for (int i = 4; i < 8; ++i) { + nir_foreach_variable_with_modes(var, b->shader, nir_var_shader_out) { + gl_varying_slot location = var->data.location; + if (state->varyings[location]) +@@ -794,7 +802,7 @@ lower_line_smooth_gs(nir_shader *shader) + b.cursor = nir_before_cf_list(&entry->body); + nir_store_var(&b, state.pos_counter, nir_imm_int(&b, 0), 1); + +- shader->info.gs.vertices_out = 2 * shader->info.gs.vertices_out; ++ shader->info.gs.vertices_out = 8 * shader->info.gs.vertices_out; + shader->info.gs.output_primitive = SHADER_PRIM_TRIANGLE_STRIP; + + return nir_shader_instructions_pass(shader, lower_line_smooth_gs_instr, +-- +2.17.1 + diff --git a/package/mesa3d/0090-zink-Only-expose-PIPE_CAP_IMAGE_ATOMIC_FLOAT_ADD-if-.patch b/package/mesa3d/0090-zink-Only-expose-PIPE_CAP_IMAGE_ATOMIC_FLOAT_ADD-if-.patch new file mode 100644 index 00000000..ef76f781 --- /dev/null +++ b/package/mesa3d/0090-zink-Only-expose-PIPE_CAP_IMAGE_ATOMIC_FLOAT_ADD-if-.patch @@ -0,0 +1,933 @@ +From 4e95620cfa24c2b00af6bb5a133897f3ecc42919 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 3 Jan 2023 14:17:48 -0800 +Subject: [PATCH 090/168] zink: Only expose PIPE_CAP_IMAGE_ATOMIC_FLOAT_ADD if + we can actually add. + +Drivers may expose the ext without the add capability, if they can +load/store/exchange. + +Fixes: c32f046ab669 ("zink: export PIPE_CAP_IMAGE_ATOMIC_FLOAT_ADD") +Part-of: +--- + .../drivers/zink/ci/zink-anv-tgl-fails.txt | 910 ++++++++++++++++++ + 1 file changed, 910 insertions(+) + +diff --git a/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt b/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt +index e69de29bb2d..76901167290 100644 +--- a/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt ++++ b/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt +@@ -0,0 +1,910 @@ ++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 ++ ++# https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20508 ++multisample-dEQP-GLES3.functional.multisample.default_framebuffer.depth,Fail ++multisample-dEQP-GLES3.functional.multisample.default_framebuffer.num_samples_line,Fail ++multisample-dEQP-GLES3.functional.multisample.default_framebuffer.num_samples_polygon,Fail ++multisample-dEQP-GLES3.functional.occlusion_query.depth_clear_stencil_write,Fail ++multisample-dEQP-GLES3.functional.occlusion_query.depth_write_depth_clear_stencil_write_stencil_clear,Fail ++multisample-dEQP-GLES3.functional.occlusion_query.depth_write_depth_clear,Fail ++multisample-dEQP-GLES3.functional.occlusion_query.depth_write_stencil_clear,Fail ++multisample-dEQP-GLES3.functional.occlusion_query.depth_write_stencil_write,Fail ++multisample-dEQP-GLES3.functional.occlusion_query.scissor_depth_clear_stencil_write,Fail ++multisample-dEQP-GLES3.functional.occlusion_query.scissor_depth_write_stencil_clear,Fail ++multisample-dEQP-GLES3.functional.occlusion_query.stencil_write,Fail ++multisample-dEQP-GLES31.functional.sample_shading.min_sample_shading.default_framebuffer_color,Fail ++multisample-dEQP-GLES31.functional.sample_shading.min_sample_shading.default_framebuffer_discard,Fail ++multisample-dEQP-GLES31.functional.shaders.multisample_interpolation.sample_qualifier.default_framebuffer,Fail ++multisample-dEQP-GLES31.functional.shaders.sample_variables.sample_id.default_framebuffer,Fail ++multisample-dEQP-GLES31.functional.shaders.sample_variables.sample_mask.discard_half_per_pixel.default_framebuffer,Fail ++multisample-dEQP-GLES31.functional.shaders.sample_variables.sample_mask.discard_half_per_sample.default_framebuffer,Fail ++multisample-dEQP-GLES31.functional.shaders.sample_variables.sample_mask.discard_half_per_two_samples.default_framebuffer,Fail ++ ++# 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 1.1@read-front clear-front-first,Fail ++spec@!opengl 1.1@read-front samples=16,Fail ++spec@!opengl 1.1@read-front samples=2,Fail ++spec@!opengl 1.1@read-front samples=4,Fail ++spec@!opengl 1.1@read-front samples=6,Fail ++spec@!opengl 1.1@read-front samples=8,Fail ++spec@!opengl 1.1@read-front,Fail ++ ++# depth texturing: zink is returning intensity shadow comparisons and depth samples, regardless of depth mode. ++# Check out the "splat" in zink_compiler.c around !is_new_style_shadow, and the swizzle rewrite for depth ++# textures in zink_create_sampler_view(). ++spec@!opengl 2.0@depth-tex-modes-glsl,Fail ++spec@arb_depth_texture@depth-tex-modes,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_shader_texture_lod@execution@arb_shader_texture_lod-texgradcube,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_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-shadow2drect,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-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-shadow1darray,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@ext_texture_array@glsl-fs-shadow2darray,Fail ++spec@ext_texture_swizzle@depth_texture_mode_and_swizzle,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-shadow1d,Fail ++spec@glsl-1.10@execution@samplers@glsl-fs-shadow1dproj-bias,Fail ++spec@glsl-1.10@execution@samplers@glsl-fs-shadow1dproj,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-shadow2d,Fail ++spec@glsl-1.10@execution@samplers@glsl-fs-shadow2dproj-bias,Fail ++spec@glsl-1.10@execution@samplers@glsl-fs-shadow2dproj,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 ++ ++# https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20506 ++spec@nv_shader_atomic_int64@execution@shared-atomicadd-int,Fail ++spec@nv_shader_atomic_int64@execution@shared-atomicand-int,Fail ++spec@nv_shader_atomic_int64@execution@shared-atomicand-uint,Fail ++spec@nv_shader_atomic_int64@execution@shared-atomiccompswap-int,Fail ++spec@nv_shader_atomic_int64@execution@shared-atomicexchange-int,Fail ++spec@nv_shader_atomic_int64@execution@shared-atomicmax-int,Fail ++spec@nv_shader_atomic_int64@execution@shared-atomicmax-uint,Fail ++spec@nv_shader_atomic_int64@execution@shared-atomicmin-int,Fail ++spec@nv_shader_atomic_int64@execution@shared-atomicor-int,Fail ++spec@nv_shader_atomic_int64@execution@shared-atomicor-uint,Fail ++spec@nv_shader_atomic_int64@execution@shared-atomicxor-int,Fail ++spec@nv_shader_atomic_int64@execution@shared-atomicxor-uint,Fail +-- +2.17.1 + diff --git a/package/mesa3d/0091-zink-Only-expose-PIPE_CAP_SHADER_ATOMIC_INT64-if-we-.patch b/package/mesa3d/0091-zink-Only-expose-PIPE_CAP_SHADER_ATOMIC_INT64-if-we-.patch new file mode 100644 index 00000000..da6dc234 --- /dev/null +++ b/package/mesa3d/0091-zink-Only-expose-PIPE_CAP_SHADER_ATOMIC_INT64-if-we-.patch @@ -0,0 +1,37 @@ +From 5cb7019231f39c6866493e2081dd77df2166d5b1 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 3 Jan 2023 14:33:44 -0800 +Subject: [PATCH 091/168] zink: Only expose PIPE_CAP_SHADER_ATOMIC_INT64 if we + can do shared and ssbos. + +Fixes: 3ac0706aa83b ("zink: export PIPE_CAP_SHADER_ATOMIC_INT64") +Part-of: +--- + src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt | 14 -------------- + 1 file changed, 14 deletions(-) + +diff --git a/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt b/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt +index 76901167290..2414a7ba682 100644 +--- a/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt ++++ b/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt +@@ -894,17 +894,3 @@ 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 +- +-# https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20506 +-spec@nv_shader_atomic_int64@execution@shared-atomicadd-int,Fail +-spec@nv_shader_atomic_int64@execution@shared-atomicand-int,Fail +-spec@nv_shader_atomic_int64@execution@shared-atomicand-uint,Fail +-spec@nv_shader_atomic_int64@execution@shared-atomiccompswap-int,Fail +-spec@nv_shader_atomic_int64@execution@shared-atomicexchange-int,Fail +-spec@nv_shader_atomic_int64@execution@shared-atomicmax-int,Fail +-spec@nv_shader_atomic_int64@execution@shared-atomicmax-uint,Fail +-spec@nv_shader_atomic_int64@execution@shared-atomicmin-int,Fail +-spec@nv_shader_atomic_int64@execution@shared-atomicor-int,Fail +-spec@nv_shader_atomic_int64@execution@shared-atomicor-uint,Fail +-spec@nv_shader_atomic_int64@execution@shared-atomicxor-int,Fail +-spec@nv_shader_atomic_int64@execution@shared-atomicxor-uint,Fail +-- +2.17.1 + diff --git a/package/mesa3d/0092-ci-Fix-VK-driver-setup-for-HWCI_START_.patch b/package/mesa3d/0092-ci-Fix-VK-driver-setup-for-HWCI_START_.patch new file mode 100644 index 00000000..74b1271c --- /dev/null +++ b/package/mesa3d/0092-ci-Fix-VK-driver-setup-for-HWCI_START_.patch @@ -0,0 +1,48 @@ +From 5c174f7df9c00ca384f348acdca4052fff547b36 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jan 2023 14:53:48 -0800 +Subject: [PATCH 092/168] ci: Fix VK driver setup for HWCI_START_*. + +Review feedback requested a change that was incorrect, causing Xorg to +start to fail, but I forgot to retest the manual -full jobs that relied on +it. + +Fixes: 99a6f2a1864f ("ci: Set the path to the VK drivers during HWCI_START_XORG/WESTON.") +Part-of: +--- + .gitlab-ci/common/init-stage2.sh | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/.gitlab-ci/common/init-stage2.sh b/.gitlab-ci/common/init-stage2.sh +index a0718bf37fc..f80cc7f8beb 100755 +--- a/.gitlab-ci/common/init-stage2.sh ++++ b/.gitlab-ci/common/init-stage2.sh +@@ -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" +-- +2.17.1 + diff --git a/package/mesa3d/0093-docs-gallium-Explain-that-MSAA-transfer_map-must-be-.patch b/package/mesa3d/0093-docs-gallium-Explain-that-MSAA-transfer_map-must-be-.patch new file mode 100644 index 00000000..47807d8d --- /dev/null +++ b/package/mesa3d/0093-docs-gallium-Explain-that-MSAA-transfer_map-must-be-.patch @@ -0,0 +1,34 @@ +From 6b522d31a348c99c8e0c8d8504a3c2866f1e7935 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jan 2023 09:11:19 -0800 +Subject: [PATCH 093/168] docs/gallium: Explain that MSAA transfer_map must be + supported. + +It's called this way in various drivers, and is an established part of the +transfer_map interface. + +Reviewed-by: Mike Blumenkrantz +Part-of: +--- + docs/gallium/context.rst | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/docs/gallium/context.rst b/docs/gallium/context.rst +index 612bdacdd3b..c1d184f69b5 100644 +--- a/docs/gallium/context.rst ++++ b/docs/gallium/context.rst +@@ -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. +-- +2.17.1 + diff --git a/package/mesa3d/0094-u_transfer_helpre-Drop-interleave-handling-from-the-.patch b/package/mesa3d/0094-u_transfer_helpre-Drop-interleave-handling-from-the-.patch new file mode 100644 index 00000000..60dabad3 --- /dev/null +++ b/package/mesa3d/0094-u_transfer_helpre-Drop-interleave-handling-from-the-.patch @@ -0,0 +1,45 @@ +From 56537f60d376905173893cf06937bf91bf6a7282 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jan 2023 11:29:23 -0800 +Subject: [PATCH 094/168] u_transfer_helpre: Drop !interleave handling from the + interleave code. + +It's only called when need_interleave_path(), and they're static functions +in this file since !17959. + +Reviewed-by: Mike Blumenkrantz +Part-of: +--- + src/gallium/auxiliary/util/u_transfer_helper.c | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c +index 73e4f1b7742..dad0a4c44b5 100644 +--- a/src/gallium/auxiliary/util/u_transfer_helper.c ++++ b/src/gallium/auxiliary/util/u_transfer_helper.c +@@ -585,9 +585,6 @@ u_transfer_helper_deinterleave_transfer_map(struct pipe_context *pctx, + 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)); +@@ -680,12 +677,6 @@ 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; + +-- +2.17.1 + diff --git a/package/mesa3d/0095-u_transfer_helper-Use-common-code-for-interleaved-un.patch b/package/mesa3d/0095-u_transfer_helper-Use-common-code-for-interleaved-un.patch new file mode 100644 index 00000000..d963290b --- /dev/null +++ b/package/mesa3d/0095-u_transfer_helper-Use-common-code-for-interleaved-un.patch @@ -0,0 +1,78 @@ +From 017a587c585671312dd3c75797c8471a7efde490 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jan 2023 11:52:19 -0800 +Subject: [PATCH 095/168] u_transfer_helper: Use common code for interleaved + unmap. + +The function was static and only used from this caller, and the only +difference was that the interleaved case didn't handle trans->ss (which +will always be unset for an interleaved mapping since interleaving splits +the underlying map of the MSAA resource into trans->trans and +trans->trans2). + +Reviewed-by: Mike Blumenkrantz +Part-of: +--- + .../auxiliary/util/u_transfer_helper.c | 36 ++----------------- + 1 file changed, 2 insertions(+), 34 deletions(-) + +diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c +index dad0a4c44b5..dc011a09dbb 100644 +--- a/src/gallium/auxiliary/util/u_transfer_helper.c ++++ b/src/gallium/auxiliary/util/u_transfer_helper.c +@@ -495,22 +495,14 @@ 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; ++ bool interleave = need_interleave_path(helper, ptrans->resource->format); + +- if (need_interleave_path(helper, ptrans->resource->format)) { +- u_transfer_helper_deinterleave_transfer_unmap(pctx, ptrans); +- return; +- } +- +- if (handle_transfer(ptrans->resource)) { ++ if (handle_transfer(ptrans->resource) || interleave) { + struct u_transfer *trans = u_transfer(ptrans); + + if (!(ptrans->usage & PIPE_MAP_FLUSH_EXPLICIT)) { +@@ -671,27 +663,3 @@ fail: + 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; +- +- 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); +-} +-- +2.17.1 + diff --git a/package/mesa3d/0096-u_transfer_helper-Merge-in-place-and-split-z-s-inter.patch b/package/mesa3d/0096-u_transfer_helper-Merge-in-place-and-split-z-s-inter.patch new file mode 100644 index 00000000..94cfa123 --- /dev/null +++ b/package/mesa3d/0096-u_transfer_helper-Merge-in-place-and-split-z-s-inter.patch @@ -0,0 +1,286 @@ +From 3273f8ba23b5e96e7f1bb7ce3577d0b1b008d1ce Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jan 2023 12:17:27 -0800 +Subject: [PATCH 096/168] u_transfer_helper: Merge in-place and split z/s + interleaved map handling. + +The paths were mostly the same, except that in-place was missing the +appropriate layering for MSAA helper re-mapping. We can instead share +more code, making the differences between the interleave packing clear, +and have the MSAA resolve blit happen once before we do the split +mappings. + +Reviewed-by: Mike Blumenkrantz +Part-of: +--- + .../auxiliary/util/u_transfer_helper.c | 205 ++++++------------ + 1 file changed, 68 insertions(+), 137 deletions(-) + +diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c +index dc011a09dbb..82ffa642ef3 100644 +--- a/src/gallium/auxiliary/util/u_transfer_helper.c ++++ b/src/gallium/auxiliary/util/u_transfer_helper.c +@@ -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"); + } +@@ -500,9 +540,8 @@ u_transfer_helper_transfer_unmap(struct pipe_context *pctx, + struct pipe_transfer *ptrans) + { + struct u_transfer_helper *helper = pctx->screen->transfer_helper; +- bool interleave = need_interleave_path(helper, ptrans->resource->format); + +- if (handle_transfer(ptrans->resource) || interleave) { ++ if (handle_transfer(ptrans->resource)) { + struct u_transfer *trans = u_transfer(ptrans); + + if (!(ptrans->usage & PIPE_MAP_FLUSH_EXPLICIT)) { +@@ -555,111 +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; +- +- 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; +-} +-- +2.17.1 + diff --git a/package/mesa3d/0097-zink-Have-u_transfer_helper-resolve-MSAA-surfaces-wh.patch b/package/mesa3d/0097-zink-Have-u_transfer_helper-resolve-MSAA-surfaces-wh.patch new file mode 100644 index 00000000..8d86b7ea --- /dev/null +++ b/package/mesa3d/0097-zink-Have-u_transfer_helper-resolve-MSAA-surfaces-wh.patch @@ -0,0 +1,62 @@ +From ad449dd3028f9bb54c165112e221647bb052932d Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jan 2023 09:08:12 -0800 +Subject: [PATCH 097/168] zink: Have u_transfer_helper resolve MSAA surfaces + when mapping. + +This fixes all the dEQP winsys multisampling failures (like +dEQP-GLES3.functional.multisample.default_framebuffer.depth) I've found so +far. + +Part-of: +--- + .../drivers/zink/ci/zink-anv-tgl-fails.txt | 20 ------------------- + src/gallium/drivers/zink/zink_resource.c | 1 + + 2 files changed, 1 insertion(+), 20 deletions(-) + +diff --git a/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt b/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt +index 2414a7ba682..4543d940413 100644 +--- a/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt ++++ b/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt +@@ -96,26 +96,6 @@ dEQP-EGL.functional.buffer_age.no_preserve.resize_before_swap.odd_render_render_ + + dEQP-EGL.functional.query_context.get_current_context.rgba8888_window,Crash + +-# https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20508 +-multisample-dEQP-GLES3.functional.multisample.default_framebuffer.depth,Fail +-multisample-dEQP-GLES3.functional.multisample.default_framebuffer.num_samples_line,Fail +-multisample-dEQP-GLES3.functional.multisample.default_framebuffer.num_samples_polygon,Fail +-multisample-dEQP-GLES3.functional.occlusion_query.depth_clear_stencil_write,Fail +-multisample-dEQP-GLES3.functional.occlusion_query.depth_write_depth_clear_stencil_write_stencil_clear,Fail +-multisample-dEQP-GLES3.functional.occlusion_query.depth_write_depth_clear,Fail +-multisample-dEQP-GLES3.functional.occlusion_query.depth_write_stencil_clear,Fail +-multisample-dEQP-GLES3.functional.occlusion_query.depth_write_stencil_write,Fail +-multisample-dEQP-GLES3.functional.occlusion_query.scissor_depth_clear_stencil_write,Fail +-multisample-dEQP-GLES3.functional.occlusion_query.scissor_depth_write_stencil_clear,Fail +-multisample-dEQP-GLES3.functional.occlusion_query.stencil_write,Fail +-multisample-dEQP-GLES31.functional.sample_shading.min_sample_shading.default_framebuffer_color,Fail +-multisample-dEQP-GLES31.functional.sample_shading.min_sample_shading.default_framebuffer_discard,Fail +-multisample-dEQP-GLES31.functional.shaders.multisample_interpolation.sample_qualifier.default_framebuffer,Fail +-multisample-dEQP-GLES31.functional.shaders.sample_variables.sample_id.default_framebuffer,Fail +-multisample-dEQP-GLES31.functional.shaders.sample_variables.sample_mask.discard_half_per_pixel.default_framebuffer,Fail +-multisample-dEQP-GLES31.functional.shaders.sample_variables.sample_mask.discard_half_per_sample.default_framebuffer,Fail +-multisample-dEQP-GLES31.functional.shaders.sample_variables.sample_mask.discard_half_per_two_samples.default_framebuffer,Fail +- + # 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 +diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c +index df5123c037c..0b43f89d44e 100644 +--- a/src/gallium/drivers/zink/zink_resource.c ++++ b/src/gallium/drivers/zink/zink_resource.c +@@ -2348,6 +2348,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) { +-- +2.17.1 + diff --git a/package/mesa3d/0098-zink-Add-an-assert-for-not-seeing-any-more-MSAA-imag.patch b/package/mesa3d/0098-zink-Add-an-assert-for-not-seeing-any-more-MSAA-imag.patch new file mode 100644 index 00000000..4e7a9244 --- /dev/null +++ b/package/mesa3d/0098-zink-Add-an-assert-for-not-seeing-any-more-MSAA-imag.patch @@ -0,0 +1,39 @@ +From e6678539bd9306db43be7dd4b9afdfcfbd47523f Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jan 2023 09:13:39 -0800 +Subject: [PATCH 098/168] zink: Add an assert for not seeing any more MSAA + image-to-buffer copies. + +Now that transfer_map gets MSAA handled by the helper, we shouldn't have +to worry about this any more. + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 07194fd2965..0e959e32714 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -4356,7 +4356,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 +4365,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, ®ion); + else +-- +2.17.1 + diff --git a/package/mesa3d/0099-zink-fix-disappearing-smooth-lines-after-workaround.patch b/package/mesa3d/0099-zink-fix-disappearing-smooth-lines-after-workaround.patch new file mode 100644 index 00000000..18566074 --- /dev/null +++ b/package/mesa3d/0099-zink-fix-disappearing-smooth-lines-after-workaround.patch @@ -0,0 +1,33 @@ +From e35947edc37466aa5990e0354bcf8e781c1cf2d2 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jan 2023 10:05:09 +0000 +Subject: [PATCH 099/168] zink: fix disappearing smooth lines after workaround + +The passthrough geometery shader was using points for smooth lines. +This meant the shader would always statically get 1 vertex and never emit a line. + +Fixes: 80285db9efe ("zink: lower smooth-lines if not supported") +Reviewed-by: Erik Faye-Lund +Part-of: +--- + src/gallium/drivers/zink/zink_program.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 60865ca5462..8367a7662da 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -1903,8 +1903,8 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx) + nir_shader *nir = nir_create_passthrough_gs( + &screen->nir_options, + ctx->gfx_stages[prev_vertex_stage]->nir, +- lower_line_stipple ? SHADER_PRIM_LINE_STRIP : SHADER_PRIM_POINTS, +- lower_line_stipple ? 2 : 1); ++ (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; +-- +2.17.1 + diff --git a/package/mesa3d/0100-zink-split-out-swapchain-render-update-fixups-into-s.patch b/package/mesa3d/0100-zink-split-out-swapchain-render-update-fixups-into-s.patch new file mode 100644 index 00000000..5af7fbc7 --- /dev/null +++ b/package/mesa3d/0100-zink-split-out-swapchain-render-update-fixups-into-s.patch @@ -0,0 +1,107 @@ +From 8f050379c262cfd210bf9462f6341aaaebdfef01 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 6 Jan 2023 14:03:32 -0500 +Subject: [PATCH 100/168] zink: split out swapchain render update fixups into + separate function + +this needs to be more granular for corner cases + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 4 ++- + src/gallium/drivers/zink/zink_render_pass.c | 34 +++++++++++++-------- + src/gallium/drivers/zink/zink_render_pass.h | 4 ++- + 3 files changed, 27 insertions(+), 15 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 0e959e32714..b64dafdfc39 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -2301,7 +2301,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; +diff --git a/src/gallium/drivers/zink/zink_render_pass.c b/src/gallium/drivers/zink/zink_render_pass.c +index ac134422c5d..8678f227741 100644 +--- a/src/gallium/drivers/zink/zink_render_pass.c ++++ b/src/gallium/drivers/zink/zink_render_pass.c +@@ -589,7 +589,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 +816,23 @@ 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; ++ 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 +846,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; + } +diff --git a/src/gallium/drivers/zink/zink_render_pass.h b/src/gallium/drivers/zink/zink_render_pass.h +index d3d74e20bfb..3d5bd417ab1 100644 +--- a/src/gallium/drivers/zink/zink_render_pass.h ++++ b/src/gallium/drivers/zink/zink_render_pass.h +@@ -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); +-- +2.17.1 + diff --git a/package/mesa3d/0101-zink-catch-a-potential-corner-case-with-dynamic-rend.patch b/package/mesa3d/0101-zink-catch-a-potential-corner-case-with-dynamic-rend.patch new file mode 100644 index 00000000..2ac3c564 --- /dev/null +++ b/package/mesa3d/0101-zink-catch-a-potential-corner-case-with-dynamic-rend.patch @@ -0,0 +1,32 @@ +From 2b12e603928bedd4020d42ae692190cd0b4349b5 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 6 Jan 2023 14:04:34 -0500 +Subject: [PATCH 101/168] zink: catch a potential corner case with dynamic + render and swapchain updates + +zink_prep_fb_attachment() calls acquire internally, which means it's theoretically +possible that fixups are required very late in this function + +never seen it happen, but who knows + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index b64dafdfc39..d2a8c0e8f66 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -2452,6 +2452,8 @@ begin_rendering(struct zink_context *ctx) + return 0; + ctx->dynamic_fb.attachments[i].imageView = iv; + } ++ if (has_swapchain) ++ zink_render_fixup_swapchain(ctx); + 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); +-- +2.17.1 + diff --git a/package/mesa3d/0102-zink-re-clamp-dynamic-render-area-when-doing-swapcha.patch b/package/mesa3d/0102-zink-re-clamp-dynamic-render-area-when-doing-swapcha.patch new file mode 100644 index 00000000..62a89844 --- /dev/null +++ b/package/mesa3d/0102-zink-re-clamp-dynamic-render-area-when-doing-swapcha.patch @@ -0,0 +1,32 @@ +From da7688db1d9ceecdefd2588a78c2eb3290ea61a0 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 6 Jan 2023 14:40:11 -0500 +Subject: [PATCH 102/168] zink: re-clamp dynamic render area when doing + swapchain fixups + +this may catch another corner case if a late fixup changes fb size + +fixes (lavapipe): +dEQP-EGL.functional.swap_buffers_with_damage.resize_before_swap.clear_render + +Part-of: +--- + src/gallium/drivers/zink/zink_render_pass.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/gallium/drivers/zink/zink_render_pass.c b/src/gallium/drivers/zink/zink_render_pass.c +index 8678f227741..45100b828d6 100644 +--- a/src/gallium/drivers/zink/zink_render_pass.c ++++ b/src/gallium/drivers/zink/zink_render_pass.c +@@ -823,6 +823,8 @@ zink_render_fixup_swapchain(struct zink_context *ctx) + 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; +-- +2.17.1 + diff --git a/package/mesa3d/0103-zink-add-a-bunch-of-asserts-for-starting-dynamic-ren.patch b/package/mesa3d/0103-zink-add-a-bunch-of-asserts-for-starting-dynamic-ren.patch new file mode 100644 index 00000000..cae13f65 --- /dev/null +++ b/package/mesa3d/0103-zink-add-a-bunch-of-asserts-for-starting-dynamic-ren.patch @@ -0,0 +1,46 @@ +From f70e90d69e944b0b0a733c5d41eba2c4737cfedd Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 6 Jan 2023 15:51:48 -0500 +Subject: [PATCH 103/168] zink: add a bunch of asserts for starting dynamic + render + +try to avoid any race condition bugs triggering later when they're +harder to catch + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index d2a8c0e8f66..2d4fda4e06c 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -2452,8 +2452,14 @@ begin_rendering(struct zink_context *ctx) + return 0; + ctx->dynamic_fb.attachments[i].imageView = iv; + } +- if (has_swapchain) ++ 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); +@@ -2462,6 +2468,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; + +-- +2.17.1 + diff --git a/package/mesa3d/0104-zink-delete-dead-code.patch b/package/mesa3d/0104-zink-delete-dead-code.patch new file mode 100644 index 00000000..c8764aca --- /dev/null +++ b/package/mesa3d/0104-zink-delete-dead-code.patch @@ -0,0 +1,51 @@ +From 18f2e9412a6a1b64a14b5f9581e90b5ccbb37e09 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jan 2023 14:47:23 -0500 +Subject: [PATCH 104/168] zink: delete dead code + +update_gfx_program_optimal() is the real version of this + +Part-of: +--- + src/gallium/drivers/zink/zink_program.c | 25 ------------------------- + 1 file changed, 25 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 8367a7662da..1eded3d2a69 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -371,31 +371,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) + { +-- +2.17.1 + diff --git a/package/mesa3d/0105-zink-only-flag-modules_changed-in-optimal-path-if-a-.patch b/package/mesa3d/0105-zink-only-flag-modules_changed-in-optimal-path-if-a-.patch new file mode 100644 index 00000000..d2308204 --- /dev/null +++ b/package/mesa3d/0105-zink-only-flag-modules_changed-in-optimal-path-if-a-.patch @@ -0,0 +1,64 @@ +From 0fca1b3f700954deffdd6bde26ac1c73ad5d321f Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 6 Jan 2023 09:58:29 -0500 +Subject: [PATCH 105/168] zink: only flag modules_changed in optimal path if a + change has occurred + +this should save some cycles when a recalc is a no-op + +Part-of: +--- + src/gallium/drivers/zink/zink_program.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 1eded3d2a69..d030517d7b1 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -599,7 +599,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); +@@ -608,7 +608,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 +@@ -616,17 +619,17 @@ 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; ++ bool changed = update_gfx_shader_module_optimal(ctx, prog, MESA_SHADER_FRAGMENT); ++ ctx->gfx_pipeline_state.modules_changed |= changed; + } + 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; + } +-- +2.17.1 + diff --git a/package/mesa3d/0106-zink-put-line-emulation-stuff-behind-optimal_keys-ch.patch b/package/mesa3d/0106-zink-put-line-emulation-stuff-behind-optimal_keys-ch.patch new file mode 100644 index 00000000..36e72b31 --- /dev/null +++ b/package/mesa3d/0106-zink-put-line-emulation-stuff-behind-optimal_keys-ch.patch @@ -0,0 +1,105 @@ +From cfbf430a7f5148a45f9daa3953a8ca72ca36c9b7 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 16:20:38 -0500 +Subject: [PATCH 106/168] zink: put line emulation stuff behind optimal_keys + check in draw + +these parts of the shader key can't be accessed in optimal_keys mode + +Part-of: +--- + src/gallium/drivers/zink/zink_draw.cpp | 65 ++++++++++++++------------ + 1 file changed, 34 insertions(+), 31 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp +index aea345d379b..d8c24e785c4 100644 +--- a/src/gallium/drivers/zink/zink_draw.cpp ++++ b/src/gallium/drivers/zink/zink_draw.cpp +@@ -548,8 +548,8 @@ zink_draw(struct pipe_context *pctx, + } + ctx->gfx_pipeline_state.gfx_prim_mode = mode; + +- if (lines_changed || rast_state_changed || +- ctx->gfx_pipeline_state.modules_changed) ++ if (!screen->optimal_keys && ++ (lines_changed || rast_state_changed || ctx->gfx_pipeline_state.modules_changed)) + zink_set_primitive_emulation_keys(ctx); + + if (index_size) { +@@ -803,41 +803,44 @@ zink_draw(struct pipe_context *pctx, + offsetof(struct zink_gfx_push_constant, default_inner_level), sizeof(float) * 6, + &ctx->tess_levels[0]); + } +- 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); ++ 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_smooth == +- 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); + +- 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; ++ 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_width), +- sizeof(uint32_t), &line_width); ++ 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); ++ } + } + } + +-- +2.17.1 + diff --git a/package/mesa3d/0107-zink-simplify-some-depth-texturing-spv.patch b/package/mesa3d/0107-zink-simplify-some-depth-texturing-spv.patch new file mode 100644 index 00000000..eac40abf --- /dev/null +++ b/package/mesa3d/0107-zink-simplify-some-depth-texturing-spv.patch @@ -0,0 +1,60 @@ +From 699949ac3e643364a59bf7607227201e43cad160 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jan 2023 15:24:59 -0500 +Subject: [PATCH 107/168] zink: simplify some depth texturing spv + +the special-casing here is no longer necessary since multi-component +depth sample ops have already been rewritten by this point + +Part-of: +--- + .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 30 ++++++++----------- + 1 file changed, 13 insertions(+), 17 deletions(-) + +diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +index f385830f5ad..a3e68b66c6e 100644 +--- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c ++++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +@@ -3846,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; +-- +2.17.1 + diff --git a/package/mesa3d/0108-zink-fix-some-weird-indentation-in-zink_set_sampler_.patch b/package/mesa3d/0108-zink-fix-some-weird-indentation-in-zink_set_sampler_.patch new file mode 100644 index 00000000..54b3faef --- /dev/null +++ b/package/mesa3d/0108-zink-fix-some-weird-indentation-in-zink_set_sampler_.patch @@ -0,0 +1,67 @@ +From d2c419f9a1dd6898c580c8b7a52be5e5e1da342b Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 12:03:40 -0500 +Subject: [PATCH 108/168] zink: fix some weird indentation in + zink_set_sampler_views + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 42 ++++++++++++------------- + 1 file changed, 21 insertions(+), 21 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 2d4fda4e06c..1e9e17b3879 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -1860,27 +1860,27 @@ 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; + } + res->sampler_binds[shader_type] |= BITFIELD_BIT(start_slot + i); + res->obj->unordered_read = false; +-- +2.17.1 + diff --git a/package/mesa3d/0109-zink-unify-some-shadow-tex-code-in-match_tex_dests_i.patch b/package/mesa3d/0109-zink-unify-some-shadow-tex-code-in-match_tex_dests_i.patch new file mode 100644 index 00000000..73ce7764 --- /dev/null +++ b/package/mesa3d/0109-zink-unify-some-shadow-tex-code-in-match_tex_dests_i.patch @@ -0,0 +1,50 @@ +From 6cc25eac406ab331acd65903ca58df5e2957d0ef Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 13:23:13 -0500 +Subject: [PATCH 109/168] zink: unify some shadow tex code in + match_tex_dests_instr() + +no functional changes + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 7366ae80a87..863fad6d8de 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -3680,14 +3680,14 @@ match_tex_dests_instr(nir_builder *b, nir_instr *in, void *data) + if (bit_size == dest_size && !rewrite_depth) + return false; + nir_ssa_def *dest = &tex->dest.ssa; ++ if (rewrite_depth) { ++ assert(!tex->is_new_style_shadow); ++ tex->dest.ssa.num_components = 1; ++ tex->is_new_style_shadow = true; ++ } + if (bit_size != dest_size) { + tex->dest.ssa.bit_size = bit_size; + tex->dest_type = nir_get_nir_type_for_glsl_base_type(ret_type); +- if (rewrite_depth) { +- assert(!tex->is_new_style_shadow); +- tex->dest.ssa.num_components = 1; +- tex->is_new_style_shadow = true; +- } + + if (is_int) { + if (glsl_unsigned_base_type_of(ret_type) == ret_type) +@@ -3703,9 +3703,6 @@ match_tex_dests_instr(nir_builder *b, nir_instr *in, void *data) + } + nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, dest, dest->parent_instr); + } else if (rewrite_depth) { +- assert(!tex->is_new_style_shadow); +- tex->dest.ssa.num_components = 1; +- tex->is_new_style_shadow = true; + nir_ssa_def *vec[4] = {dest, dest, dest, dest}; + nir_ssa_def *splat = nir_vec(b, vec, num_components); + nir_ssa_def_rewrite_uses_after(dest, splat, splat->parent_instr); +-- +2.17.1 + diff --git a/package/mesa3d/0110-zink-use-optimal-key-for-pipeline-library-hash.patch b/package/mesa3d/0110-zink-use-optimal-key-for-pipeline-library-hash.patch new file mode 100644 index 00000000..e4aa71f4 --- /dev/null +++ b/package/mesa3d/0110-zink-use-optimal-key-for-pipeline-library-hash.patch @@ -0,0 +1,29 @@ +From f1dac650190095f516086f10ee04a5c4bcf22953 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 15:44:37 -0500 +Subject: [PATCH 110/168] zink: use optimal key for pipeline library hash + +this doesn't really change anything other than making the set collide less + +Part-of: +--- + src/gallium/drivers/zink/zink_program.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index d030517d7b1..f10546f48f8 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -429,7 +429,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; + } + + +-- +2.17.1 + diff --git a/package/mesa3d/0111-zink-add-a-fs-base-key-fix-optimal-fs-key-packing.patch b/package/mesa3d/0111-zink-add-a-fs-base-key-fix-optimal-fs-key-packing.patch new file mode 100644 index 00000000..151f729d --- /dev/null +++ b/package/mesa3d/0111-zink-add-a-fs-base-key-fix-optimal-fs-key-packing.patch @@ -0,0 +1,258 @@ +From e4389b6f2121fa4179627bb7a31641818e652341 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jan 2023 14:54:25 -0500 +Subject: [PATCH 111/168] zink: add a fs base key, fix optimal fs key packing + +the optimal fs key gets at most 16 bits, so it's crucial to only use +the ones that are needed in order to conserve bits for things needed +by all drivers + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 14 ++++---- + src/gallium/drivers/zink/zink_context.c | 4 +-- + src/gallium/drivers/zink/zink_program.c | 4 +-- + src/gallium/drivers/zink/zink_program.h | 33 ++++++++++++++----- + .../drivers/zink/zink_program_state.hpp | 2 +- + src/gallium/drivers/zink/zink_shader_keys.h | 22 ++++++++++--- + src/gallium/drivers/zink/zink_state.c | 6 ++-- + 7 files changed, 57 insertions(+), 28 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 863fad6d8de..36cb677a355 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2877,7 +2877,7 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + need_optimize = true; + } + +- if (!zink_fs_key(key)->samples && ++ if (!zink_fs_key_base(key)->samples && + nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)) { + /* VK will always use gl_SampleMask[] values even if sample count is 0, + * so we need to skip this write here to mimic GL's behavior of ignoring it +@@ -2890,14 +2890,14 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_shader_temp, NULL); + need_optimize = true; + } +- if (zink_fs_key(key)->force_dual_color_blend && nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DATA1)) { ++ if (zink_fs_key_base(key)->force_dual_color_blend && nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DATA1)) { + NIR_PASS_V(nir, lower_dual_blend); + } +- if (zink_fs_key(key)->coord_replace_bits) +- NIR_PASS_V(nir, nir_lower_texcoord_replace, zink_fs_key(key)->coord_replace_bits, false, false); +- if (zink_fs_key(key)->point_coord_yinvert) ++ if (zink_fs_key_base(key)->coord_replace_bits) ++ NIR_PASS_V(nir, nir_lower_texcoord_replace, zink_fs_key_base(key)->coord_replace_bits, false, false); ++ if (zink_fs_key_base(key)->point_coord_yinvert) + NIR_PASS_V(nir, invert_point_coord); +- if (zink_fs_key(key)->force_persample_interp || zink_fs_key(key)->fbfetch_ms) { ++ if (zink_fs_key_base(key)->force_persample_interp || zink_fs_key_base(key)->fbfetch_ms) { + nir_foreach_shader_in_variable(var, nir) + var->data.sample = true; + nir->info.fs.uses_sample_qualifier = true; +@@ -2905,7 +2905,7 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + } + if (nir->info.fs.uses_fbfetch_output) { + nir_variable *fbfetch = NULL; +- NIR_PASS_V(nir, lower_fbfetch, &fbfetch, zink_fs_key(key)->fbfetch_ms); ++ NIR_PASS_V(nir, lower_fbfetch, &fbfetch, zink_fs_key_base(key)->fbfetch_ms); + /* old variable must be deleted to avoid spirv errors */ + fbfetch->data.mode = nir_var_shader_temp; + nir_fixup_deref_modes(nir); +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 1e9e17b3879..8a7b20ec6d8 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -2243,8 +2243,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) { +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index f10546f48f8..5f9a0e6b6f4 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -1450,9 +1450,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; + } + } + +diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h +index 322f10155b6..0e76b8b2590 100644 +--- a/src/gallium/drivers/zink/zink_program.h ++++ b/src/gallium/drivers/zink/zink_program.h +@@ -240,21 +240,36 @@ 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 * +-zink_get_fs_key(struct zink_context *ctx) ++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; ++ &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) ++{ ++ 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 * +@@ -330,13 +345,13 @@ 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; + } + } + +diff --git a/src/gallium/drivers/zink/zink_program_state.hpp b/src/gallium/drivers/zink/zink_program_state.hpp +index 4711047b04f..3111a7a277a 100644 +--- a/src/gallium/drivers/zink/zink_program_state.hpp ++++ b/src/gallium/drivers/zink/zink_program_state.hpp +@@ -253,7 +253,7 @@ zink_get_gfx_pipeline(struct zink_context *ctx, + !ctx->gfx_pipeline_state.render_pass && + /* 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 */ +diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h +index 6c6a18aadda..8e9565d8a06 100644 +--- a/src/gallium/drivers/zink/zink_shader_keys.h ++++ b/src/gallium/drivers/zink/zink_shader_keys.h +@@ -66,16 +66,22 @@ struct zink_gs_key { + unsigned size; + }; + +-struct zink_fs_key { ++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; ++ 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; +- uint8_t pad : 1; +- uint8_t coord_replace_bits; ++ uint16_t pad2 : 14; + }; + + struct zink_tcs_key { +@@ -100,6 +106,7 @@ struct zink_shader_key { + struct zink_tcs_key tcs; + struct zink_gs_key gs; + struct zink_fs_key fs; ++ struct zink_fs_key_base fs_base; + } key; + struct zink_shader_key_base base; + unsigned inline_uniforms:1; +@@ -110,7 +117,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; +@@ -133,6 +140,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) + { +diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c +index e5b82bda278..bf4ba1e9f4c 100644 +--- a/src/gallium/drivers/zink/zink_state.c ++++ b/src/gallium/drivers/zink/zink_state.c +@@ -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; + } + } +@@ -683,7 +683,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; +-- +2.17.1 + diff --git a/package/mesa3d/0112-zink-add-a-condition-to-needs_write_s.patch b/package/mesa3d/0112-zink-add-a-condition-to-needs_write_s.patch new file mode 100644 index 00000000..09b68f2f --- /dev/null +++ b/package/mesa3d/0112-zink-add-a-condition-to-needs_write_s.patch @@ -0,0 +1,29 @@ +From b81170ba7d2236aa28a7af86cae9bdc39fda268e Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Sat, 10 Dec 2022 11:12:58 +0000 +Subject: [PATCH 112/168] zink: add a condition to needs_write_s + +Previously missing check on the stencil write, condition added to needs_write_s using util_writes_stencil + +Part-of: +--- + src/gallium/drivers/zink/zink_render_pass.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_render_pass.c b/src/gallium/drivers/zink/zink_render_pass.c +index 45100b828d6..91629fa4e2d 100644 +--- a/src/gallium/drivers/zink/zink_render_pass.c ++++ b/src/gallium/drivers/zink/zink_render_pass.c +@@ -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; +-- +2.17.1 + diff --git a/package/mesa3d/0113-zink-fix-the-stencil-write.patch b/package/mesa3d/0113-zink-fix-the-stencil-write.patch new file mode 100644 index 00000000..2a430cdf --- /dev/null +++ b/package/mesa3d/0113-zink-fix-the-stencil-write.patch @@ -0,0 +1,38 @@ +From c463a132f88a0999c354e90e86a6a4646be6de99 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 3 Jan 2023 10:52:10 +0800 +Subject: [PATCH 113/168] zink: fix the stencil write + +Stencil writing also needs to be considered when setting the flag renderpass + +Part-of: +--- + src/gallium/drivers/zink/zink_state.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c +index bf4ba1e9f4c..b4512ea7cef 100644 +--- a/src/gallium/drivers/zink/zink_state.c ++++ b/src/gallium/drivers/zink/zink_state.c +@@ -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; + } +-- +2.17.1 + diff --git a/package/mesa3d/0114-gallium-draw-use-nir_shader_instructions_pass-for-ni.patch b/package/mesa3d/0114-gallium-draw-use-nir_shader_instructions_pass-for-ni.patch new file mode 100644 index 00000000..3f434f80 --- /dev/null +++ b/package/mesa3d/0114-gallium-draw-use-nir_shader_instructions_pass-for-ni.patch @@ -0,0 +1,142 @@ +From e733c6f9ca59a068884713fbdad3a138db82f15f Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 24 Nov 2022 15:47:38 +0100 +Subject: [PATCH 114/168] gallium/draw: use nir_shader_instructions_pass for + nir_lower_aaline_fs + +This just cuts away some needless boilerplate code. + +Reviewed-by: Emma Anholt +Part-of: +--- + src/gallium/auxiliary/nir/nir_draw_helpers.c | 98 ++++++++------------ + 1 file changed, 38 insertions(+), 60 deletions(-) + +diff --git a/src/gallium/auxiliary/nir/nir_draw_helpers.c b/src/gallium/auxiliary/nir/nir_draw_helpers.c +index 4588b56f461..1e70ef72315 100644 +--- a/src/gallium/auxiliary/nir/nir_draw_helpers.c ++++ b/src/gallium/auxiliary/nir/nir_draw_helpers.c +@@ -147,70 +147,51 @@ nir_lower_pstipple_fs(struct nir_shader *shader, + } + + typedef struct { +- nir_builder b; +- nir_shader *shader; + nir_variable *line_width_input; + } 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; +- +- nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); +- if (intrin->intrinsic != nir_intrinsic_store_deref) +- continue; +- +- 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_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))))); +- +- tmp = nir_fmul(b, nir_channel(b, tmp, 0), +- nir_fmin(b, nir_channel(b, tmp, 1), len)); +- tmp = nir_fmul(b, nir_channel(b, out_input, 3), tmp); +- +- 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)); +- } +- +-} +- +-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); +- } ++ lower_aaline *state = data; ++ ++ if (instr->type != nir_instr_type_intrinsic) ++ return false; ++ ++ nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); ++ if (intrin->intrinsic != nir_intrinsic_store_deref) ++ return false; ++ ++ 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; ++ ++ 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))))); ++ ++ tmp = nir_fmul(b, nir_channel(b, tmp, 0), ++ nir_fmin(b, nir_channel(b, tmp, 1), len)); ++ tmp = nir_fmul(b, nir_channel(b, out_input, 3), tmp); ++ ++ 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) + { +- lower_aaline state = { +- .shader = shader, +- }; ++ lower_aaline state; + if (shader->info.stage != MESA_SHADER_FRAGMENT) + return; + +@@ -235,11 +216,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 { +-- +2.17.1 + diff --git a/package/mesa3d/0115-gallium-draw-assert-shader-stage.patch b/package/mesa3d/0115-gallium-draw-assert-shader-stage.patch new file mode 100644 index 00000000..365853c4 --- /dev/null +++ b/package/mesa3d/0115-gallium-draw-assert-shader-stage.patch @@ -0,0 +1,31 @@ +From fdcfa55e2ab338da81a1173b88cf7619cb6cf48a Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 24 Nov 2022 15:52:18 +0100 +Subject: [PATCH 115/168] gallium/draw: assert shader-stage + +Nobody calls this for the wrong shader-stage. Let's turn that check into +an assert instead. + +Reviewed-by: Emma Anholt +Part-of: +--- + src/gallium/auxiliary/nir/nir_draw_helpers.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/gallium/auxiliary/nir/nir_draw_helpers.c b/src/gallium/auxiliary/nir/nir_draw_helpers.c +index 1e70ef72315..a3f4de32d9c 100644 +--- a/src/gallium/auxiliary/nir/nir_draw_helpers.c ++++ b/src/gallium/auxiliary/nir/nir_draw_helpers.c +@@ -192,8 +192,7 @@ void + nir_lower_aaline_fs(struct nir_shader *shader, int *varying) + { + lower_aaline state; +- 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) { +-- +2.17.1 + diff --git a/package/mesa3d/0116-gallium-draw-support-lowering-stipple-smooth.patch b/package/mesa3d/0116-gallium-draw-support-lowering-stipple-smooth.patch new file mode 100644 index 00000000..672bd4c7 --- /dev/null +++ b/package/mesa3d/0116-gallium-draw-support-lowering-stipple-smooth.patch @@ -0,0 +1,143 @@ +From 1bfb157b75ce37743e24db7b29759101d503107c Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 2 Dec 2022 13:33:48 +0100 +Subject: [PATCH 116/168] gallium/draw: support lowering stipple + smooth + +When computing line smoothing, we can also do something similar to +compute the line stippling. This can be useful for some drivers, who +can't easily split the lines before rasterizing them. + +This does lead to slightly inaccurate stippling, because the +line-smoothing extends the line-length by a small amount. That leads to +the line-stippling pattern being over-stretched over the line-segment by +a fraction of a pixel in lenght. For short lines, this can be quite a +lot of error. + +Reviewed-by: Soroush Kashani +Part-of: +--- + src/gallium/auxiliary/draw/draw_pipe_aaline.c | 2 +- + src/gallium/auxiliary/nir/nir_draw_helpers.c | 48 +++++++++++++++++-- + src/gallium/auxiliary/nir/nir_draw_helpers.h | 4 +- + src/gallium/drivers/zink/zink_compiler.c | 2 +- + 4 files changed, 50 insertions(+), 6 deletions(-) + +diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c +index 464f9c3dd96..d2bc475b243 100644 +--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c ++++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c +@@ -361,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; +diff --git a/src/gallium/auxiliary/nir/nir_draw_helpers.c b/src/gallium/auxiliary/nir/nir_draw_helpers.c +index a3f4de32d9c..0ebc1ef0b69 100644 +--- a/src/gallium/auxiliary/nir/nir_draw_helpers.c ++++ b/src/gallium/auxiliary/nir/nir_draw_helpers.c +@@ -148,6 +148,8 @@ nir_lower_pstipple_fs(struct nir_shader *shader, + + typedef struct { + nir_variable *line_width_input; ++ nir_variable *stipple_counter; ++ nir_variable *stipple_pattern; + } lower_aaline; + + static bool +@@ -176,8 +178,43 @@ lower_aaline_instr(nir_builder *b, nir_instr *instr, void *data) + 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 *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), len)); ++ nir_fmin(b, nir_channel(b, tmp, 1), max)); + tmp = nir_fmul(b, nir_channel(b, out_input, 3), tmp); + + nir_ssa_def *out = nir_vec4(b, nir_channel(b, out_input, 0), +@@ -189,9 +226,14 @@ lower_aaline_instr(nir_builder *b, nir_instr *instr, void *data) + } + + 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; ++ lower_aaline state = { ++ .stipple_counter = stipple_counter, ++ .stipple_pattern = stipple_pattern, ++ }; + assert(shader->info.stage == MESA_SHADER_FRAGMENT); + + int highest_location = -1, highest_drv_location = -1; +diff --git a/src/gallium/auxiliary/nir/nir_draw_helpers.h b/src/gallium/auxiliary/nir/nir_draw_helpers.h +index 4262c45ef42..114fc8d89b4 100644 +--- a/src/gallium/auxiliary/nir/nir_draw_helpers.h ++++ b/src/gallium/auxiliary/nir/nir_draw_helpers.h +@@ -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); +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 36cb677a355..8b6e67cc461 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -813,7 +813,7 @@ static bool + lower_line_smooth_fs(nir_shader *shader) + { + int dummy; +- nir_lower_aaline_fs(shader, &dummy); ++ nir_lower_aaline_fs(shader, &dummy, NULL, NULL); + return true; + } + +-- +2.17.1 + diff --git a/package/mesa3d/0117-zink-lower-stipple-smooth.patch b/package/mesa3d/0117-zink-lower-stipple-smooth.patch new file mode 100644 index 00000000..8672a720 --- /dev/null +++ b/package/mesa3d/0117-zink-lower-stipple-smooth.patch @@ -0,0 +1,80 @@ +From 34bd7d942173a7c4c2f6cae0fdabdb9cdadb5131 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 2 Dec 2022 13:39:10 +0100 +Subject: [PATCH 117/168] zink: lower stipple + smooth + +We can use the new functionality in the draw-helper to implement +stippled smooth lines instead of what we currently do, which is aliased +stipping on smooth lines. + +Reviewed-by: Soroush Kashani +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 40 +++++++++++++++++++----- + 1 file changed, 33 insertions(+), 7 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 8b6e67cc461..11fdb6389dc 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -810,10 +810,37 @@ lower_line_smooth_gs(nir_shader *shader) + } + + static bool +-lower_line_smooth_fs(nir_shader *shader) ++lower_line_smooth_fs(nir_shader *shader, bool lower_stipple) + { + int dummy; +- nir_lower_aaline_fs(shader, &dummy, NULL, NULL); ++ nir_builder b; ++ ++ nir_variable *stipple_counter = NULL, *stipple_pattern = NULL; ++ if (lower_stipple) { ++ stipple_counter = nir_variable_create(shader, nir_var_shader_in, ++ glsl_float_type(), ++ "__stipple"); ++ stipple_counter->data.interpolation = INTERP_MODE_NOPERSPECTIVE; ++ stipple_counter->data.driver_location = shader->num_inputs++; ++ stipple_counter->data.location = ++ MAX2(util_last_bit64(shader->info.inputs_read), VARYING_SLOT_VAR0); ++ shader->info.inputs_read |= BITFIELD64_BIT(stipple_counter->data.location); ++ ++ stipple_pattern = nir_variable_create(shader, nir_var_shader_temp, ++ glsl_uint_type(), ++ "stipple_pattern"); ++ ++ // initialize stipple_pattern ++ nir_function_impl *entry = nir_shader_get_entrypoint(shader); ++ nir_builder_init(&b, entry); ++ b.cursor = nir_before_cf_list(&entry->body); ++ nir_ssa_def *pattern = nir_load_push_constant(&b, 1, 32, ++ nir_imm_int(&b, ZINK_GFX_PUSHCONST_LINE_STIPPLE_PATTERN), ++ .base = 1); ++ nir_store_var(&b, stipple_pattern, pattern, 1); ++ } ++ ++ nir_lower_aaline_fs(shader, &dummy, stipple_counter, stipple_pattern); + return true; + } + +@@ -2869,13 +2896,12 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + } + break; + case MESA_SHADER_FRAGMENT: +- if (zink_fs_key(key)->lower_line_stipple) +- NIR_PASS_V(nir, lower_line_stipple_fs); +- + if (zink_fs_key(key)->lower_line_smooth) { +- NIR_PASS_V(nir, lower_line_smooth_fs); ++ NIR_PASS_V(nir, lower_line_smooth_fs, ++ zink_fs_key(key)->lower_line_stipple); + need_optimize = true; +- } ++ } else if (zink_fs_key(key)->lower_line_stipple) ++ NIR_PASS_V(nir, lower_line_stipple_fs); + + if (!zink_fs_key_base(key)->samples && + nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)) { +-- +2.17.1 + diff --git a/package/mesa3d/0118-zink-prune-old-swapchains-on-present.patch b/package/mesa3d/0118-zink-prune-old-swapchains-on-present.patch new file mode 100644 index 00000000..ca4bf3cc --- /dev/null +++ b/package/mesa3d/0118-zink-prune-old-swapchains-on-present.patch @@ -0,0 +1,43 @@ +From c0fa2c260752363de3250a386cfce27296839546 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 9 Jan 2023 13:51:16 -0500 +Subject: [PATCH 118/168] zink: prune old swapchains on present + +pruning old swapchains is challenging because there's no way to definitively +know when to destroy them without VK_EXT_swapchain_maintenance1 which isn't +supported yet + +initially, I handled it by only pruning on shutdown and whenever a new swapchain +was created since those are both safe points, but this leads to scenarios where +a dead swapchain can exist for the entire lifetime of an application +if the swapinterval is changed + +to avoid such ballooning, check whether the current swapchain has ever presented +on each present queue and then prune based on this + +fixes #7529 + +Part-of: +--- + src/gallium/drivers/zink/zink_kopper.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/gallium/drivers/zink/zink_kopper.c b/src/gallium/drivers/zink/zink_kopper.c +index a67b7566af7..22a1e66b102 100644 +--- a/src/gallium/drivers/zink/zink_kopper.c ++++ b/src/gallium/drivers/zink/zink_kopper.c +@@ -730,6 +730,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; +-- +2.17.1 + diff --git a/package/mesa3d/0119-zink-whitespace-fixup.patch b/package/mesa3d/0119-zink-whitespace-fixup.patch new file mode 100644 index 00000000..1b05e476 --- /dev/null +++ b/package/mesa3d/0119-zink-whitespace-fixup.patch @@ -0,0 +1,390 @@ +From 8712c8af1300948b4950558fbf36d4f439293b3e Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 21 Apr 2022 13:09:47 +0200 +Subject: [PATCH 119/168] zink: whitespace fixup + +This just cleans up some indentation, no functional changes. + +Part-of: +--- + src/gallium/drivers/zink/zink_bo.c | 6 +- + src/gallium/drivers/zink/zink_device_info.py | 245 ++++++++++--------- + src/gallium/drivers/zink/zink_render_pass.c | 2 +- + 3 files changed, 136 insertions(+), 117 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_bo.c b/src/gallium/drivers/zink/zink_bo.c +index 011d1b85195..552887f50cf 100644 +--- a/src/gallium/drivers/zink/zink_bo.c ++++ b/src/gallium/drivers/zink/zink_bo.c +@@ -969,9 +969,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]; +diff --git a/src/gallium/drivers/zink/zink_device_info.py b/src/gallium/drivers/zink/zink_device_info.py +index 86f3c8cf4d0..ec416f2edf7 100644 +--- a/src/gallium/drivers/zink/zink_device_info.py ++++ b/src/gallium/drivers/zink/zink_device_info.py +@@ -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,56 @@ 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_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 +178,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 +246,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)) +diff --git a/src/gallium/drivers/zink/zink_render_pass.c b/src/gallium/drivers/zink/zink_render_pass.c +index 91629fa4e2d..2bcb2b890dc 100644 +--- a/src/gallium/drivers/zink/zink_render_pass.c ++++ b/src/gallium/drivers/zink/zink_render_pass.c +@@ -367,7 +367,7 @@ zink_init_zs_attachment(struct zink_context *ctx, struct zink_rt_attrib *rt) + (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 = (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)) || ++ 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; +-- +2.17.1 + diff --git a/package/mesa3d/0120-zink-remove-depth_clip_control_missing-workaround.patch b/package/mesa3d/0120-zink-remove-depth_clip_control_missing-workaround.patch new file mode 100644 index 00000000..21cb73fb --- /dev/null +++ b/package/mesa3d/0120-zink-remove-depth_clip_control_missing-workaround.patch @@ -0,0 +1,86 @@ +From a469545071724289cb851742a2a5cab743b3226f Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 17 Jan 2023 09:53:41 +0100 +Subject: [PATCH 120/168] zink: remove depth_clip_control_missing workaround + +The ANV bug this was meant to represent has been long fixed, and the +workaround has just been a proxy for EXT_depth_clip_control for a while +now. + +Let's simplify things a bit, by removing this flag. + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 2 +- + src/gallium/drivers/zink/zink_pipeline.c | 2 +- + src/gallium/drivers/zink/zink_screen.c | 1 - + src/gallium/drivers/zink/zink_state.c | 2 +- + src/gallium/drivers/zink/zink_types.h | 1 - + 5 files changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 11fdb6389dc..93a88ea46e4 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2887,7 +2887,7 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + if (zs->sinfo.have_xfb) + sinfo->last_vertex = true; + +- if (!zink_vs_key_base(key)->clip_halfz && screen->driver_workarounds.depth_clip_control_missing) { ++ if (!zink_vs_key_base(key)->clip_halfz && !screen->info.have_EXT_depth_clip_control) { + NIR_PASS_V(nir, nir_lower_clip_halfz); + } + if (zink_vs_key_base(key)->push_drawid) { +diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c +index 731288a83f9..e7e0e567175 100644 +--- a/src/gallium/drivers/zink/zink_pipeline.c ++++ b/src/gallium/drivers/zink/zink_pipeline.c +@@ -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}; +diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c +index c0ba0861fe1..29e20a2ba89 100644 +--- a/src/gallium/drivers/zink/zink_screen.c ++++ b/src/gallium/drivers/zink/zink_screen.c +@@ -2335,7 +2335,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; +diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c +index b4512ea7cef..17df1cd06b5 100644 +--- a/src/gallium/drivers/zink/zink_state.c ++++ b/src/gallium/drivers/zink/zink_state.c +@@ -650,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; +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index 4b6a0100396..0164bf2e348 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -1277,7 +1277,6 @@ struct zink_screen { + + struct { + bool broken_l4a4; +- bool depth_clip_control_missing; + bool implicit_sync; + bool always_feedback_loop; + bool always_feedback_loop_zs; +-- +2.17.1 + diff --git a/package/mesa3d/0121-zink-add-a-util-function-for-creating-semaphores.patch b/package/mesa3d/0121-zink-add-a-util-function-for-creating-semaphores.patch new file mode 100644 index 00000000..d89df9bc --- /dev/null +++ b/package/mesa3d/0121-zink-add-a-util-function-for-creating-semaphores.patch @@ -0,0 +1,54 @@ +From 975d08ac2f7f8f70655eb91dd071fa13e8e7de6f Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 19 Sep 2022 16:12:57 -0400 +Subject: [PATCH 121/168] zink: add a util function for creating semaphores + +annoying to keep copy/pasting this around + +Part-of: +--- + src/gallium/drivers/zink/zink_screen.c | 13 +++++++++++++ + src/gallium/drivers/zink/zink_screen.h | 3 +++ + 2 files changed, 16 insertions(+) + +diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c +index 29e20a2ba89..bb3f92c9612 100644 +--- a/src/gallium/drivers/zink/zink_screen.c ++++ b/src/gallium/drivers/zink/zink_screen.c +@@ -2454,6 +2454,19 @@ 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; ++ 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) + { +diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h +index e678eb47f4f..1eed13c197c 100644 +--- a/src/gallium/drivers/zink/zink_screen.h ++++ b/src/gallium/drivers/zink/zink_screen.h +@@ -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); + +-- +2.17.1 + diff --git a/package/mesa3d/0122-zink-add-a-binary-semaphore-cache.patch b/package/mesa3d/0122-zink-add-a-binary-semaphore-cache.patch new file mode 100644 index 00000000..c5e9e01d --- /dev/null +++ b/package/mesa3d/0122-zink-add-a-binary-semaphore-cache.patch @@ -0,0 +1,92 @@ +From 68b3ac8688ee43cd7efa1e592392124a0c0aaa14 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 12 Jan 2023 14:21:20 -0500 +Subject: [PATCH 122/168] zink: add a binary semaphore cache + +after being waited upon, a binary semaphore can be reused, which saves +tons of present-related ioctls when fps is high + +Part-of: +--- + src/gallium/drivers/zink/zink_batch.c | 9 +++++++-- + src/gallium/drivers/zink/zink_screen.c | 15 +++++++++++++++ + src/gallium/drivers/zink/zink_types.h | 3 +++ + 3 files changed, 25 insertions(+), 2 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c +index 7063463404d..5ee10eadf63 100644 +--- a/src/gallium/drivers/zink/zink_batch.c ++++ b/src/gallium/drivers/zink/zink_batch.c +@@ -198,8 +198,13 @@ 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); ++ /* check the arrays first to avoid locking unnecessarily */ ++ if (!util_dynarray_contains(&bs->unref_semaphores, VkSemaphore)) ++ return; ++ simple_mtx_lock(&screen->semaphores_lock); ++ util_dynarray_append_dynarray(&screen->semaphores, &bs->unref_semaphores); ++ util_dynarray_clear(&bs->unref_semaphores); ++ simple_mtx_unlock(&screen->semaphores_lock); + } + + /* utility for resetting a batch state; called on context destruction */ +diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c +index bb3f92c9612..90ff84e9cb3 100644 +--- a/src/gallium/drivers/zink/zink_screen.c ++++ b/src/gallium/drivers/zink/zink_screen.c +@@ -1415,6 +1415,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); +@@ -2463,6 +2467,14 @@ zink_create_semaphore(struct zink_screen *screen) + 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; + } +@@ -2725,6 +2737,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; +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index 0164bf2e348..5aa2b0579b0 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -1184,6 +1184,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; +-- +2.17.1 + diff --git a/package/mesa3d/0123-zink-move-semaphore-caching-to-zink_reset_batch_stat.patch b/package/mesa3d/0123-zink-move-semaphore-caching-to-zink_reset_batch_stat.patch new file mode 100644 index 00000000..ef48a0cf --- /dev/null +++ b/package/mesa3d/0123-zink-move-semaphore-caching-to-zink_reset_batch_stat.patch @@ -0,0 +1,87 @@ +From a26fddec98bfbf1f4269dc8e5b51edf829298a12 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 12 Jan 2023 14:25:25 -0500 +Subject: [PATCH 123/168] zink: move semaphore caching to + zink_reset_batch_state() + +this makes semaphores available for reuse more rapidly + +Part-of: +--- + src/gallium/drivers/zink/zink_batch.c | 26 +++++++++----------------- + src/gallium/drivers/zink/zink_types.h | 1 - + 2 files changed, 9 insertions(+), 18 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c +index 5ee10eadf63..b1ac83b1bd8 100644 +--- a/src/gallium/drivers/zink/zink_batch.c ++++ b/src/gallium/drivers/zink/zink_batch.c +@@ -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,13 +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); + } +- /* check the arrays first to avoid locking unnecessarily */ +- if (!util_dynarray_contains(&bs->unref_semaphores, VkSemaphore)) +- return; +- simple_mtx_lock(&screen->semaphores_lock); +- util_dynarray_append_dynarray(&screen->semaphores, &bs->unref_semaphores); +- util_dynarray_clear(&bs->unref_semaphores); +- simple_mtx_unlock(&screen->semaphores_lock); + } + + /* utility for resetting a batch state; called on context destruction */ +@@ -274,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); +@@ -331,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); +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index 5aa2b0579b0..ac262b84e02 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -502,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; + +-- +2.17.1 + diff --git a/package/mesa3d/0124-zink-consolidate-semaphore-creation-where-possible.patch b/package/mesa3d/0124-zink-consolidate-semaphore-creation-where-possible.patch new file mode 100644 index 00000000..8edf16b2 --- /dev/null +++ b/package/mesa3d/0124-zink-consolidate-semaphore-creation-where-possible.patch @@ -0,0 +1,105 @@ +From 2143a73fe42dd9e3c63e49e04b760d76ee441e04 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 12 Jan 2023 14:49:26 -0500 +Subject: [PATCH 124/168] zink: consolidate semaphore creation where possible + +all cacheable semaphores should now be using the cache + +Part-of: +--- + src/gallium/drivers/zink/zink_bo.c | 19 +++---------------- + src/gallium/drivers/zink/zink_kopper.c | 20 +++++--------------- + 2 files changed, 8 insertions(+), 31 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_bo.c b/src/gallium/drivers/zink/zink_bo.c +index 552887f50cf..d5152ce5ef8 100644 +--- a/src/gallium/drivers/zink/zink_bo.c ++++ b/src/gallium/drivers/zink/zink_bo.c +@@ -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; +diff --git a/src/gallium/drivers/zink/zink_kopper.c b/src/gallium/drivers/zink/zink_kopper.c +index 22a1e66b102..819d72e7dfd 100644 +--- a/src/gallium/drivers/zink/zink_kopper.c ++++ b/src/gallium/drivers/zink/zink_kopper.c +@@ -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 { +-- +2.17.1 + diff --git a/package/mesa3d/0125-zink-simplify-some-dynarray-concat-descriptor-code.patch b/package/mesa3d/0125-zink-simplify-some-dynarray-concat-descriptor-code.patch new file mode 100644 index 00000000..9f3a6b97 --- /dev/null +++ b/package/mesa3d/0125-zink-simplify-some-dynarray-concat-descriptor-code.patch @@ -0,0 +1,38 @@ +From c8eae078337fa0f8233d639496c7082270f97871 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 12 Jan 2023 14:27:19 -0500 +Subject: [PATCH 125/168] zink: simplify some dynarray concat descriptor code + +TIL this exists + +Part-of: +--- + src/gallium/drivers/zink/zink_descriptors.c | 12 +++--------- + 1 file changed, 3 insertions(+), 9 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_descriptors.c b/src/gallium/drivers/zink/zink_descriptors.c +index f8c8467c545..d6285ec89a3 100644 +--- a/src/gallium/drivers/zink/zink_descriptors.c ++++ b/src/gallium/drivers/zink/zink_descriptors.c +@@ -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 */ +-- +2.17.1 + diff --git a/package/mesa3d/0126-zink-add-pass-checking-for-lod-overflow-in-txf.patch b/package/mesa3d/0126-zink-add-pass-checking-for-lod-overflow-in-txf.patch new file mode 100644 index 00000000..da31039b --- /dev/null +++ b/package/mesa3d/0126-zink-add-pass-checking-for-lod-overflow-in-txf.patch @@ -0,0 +1,101 @@ +From 64ef910049dd16eb44ab879825263ef08f17c894 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 27 Oct 2022 23:39:33 +0100 +Subject: [PATCH 126/168] zink: add pass checking for lod overflow in txf + +Will be used later to workaround missing robustImageAccess2 along +with robustImageAccess. + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 74 ++++++++++++++++++++++++ + 1 file changed, 74 insertions(+) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 93a88ea46e4..f9c965d4009 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -1237,6 +1237,80 @@ lower_fbfetch(nir_shader *shader, nir_variable **fbfetch, bool ms) + return nir_shader_instructions_pass(shader, lower_fbfetch_instr, nir_metadata_dominance, (void*)ms); + } + ++/* ++ * Add a check for out of bounds LOD for every texel fetch op ++ * It boils down to: ++ * - if (lod < query_levels(tex)) ++ * - res = txf(tex) ++ * - else ++ * - res = (0, 0, 0, 1) ++ */ ++static bool ++lower_txf_lod_robustness_instr(nir_builder *b, nir_instr *in, void *data) ++{ ++ if (in->type != nir_instr_type_tex) ++ return false; ++ nir_tex_instr *txf = nir_instr_as_tex(in); ++ if (txf->op != nir_texop_txf) ++ return false; ++ ++ b->cursor = nir_before_instr(in); ++ int lod_idx = nir_tex_instr_src_index(txf, nir_tex_src_lod); ++ assert(lod_idx >= 0); ++ nir_src lod_src = txf->src[lod_idx].src; ++ if (nir_src_is_const(lod_src) && nir_src_as_const_value(lod_src)->u32 == 0) ++ return false; ++ ++ assert(lod_src.is_ssa); ++ nir_ssa_def *lod = lod_src.ssa; ++ ++ int offset_idx = nir_tex_instr_src_index(txf, nir_tex_src_texture_offset); ++ int handle_idx = nir_tex_instr_src_index(txf, nir_tex_src_texture_handle); ++ nir_tex_instr *levels = nir_tex_instr_create(b->shader, ++ !!(offset_idx >= 0) + !!(handle_idx >= 0)); ++ levels->op = nir_texop_query_levels; ++ levels->texture_index = txf->texture_index; ++ levels->dest_type = nir_type_int | lod->bit_size; ++ if (offset_idx >= 0) { ++ levels->src[0].src_type = nir_tex_src_texture_offset; ++ nir_src_copy(&levels->src[0].src, &txf->src[offset_idx].src, &levels->instr); ++ } ++ if (handle_idx >= 0) { ++ levels->src[!!(offset_idx >= 0)].src_type = nir_tex_src_texture_handle; ++ nir_src_copy(&levels->src[!!(offset_idx >= 0)].src, &txf->src[handle_idx].src, &levels->instr); ++ } ++ nir_ssa_dest_init(&levels->instr, &levels->dest, ++ nir_tex_instr_dest_size(levels), 32, NULL); ++ nir_builder_instr_insert(b, &levels->instr); ++ ++ nir_if *lod_oob_if = nir_push_if(b, nir_ilt(b, lod, &levels->dest.ssa)); ++ nir_tex_instr *new_txf = nir_instr_as_tex(nir_instr_clone(b->shader, in)); ++ nir_builder_instr_insert(b, &new_txf->instr); ++ ++ nir_if *lod_oob_else = nir_push_else(b, lod_oob_if); ++ nir_const_value oob_values[4] = {0}; ++ unsigned bit_size = nir_alu_type_get_type_size(txf->dest_type); ++ oob_values[3] = (txf->dest_type & nir_type_float) ? ++ nir_const_value_for_float(1.0, bit_size) : nir_const_value_for_uint(1, bit_size); ++ nir_ssa_def *oob_val = nir_build_imm(b, nir_tex_instr_dest_size(txf), bit_size, oob_values); ++ ++ nir_pop_if(b, lod_oob_else); ++ nir_ssa_def *robust_txf = nir_if_phi(b, &new_txf->dest.ssa, oob_val); ++ ++ nir_ssa_def_rewrite_uses(&txf->dest.ssa, robust_txf); ++ nir_instr_remove_v(in); ++ return true; ++} ++ ++/* This pass is used to workaround the lack of out of bounds LOD robustness ++ * for texel fetch ops in VK_EXT_image_robustness. ++ */ ++static bool ++lower_txf_lod_robustness(nir_shader *shader) ++{ ++ return nir_shader_instructions_pass(shader, lower_txf_lod_robustness_instr, nir_metadata_none, NULL); ++} ++ + /* check for a genuine gl_PointSize output vs one from nir_lower_point_size_mov */ + static bool + check_psiz(struct nir_shader *s) +-- +2.17.1 + diff --git a/package/mesa3d/0127-zink-add-zink_cs_key.patch b/package/mesa3d/0127-zink-add-zink_cs_key.patch new file mode 100644 index 00000000..b972468b --- /dev/null +++ b/package/mesa3d/0127-zink-add-zink_cs_key.patch @@ -0,0 +1,78 @@ +From d694a30fc22f6e24978b2e66776584863cd16be5 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 20 Jan 2023 16:02:34 +0000 +Subject: [PATCH 127/168] zink: add zink_cs_key + +Also, add shader key handling to compute programs. +This will be used later on for the rb_image workaround. + +Part-of: +--- + src/gallium/drivers/zink/zink_program.c | 7 ++++--- + src/gallium/drivers/zink/zink_shader_keys.h | 15 ++++++++++++++- + 2 files changed, 18 insertions(+), 4 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 5f9a0e6b6f4..2a3fad794e6 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -751,13 +751,14 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c + } + 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); + 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)); + zm->hash = shader_module_hash(zm); + zm->default_variant = false; + if (inline_size) +diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h +index 8e9565d8a06..a068fc018a0 100644 +--- a/src/gallium/drivers/zink/zink_shader_keys.h ++++ b/src/gallium/drivers/zink/zink_shader_keys.h +@@ -88,6 +88,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 { ++ uint32_t pad : 32; ++}; ++ + struct zink_shader_key_base { + uint32_t nonseamless_cube_mask; + uint32_t inlined_uniform_values[MAX_INLINABLE_UNIFORMS]; +@@ -107,6 +114,7 @@ struct zink_shader_key { + 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; +@@ -181,6 +189,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 +-- +2.17.1 + diff --git a/package/mesa3d/0128-zink-add-VK_EXT_image_robustness.patch b/package/mesa3d/0128-zink-add-VK_EXT_image_robustness.patch new file mode 100644 index 00000000..7d06f3c9 --- /dev/null +++ b/package/mesa3d/0128-zink-add-VK_EXT_image_robustness.patch @@ -0,0 +1,27 @@ +From adec4a54cb5437b660492e21d0ac09577967bf60 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 20 Jan 2023 16:58:27 +0000 +Subject: [PATCH 128/168] zink: add VK_EXT_image_robustness + +Part-of: +--- + src/gallium/drivers/zink/zink_device_info.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/gallium/drivers/zink/zink_device_info.py b/src/gallium/drivers/zink/zink_device_info.py +index ec416f2edf7..2847a16fac4 100644 +--- a/src/gallium/drivers/zink/zink_device_info.py ++++ b/src/gallium/drivers/zink/zink_device_info.py +@@ -164,6 +164,9 @@ EXTENSIONS = [ + 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", +-- +2.17.1 + diff --git a/package/mesa3d/0129-zink-add-robust_access-field-to-shader-key.patch b/package/mesa3d/0129-zink-add-robust_access-field-to-shader-key.patch new file mode 100644 index 00000000..b271738e --- /dev/null +++ b/package/mesa3d/0129-zink-add-robust_access-field-to-shader-key.patch @@ -0,0 +1,50 @@ +From 7a400afc4201d377bdb4a695fb0b1615348659cf Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 20 Jan 2023 16:59:41 +0000 +Subject: [PATCH 129/168] zink: add robust_access field to shader key + +Since shaders can be shared even between robust and non-robust +contexts, the robustness state needs to be tracked. + +Part-of: +--- + src/gallium/drivers/zink/zink_shader_keys.h | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h +index a068fc018a0..320abcd81d2 100644 +--- a/src/gallium/drivers/zink/zink_shader_keys.h ++++ b/src/gallium/drivers/zink/zink_shader_keys.h +@@ -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 { +@@ -81,7 +82,8 @@ struct zink_fs_key { + /* non-optimal bits after this point */ + bool lower_line_stipple : 1; + bool lower_line_smooth : 1; +- uint16_t pad2 : 14; ++ bool robust_access : 1; ++ uint16_t pad2 : 13; + }; + + struct zink_tcs_key { +@@ -92,7 +94,8 @@ struct zink_tcs_key { + * ctx->compute_pipeline_state.key.size is set in zink_context_create. + */ + struct zink_cs_key { +- uint32_t pad : 32; ++ bool robust_access : 1; ++ uint32_t pad : 31; + }; + + struct zink_shader_key_base { +-- +2.17.1 + diff --git a/package/mesa3d/0130-zink-lower-LOD-invalid-txf-when-imageRobustAccess2-i.patch b/package/mesa3d/0130-zink-lower-LOD-invalid-txf-when-imageRobustAccess2-i.patch new file mode 100644 index 00000000..a8488342 --- /dev/null +++ b/package/mesa3d/0130-zink-lower-LOD-invalid-txf-when-imageRobustAccess2-i.patch @@ -0,0 +1,187 @@ +From c0d7796e66051615f3388e430d61ccace233d4cb Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 20 Jan 2023 17:00:56 +0000 +Subject: [PATCH 130/168] zink: lower LOD-invalid txf when imageRobustAccess2 + is missing + +GL robust buffer access applies to texelFetch with out of bounds LODs. +imageRobustAccess2 guarantees this, but imageRobustAccess does not. +Therefore, the txf robustness lowering pass from earlier is used +to provide this guarantee and support ARB/KHR robust_buffer_access_behavior. + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 9 +++++++++ + src/gallium/drivers/zink/zink_context.c | 12 ++++++++++++ + src/gallium/drivers/zink/zink_program.c | 12 ++++++++---- + src/gallium/drivers/zink/zink_screen.c | 12 ++++++++++-- + src/gallium/drivers/zink/zink_types.h | 1 + + 5 files changed, 40 insertions(+), 6 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index f9c965d4009..9ff54faa379 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2968,6 +2968,8 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + NIR_PASS_V(nir, lower_drawid); + } + } ++ if (zink_vs_key_base(key)->robust_access) ++ NIR_PASS(need_optimize, nir, lower_txf_lod_robustness); + break; + case MESA_SHADER_FRAGMENT: + if (zink_fs_key(key)->lower_line_smooth) { +@@ -2977,6 +2979,9 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + } else if (zink_fs_key(key)->lower_line_stipple) + NIR_PASS_V(nir, lower_line_stipple_fs); + ++ if (zink_fs_key(key)->robust_access) ++ NIR_PASS(need_optimize, nir, lower_txf_lod_robustness); ++ + if (!zink_fs_key_base(key)->samples && + nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)) { + /* VK will always use gl_SampleMask[] values even if sample count is 0, +@@ -3022,6 +3027,10 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad + need_optimize = true; + } + break; ++ case MESA_SHADER_COMPUTE: ++ if (zink_cs_key(key)->robust_access) ++ NIR_PASS(need_optimize, nir, lower_txf_lod_robustness); ++ break; + default: break; + } + if (key->base.nonseamless_cube_mask) { +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 8a7b20ec6d8..6e5ce3b7290 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -4742,6 +4742,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; + +@@ -4859,6 +4860,17 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) + 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_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)) +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 2a3fad794e6..6d8b41b5707 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -707,6 +707,8 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c + struct zink_shader_module *zm = NULL; + unsigned inline_size = 0, nonseamless_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)) { +@@ -718,7 +720,7 @@ 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 (inline_size || nonseamless_size) { ++ if (inline_size || nonseamless_size || zink_cs_key(key)->robust_access) { + 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; +@@ -754,7 +756,7 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c + zm->key_size = key->size; + memcpy(zm->key, key, key->size); + zm->has_nonseamless = !!nonseamless_size; +- assert(nonseamless_size || inline_size); ++ assert(nonseamless_size || inline_size || zink_cs_key(key)->robust_access); + if (nonseamless_size) + memcpy(zm->key + zm->key_size, &key->base.nonseamless_cube_mask, nonseamless_size); + if (inline_size) +@@ -765,7 +767,7 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c + 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) + util_dynarray_append(&comp->shader_cache[!!nonseamless_size], void*, zm); + } + if (comp->curr == zm) +@@ -1026,7 +1028,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); +diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c +index 90ff84e9cb3..0d15f30e467 100644 +--- a/src/gallium/drivers/zink/zink_screen.c ++++ b/src/gallium/drivers/zink/zink_screen.c +@@ -576,7 +576,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; +@@ -2426,6 +2427,12 @@ init_driver_workarounds(struct zink_screen *screen) + 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) + screen->driver_workarounds.track_renderpasses = true; +@@ -2773,7 +2780,8 @@ zink_internal_create_screen(const struct pipe_screen_config *config) + !screen->driconf.inline_uniforms && + !screen->driver_workarounds.no_linestipple && + !screen->driver_workarounds.no_linesmooth && +- !screen->driver_workarounds.no_hw_gl_point; ++ !screen->driver_workarounds.no_hw_gl_point && ++ !screen->driver_workarounds.lower_robustImageAccess2; + if (!screen->optimal_keys) + screen->info.have_EXT_graphics_pipeline_library = false; + +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index ac262b84e02..ce247ba3042 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -1287,6 +1287,7 @@ struct zink_screen { + bool no_linestipple; + bool no_linesmooth; + bool no_hw_gl_point; ++ bool lower_robustImageAccess2; + unsigned z16_unscaled_bias; + unsigned z24_unscaled_bias; + } driver_workarounds; +-- +2.17.1 + diff --git a/package/mesa3d/0131-zink-update-gl43-profile-to-allow-imageRobustAccess.patch b/package/mesa3d/0131-zink-update-gl43-profile-to-allow-imageRobustAccess.patch new file mode 100644 index 00000000..eef767a5 --- /dev/null +++ b/package/mesa3d/0131-zink-update-gl43-profile-to-allow-imageRobustAccess.patch @@ -0,0 +1,96 @@ +From 5f4828f84c3344eaaac50fd4d5c6a67af978c36f Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 20 Jan 2023 17:31:53 +0000 +Subject: [PATCH 131/168] zink: update gl43 profile to allow imageRobustAccess + +Now that zink can use imageRobustAccess and handle txf with invalid LODs, +update the profile to require either VK_EXT_image_robustness or VK_EXT_robustness2. + +Part-of: +--- + .../drivers/zink/VP_ZINK_requirements.json | 34 ++++++++++++++++++- + 1 file changed, 33 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/VP_ZINK_requirements.json b/src/gallium/drivers/zink/VP_ZINK_requirements.json +index 262a690993d..8bd5eb85d40 100644 +--- a/src/gallium/drivers/zink/VP_ZINK_requirements.json ++++ b/src/gallium/drivers/zink/VP_ZINK_requirements.json +@@ -189,6 +189,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": { +@@ -675,7 +702,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": { +@@ -696,6 +724,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" + ] + }, +@@ -717,6 +746,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" + ] +@@ -739,6 +769,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" +@@ -762,6 +793,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", +-- +2.17.1 + diff --git a/package/mesa3d/0132-zink-flag-old-style-shadow-tex-mask-for-fragment-sha.patch b/package/mesa3d/0132-zink-flag-old-style-shadow-tex-mask-for-fragment-sha.patch new file mode 100644 index 00000000..38c2999f --- /dev/null +++ b/package/mesa3d/0132-zink-flag-old-style-shadow-tex-mask-for-fragment-sha.patch @@ -0,0 +1,83 @@ +From 333aa424e9c14ac1c3fcea7a25b045be6fe5fc3e Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 13:32:25 -0500 +Subject: [PATCH 132/168] zink: flag old-style shadow tex mask for fragment + shaders + +this will be useful for handling depth texturing modes + +only 32 are tracked now for performance reasons + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 19 ++++++++++++++++--- + src/gallium/drivers/zink/zink_types.h | 1 + + 2 files changed, 17 insertions(+), 3 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 9ff54faa379..44fa8789a8b 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -3753,6 +3753,15 @@ lower_sparse(nir_shader *shader) + return nir_shader_instructions_pass(shader, lower_sparse_instr, nir_metadata_dominance, NULL); + } + ++static void ++flag_shadow_tex(nir_variable *var, struct zink_shader *zs) ++{ ++ /* unconvert from zink_binding() */ ++ uint32_t sampler_id = var->data.binding - (PIPE_MAX_SAMPLERS * MESA_SHADER_FRAGMENT); ++ assert(sampler_id < 32); //bitfield size for tracking ++ zs->fs.legacy_shadow_mask |= BITFIELD_BIT(sampler_id); ++} ++ + static bool + match_tex_dests_instr(nir_builder *b, nir_instr *in, void *data) + { +@@ -3793,6 +3802,10 @@ match_tex_dests_instr(nir_builder *b, nir_instr *in, void *data) + assert(!tex->is_new_style_shadow); + tex->dest.ssa.num_components = 1; + tex->is_new_style_shadow = true; ++ if (b->shader->info.stage == MESA_SHADER_FRAGMENT) ++ flag_shadow_tex(var, data); ++ else ++ mesa_loge("unhandled old-style shadow sampler in non-fragment stage!"); + } + if (bit_size != dest_size) { + tex->dest.ssa.bit_size = bit_size; +@@ -3820,9 +3833,9 @@ match_tex_dests_instr(nir_builder *b, nir_instr *in, void *data) + } + + static bool +-match_tex_dests(nir_shader *shader) ++match_tex_dests(nir_shader *shader, struct zink_shader *zs) + { +- return nir_shader_instructions_pass(shader, match_tex_dests_instr, nir_metadata_dominance, NULL); ++ return nir_shader_instructions_pass(shader, match_tex_dests_instr, nir_metadata_dominance, zs); + } + + static bool +@@ -4276,7 +4289,7 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir, + if (!screen->info.feats.features.shaderInt64 || !screen->info.feats.features.shaderFloat64) + NIR_PASS_V(nir, lower_64bit_vars, screen->info.feats.features.shaderInt64); + if (nir->info.stage != MESA_SHADER_KERNEL) +- NIR_PASS_V(nir, match_tex_dests); ++ NIR_PASS_V(nir, match_tex_dests, ret); + + ret->nir = nir; + nir_foreach_shader_out_variable(var, nir) +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index ce247ba3042..c984eed9daa 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -689,6 +689,7 @@ struct zink_shader { + } non_fs; + + struct { ++ uint32_t legacy_shadow_mask; //is_new_style_shadow is false for these + nir_variable *fbfetch; //for fs output + } fs; + }; +-- +2.17.1 + diff --git a/package/mesa3d/0133-zink-break-out-tex-dest-rewriting-into-separate-func.patch b/package/mesa3d/0133-zink-break-out-tex-dest-rewriting-into-separate-func.patch new file mode 100644 index 00000000..e0b76fdf --- /dev/null +++ b/package/mesa3d/0133-zink-break-out-tex-dest-rewriting-into-separate-func.patch @@ -0,0 +1,150 @@ +From 20814cd9146f90458a5861e0d3ddd07f11f80405 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 13:36:13 -0500 +Subject: [PATCH 133/168] zink: break out tex dest rewriting into separate + function + +no functional changes + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 109 ++++++++++++----------- + 1 file changed, 56 insertions(+), 53 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 44fa8789a8b..2a2becd9bb5 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2883,6 +2883,61 @@ invert_point_coord(nir_shader *nir) + return nir_shader_instructions_pass(nir, invert_point_coord_instr, nir_metadata_dominance, NULL); + } + ++static void ++flag_shadow_tex(nir_variable *var, struct zink_shader *zs) ++{ ++ /* unconvert from zink_binding() */ ++ uint32_t sampler_id = var->data.binding - (PIPE_MAX_SAMPLERS * MESA_SHADER_FRAGMENT); ++ assert(sampler_id < 32); //bitfield size for tracking ++ zs->fs.legacy_shadow_mask |= BITFIELD_BIT(sampler_id); ++} ++ ++static bool ++rewrite_tex_dest(nir_builder *b, nir_tex_instr *tex, nir_variable *var, void *data) ++{ ++ assert(var); ++ const struct glsl_type *type = glsl_without_array(var->type); ++ enum glsl_base_type ret_type = glsl_get_sampler_result_type(type); ++ bool is_int = glsl_base_type_is_integer(ret_type); ++ unsigned bit_size = glsl_base_type_get_bit_size(ret_type); ++ unsigned dest_size = nir_dest_bit_size(tex->dest); ++ b->cursor = nir_after_instr(&tex->instr); ++ unsigned num_components = nir_dest_num_components(tex->dest); ++ bool rewrite_depth = tex->is_shadow && num_components > 1 && tex->op != nir_texop_tg4 && !tex->is_sparse; ++ if (bit_size == dest_size && !rewrite_depth) ++ return false; ++ nir_ssa_def *dest = &tex->dest.ssa; ++ if (rewrite_depth) { ++ if (b->shader->info.stage == MESA_SHADER_FRAGMENT) ++ flag_shadow_tex(var, data); ++ else ++ mesa_loge("unhandled old-style shadow sampler in non-fragment stage!"); ++ } ++ if (bit_size != dest_size) { ++ tex->dest.ssa.bit_size = bit_size; ++ tex->dest_type = nir_get_nir_type_for_glsl_base_type(ret_type); ++ ++ if (is_int) { ++ if (glsl_unsigned_base_type_of(ret_type) == ret_type) ++ dest = nir_u2uN(b, &tex->dest.ssa, dest_size); ++ else ++ dest = nir_i2iN(b, &tex->dest.ssa, dest_size); ++ } else { ++ dest = nir_f2fN(b, &tex->dest.ssa, dest_size); ++ } ++ if (rewrite_depth) { ++ nir_ssa_def *vec[4] = {dest, dest, dest, dest}; ++ dest = nir_vec(b, vec, num_components); ++ } ++ nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, dest, dest->parent_instr); ++ } else if (rewrite_depth) { ++ nir_ssa_def *vec[4] = {dest, dest, dest, dest}; ++ nir_ssa_def *splat = nir_vec(b, vec, num_components); ++ nir_ssa_def_rewrite_uses_after(dest, splat, splat->parent_instr); ++ } ++ return true; ++} ++ + VkShaderModule + zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shader *base_nir, const struct zink_shader_key *key) + { +@@ -3753,15 +3808,6 @@ lower_sparse(nir_shader *shader) + return nir_shader_instructions_pass(shader, lower_sparse_instr, nir_metadata_dominance, NULL); + } + +-static void +-flag_shadow_tex(nir_variable *var, struct zink_shader *zs) +-{ +- /* unconvert from zink_binding() */ +- uint32_t sampler_id = var->data.binding - (PIPE_MAX_SAMPLERS * MESA_SHADER_FRAGMENT); +- assert(sampler_id < 32); //bitfield size for tracking +- zs->fs.legacy_shadow_mask |= BITFIELD_BIT(sampler_id); +-} +- + static bool + match_tex_dests_instr(nir_builder *b, nir_instr *in, void *data) + { +@@ -3786,50 +3832,7 @@ match_tex_dests_instr(nir_builder *b, nir_instr *in, void *data) + } + } + } +- assert(var); +- const struct glsl_type *type = glsl_without_array(var->type); +- enum glsl_base_type ret_type = glsl_get_sampler_result_type(type); +- bool is_int = glsl_base_type_is_integer(ret_type); +- unsigned bit_size = glsl_base_type_get_bit_size(ret_type); +- unsigned dest_size = nir_dest_bit_size(tex->dest); +- b->cursor = nir_after_instr(in); +- unsigned num_components = nir_dest_num_components(tex->dest); +- bool rewrite_depth = tex->is_shadow && num_components > 1 && tex->op != nir_texop_tg4 && !tex->is_sparse; +- if (bit_size == dest_size && !rewrite_depth) +- return false; +- nir_ssa_def *dest = &tex->dest.ssa; +- if (rewrite_depth) { +- assert(!tex->is_new_style_shadow); +- tex->dest.ssa.num_components = 1; +- tex->is_new_style_shadow = true; +- if (b->shader->info.stage == MESA_SHADER_FRAGMENT) +- flag_shadow_tex(var, data); +- else +- mesa_loge("unhandled old-style shadow sampler in non-fragment stage!"); +- } +- if (bit_size != dest_size) { +- tex->dest.ssa.bit_size = bit_size; +- tex->dest_type = nir_get_nir_type_for_glsl_base_type(ret_type); +- +- if (is_int) { +- if (glsl_unsigned_base_type_of(ret_type) == ret_type) +- dest = nir_u2uN(b, &tex->dest.ssa, dest_size); +- else +- dest = nir_i2iN(b, &tex->dest.ssa, dest_size); +- } else { +- dest = nir_f2fN(b, &tex->dest.ssa, dest_size); +- } +- if (rewrite_depth) { +- nir_ssa_def *vec[4] = {dest, dest, dest, dest}; +- dest = nir_vec(b, vec, num_components); +- } +- nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, dest, dest->parent_instr); +- } else if (rewrite_depth) { +- nir_ssa_def *vec[4] = {dest, dest, dest, dest}; +- nir_ssa_def *splat = nir_vec(b, vec, num_components); +- nir_ssa_def_rewrite_uses_after(dest, splat, splat->parent_instr); +- } +- return true; ++ return rewrite_tex_dest(b, tex, var, data); + } + + static bool +-- +2.17.1 + diff --git a/package/mesa3d/0134-zink-add-an-extra_data-param-to-zink_shader_compile.patch b/package/mesa3d/0134-zink-add-an-extra_data-param-to-zink_shader_compile.patch new file mode 100644 index 00000000..e9170d2a --- /dev/null +++ b/package/mesa3d/0134-zink-add-an-extra_data-param-to-zink_shader_compile.patch @@ -0,0 +1,87 @@ +From 03bbf04236054b312596ecd379f53f58c3a550b9 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 16:27:43 -0500 +Subject: [PATCH 134/168] zink: add an extra_data param to zink_shader_compile + +this is extra shader key data that can be used in various ways per stage +and is too large to fit into the shader key + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 3 ++- + src/gallium/drivers/zink/zink_compiler.h | 3 ++- + src/gallium/drivers/zink/zink_program.c | 8 ++++---- + 3 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 2a2becd9bb5..6b4c0a96bf6 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2939,7 +2939,8 @@ rewrite_tex_dest(nir_builder *b, nir_tex_instr *tex, nir_variable *var, void *da + } + + VkShaderModule +-zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shader *base_nir, const struct zink_shader_key *key) ++zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, ++ nir_shader *base_nir, const struct zink_shader_key *key, const void *extra_data) + { + VkShaderModule mod = VK_NULL_HANDLE; + struct zink_shader_info *sinfo = &zs->sinfo; +diff --git a/src/gallium/drivers/zink/zink_compiler.h b/src/gallium/drivers/zink/zink_compiler.h +index 1572aa3b239..a1c894d3853 100644 +--- a/src/gallium/drivers/zink/zink_compiler.h ++++ b/src/gallium/drivers/zink/zink_compiler.h +@@ -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 * +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 6d8b41b5707..f8b4c190898 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -140,7 +140,7 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr + 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, NULL); + } + if (!mod) { + FREE(zm); +@@ -240,7 +240,7 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr + 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, NULL); + } + if (!mod) { + FREE(zm); +@@ -746,7 +746,7 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c + if (!zm) { + return; + } +- mod = zink_shader_compile(screen, zs, comp->shader->nir, key); ++ mod = zink_shader_compile(screen, zs, comp->shader->nir, key, NULL); + if (!mod) { + FREE(zm); + return; +@@ -992,7 +992,7 @@ 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); +-- +2.17.1 + diff --git a/package/mesa3d/0135-zink-track-depth-swizzle-on-samplerviews.patch b/package/mesa3d/0135-zink-track-depth-swizzle-on-samplerviews.patch new file mode 100644 index 00000000..577eaf17 --- /dev/null +++ b/package/mesa3d/0135-zink-track-depth-swizzle-on-samplerviews.patch @@ -0,0 +1,74 @@ +From fa4446e692cac8f8680775b882daf213acf762ae Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 16:28:33 -0500 +Subject: [PATCH 135/168] zink: track depth swizzle on samplerviews + +this will provide info for shader rewrites + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 13 +++++++++++++ + src/gallium/drivers/zink/zink_shader_keys.h | 9 +++++++++ + src/gallium/drivers/zink/zink_types.h | 2 ++ + 3 files changed, 24 insertions(+) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 6e5ce3b7290..ab5abc94d63 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -984,6 +984,19 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres, + 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) { ++ 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) ++ sampler_view->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] = { + sampler_view->base.swizzle_r, +diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h +index 320abcd81d2..b11ab0c03d8 100644 +--- a/src/gallium/drivers/zink/zink_shader_keys.h ++++ b/src/gallium/drivers/zink/zink_shader_keys.h +@@ -67,6 +67,15 @@ struct zink_gs_key { + unsigned size; + }; + ++struct zink_fs_shadow_swizzle { ++ uint8_t s[4]; ++}; ++ ++struct zink_fs_shadow_key { ++ uint32_t mask; ++ struct zink_fs_shadow_swizzle swizzle[32]; ++}; ++ + struct zink_fs_key_base { + bool point_coord_yinvert : 1; + bool samples : 1; +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index c984eed9daa..2e8cb1aae25 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -1414,6 +1414,8 @@ struct zink_sampler_view { + struct zink_buffer_view *buffer_view; + }; + struct zink_surface *cube_array; ++ bool shadow_needs_shader_swizzle; ++ struct zink_fs_shadow_swizzle swizzle; + }; + + struct zink_image_view { +-- +2.17.1 + diff --git a/package/mesa3d/0136-zink-add-a-fs-shader-key-member-to-indicate-depth-te.patch b/package/mesa3d/0136-zink-add-a-fs-shader-key-member-to-indicate-depth-te.patch new file mode 100644 index 00000000..c1e37729 --- /dev/null +++ b/package/mesa3d/0136-zink-add-a-fs-shader-key-member-to-indicate-depth-te.patch @@ -0,0 +1,153 @@ +From 66c8225ea81814746cd21fa9949cae112ccbb845 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 16:34:18 -0500 +Subject: [PATCH 136/168] zink: add a fs shader key member to indicate depth + texturing mode + +this does nothing now besides track the data + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 21 +++++++++++++++++++ + src/gallium/drivers/zink/zink_program.c | 1 + + src/gallium/drivers/zink/zink_program.h | 9 ++++++++ + .../drivers/zink/zink_program_state.hpp | 2 ++ + src/gallium/drivers/zink/zink_shader_keys.h | 3 ++- + src/gallium/drivers/zink/zink_types.h | 3 +++ + 6 files changed, 38 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index ab5abc94d63..7dea60a0a96 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -1840,6 +1840,7 @@ zink_set_sampler_views(struct pipe_context *pctx, + 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]); +@@ -1894,12 +1895,27 @@ zink_set_sampler_views(struct pipe_context *pctx, + update = true; + zink_batch_resource_usage_set(&ctx->batch, res, false, false); + res->obj->unordered_write = false; ++ if (b->shadow_needs_shader_swizzle) { ++ assert(start_slot + i < 32); //bitfield size ++ ctx->di.shadow.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.shadow.swizzle[start_slot + i], ++ &b->swizzle, sizeof(struct zink_fs_shadow_swizzle)); ++ memcpy(&ctx->di.shadow.swizzle[start_slot + i], &b->swizzle, sizeof(struct zink_fs_shadow_swizzle)); ++ } else if (ctx->di.shadow.mask) { ++ assert(start_slot + i < 32); //bitfield size ++ ctx->di.shadow.mask &= ~BITFIELD_BIT(start_slot + i); ++ } + } + res->sampler_binds[shader_type] |= BITFIELD_BIT(start_slot + i); + res->obj->unordered_read = false; + } else if (a) { + unbind_samplerview(ctx, shader_type, start_slot + i); + update = true; ++ if (ctx->di.shadow.mask) { ++ assert(start_slot + i < 32); //bitfield size ++ ctx->di.shadow.mask &= ~BITFIELD_BIT(start_slot + i); ++ } + } + if (take_ownership) { + pipe_sampler_view_reference(&ctx->sampler_views[shader_type][start_slot + i], NULL); +@@ -1916,6 +1932,10 @@ zink_set_sampler_views(struct pipe_context *pctx, + &ctx->sampler_views[shader_type][start_slot + i], + NULL); + update_descriptor_state_sampler(ctx, shader_type, start_slot + i, NULL); ++ if (ctx->di.shadow.mask) { ++ assert(start_slot + i < 32); //bitfield size ++ ctx->di.shadow.mask &= ~BITFIELD_BIT(start_slot + i); ++ } + } + ctx->di.num_sampler_views[shader_type] = start_slot + num_views; + if (update) { +@@ -1923,6 +1943,7 @@ 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); ++ zink_set_fs_shadow_needs_shader_swizzle_key(ctx, shadow_update); + } + } + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index f8b4c190898..f0640617b63 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -1484,6 +1484,7 @@ 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_fs_shadow_needs_shader_swizzle_key(ctx, false); + } + zink_update_fbfetch(ctx); + } +diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h +index 0e76b8b2590..f8f0b0777c7 100644 +--- a/src/gallium/drivers/zink/zink_program.h ++++ b/src/gallium/drivers/zink/zink_program.h +@@ -355,6 +355,15 @@ zink_set_fs_point_coord_key(struct zink_context *ctx) + } + } + ++static inline void ++zink_set_fs_shadow_needs_shader_swizzle_key(struct zink_context *ctx, bool swizzle_update) ++{ ++ 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.shadow.mask) > 0; ++ if (enable != fs->shadow_needs_shader_swizzle || (enable && swizzle_update)) ++ zink_set_fs_base_key(ctx)->shadow_needs_shader_swizzle = enable; ++} ++ + void + zink_set_primitive_emulation_keys(struct zink_context *ctx); + +diff --git a/src/gallium/drivers/zink/zink_program_state.hpp b/src/gallium/drivers/zink/zink_program_state.hpp +index 3111a7a277a..0a5a40bf98c 100644 +--- a/src/gallium/drivers/zink/zink_program_state.hpp ++++ b/src/gallium/drivers/zink/zink_program_state.hpp +@@ -251,6 +251,8 @@ 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_base_key(ctx)->fbfetch_ms && +diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h +index b11ab0c03d8..ccc160f0d2d 100644 +--- a/src/gallium/drivers/zink/zink_shader_keys.h ++++ b/src/gallium/drivers/zink/zink_shader_keys.h +@@ -82,7 +82,8 @@ struct zink_fs_key_base { + 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_fs_shadow_key after the key data ++ uint8_t pad : 2; + uint8_t coord_replace_bits; + }; + +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index 2e8cb1aae25..7e732f12c69 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -1652,6 +1652,9 @@ struct zink_context { + + VkDescriptorImageInfo fbfetch; + ++ /* the current state of the shadow swizzle data */ ++ struct zink_fs_shadow_key shadow; ++ + struct zink_resource *descriptor_res[ZINK_DESCRIPTOR_BASE_TYPES][MESA_SHADER_STAGES][PIPE_MAX_SAMPLERS]; + + struct { +-- +2.17.1 + diff --git a/package/mesa3d/0137-zink-rework-depth-sampler-splatting-in-shaders.patch b/package/mesa3d/0137-zink-rework-depth-sampler-splatting-in-shaders.patch new file mode 100644 index 00000000..233b46fe --- /dev/null +++ b/package/mesa3d/0137-zink-rework-depth-sampler-splatting-in-shaders.patch @@ -0,0 +1,149 @@ +From ef45b9fd93e4713ba5ba83d6d8a3aeaea23d2a42 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 16:36:30 -0500 +Subject: [PATCH 137/168] zink: rework depth sampler splatting in shaders + +this enables passing a zink_fs_shadow_key to the compiler to manually +apply a swizzle other than R/R/R/R to depth texture results + +currently no data is passed, so the previous splatting behavior is preserved + +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 78 +++++++++++++++++++++--- + 1 file changed, 70 insertions(+), 8 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 6b4c0a96bf6..35d4988b44d 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2892,7 +2892,7 @@ flag_shadow_tex(nir_variable *var, struct zink_shader *zs) + zs->fs.legacy_shadow_mask |= BITFIELD_BIT(sampler_id); + } + +-static bool ++static nir_ssa_def * + rewrite_tex_dest(nir_builder *b, nir_tex_instr *tex, nir_variable *var, void *data) + { + assert(var); +@@ -2905,13 +2905,14 @@ rewrite_tex_dest(nir_builder *b, nir_tex_instr *tex, nir_variable *var, void *da + unsigned num_components = nir_dest_num_components(tex->dest); + bool rewrite_depth = tex->is_shadow && num_components > 1 && tex->op != nir_texop_tg4 && !tex->is_sparse; + if (bit_size == dest_size && !rewrite_depth) +- return false; ++ return NULL; + nir_ssa_def *dest = &tex->dest.ssa; +- if (rewrite_depth) { ++ if (rewrite_depth && data) { + if (b->shader->info.stage == MESA_SHADER_FRAGMENT) + flag_shadow_tex(var, data); + else + mesa_loge("unhandled old-style shadow sampler in non-fragment stage!"); ++ return NULL; + } + if (bit_size != dest_size) { + tex->dest.ssa.bit_size = bit_size; +@@ -2925,12 +2926,65 @@ rewrite_tex_dest(nir_builder *b, nir_tex_instr *tex, nir_variable *var, void *da + } else { + dest = nir_f2fN(b, &tex->dest.ssa, dest_size); + } +- if (rewrite_depth) { +- nir_ssa_def *vec[4] = {dest, dest, dest, dest}; +- dest = nir_vec(b, vec, num_components); +- } ++ if (rewrite_depth) ++ return dest; + nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, dest, dest->parent_instr); + } else if (rewrite_depth) { ++ return dest; ++ } ++ return dest; ++} ++ ++static bool ++lower_shadow_tex_instr(nir_builder *b, nir_instr *instr, void *data) ++{ ++ struct zink_fs_shadow_key *shadow = data; ++ if (instr->type != nir_instr_type_tex) ++ return false; ++ nir_tex_instr *tex = nir_instr_as_tex(instr); ++ if (tex->op == nir_texop_txs || tex->op == nir_texop_lod || !tex->is_shadow || tex->is_new_style_shadow) ++ return false; ++ int handle = nir_tex_instr_src_index(tex, nir_tex_src_texture_handle); ++ nir_variable *var = NULL; ++ if (handle != -1) ++ /* gtfo bindless depth texture mode */ ++ return false; ++ nir_foreach_variable_with_modes(img, b->shader, nir_var_uniform) { ++ if (glsl_type_is_sampler(glsl_without_array(img->type))) { ++ unsigned size = glsl_type_is_array(img->type) ? glsl_get_aoa_size(img->type) : 1; ++ if (tex->texture_index >= img->data.driver_location && ++ tex->texture_index < img->data.driver_location + size) { ++ var = img; ++ break; ++ } ++ } ++ } ++ assert(var); ++ uint32_t sampler_id = var->data.binding - (PIPE_MAX_SAMPLERS * MESA_SHADER_FRAGMENT); ++ unsigned num_components = nir_dest_num_components(tex->dest); ++ nir_ssa_def *dest = rewrite_tex_dest(b, tex, var, NULL); ++ assert(!tex->is_new_style_shadow); ++ tex->dest.ssa.num_components = 1; ++ tex->is_new_style_shadow = true; ++ if (shadow && (shadow->mask & BITFIELD_BIT(sampler_id))) { ++ /* these require manual swizzles */ ++ nir_ssa_def *vec[4]; ++ for (unsigned i = 0; i < ARRAY_SIZE(vec); i++) { ++ switch (shadow->swizzle[sampler_id].s[i]) { ++ case PIPE_SWIZZLE_0: ++ vec[i] = nir_imm_zero(b, 1, nir_dest_bit_size(tex->dest)); ++ break; ++ case PIPE_SWIZZLE_1: ++ vec[i] = nir_imm_floatN_t(b, 1, nir_dest_bit_size(tex->dest)); ++ break; ++ default: ++ vec[i] = dest; ++ break; ++ } ++ } ++ nir_ssa_def *swizzle = nir_vec(b, vec, num_components); ++ nir_ssa_def_rewrite_uses_after(dest, swizzle, swizzle->parent_instr); ++ } else { + nir_ssa_def *vec[4] = {dest, dest, dest, dest}; + nir_ssa_def *splat = nir_vec(b, vec, num_components); + nir_ssa_def_rewrite_uses_after(dest, splat, splat->parent_instr); +@@ -2938,6 +2992,12 @@ rewrite_tex_dest(nir_builder *b, nir_tex_instr *tex, nir_variable *var, void *da + return true; + } + ++static bool ++lower_shadow_tex(nir_shader *nir, const void *shadow) ++{ ++ return nir_shader_instructions_pass(nir, lower_shadow_tex_instr, nir_metadata_dominance | nir_metadata_block_index, (void*)shadow); ++} ++ + VkShaderModule + zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, + nir_shader *base_nir, const struct zink_shader_key *key, const void *extra_data) +@@ -3064,6 +3124,8 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, + nir->info.fs.uses_sample_qualifier = true; + nir->info.fs.uses_sample_shading = true; + } ++ if (zs->fs.legacy_shadow_mask) ++ NIR_PASS_V(nir, lower_shadow_tex, zink_fs_key_base(key)->shadow_needs_shader_swizzle ? extra_data : NULL); + if (nir->info.fs.uses_fbfetch_output) { + nir_variable *fbfetch = NULL; + NIR_PASS_V(nir, lower_fbfetch, &fbfetch, zink_fs_key_base(key)->fbfetch_ms); +@@ -3833,7 +3895,7 @@ match_tex_dests_instr(nir_builder *b, nir_instr *in, void *data) + } + } + } +- return rewrite_tex_dest(b, tex, var, data); ++ return !!rewrite_tex_dest(b, tex, var, data); + } + + static bool +-- +2.17.1 + diff --git a/package/mesa3d/0138-zink-block-pipeline-fast-pathing-for-any-programs-us.patch b/package/mesa3d/0138-zink-block-pipeline-fast-pathing-for-any-programs-us.patch new file mode 100644 index 00000000..da0c921b --- /dev/null +++ b/package/mesa3d/0138-zink-block-pipeline-fast-pathing-for-any-programs-us.patch @@ -0,0 +1,33 @@ +From 8b273c3bf9e799a37c42662ea02b00934433a5f3 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 16:39:08 -0500 +Subject: [PATCH 138/168] zink: block pipeline fast-pathing for any programs + using depth texture modes + +the data for this is too big to compress into a shader key, so these pipelines +will always consume more cpu + +Part-of: +--- + src/gallium/drivers/zink/zink_program_state.hpp | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_program_state.hpp b/src/gallium/drivers/zink/zink_program_state.hpp +index 0a5a40bf98c..3c8322efac5 100644 +--- a/src/gallium/drivers/zink/zink_program_state.hpp ++++ b/src/gallium/drivers/zink/zink_program_state.hpp +@@ -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; + } +-- +2.17.1 + diff --git a/package/mesa3d/0139-zink-plug-in-the-program-module-parts-of-shadow-text.patch b/package/mesa3d/0139-zink-plug-in-the-program-module-parts-of-shadow-text.patch new file mode 100644 index 00000000..58009592 --- /dev/null +++ b/package/mesa3d/0139-zink-plug-in-the-program-module-parts-of-shadow-text.patch @@ -0,0 +1,252 @@ +From 420c5d68b31cd1590cf787f6d837842896c2aecb Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 16:43:08 -0500 +Subject: [PATCH 139/168] zink: plug in the program/module parts of shadow + texture mode emulation + +this is clunky because of how big the swizzle data block is, +but the gist of it is the data block is stored onto the shader module key +after all the other data, and then it gets manually hashed/compared in +relevant cases + +it's gross, but so is this functionality + +Part-of: +--- + src/gallium/drivers/zink/zink_program.c | 38 +++++++++++++++++-- + .../drivers/zink/zink_program_state.hpp | 26 ++++++++----- + src/gallium/drivers/zink/zink_types.h | 4 +- + 3 files changed, 55 insertions(+), 13 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index f0640617b63..8ccd06dcd7a 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -131,7 +131,10 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr + 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->non_fs.is_generated; +- zm = malloc(sizeof(struct zink_shader_module) + key->size + (!has_nonseamless ? nonseamless_size : 0) + inline_size * sizeof(uint32_t)); ++ const bool shadow_needs_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_fs_shadow_key) : 0)); + if (!zm) { + return NULL; + } +@@ -166,6 +169,10 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr + zm->hash = patch_vertices; + else + zm->hash = shader_module_hash(zm); ++ if (unlikely(shadow_needs_shader_swizzle)) { ++ memcpy(zm->key + key->size + nonseamless_size + inline_size * sizeof(uint32_t), &ctx->di.shadow, sizeof(struct zink_fs_shadow_key)); ++ zm->hash ^= _mesa_hash_data(&ctx->di.shadow, sizeof(struct zink_fs_shadow_key)); ++ } + zm->default_variant = !inline_size && !util_dynarray_contains(&prog->shader_cache[stage][0][0], void*); + if (inline_size) + prog->inlined_variant_count[stage]++; +@@ -185,6 +192,7 @@ 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->non_fs.is_generated; ++ const bool shadow_needs_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 *); +@@ -199,6 +207,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.shadow, sizeof(struct zink_fs_shadow_key))) ++ continue; ++ } + } + if (i > 0) { + struct zink_shader_module *zero = pzm[0]; +@@ -221,17 +235,19 @@ 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; ++ 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_fs_shadow_key) : 0)); + if (!zm) { + return NULL; + } +@@ -254,6 +270,8 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr + 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.shadow, sizeof(struct zink_fs_shadow_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); +@@ -268,12 +286,14 @@ get_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_screen + { + /* non-generated tcs won't use the shader key */ + 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; ++ 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 { +@@ -291,6 +311,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.shadow, sizeof(struct zink_fs_shadow_key))) ++ continue; ++ } + } + if (i > 0) { + struct zink_shader_module *zero = pzm[0]; +@@ -623,9 +648,16 @@ update_gfx_program_optimal(struct zink_context *ctx, struct zink_gfx_program *pr + 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) { ++ 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_fs_shadow_key*)pzm[0]->key + sizeof(uint16_t); ++ } + } + 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) { +diff --git a/src/gallium/drivers/zink/zink_program_state.hpp b/src/gallium/drivers/zink/zink_program_state.hpp +index 3c8322efac5..0e78e9ea9c1 100644 +--- a/src/gallium/drivers/zink/zink_program_state.hpp ++++ b/src/gallium/drivers/zink/zink_program_state.hpp +@@ -362,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]) +@@ -387,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 + 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; + return equals_gfx_pipeline_state; ++ } + return equals_gfx_pipeline_state; + } + +@@ -398,6 +405,7 @@ template + 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]->non_fs.is_generated) +@@ -407,30 +415,30 @@ get_gfx_pipeline_stage_eq_func(struct zink_gfx_program *prog, bool optimal_keys) + if (vertex_stages == BITFIELD_MASK(MESA_SHADER_FRAGMENT)) + /* all stages */ + return get_optimal_gfx_pipeline_stage_eq_func(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(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(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(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(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(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(optimal_keys); ++ BITFIELD_BIT(MESA_SHADER_VERTEX) | BITFIELD_BIT(MESA_SHADER_FRAGMENT)>(optimal_keys, shadow_needs_shader_swizzle); + } + + equals_gfx_pipeline_state_func +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index 7e732f12c69..e97fcd16b37 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -756,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_fs_shadow_key *shadow; + bool sample_locations_enabled; + enum pipe_prim_type shader_rast_prim, rast_prim; /* reduced type or max for unknown */ + union { +@@ -834,7 +835,7 @@ struct zink_shader_module { + bool has_nonseamless; + uint8_t num_uniforms; + uint8_t key_size; +- uint8_t key[0]; /* | key | uniforms | */ ++ uint8_t key[0]; /* | key | uniforms | shadow swizzle | */ + }; + + struct zink_program { +@@ -859,6 +860,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 { +-- +2.17.1 + diff --git a/package/mesa3d/0140-zink-create-another-samplerview-for-shadow-textures.patch b/package/mesa3d/0140-zink-create-another-samplerview-for-shadow-textures.patch new file mode 100644 index 00000000..df9c2962 --- /dev/null +++ b/package/mesa3d/0140-zink-create-another-samplerview-for-shadow-textures.patch @@ -0,0 +1,148 @@ +From 7fe27696066da7f9562415fad158073a0235cb0a Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 6 Jan 2023 10:38:22 -0500 +Subject: [PATCH 140/168] zink: create another samplerview for shadow textures + +when doing legacy depth texture mode sampling, it's necessary to keep +another view that has the right (R in component 0) swizzle so that depth +values can actually be returned in cases where it would otherwise be +a constant value due to swizzling + +this also allows zink_sampler_view::shadow_needs_shader_swizzle to be removed + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 24 ++++++++++++++++++++++-- + src/gallium/drivers/zink/zink_context.h | 3 +++ + src/gallium/drivers/zink/zink_program.c | 3 +++ + src/gallium/drivers/zink/zink_types.h | 2 +- + 4 files changed, 29 insertions(+), 3 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 7dea60a0a96..73e5542d33a 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -523,6 +523,8 @@ get_imageview_for_binding(struct zink_context *ctx, gl_shader_stage stage, enum + /* 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->shadow && stage == MESA_SHADER_FRAGMENT && ctx->gfx_stages[MESA_SHADER_FRAGMENT] && ++ (ctx->di.shadow.mask & ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & BITFIELD_BIT(idx)) ? sampler_view->shadow : + sampler_view->image_view; + } + case ZINK_DESCRIPTOR_TYPE_IMAGE: { +@@ -644,6 +646,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,6 +973,7 @@ 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 && +@@ -989,7 +999,7 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres, + 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) +- sampler_view->shadow_needs_shader_swizzle = true; ++ 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); +@@ -1052,6 +1062,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->shadow = (struct zink_surface*)zink_get_surface(ctx, pres, &templ, &ivci); + } + err = !sampler_view->image_view; + } else { +@@ -1097,6 +1116,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->shadow, NULL); + } + pipe_resource_reference(&pview->texture, NULL); + FREE_CL(view); +@@ -1895,7 +1915,7 @@ zink_set_sampler_views(struct pipe_context *pctx, + update = true; + zink_batch_resource_usage_set(&ctx->batch, res, false, false); + res->obj->unordered_write = false; +- if (b->shadow_needs_shader_swizzle) { ++ if (b->shadow) { + assert(start_slot + i < 32); //bitfield size + ctx->di.shadow.mask |= BITFIELD_BIT(start_slot + i); + /* this is already gonna be slow, so don't bother trying to micro-optimize */ +diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h +index 3fd64a87e4c..e20980a335f 100644 +--- a/src/gallium/drivers/zink/zink_context.h ++++ b/src/gallium/drivers/zink/zink_context.h +@@ -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); + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 8ccd06dcd7a..568ac5c0980 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -1500,6 +1500,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) { +@@ -1517,6 +1518,8 @@ zink_bind_fs_state(struct pipe_context *pctx, + ctx->gfx_pipeline_state.rast_attachment_order = nir->info.fs.uses_fbfetch_output; + } + zink_set_fs_shadow_needs_shader_swizzle_key(ctx, false); ++ if (shadow_mask != ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask) ++ zink_update_shadow_samplerviews(ctx, shadow_mask | ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask); + } + zink_update_fbfetch(ctx); + } +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index e97fcd16b37..6e354d6db05 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -1416,7 +1416,7 @@ struct zink_sampler_view { + struct zink_buffer_view *buffer_view; + }; + struct zink_surface *cube_array; +- bool shadow_needs_shader_swizzle; ++ struct zink_surface *shadow; + struct zink_fs_shadow_swizzle swizzle; + }; + +-- +2.17.1 + diff --git a/package/mesa3d/0141-zink-remove-old-depth-swizzle-workaround.patch b/package/mesa3d/0141-zink-remove-old-depth-swizzle-workaround.patch new file mode 100644 index 00000000..455e2d9e --- /dev/null +++ b/package/mesa3d/0141-zink-remove-old-depth-swizzle-workaround.patch @@ -0,0 +1,48 @@ +From 2d141f23884d28862d890009dd4d44595e5269d6 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 4 Jan 2023 15:24:24 -0500 +Subject: [PATCH 141/168] zink: remove old depth swizzle workaround + +this is already handled in match_tex_dests(), so it does nothing here + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 22 ++++------------------ + 1 file changed, 4 insertions(+), 18 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 73e5542d33a..6457ecba6d0 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -976,24 +976,10 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres, + 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) { + VkComponentSwizzle *swizzle = (VkComponentSwizzle*)&ivci.components; + for (unsigned i = 0; i < 4; i++) { +-- +2.17.1 + diff --git a/package/mesa3d/0142-zink-pass-depth-swizzle-data-block-to-shader-compile.patch b/package/mesa3d/0142-zink-pass-depth-swizzle-data-block-to-shader-compile.patch new file mode 100644 index 00000000..9cb03a7a --- /dev/null +++ b/package/mesa3d/0142-zink-pass-depth-swizzle-data-block-to-shader-compile.patch @@ -0,0 +1,201 @@ +From bb7c1fe9802e72efb1a2a38a3d4007eeaba83bce Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 5 Jan 2023 16:49:23 -0500 +Subject: [PATCH 142/168] zink: pass depth swizzle data block to shader compile + +with everything now hooked up, this should fix all related test failures + +Part-of: +--- + .../drivers/zink/ci/zink-anv-tgl-fails.txt | 63 ------------------- + .../drivers/zink/ci/zink-lvp-fails.txt | 50 --------------- + src/gallium/drivers/zink/zink_program.c | 4 +- + 3 files changed, 2 insertions(+), 115 deletions(-) + +diff --git a/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt b/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt +index 4543d940413..36ff7cbcd6d 100644 +--- a/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt ++++ b/src/gallium/drivers/zink/ci/zink-anv-tgl-fails.txt +@@ -266,69 +266,6 @@ spec@!opengl 1.1@linestipple,Fail + # (and more) + spec@!opengl 1.1@polygon-mode,Fail + +-spec@!opengl 1.1@read-front clear-front-first,Fail +-spec@!opengl 1.1@read-front samples=16,Fail +-spec@!opengl 1.1@read-front samples=2,Fail +-spec@!opengl 1.1@read-front samples=4,Fail +-spec@!opengl 1.1@read-front samples=6,Fail +-spec@!opengl 1.1@read-front samples=8,Fail +-spec@!opengl 1.1@read-front,Fail +- +-# depth texturing: zink is returning intensity shadow comparisons and depth samples, regardless of depth mode. +-# Check out the "splat" in zink_compiler.c around !is_new_style_shadow, and the swizzle rewrite for depth +-# textures in zink_create_sampler_view(). +-spec@!opengl 2.0@depth-tex-modes-glsl,Fail +-spec@arb_depth_texture@depth-tex-modes,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_shader_texture_lod@execution@arb_shader_texture_lod-texgradcube,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_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-shadow2drect,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-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-shadow1darray,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@ext_texture_array@glsl-fs-shadow2darray,Fail +-spec@ext_texture_swizzle@depth_texture_mode_and_swizzle,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-shadow1d,Fail +-spec@glsl-1.10@execution@samplers@glsl-fs-shadow1dproj-bias,Fail +-spec@glsl-1.10@execution@samplers@glsl-fs-shadow1dproj,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-shadow2d,Fail +-spec@glsl-1.10@execution@samplers@glsl-fs-shadow2dproj-bias,Fail +-spec@glsl-1.10@execution@samplers@glsl-fs-shadow2dproj,Fail +- + spec@!opengl 2.0@gl-2.0-edgeflag-immediate,Fail + spec@!opengl 2.0@gl-2.0-edgeflag,Fail + +diff --git a/src/gallium/drivers/zink/ci/zink-lvp-fails.txt b/src/gallium/drivers/zink/ci/zink-lvp-fails.txt +index 54d5bbc7e08..c1aa22b9704 100644 +--- a/src/gallium/drivers/zink/ci/zink-lvp-fails.txt ++++ b/src/gallium/drivers/zink/ci/zink-lvp-fails.txt +@@ -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 +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 568ac5c0980..98a3ddeff41 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -143,7 +143,7 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr + assert(ctx); //TODO async + mod = zink_shader_tcs_compile(screen, zs, patch_vertices); + } else { +- mod = zink_shader_compile(screen, zs, prog->nir[stage], key, NULL); ++ mod = zink_shader_compile(screen, zs, prog->nir[stage], key, &ctx->di.shadow); + } + if (!mod) { + FREE(zm); +@@ -256,7 +256,7 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr + 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, NULL); ++ mod = zink_shader_compile(screen, zs, prog->nir[stage], (struct zink_shader_key*)key, shadow_needs_shader_swizzle ? &ctx->di.shadow : NULL); + } + if (!mod) { + FREE(zm); +-- +2.17.1 + diff --git a/package/mesa3d/0143-zink-reorder-commands-more-aggressively.patch b/package/mesa3d/0143-zink-reorder-commands-more-aggressively.patch new file mode 100644 index 00000000..95da507d --- /dev/null +++ b/package/mesa3d/0143-zink-reorder-commands-more-aggressively.patch @@ -0,0 +1,46 @@ +From 5187ee2ffa810bf07e197a1e49cc323150fe9d56 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 24 Jan 2023 15:52:58 -0500 +Subject: [PATCH 143/168] zink: reorder commands more aggressively + +by starting resources in the unordered state in a given batch, they +gain more opportunities to be promoted to the barrier cmdbuf and avoid +breaking renderpasses + +Part-of: +--- + src/gallium/drivers/zink/zink_batch.c | 4 ++-- + src/gallium/drivers/zink/zink_resource.c | 2 ++ + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c +index b1ac83b1bd8..dd0d8e7ec3b 100644 +--- a/src/gallium/drivers/zink/zink_batch.c ++++ b/src/gallium/drivers/zink/zink_batch.c +@@ -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 */ +diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c +index 0b43f89d44e..da97fe94c29 100644 +--- a/src/gallium/drivers/zink/zink_resource.c ++++ b/src/gallium/drivers/zink/zink_resource.c +@@ -590,6 +590,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}; +-- +2.17.1 + diff --git a/package/mesa3d/0144-zink-relax-bresenhamLines-requirement-for-non-strict.patch b/package/mesa3d/0144-zink-relax-bresenhamLines-requirement-for-non-strict.patch new file mode 100644 index 00000000..23ce51aa --- /dev/null +++ b/package/mesa3d/0144-zink-relax-bresenhamLines-requirement-for-non-strict.patch @@ -0,0 +1,188 @@ +From 4a3871417d26c9f2d214b49930886a0e16f05f69 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 10 Nov 2022 22:46:49 +0000 +Subject: [PATCH 144/168] zink: relax bresenhamLines requirement for + non-strictLine drivers + +non-strictLine Vulkan drivers use either parallelogram or bresenham +rasterization for default line modes. +This method of rasterisation produces close enough results that it +in practice is GL/GLES spec compliant (at least cts wise). +Don't emit a feature missing warning for this case. + +cc: mesa-stable + +Part-of: +--- + .../drivers/zink/VP_ZINK_requirements.json | 37 +++++++++++++++---- + src/gallium/drivers/zink/zink_pipeline.c | 7 +++- + 2 files changed, 35 insertions(+), 9 deletions(-) + +diff --git a/src/gallium/drivers/zink/VP_ZINK_requirements.json b/src/gallium/drivers/zink/VP_ZINK_requirements.json +index 8bd5eb85d40..ab41389f08b 100644 +--- a/src/gallium/drivers/zink/VP_ZINK_requirements.json ++++ b/src/gallium/drivers/zink/VP_ZINK_requirements.json +@@ -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 +@@ -576,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": { +@@ -588,6 +599,7 @@ + "vulkan10requirements", + "gl21_baseline", + [ "gl21_baseline_vk10", "gl21_baseline_vk12" ], ++ [ "gl21_baseline_line_bresenham", "gl21_baseline_line_non_strict" ], + "gl30_baseline" + ] + }, +@@ -600,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" + ] +@@ -613,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" +@@ -627,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", +@@ -642,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", +@@ -658,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", +@@ -675,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", +@@ -694,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", +@@ -715,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", +@@ -737,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", +@@ -760,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", +@@ -784,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", +diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c +index e7e0e567175..0e30e4eac80 100644 +--- a/src/gallium/drivers/zink/zink_pipeline.c ++++ b/src/gallium/drivers/zink/zink_pipeline.c +@@ -301,9 +301,12 @@ 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 ++ /* 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 || screen->info.props.limits.strictLines) + warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][0]); +- } else ++ } else if (mode_idx || screen->info.props.limits.strictLines) + warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][hw_rast_state->line_stipple_enable]); + } + +-- +2.17.1 + diff --git a/package/mesa3d/0145-zink-set-PIPE_CAP_SURFACE_REINTERPRET_BLOCKS.patch b/package/mesa3d/0145-zink-set-PIPE_CAP_SURFACE_REINTERPRET_BLOCKS.patch new file mode 100644 index 00000000..58d11395 --- /dev/null +++ b/package/mesa3d/0145-zink-set-PIPE_CAP_SURFACE_REINTERPRET_BLOCKS.patch @@ -0,0 +1,47 @@ +From ddc569368babf7ee8ebd3fb558fa78fe88b2b417 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 9 Feb 2023 09:22:14 -0500 +Subject: [PATCH 145/168] zink: set PIPE_CAP_SURFACE_REINTERPRET_BLOCKS + +this fixes perf for CompressedTexSubImage and makes DOOM2016 run at full speed + +ref #8223 + +Part-of: +--- + src/gallium/drivers/zink/zink_resource.c | 4 ++++ + src/gallium/drivers/zink/zink_screen.c | 3 +++ + 2 files changed, 7 insertions(+) + +diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c +index da97fe94c29..65e404d532b 100644 +--- a/src/gallium/drivers/zink/zink_resource.c ++++ b/src/gallium/drivers/zink/zink_resource.c +@@ -460,6 +460,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; + +diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c +index 0d15f30e467..136dc401874 100644 +--- a/src/gallium/drivers/zink/zink_screen.c ++++ b/src/gallium/drivers/zink/zink_screen.c +@@ -512,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: +-- +2.17.1 + diff --git a/package/mesa3d/0146-zink-ralloc-zink_shader-structs.patch b/package/mesa3d/0146-zink-ralloc-zink_shader-structs.patch new file mode 100644 index 00000000..725dc946 --- /dev/null +++ b/package/mesa3d/0146-zink-ralloc-zink_shader-structs.patch @@ -0,0 +1,45 @@ +From ff17c395cbbedf67dbfea68773bcbe920e4a0cd1 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 6 Feb 2023 15:50:06 -0500 +Subject: [PATCH 146/168] zink: ralloc zink_shader structs + +Reviewed-by: Emma Anholt +Part-of: +--- + src/gallium/drivers/zink/zink_compiler.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 35d4988b44d..ae806f45293 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -4163,7 +4163,7 @@ struct zink_shader * + zink_shader_create(struct zink_screen *screen, struct nir_shader *nir, + const struct pipe_stream_output_info *so_info) + { +- struct zink_shader *ret = CALLOC_STRUCT(zink_shader); ++ struct zink_shader *ret = rzalloc(NULL, struct zink_shader); + bool have_psiz = false; + + ret->sinfo.have_vulkan_memory_model = screen->info.have_KHR_vulkan_memory_model; +@@ -4464,7 +4464,7 @@ zink_shader_free(struct zink_screen *screen, struct zink_shader *shader) + _mesa_set_destroy(shader->programs, NULL); + ralloc_free(shader->nir); + ralloc_free(shader->spirv); +- FREE(shader); ++ ralloc_free(shader); + } + + +@@ -4501,7 +4501,7 @@ void main() + struct zink_shader * + zink_shader_tcs_create(struct zink_screen *screen, struct zink_shader *vs, unsigned vertices_per_patch) + { +- struct zink_shader *ret = CALLOC_STRUCT(zink_shader); ++ struct zink_shader *ret = rzalloc(NULL, struct zink_shader); + ret->hash = _mesa_hash_pointer(ret); + ret->programs = _mesa_pointer_set_create(NULL); + simple_mtx_init(&ret->lock, mtx_plain); +-- +2.17.1 + diff --git a/package/mesa3d/0147-zink-fix-compute-shader-leaks.patch b/package/mesa3d/0147-zink-fix-compute-shader-leaks.patch new file mode 100644 index 00000000..3d467fd5 --- /dev/null +++ b/package/mesa3d/0147-zink-fix-compute-shader-leaks.patch @@ -0,0 +1,37 @@ +From 5dd981324ab578e738a543e9d50ce44442caabcd Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Sun, 12 Feb 2023 00:36:29 +0000 +Subject: [PATCH 147/168] zink: fix compute shader leaks + +Compute program owns the nir and zink shaders now and must free them +too when destroyed. + +Fixes: 4cb4bb555e7 ("zink: create compute programs from compute shaders directly") +Part-of: +--- + src/gallium/drivers/zink/zink_program.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 98a3ddeff41..14a21d6b901 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -1243,8 +1243,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]); + +-- +2.17.1 + diff --git a/package/mesa3d/0148-zink-allocate-program-shader-caches-from-the-program.patch b/package/mesa3d/0148-zink-allocate-program-shader-caches-from-the-program.patch new file mode 100644 index 00000000..d323aca7 --- /dev/null +++ b/package/mesa3d/0148-zink-allocate-program-shader-caches-from-the-program.patch @@ -0,0 +1,48 @@ +From ef516e97c3d9ee6cc80f4d6d4576814f11a321e4 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Sun, 12 Feb 2023 17:05:15 +0000 +Subject: [PATCH 148/168] zink: allocate program shader caches from the + program's mem ctx + +these will now be freed when the program itself is freed. + +cc: mesa-stable + +Part-of: +--- + src/gallium/drivers/zink/zink_program.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 14a21d6b901..828200959a1 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -901,10 +901,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); +@@ -1026,8 +1026,8 @@ precompile_compute_job(void *data, void *gdata, int thread_index) + assert(comp->module); + 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); +-- +2.17.1 + diff --git a/package/mesa3d/0149-zink-free-resource-objects-views-array-during-destru.patch b/package/mesa3d/0149-zink-free-resource-objects-views-array-during-destru.patch new file mode 100644 index 00000000..b5f8de09 --- /dev/null +++ b/package/mesa3d/0149-zink-free-resource-objects-views-array-during-destru.patch @@ -0,0 +1,30 @@ +From dc1ce8e5fadea1a4e26412c974b3a1f6fa8e2ddc Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 13 Feb 2023 14:38:26 +0000 +Subject: [PATCH 149/168] zink: free resource objects' views array during + destruction + +since the array is not ralloc managed, it has be explicitly freed. + +cc: mesa-stable + +Part-of: +--- + src/gallium/drivers/zink/zink_resource.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c +index 65e404d532b..9b544270885 100644 +--- a/src/gallium/drivers/zink/zink_resource.c ++++ b/src/gallium/drivers/zink/zink_resource.c +@@ -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); +-- +2.17.1 + diff --git a/package/mesa3d/0150-zink-fix-indentation-of-rebind_image.patch b/package/mesa3d/0150-zink-fix-indentation-of-rebind_image.patch new file mode 100644 index 00000000..a25abcf9 --- /dev/null +++ b/package/mesa3d/0150-zink-fix-indentation-of-rebind_image.patch @@ -0,0 +1,76 @@ +From b6323160762cb17195b72bada94d1398cd5f8db3 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 13 Feb 2023 14:52:33 -0500 +Subject: [PATCH 150/168] zink: fix indentation of rebind_image() + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 52 ++++++++++++------------- + 1 file changed, 26 insertions(+), 26 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 6457ecba6d0..ff977d9e141 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -4563,32 +4563,32 @@ 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); +- } +- } +- } ++ 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 +-- +2.17.1 + diff --git a/package/mesa3d/0151-zink-only-try-for-a-fb-rebind-if-fb-binds-exist-in-r.patch b/package/mesa3d/0151-zink-only-try-for-a-fb-rebind-if-fb-binds-exist-in-r.patch new file mode 100644 index 00000000..42410dbb --- /dev/null +++ b/package/mesa3d/0151-zink-only-try-for-a-fb-rebind-if-fb-binds-exist-in-r.patch @@ -0,0 +1,28 @@ +From f738d23f819c20855bab42c76ae22d9cef3a8611 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 13 Feb 2023 14:52:57 -0500 +Subject: [PATCH 151/168] zink: only try for a fb rebind if fb binds exist in + rebind_image() + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index ff977d9e141..394b15d7158 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -4563,7 +4563,8 @@ 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 (res->fb_binds) ++ zink_rebind_framebuffer(ctx, res); + if (!zink_resource_has_binds(res)) + return; + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { +-- +2.17.1 + diff --git a/package/mesa3d/0152-zink-account-for-null-surface-when-trying-to-retain-.patch b/package/mesa3d/0152-zink-account-for-null-surface-when-trying-to-retain-.patch new file mode 100644 index 00000000..b00fd517 --- /dev/null +++ b/package/mesa3d/0152-zink-account-for-null-surface-when-trying-to-retain-.patch @@ -0,0 +1,29 @@ +From d72c83c7829af33fdc48a493d776e34652127bdf Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 13 Feb 2023 14:53:43 -0500 +Subject: [PATCH 152/168] zink: account for null surface when trying to retain + clears on fb bind + +not currently possible but will be soon + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 394b15d7158..4589a3a793a 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -2993,7 +2993,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) +-- +2.17.1 + diff --git a/package/mesa3d/0153-zink-break-out-pipe_surface-init-for-new-surface-cre.patch b/package/mesa3d/0153-zink-break-out-pipe_surface-init-for-new-surface-cre.patch new file mode 100644 index 00000000..5a4d9c84 --- /dev/null +++ b/package/mesa3d/0153-zink-break-out-pipe_surface-init-for-new-surface-cre.patch @@ -0,0 +1,69 @@ +From 0a5c4c9a97a0ba8faaa210c82281543b874b6b68 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 13 Feb 2023 14:55:14 -0500 +Subject: [PATCH 153/168] zink: break out pipe_surface init for new surface + creation + +no functional changes + +Part-of: +--- + src/gallium/drivers/zink/zink_surface.c | 28 +++++++++++++++---------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_surface.c b/src/gallium/drivers/zink/zink_surface.c +index d0afa8e5971..73b3decb99a 100644 +--- a/src/gallium/drivers/zink/zink_surface.c ++++ b/src/gallium/drivers/zink/zink_surface.c +@@ -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); +-- +2.17.1 + diff --git a/package/mesa3d/0154-zink-const-ify-a-surface-param.patch b/package/mesa3d/0154-zink-const-ify-a-surface-param.patch new file mode 100644 index 00000000..319ed780 --- /dev/null +++ b/package/mesa3d/0154-zink-const-ify-a-surface-param.patch @@ -0,0 +1,26 @@ +From 4157166b9e83e748c97801c93c11bac6675d69f9 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 13 Feb 2023 14:55:31 -0500 +Subject: [PATCH 154/168] zink: const-ify a surface param + +Part-of: +--- + src/gallium/drivers/zink/zink_surface.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_surface.c b/src/gallium/drivers/zink/zink_surface.c +index 73b3decb99a..5381e54b261 100644 +--- a/src/gallium/drivers/zink/zink_surface.c ++++ b/src/gallium/drivers/zink/zink_surface.c +@@ -253,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; +-- +2.17.1 + diff --git a/package/mesa3d/0155-zink-don-t-handle-mutable-init-on-surface-creation-w.patch b/package/mesa3d/0155-zink-don-t-handle-mutable-init-on-surface-creation-w.patch new file mode 100644 index 00000000..f5688f99 --- /dev/null +++ b/package/mesa3d/0155-zink-don-t-handle-mutable-init-on-surface-creation-w.patch @@ -0,0 +1,133 @@ +From 150597ede7176416053dfd65bde0850e3c52a862 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 13 Feb 2023 14:56:06 -0500 +Subject: [PATCH 155/168] zink: don't handle mutable init on surface creation + with tc enabled + +using the cmdbuf during this call is illegal and causes desync, thus +the initialization has to be deferred until the surface is bound + +fixes #7579 + +Part-of: +--- + src/gallium/drivers/zink/zink_context.c | 18 +++++++++++++++++ + src/gallium/drivers/zink/zink_surface.c | 26 +++++++++++++++++++++---- + src/gallium/drivers/zink/zink_types.h | 1 + + 3 files changed, 41 insertions(+), 4 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 4589a3a793a..fb790450c5b 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -2970,6 +2970,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) +@@ -3056,6 +3072,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) { +@@ -3085,6 +3102,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) +diff --git a/src/gallium/drivers/zink/zink_surface.c b/src/gallium/drivers/zink/zink_surface.c +index 5381e54b261..0ac38252250 100644 +--- a/src/gallium/drivers/zink/zink_surface.c ++++ b/src/gallium/drivers/zink/zink_surface.c +@@ -272,10 +272,18 @@ 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); ++ } ++ ++ 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; +@@ -291,12 +299,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) { +@@ -358,6 +373,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); +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index 6e354d6db05..d6084b27e39 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -1346,6 +1346,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 */ +-- +2.17.1 + diff --git a/package/mesa3d/0156-zink-verify-compressed-format-layer-count-when-creat.patch b/package/mesa3d/0156-zink-verify-compressed-format-layer-count-when-creat.patch new file mode 100644 index 00000000..68d1bb44 --- /dev/null +++ b/package/mesa3d/0156-zink-verify-compressed-format-layer-count-when-creat.patch @@ -0,0 +1,38 @@ +From 116763f11d5a1415a6c999b5149401aa1e33a39d Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 13 Feb 2023 16:43:21 -0500 +Subject: [PATCH 156/168] zink: verify compressed format layer count when + creating surfaces + +this is illegal for some cases, and mesa/st is equipped to handle +per-layer copying here + +fixes #8283 + +Part-of: +--- + src/gallium/drivers/zink/zink_surface.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/gallium/drivers/zink/zink_surface.c b/src/gallium/drivers/zink/zink_surface.c +index 0ac38252250..9b4c86e6517 100644 +--- a/src/gallium/drivers/zink/zink_surface.c ++++ b/src/gallium/drivers/zink/zink_surface.c +@@ -277,6 +277,14 @@ zink_create_surface(struct pipe_context *pctx, + 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) { +-- +2.17.1 + diff --git a/package/mesa3d/0157-Kopper-Fix-unsupport-DRM-format-modifier-being-intre.patch b/package/mesa3d/0157-Kopper-Fix-unsupport-DRM-format-modifier-being-intre.patch new file mode 100644 index 00000000..a5065c94 --- /dev/null +++ b/package/mesa3d/0157-Kopper-Fix-unsupport-DRM-format-modifier-being-intre.patch @@ -0,0 +1,28 @@ +From 10854f30d380f8cd500893e9eac37c0ac3c48819 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 22 Jul 2022 13:00:14 +0100 +Subject: [PATCH 157/168] Kopper: Fix unsupport DRM format modifier being + intrepreted as use internal + +If X server does not have DRM format modifiers enables, it returns invalid format. +This being returned for glXBindTexImageEXT means to use native (linear) format. +--- + src/gallium/frontends/dri/kopper.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/gallium/frontends/dri/kopper.c b/src/gallium/frontends/dri/kopper.c +index 5268f1fb9fb..54273647cc1 100644 +--- a/src/gallium/frontends/dri/kopper.c ++++ b/src/gallium/frontends/dri/kopper.c +@@ -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 */ +-- +2.17.1 + diff --git a/package/mesa3d/0158-zink-fix-incorrect-line-mode-check-for-bresenham.patch b/package/mesa3d/0158-zink-fix-incorrect-line-mode-check-for-bresenham.patch new file mode 100644 index 00000000..39c0cb14 --- /dev/null +++ b/package/mesa3d/0158-zink-fix-incorrect-line-mode-check-for-bresenham.patch @@ -0,0 +1,30 @@ +From ffd15cd3d77f33bb9db6c063282e96ef16a1148d Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 16 Feb 2023 09:43:40 +0000 +Subject: [PATCH 158/168] zink: fix incorrect line mode check for bresenham + +the line requirement check logic was assuming mode index 0 +is bresenhamLines, but it is actually rectangularLines. +--- + src/gallium/drivers/zink/zink_pipeline.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c +index 0e30e4eac80..d31188ca0ff 100644 +--- a/src/gallium/drivers/zink/zink_pipeline.c ++++ b/src/gallium/drivers/zink/zink_pipeline.c +@@ -304,9 +304,9 @@ zink_create_gfx_pipeline(struct zink_screen *screen, + /* 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 || screen->info.props.limits.strictLines) ++ 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 || screen->info.props.limits.strictLines) ++ } 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]); + } + +-- +2.17.1 + diff --git a/package/mesa3d/0159-zink-disable-implicit_sync-for-IMG-driver.patch b/package/mesa3d/0159-zink-disable-implicit_sync-for-IMG-driver.patch new file mode 100644 index 00000000..e27ceb6d --- /dev/null +++ b/package/mesa3d/0159-zink-disable-implicit_sync-for-IMG-driver.patch @@ -0,0 +1,26 @@ +From 39bf13e1df264c3c5af6055adae2c3e8e783d02c Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Thu, 16 Feb 2023 09:46:15 +0000 +Subject: [PATCH 159/168] zink: disable implicit_sync for IMG driver + +IMG proprietary driver also uses mesa WSI and so +does not need implicit sync. +--- + src/gallium/drivers/zink/zink_screen.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c +index 136dc401874..8c27198c599 100644 +--- a/src/gallium/drivers/zink/zink_screen.c ++++ b/src/gallium/drivers/zink/zink_screen.c +@@ -2305,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: +-- +2.17.1 + diff --git a/package/mesa3d/0160-zink-fix-shadow-mask-change-logic-when-binding-sampl.patch b/package/mesa3d/0160-zink-fix-shadow-mask-change-logic-when-binding-sampl.patch new file mode 100644 index 00000000..041a2d1c --- /dev/null +++ b/package/mesa3d/0160-zink-fix-shadow-mask-change-logic-when-binding-sampl.patch @@ -0,0 +1,80 @@ +From 28b9e5acb6cb438fff527af5120ff102bb829576 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Sat, 25 Feb 2023 22:19:49 +0000 +Subject: [PATCH 160/168] zink: fix shadow mask change logic when binding + sampler views + +First make sure shadow mask change sets dirty state. +Second move shadow mask bit removal to unbind_samplerview which +is cleaner and correctly clears the shadow bit when binding buffer texture. + +Fixes: 5193f4f712b ("zink: add a fs shader key member to indicate depth texturing mode") +--- + src/gallium/drivers/zink/zink_context.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index fb790450c5b..a6284cd39f4 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -1828,6 +1828,10 @@ unbind_samplerview(struct zink_context *ctx, gl_shader_stage stage, unsigned slo + unbind_descriptor_stage(res, stage); + unbind_descriptor_reads(res, stage); + } ++ if (stage == MESA_SHADER_FRAGMENT) { ++ assert(slot < 32); ++ ctx->di.shadow.mask &= ~BITFIELD_BIT(slot); ++ } + } + + static void +@@ -1843,6 +1847,7 @@ 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.shadow.mask; + ctx->di.cubes[shader_type] &= ~mask; + + bool update = false; +@@ -1908,7 +1913,7 @@ zink_set_sampler_views(struct pipe_context *pctx, + shadow_update |= memcmp(&ctx->di.shadow.swizzle[start_slot + i], + &b->swizzle, sizeof(struct zink_fs_shadow_swizzle)); + memcpy(&ctx->di.shadow.swizzle[start_slot + i], &b->swizzle, sizeof(struct zink_fs_shadow_swizzle)); +- } else if (ctx->di.shadow.mask) { ++ } else if (shader_type == MESA_SHADER_FRAGMENT) { + assert(start_slot + i < 32); //bitfield size + ctx->di.shadow.mask &= ~BITFIELD_BIT(start_slot + i); + } +@@ -1918,10 +1923,6 @@ zink_set_sampler_views(struct pipe_context *pctx, + } else if (a) { + unbind_samplerview(ctx, shader_type, start_slot + i); + update = true; +- if (ctx->di.shadow.mask) { +- assert(start_slot + i < 32); //bitfield size +- ctx->di.shadow.mask &= ~BITFIELD_BIT(start_slot + i); +- } + } + if (take_ownership) { + pipe_sampler_view_reference(&ctx->sampler_views[shader_type][start_slot + i], NULL); +@@ -1938,10 +1939,6 @@ zink_set_sampler_views(struct pipe_context *pctx, + &ctx->sampler_views[shader_type][start_slot + i], + NULL); + update_descriptor_state_sampler(ctx, shader_type, start_slot + i, NULL); +- if (ctx->di.shadow.mask) { +- assert(start_slot + i < 32); //bitfield size +- ctx->di.shadow.mask &= ~BITFIELD_BIT(start_slot + i); +- } + } + ctx->di.num_sampler_views[shader_type] = start_slot + num_views; + if (update) { +@@ -1949,6 +1946,7 @@ 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.shadow.mask; + zink_set_fs_shadow_needs_shader_swizzle_key(ctx, shadow_update); + } + } +-- +2.17.1 + diff --git a/package/mesa3d/0161-zink-track-shadow-swizzle-for-all-shader-stages.patch b/package/mesa3d/0161-zink-track-shadow-swizzle-for-all-shader-stages.patch new file mode 100644 index 00000000..c0af7207 --- /dev/null +++ b/package/mesa3d/0161-zink-track-shadow-swizzle-for-all-shader-stages.patch @@ -0,0 +1,167 @@ +From a2e1ac2f866579552f2deb4f3746b3c01b27d76d Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Sat, 25 Feb 2023 22:27:30 +0000 +Subject: [PATCH 161/168] zink: track shadow swizzle for all shader stages + +this will be used later on to enable the pass in all +shader stages. +--- + src/gallium/drivers/zink/zink_context.c | 22 ++++++++++------------ + src/gallium/drivers/zink/zink_program.c | 14 +++++++------- + src/gallium/drivers/zink/zink_program.h | 2 +- + src/gallium/drivers/zink/zink_types.h | 2 +- + 4 files changed, 19 insertions(+), 21 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index a6284cd39f4..60de3771837 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -524,7 +524,7 @@ get_imageview_for_binding(struct zink_context *ctx, gl_shader_stage stage, enum + return (ctx->di.emulate_nonseamless[stage] & ctx->di.cubes[stage] & BITFIELD_BIT(idx)) ? + sampler_view->cube_array : + sampler_view->shadow && stage == MESA_SHADER_FRAGMENT && ctx->gfx_stages[MESA_SHADER_FRAGMENT] && +- (ctx->di.shadow.mask & ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & BITFIELD_BIT(idx)) ? sampler_view->shadow : ++ (ctx->di.shadow[MESA_SHADER_FRAGMENT].mask & ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & BITFIELD_BIT(idx)) ? sampler_view->shadow : + sampler_view->image_view; + } + case ZINK_DESCRIPTOR_TYPE_IMAGE: { +@@ -1828,10 +1828,8 @@ unbind_samplerview(struct zink_context *ctx, gl_shader_stage stage, unsigned slo + unbind_descriptor_stage(res, stage); + unbind_descriptor_reads(res, stage); + } +- if (stage == MESA_SHADER_FRAGMENT) { +- assert(slot < 32); +- ctx->di.shadow.mask &= ~BITFIELD_BIT(slot); +- } ++ assert(slot < 32); ++ ctx->di.shadow[stage].mask &= ~BITFIELD_BIT(slot); + } + + static void +@@ -1847,7 +1845,7 @@ 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.shadow.mask; ++ uint32_t shadow_mask = ctx->di.shadow[shader_type].mask; + ctx->di.cubes[shader_type] &= ~mask; + + bool update = false; +@@ -1908,14 +1906,14 @@ zink_set_sampler_views(struct pipe_context *pctx, + res->obj->unordered_write = false; + if (b->shadow) { + assert(start_slot + i < 32); //bitfield size +- ctx->di.shadow.mask |= BITFIELD_BIT(start_slot + i); ++ ctx->di.shadow[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.shadow.swizzle[start_slot + i], ++ shadow_update |= memcmp(&ctx->di.shadow[shader_type].swizzle[start_slot + i], + &b->swizzle, sizeof(struct zink_fs_shadow_swizzle)); +- memcpy(&ctx->di.shadow.swizzle[start_slot + i], &b->swizzle, sizeof(struct zink_fs_shadow_swizzle)); +- } else if (shader_type == MESA_SHADER_FRAGMENT) { ++ memcpy(&ctx->di.shadow[shader_type].swizzle[start_slot + i], &b->swizzle, sizeof(struct zink_fs_shadow_swizzle)); ++ } else { + assert(start_slot + i < 32); //bitfield size +- ctx->di.shadow.mask &= ~BITFIELD_BIT(start_slot + i); ++ ctx->di.shadow[shader_type].mask &= ~BITFIELD_BIT(start_slot + i); + } + } + res->sampler_binds[shader_type] |= BITFIELD_BIT(start_slot + i); +@@ -1946,7 +1944,7 @@ 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.shadow.mask; ++ shadow_update |= shadow_mask != ctx->di.shadow[shader_type].mask; + zink_set_fs_shadow_needs_shader_swizzle_key(ctx, shadow_update); + } + } +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 828200959a1..7103e814a92 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -143,7 +143,7 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr + assert(ctx); //TODO async + mod = zink_shader_tcs_compile(screen, zs, patch_vertices); + } else { +- mod = zink_shader_compile(screen, zs, prog->nir[stage], key, &ctx->di.shadow); ++ mod = zink_shader_compile(screen, zs, prog->nir[stage], key, &ctx->di.shadow[stage]); + } + if (!mod) { + FREE(zm); +@@ -170,8 +170,8 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr + else + zm->hash = shader_module_hash(zm); + if (unlikely(shadow_needs_shader_swizzle)) { +- memcpy(zm->key + key->size + nonseamless_size + inline_size * sizeof(uint32_t), &ctx->di.shadow, sizeof(struct zink_fs_shadow_key)); +- zm->hash ^= _mesa_hash_data(&ctx->di.shadow, sizeof(struct zink_fs_shadow_key)); ++ memcpy(zm->key + key->size + nonseamless_size + inline_size * sizeof(uint32_t), &ctx->di.shadow[stage], sizeof(struct zink_fs_shadow_key)); ++ zm->hash ^= _mesa_hash_data(&ctx->di.shadow[stage], sizeof(struct zink_fs_shadow_key)); + } + zm->default_variant = !inline_size && !util_dynarray_contains(&prog->shader_cache[stage][0][0], void*); + if (inline_size) +@@ -210,7 +210,7 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *screen + 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.shadow, sizeof(struct zink_fs_shadow_key))) ++ &ctx->di.shadow[stage], sizeof(struct zink_fs_shadow_key))) + continue; + } + } +@@ -256,7 +256,7 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr + 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, shadow_needs_shader_swizzle ? &ctx->di.shadow : NULL); ++ mod = zink_shader_compile(screen, zs, prog->nir[stage], (struct zink_shader_key*)key, shadow_needs_shader_swizzle ? &ctx->di.shadow[stage] : NULL); + } + if (!mod) { + FREE(zm); +@@ -271,7 +271,7 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr + /* sanitize actual key bits */ + *data = (*key) & mask; + if (unlikely(shadow_needs_shader_swizzle)) +- memcpy(&data[1], &ctx->di.shadow, sizeof(struct zink_fs_shadow_key)); ++ memcpy(&data[1], &ctx->di.shadow[stage], sizeof(struct zink_fs_shadow_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); +@@ -313,7 +313,7 @@ get_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_screen + 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.shadow, sizeof(struct zink_fs_shadow_key))) ++ if (memcmp(iter->key + sizeof(uint16_t), &ctx->di.shadow[stage], sizeof(struct zink_fs_shadow_key))) + continue; + } + } +diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h +index f8f0b0777c7..b92d452fb2c 100644 +--- a/src/gallium/drivers/zink/zink_program.h ++++ b/src/gallium/drivers/zink/zink_program.h +@@ -359,7 +359,7 @@ static inline void + zink_set_fs_shadow_needs_shader_swizzle_key(struct zink_context *ctx, bool swizzle_update) + { + 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.shadow.mask) > 0; ++ bool enable = ctx->gfx_stages[MESA_SHADER_FRAGMENT] && (ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & ctx->di.shadow[MESA_SHADER_FRAGMENT].mask) > 0; + if (enable != fs->shadow_needs_shader_swizzle || (enable && swizzle_update)) + zink_set_fs_base_key(ctx)->shadow_needs_shader_swizzle = enable; + } +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index d6084b27e39..5893d359a83 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -1656,7 +1656,7 @@ struct zink_context { + VkDescriptorImageInfo fbfetch; + + /* the current state of the shadow swizzle data */ +- struct zink_fs_shadow_key shadow; ++ struct zink_fs_shadow_key shadow[MESA_SHADER_STAGES]; + + struct zink_resource *descriptor_res[ZINK_DESCRIPTOR_BASE_TYPES][MESA_SHADER_STAGES][PIPE_MAX_SAMPLERS]; + +-- +2.17.1 + diff --git a/package/mesa3d/0162-zink-minor-formatting-change.patch b/package/mesa3d/0162-zink-minor-formatting-change.patch new file mode 100644 index 00000000..328cc172 --- /dev/null +++ b/package/mesa3d/0162-zink-minor-formatting-change.patch @@ -0,0 +1,27 @@ +From e588b6effafea6be2f707f4a6d14293a033858cf Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Tue, 28 Feb 2023 10:09:46 +0000 +Subject: [PATCH 162/168] zink: minor formatting change + +that line was becoming too long. +--- + src/gallium/drivers/zink/zink_program.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h +index b92d452fb2c..cd8c04c99ec 100644 +--- a/src/gallium/drivers/zink/zink_program.h ++++ b/src/gallium/drivers/zink/zink_program.h +@@ -359,7 +359,8 @@ static inline void + zink_set_fs_shadow_needs_shader_swizzle_key(struct zink_context *ctx, bool swizzle_update) + { + 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.shadow[MESA_SHADER_FRAGMENT].mask) > 0; ++ bool enable = ctx->gfx_stages[MESA_SHADER_FRAGMENT] && ++ (ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & ctx->di.shadow[MESA_SHADER_FRAGMENT].mask) > 0; + if (enable != fs->shadow_needs_shader_swizzle || (enable && swizzle_update)) + zink_set_fs_base_key(ctx)->shadow_needs_shader_swizzle = enable; + } +-- +2.17.1 + diff --git a/package/mesa3d/0163-zink-add-needs_zs_shader_swizzle-shader-key.patch b/package/mesa3d/0163-zink-add-needs_zs_shader_swizzle-shader-key.patch new file mode 100644 index 00000000..24a9980c --- /dev/null +++ b/package/mesa3d/0163-zink-add-needs_zs_shader_swizzle-shader-key.patch @@ -0,0 +1,176 @@ +From 6119f8d9e9cf9b2872104374b8e4924f040b58fe Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 24 Feb 2023 13:55:12 +0000 +Subject: [PATCH 163/168] zink: add needs_zs_shader_swizzle shader key + +This will be used later, but for now it should always be disabled. +--- + src/gallium/drivers/zink/zink_program.c | 38 +++++++++++++++------ + src/gallium/drivers/zink/zink_shader_keys.h | 1 + + src/gallium/drivers/zink/zink_types.h | 3 +- + 3 files changed, 31 insertions(+), 11 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 7103e814a92..c333826b97f 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -59,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)) && +@@ -85,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); + } + +@@ -131,7 +134,8 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr + 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->non_fs.is_generated; +- const bool shadow_needs_shader_swizzle = stage == MESA_SHADER_FRAGMENT && key->key.fs.base.shadow_needs_shader_swizzle; ++ 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_fs_shadow_key) : 0)); +@@ -162,6 +166,7 @@ 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)); +@@ -173,7 +178,7 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr + memcpy(zm->key + key->size + nonseamless_size + inline_size * sizeof(uint32_t), &ctx->di.shadow[stage], sizeof(struct zink_fs_shadow_key)); + zm->hash ^= _mesa_hash_data(&ctx->di.shadow[stage], sizeof(struct zink_fs_shadow_key)); + } +- zm->default_variant = !inline_size && !util_dynarray_contains(&prog->shader_cache[stage][0][0], void*); ++ 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); +@@ -192,7 +197,8 @@ 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->non_fs.is_generated; +- const bool shadow_needs_shader_swizzle = stage == MESA_SHADER_FRAGMENT && unlikely(key->key.fs.base.shadow_needs_shader_swizzle); ++ 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 *); +@@ -737,7 +743,7 @@ 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); +@@ -751,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_fs_shadow_key); + +- if (inline_size || nonseamless_size || zink_cs_key(key)->robust_access) { ++ 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; +@@ -762,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.shadow[MESA_SHADER_COMPUTE], zs_swizzle_size)) ++ continue; ++ } + if (i > 0) { + struct zink_shader_module *zero = pzm[0]; + pzm[0] = iter; +@@ -774,11 +788,11 @@ 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, NULL); ++ mod = zink_shader_compile(screen, zs, comp->shader->nir, key, zs_swizzle_size ? &ctx->di.shadow[MESA_SHADER_COMPUTE] : NULL); + if (!mod) { + FREE(zm); + return; +@@ -788,18 +802,22 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c + zm->key_size = key->size; + memcpy(zm->key, key, key->size); + zm->has_nonseamless = !!nonseamless_size; +- assert(nonseamless_size || inline_size || zink_cs_key(key)->robust_access); ++ 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 + zm->key_size, &key->base.nonseamless_cube_mask, nonseamless_size); + if (inline_size) + 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.shadow[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 || zink_cs_key(key)->robust_access) ++ 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) +diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h +index ccc160f0d2d..97977311270 100644 +--- a/src/gallium/drivers/zink/zink_shader_keys.h ++++ b/src/gallium/drivers/zink/zink_shader_keys.h +@@ -109,6 +109,7 @@ struct zink_cs_key { + }; + + struct zink_shader_key_base { ++ bool needs_zs_shader_swizzle; + uint32_t nonseamless_cube_mask; + uint32_t inlined_uniform_values[MAX_INLINABLE_UNIFORMS]; + }; +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index 5893d359a83..dbb3322d35f 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -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 | shadow swizzle | */ ++ uint8_t key[0]; /* | key | uniforms | zs shader swizzle | */ + }; + + struct zink_program { +-- +2.17.1 + diff --git a/package/mesa3d/0164-zink-extend-shadow-swizzle-pass-to-all-zs-textures.patch b/package/mesa3d/0164-zink-extend-shadow-swizzle-pass-to-all-zs-textures.patch new file mode 100644 index 00000000..36498158 --- /dev/null +++ b/package/mesa3d/0164-zink-extend-shadow-swizzle-pass-to-all-zs-textures.patch @@ -0,0 +1,159 @@ +From c1a6f6d63de53ec0d845e6450089b8bdf5057849 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Sun, 26 Feb 2023 17:48:53 +0000 +Subject: [PATCH 164/168] zink: extend shadow swizzle pass to all zs textures + +if needs_zs_shader_swizzle is used, apply constant swizzles to all +depth/stencil textures and not just shadow samplers. +--- + src/gallium/drivers/zink/zink_compiler.c | 83 +++++++++++++++++++----- + 1 file changed, 68 insertions(+), 15 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index ae806f45293..420e2b7a791 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2935,14 +2935,26 @@ rewrite_tex_dest(nir_builder *b, nir_tex_instr *tex, nir_variable *var, void *da + return dest; + } + ++struct lower_zs_swizzle_state { ++ bool shadow_only; ++ unsigned base_sampler_id; ++ const struct zink_fs_shadow_key *swizzle; ++}; ++ + static bool +-lower_shadow_tex_instr(nir_builder *b, nir_instr *instr, void *data) ++lower_zs_swizzle_tex_instr(nir_builder *b, nir_instr *instr, void *data) + { +- struct zink_fs_shadow_key *shadow = data; ++ struct lower_zs_swizzle_state *state = data; ++ const struct zink_fs_shadow_key *swizzle_key = state->swizzle; ++ assert(state->shadow_only || swizzle_key); + if (instr->type != nir_instr_type_tex) + return false; + nir_tex_instr *tex = nir_instr_as_tex(instr); +- if (tex->op == nir_texop_txs || tex->op == nir_texop_lod || !tex->is_shadow || tex->is_new_style_shadow) ++ if (tex->op == nir_texop_txs || tex->op == nir_texop_lod || ++ (!tex->is_shadow && state->shadow_only) || tex->is_new_style_shadow) ++ return false; ++ if (tex->is_shadow && tex->op == nir_texop_tg4) ++ /* Will not even try to emulate the shadow comparison */ + return false; + int handle = nir_tex_instr_src_index(tex, nir_tex_src_texture_handle); + nir_variable *var = NULL; +@@ -2960,31 +2972,66 @@ lower_shadow_tex_instr(nir_builder *b, nir_instr *instr, void *data) + } + } + assert(var); +- uint32_t sampler_id = var->data.binding - (PIPE_MAX_SAMPLERS * MESA_SHADER_FRAGMENT); ++ uint32_t sampler_id = var->data.binding - state->base_sampler_id; ++ const struct glsl_type *type = glsl_without_array(var->type); ++ enum glsl_base_type ret_type = glsl_get_sampler_result_type(type); ++ bool is_int = glsl_base_type_is_integer(ret_type); + unsigned num_components = nir_dest_num_components(tex->dest); ++ if (tex->is_shadow) ++ tex->is_new_style_shadow = true; + nir_ssa_def *dest = rewrite_tex_dest(b, tex, var, NULL); +- assert(!tex->is_new_style_shadow); +- tex->dest.ssa.num_components = 1; +- tex->is_new_style_shadow = true; +- if (shadow && (shadow->mask & BITFIELD_BIT(sampler_id))) { ++ assert(dest || !state->shadow_only); ++ if (!dest && !(swizzle_key->mask & BITFIELD_BIT(sampler_id))) ++ return false; ++ else if (!dest) ++ dest = &tex->dest.ssa; ++ else ++ tex->dest.ssa.num_components = 1; ++ if (swizzle_key && (swizzle_key->mask & BITFIELD_BIT(sampler_id))) { + /* these require manual swizzles */ ++ if (tex->op == nir_texop_tg4) { ++ assert(!tex->is_shadow); ++ nir_ssa_def *swizzle; ++ switch (swizzle_key->swizzle[sampler_id].s[tex->component]) { ++ case PIPE_SWIZZLE_0: ++ swizzle = nir_imm_zero(b, 4, nir_dest_bit_size(tex->dest)); ++ break; ++ case PIPE_SWIZZLE_1: ++ if (is_int) ++ swizzle = nir_imm_intN_t(b, 4, nir_dest_bit_size(tex->dest)); ++ else ++ swizzle = nir_imm_floatN_t(b, 4, nir_dest_bit_size(tex->dest)); ++ break; ++ default: ++ if (!tex->component) ++ return false; ++ tex->component = 0; ++ return true; ++ } ++ nir_ssa_def_rewrite_uses_after(dest, swizzle, swizzle->parent_instr); ++ return true; ++ } + nir_ssa_def *vec[4]; + for (unsigned i = 0; i < ARRAY_SIZE(vec); i++) { +- switch (shadow->swizzle[sampler_id].s[i]) { ++ switch (swizzle_key->swizzle[sampler_id].s[i]) { + case PIPE_SWIZZLE_0: + vec[i] = nir_imm_zero(b, 1, nir_dest_bit_size(tex->dest)); + break; + case PIPE_SWIZZLE_1: +- vec[i] = nir_imm_floatN_t(b, 1, nir_dest_bit_size(tex->dest)); ++ if (is_int) ++ vec[i] = nir_imm_intN_t(b, 1, nir_dest_bit_size(tex->dest)); ++ else ++ vec[i] = nir_imm_floatN_t(b, 1, nir_dest_bit_size(tex->dest)); + break; + default: +- vec[i] = dest; ++ vec[i] = dest->num_components == 1 ? dest : nir_channel(b, dest, i); + break; + } + } + nir_ssa_def *swizzle = nir_vec(b, vec, num_components); + nir_ssa_def_rewrite_uses_after(dest, swizzle, swizzle->parent_instr); + } else { ++ assert(tex->is_shadow); + nir_ssa_def *vec[4] = {dest, dest, dest, dest}; + nir_ssa_def *splat = nir_vec(b, vec, num_components); + nir_ssa_def_rewrite_uses_after(dest, splat, splat->parent_instr); +@@ -2993,9 +3040,11 @@ lower_shadow_tex_instr(nir_builder *b, nir_instr *instr, void *data) + } + + static bool +-lower_shadow_tex(nir_shader *nir, const void *shadow) ++lower_zs_swizzle_tex(nir_shader *nir, const void *swizzle, bool shadow_only) + { +- return nir_shader_instructions_pass(nir, lower_shadow_tex_instr, nir_metadata_dominance | nir_metadata_block_index, (void*)shadow); ++ unsigned base_sampler_id = gl_shader_stage_is_compute(nir->info.stage) ? 0 : PIPE_MAX_SAMPLERS * nir->info.stage; ++ struct lower_zs_swizzle_state state = {shadow_only, base_sampler_id, swizzle}; ++ return nir_shader_instructions_pass(nir, lower_zs_swizzle_tex_instr, nir_metadata_dominance | nir_metadata_block_index, (void*)&state); + } + + VkShaderModule +@@ -3124,8 +3173,8 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, + nir->info.fs.uses_sample_qualifier = true; + nir->info.fs.uses_sample_shading = true; + } +- if (zs->fs.legacy_shadow_mask) +- NIR_PASS_V(nir, lower_shadow_tex, zink_fs_key_base(key)->shadow_needs_shader_swizzle ? extra_data : NULL); ++ if (zs->fs.legacy_shadow_mask && !key->base.needs_zs_shader_swizzle) ++ NIR_PASS(need_optimize, nir, lower_zs_swizzle_tex, zink_fs_key_base(key)->shadow_needs_shader_swizzle ? extra_data : NULL, true); + if (nir->info.fs.uses_fbfetch_output) { + nir_variable *fbfetch = NULL; + NIR_PASS_V(nir, lower_fbfetch, &fbfetch, zink_fs_key_base(key)->fbfetch_ms); +@@ -3151,6 +3200,10 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, + break; + default: break; + } ++ if (key->base.needs_zs_shader_swizzle) { ++ assert(extra_data); ++ NIR_PASS(need_optimize, nir, lower_zs_swizzle_tex, extra_data, false); ++ } + if (key->base.nonseamless_cube_mask) { + NIR_PASS_V(nir, zink_lower_cubemap_to_array, key->base.nonseamless_cube_mask); + need_optimize = true; +-- +2.17.1 + diff --git a/package/mesa3d/0165-zink-add-depth-stencil-needs-shader-swizzle-workarou.patch b/package/mesa3d/0165-zink-add-depth-stencil-needs-shader-swizzle-workarou.patch new file mode 100644 index 00000000..a595971f --- /dev/null +++ b/package/mesa3d/0165-zink-add-depth-stencil-needs-shader-swizzle-workarou.patch @@ -0,0 +1,58 @@ +From 4d4ddb80d1761f0bed1a949dcaa6981a823a87b5 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Fri, 24 Feb 2023 10:04:39 +0000 +Subject: [PATCH 165/168] zink: add depth/stencil needs shader swizzle + workaround field + +--- + src/gallium/drivers/zink/zink_screen.c | 14 +++++++++++++- + src/gallium/drivers/zink/zink_types.h | 1 + + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c +index 8c27198c599..a7b720a43cf 100644 +--- a/src/gallium/drivers/zink/zink_screen.c ++++ b/src/gallium/drivers/zink/zink_screen.c +@@ -2430,6 +2430,17 @@ 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 = +@@ -2785,7 +2796,8 @@ zink_internal_create_screen(const struct pipe_screen_config *config) + !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.lower_robustImageAccess2 && ++ !screen->driver_workarounds.needs_zs_shader_swizzle; + if (!screen->optimal_keys) + screen->info.have_EXT_graphics_pipeline_library = false; + +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index dbb3322d35f..991100885d1 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -1292,6 +1292,7 @@ struct zink_screen { + 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; +-- +2.17.1 + diff --git a/package/mesa3d/0166-zink-workaround-undefined-swizzle-1-for-z-s-textures.patch b/package/mesa3d/0166-zink-workaround-undefined-swizzle-1-for-z-s-textures.patch new file mode 100644 index 00000000..888dcd94 --- /dev/null +++ b/package/mesa3d/0166-zink-workaround-undefined-swizzle-1-for-z-s-textures.patch @@ -0,0 +1,132 @@ +From b9b174b3db3fb4497f1ba066715cbce778b56798 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Sat, 25 Feb 2023 22:24:00 +0000 +Subject: [PATCH 166/168] zink: workaround undefined swizzle 1 for z/s textures + +using swizzle 1 with z/s textures returns undefined data +on some Imagination hardware. +Work around this by using the same shader swizzling used for +shadow samplers. +--- + src/gallium/drivers/zink/zink_context.c | 24 +++++++++++++-------- + src/gallium/drivers/zink/zink_program.c | 5 +++-- + src/gallium/drivers/zink/zink_program.h | 28 ++++++++++++++++--------- + 3 files changed, 36 insertions(+), 21 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 60de3771837..4965eaf1ab5 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -521,11 +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->shadow && stage == MESA_SHADER_FRAGMENT && ctx->gfx_stages[MESA_SHADER_FRAGMENT] && +- (ctx->di.shadow[MESA_SHADER_FRAGMENT].mask & ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & BITFIELD_BIT(idx)) ? sampler_view->shadow : +- 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.shadow[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.shadow[MESA_SHADER_FRAGMENT].mask & ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & BITFIELD_BIT(idx)); ++ if (sampler_view->shadow && (needs_zs_shader_swizzle || needs_shadow_shader_swizzle)) ++ return sampler_view->shadow; ++ return sampler_view->image_view; + } + case ZINK_DESCRIPTOR_TYPE_IMAGE: { + struct zink_image_view *image_view = &ctx->image_views[stage][idx]; +@@ -980,11 +984,13 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres, + 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) { ++ 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) ++ 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 */ +@@ -1944,8 +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.shadow[shader_type].mask; +- zink_set_fs_shadow_needs_shader_swizzle_key(ctx, shadow_update); ++ shadow_update |= shadow_mask != ctx->di.shadow[shader_type].mask; ++ zink_set_zs_needs_shader_swizzle_key(ctx, shader_type, shadow_update); + } + } + +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index c333826b97f..19ac2fe27bf 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -1540,8 +1540,9 @@ 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_fs_shadow_needs_shader_swizzle_key(ctx, false); +- if (shadow_mask != ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask) ++ 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); +diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h +index cd8c04c99ec..a909f6f675a 100644 +--- a/src/gallium/drivers/zink/zink_program.h ++++ b/src/gallium/drivers/zink/zink_program.h +@@ -355,16 +355,6 @@ zink_set_fs_point_coord_key(struct zink_context *ctx) + } + } + +-static inline void +-zink_set_fs_shadow_needs_shader_swizzle_key(struct zink_context *ctx, bool swizzle_update) +-{ +- 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.shadow[MESA_SHADER_FRAGMENT].mask) > 0; +- if (enable != fs->shadow_needs_shader_swizzle || (enable && swizzle_update)) +- zink_set_fs_base_key(ctx)->shadow_needs_shader_swizzle = enable; +-} +- + void + zink_set_primitive_emulation_keys(struct zink_context *ctx); + +@@ -383,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.shadow[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.shadow[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 +-- +2.17.1 + diff --git a/package/mesa3d/0167-zink-rename-shadow-key-to-zs-swizzle.patch b/package/mesa3d/0167-zink-rename-shadow-key-to-zs-swizzle.patch new file mode 100644 index 00000000..fb0b8381 --- /dev/null +++ b/package/mesa3d/0167-zink-rename-shadow-key-to-zs-swizzle.patch @@ -0,0 +1,339 @@ +From bbebb432635d620fbf37eb8c685e63be65ad9eaa Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Mon, 27 Feb 2023 13:23:59 +0000 +Subject: [PATCH 167/168] zink: rename shadow key to zs swizzle + +No functional change. + +The shadow shader swizzle pass has been extended to optionally +include all z/s textures. +Rename the structs/variables to reflect this now. +--- + src/gallium/drivers/zink/zink_compiler.c | 4 +-- + src/gallium/drivers/zink/zink_context.c | 30 ++++++++++----------- + src/gallium/drivers/zink/zink_program.c | 28 +++++++++---------- + src/gallium/drivers/zink/zink_program.h | 4 +-- + src/gallium/drivers/zink/zink_shader_keys.h | 8 +++--- + src/gallium/drivers/zink/zink_types.h | 10 +++---- + 6 files changed, 42 insertions(+), 42 deletions(-) + +diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c +index 420e2b7a791..7ce8edabbbf 100644 +--- a/src/gallium/drivers/zink/zink_compiler.c ++++ b/src/gallium/drivers/zink/zink_compiler.c +@@ -2938,14 +2938,14 @@ rewrite_tex_dest(nir_builder *b, nir_tex_instr *tex, nir_variable *var, void *da + struct lower_zs_swizzle_state { + bool shadow_only; + unsigned base_sampler_id; +- const struct zink_fs_shadow_key *swizzle; ++ const struct zink_zs_swizzle_key *swizzle; + }; + + static bool + lower_zs_swizzle_tex_instr(nir_builder *b, nir_instr *instr, void *data) + { + struct lower_zs_swizzle_state *state = data; +- const struct zink_fs_shadow_key *swizzle_key = state->swizzle; ++ const struct zink_zs_swizzle_key *swizzle_key = state->swizzle; + assert(state->shadow_only || swizzle_key); + if (instr->type != nir_instr_type_tex) + return false; +diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c +index 4965eaf1ab5..6326c2144c2 100644 +--- a/src/gallium/drivers/zink/zink_context.c ++++ b/src/gallium/drivers/zink/zink_context.c +@@ -523,12 +523,12 @@ get_imageview_for_binding(struct zink_context *ctx, gl_shader_stage stage, enum + /* if this is a non-seamless cube sampler, return the cube array 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.shadow[stage].mask & BITFIELD_BIT(idx)) && ++ 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.shadow[MESA_SHADER_FRAGMENT].mask & ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & BITFIELD_BIT(idx)); +- if (sampler_view->shadow && (needs_zs_shader_swizzle || needs_shadow_shader_swizzle)) +- return sampler_view->shadow; ++ (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: { +@@ -1062,7 +1062,7 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres, + ivci.components.g = VK_COMPONENT_SWIZZLE_R; + ivci.components.b = VK_COMPONENT_SWIZZLE_R; + ivci.components.a = VK_COMPONENT_SWIZZLE_R; +- sampler_view->shadow = (struct zink_surface*)zink_get_surface(ctx, pres, &templ, &ivci); ++ sampler_view->zs_view = (struct zink_surface*)zink_get_surface(ctx, pres, &templ, &ivci); + } + err = !sampler_view->image_view; + } else { +@@ -1108,7 +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->shadow, NULL); ++ zink_surface_reference(zink_screen(pctx->screen), &view->zs_view, NULL); + } + pipe_resource_reference(&pview->texture, NULL); + FREE_CL(view); +@@ -1835,7 +1835,7 @@ unbind_samplerview(struct zink_context *ctx, gl_shader_stage stage, unsigned slo + unbind_descriptor_reads(res, stage); + } + assert(slot < 32); +- ctx->di.shadow[stage].mask &= ~BITFIELD_BIT(slot); ++ ctx->di.zs_swizzle[stage].mask &= ~BITFIELD_BIT(slot); + } + + static void +@@ -1851,7 +1851,7 @@ 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.shadow[shader_type].mask; ++ uint32_t shadow_mask = ctx->di.zs_swizzle[shader_type].mask; + ctx->di.cubes[shader_type] &= ~mask; + + bool update = false; +@@ -1910,16 +1910,16 @@ zink_set_sampler_views(struct pipe_context *pctx, + update = true; + zink_batch_resource_usage_set(&ctx->batch, res, false, false); + res->obj->unordered_write = false; +- if (b->shadow) { ++ if (b->zs_view) { + assert(start_slot + i < 32); //bitfield size +- ctx->di.shadow[shader_type].mask |= BITFIELD_BIT(start_slot + i); ++ 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.shadow[shader_type].swizzle[start_slot + i], +- &b->swizzle, sizeof(struct zink_fs_shadow_swizzle)); +- memcpy(&ctx->di.shadow[shader_type].swizzle[start_slot + i], &b->swizzle, sizeof(struct zink_fs_shadow_swizzle)); ++ 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.shadow[shader_type].mask &= ~BITFIELD_BIT(start_slot + i); ++ ctx->di.zs_swizzle[shader_type].mask &= ~BITFIELD_BIT(start_slot + i); + } + } + res->sampler_binds[shader_type] |= BITFIELD_BIT(start_slot + i); +@@ -1950,7 +1950,7 @@ 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.shadow[shader_type].mask; ++ shadow_update |= shadow_mask != ctx->di.zs_swizzle[shader_type].mask; + zink_set_zs_needs_shader_swizzle_key(ctx, shader_type, shadow_update); + } + } +diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c +index 19ac2fe27bf..c0b9739a3e6 100644 +--- a/src/gallium/drivers/zink/zink_program.c ++++ b/src/gallium/drivers/zink/zink_program.c +@@ -138,7 +138,7 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr + (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_fs_shadow_key) : 0)); ++ (shadow_needs_shader_swizzle ? sizeof(struct zink_zs_swizzle_key) : 0)); + if (!zm) { + return NULL; + } +@@ -147,7 +147,7 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr + assert(ctx); //TODO async + mod = zink_shader_tcs_compile(screen, zs, patch_vertices); + } else { +- mod = zink_shader_compile(screen, zs, prog->nir[stage], key, &ctx->di.shadow[stage]); ++ mod = zink_shader_compile(screen, zs, prog->nir[stage], key, &ctx->di.zs_swizzle[stage]); + } + if (!mod) { + FREE(zm); +@@ -175,8 +175,8 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr + else + zm->hash = shader_module_hash(zm); + if (unlikely(shadow_needs_shader_swizzle)) { +- memcpy(zm->key + key->size + nonseamless_size + inline_size * sizeof(uint32_t), &ctx->di.shadow[stage], sizeof(struct zink_fs_shadow_key)); +- zm->hash ^= _mesa_hash_data(&ctx->di.shadow[stage], sizeof(struct zink_fs_shadow_key)); ++ 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) +@@ -216,7 +216,7 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *screen + 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.shadow[stage], sizeof(struct zink_fs_shadow_key))) ++ &ctx->di.zs_swizzle[stage], sizeof(struct zink_zs_swizzle_key))) + continue; + } + } +@@ -253,7 +253,7 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr + key = NULL; + } + size_t key_size = sizeof(uint16_t); +- zm = calloc(1, sizeof(struct zink_shader_module) + (key ? key_size : 0) + (unlikely(shadow_needs_shader_swizzle) ? sizeof(struct zink_fs_shadow_key) : 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; + } +@@ -262,7 +262,7 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr + 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, shadow_needs_shader_swizzle ? &ctx->di.shadow[stage] : NULL); ++ 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); +@@ -277,7 +277,7 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr + /* sanitize actual key bits */ + *data = (*key) & mask; + if (unlikely(shadow_needs_shader_swizzle)) +- memcpy(&data[1], &ctx->di.shadow[stage], sizeof(struct zink_fs_shadow_key)); ++ 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); +@@ -319,7 +319,7 @@ get_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_screen + 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.shadow[stage], sizeof(struct zink_fs_shadow_key))) ++ if (memcmp(iter->key + sizeof(uint16_t), &ctx->di.zs_swizzle[stage], sizeof(struct zink_zs_swizzle_key))) + continue; + } + } +@@ -662,7 +662,7 @@ update_gfx_program_optimal(struct zink_context *ctx, struct zink_gfx_program *pr + 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_fs_shadow_key*)pzm[0]->key + sizeof(uint16_t); ++ 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]->non_fs.is_generated && +@@ -758,7 +758,7 @@ 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_fs_shadow_key); ++ zs_swizzle_size = sizeof(struct zink_zs_swizzle_key); + + if (inline_size || nonseamless_size || zink_cs_key(key)->robust_access || zs_swizzle_size) { + struct util_dynarray *shader_cache = &comp->shader_cache[!!nonseamless_size]; +@@ -773,7 +773,7 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c + 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.shadow[MESA_SHADER_COMPUTE], zs_swizzle_size)) ++ &ctx->di.zs_swizzle[MESA_SHADER_COMPUTE], zs_swizzle_size)) + continue; + } + if (i > 0) { +@@ -792,7 +792,7 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c + if (!zm) { + return; + } +- mod = zink_shader_compile(screen, zs, comp->shader->nir, key, zs_swizzle_size ? &ctx->di.shadow[MESA_SHADER_COMPUTE] : NULL); ++ 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; +@@ -809,7 +809,7 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c + if (inline_size) + 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.shadow[MESA_SHADER_COMPUTE], 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; +diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h +index a909f6f675a..d33bbd14e47 100644 +--- a/src/gallium/drivers/zink/zink_program.h ++++ b/src/gallium/drivers/zink/zink_program.h +@@ -380,12 +380,12 @@ zink_set_zs_needs_shader_swizzle_key(struct zink_context *ctx, gl_shader_stage p + 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.shadow[pstage].mask) > 0; ++ 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.shadow[pstage].mask; ++ 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; +diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h +index 97977311270..865c03684c3 100644 +--- a/src/gallium/drivers/zink/zink_shader_keys.h ++++ b/src/gallium/drivers/zink/zink_shader_keys.h +@@ -67,13 +67,13 @@ struct zink_gs_key { + unsigned size; + }; + +-struct zink_fs_shadow_swizzle { ++struct zink_zs_swizzle { + uint8_t s[4]; + }; + +-struct zink_fs_shadow_key { ++struct zink_zs_swizzle_key { + uint32_t mask; +- struct zink_fs_shadow_swizzle swizzle[32]; ++ struct zink_zs_swizzle swizzle[32]; + }; + + struct zink_fs_key_base { +@@ -82,7 +82,7 @@ struct zink_fs_key_base { + bool force_dual_color_blend : 1; + bool force_persample_interp : 1; + bool fbfetch_ms : 1; +- bool shadow_needs_shader_swizzle : 1; //append zink_fs_shadow_key after the key data ++ bool shadow_needs_shader_swizzle : 1; //append zink_zs_swizzle_key after the key data + uint8_t pad : 2; + uint8_t coord_replace_bits; + }; +diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h +index 991100885d1..77afb1f69c9 100644 +--- a/src/gallium/drivers/zink/zink_types.h ++++ b/src/gallium/drivers/zink/zink_types.h +@@ -756,7 +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_fs_shadow_key *shadow; ++ 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 { +@@ -1419,8 +1419,8 @@ struct zink_sampler_view { + struct zink_buffer_view *buffer_view; + }; + struct zink_surface *cube_array; +- struct zink_surface *shadow; +- struct zink_fs_shadow_swizzle swizzle; ++ struct zink_surface *zs_view; ++ struct zink_zs_swizzle swizzle; + }; + + struct zink_image_view { +@@ -1657,8 +1657,8 @@ struct zink_context { + + VkDescriptorImageInfo fbfetch; + +- /* the current state of the shadow swizzle data */ +- struct zink_fs_shadow_key shadow[MESA_SHADER_STAGES]; ++ /* 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]; + +-- +2.17.1 + diff --git a/package/mesa3d/0168-kopper-add-compatibility-to-old-style-DRI-interface.patch b/package/mesa3d/0168-kopper-add-compatibility-to-old-style-DRI-interface.patch new file mode 100644 index 00000000..cadef182 --- /dev/null +++ b/package/mesa3d/0168-kopper-add-compatibility-to-old-style-DRI-interface.patch @@ -0,0 +1,31 @@ +From 47d0406885950a8c4c174e7d473559844104f777 Mon Sep 17 00:00:00 2001 +From: Imagination Technologies +Date: Wed, 15 Feb 2023 13:10:11 +0000 +Subject: [PATCH 168/168] kopper: add compatibility to old style DRI interface + +Needed after "Add PVR Gallium driver" to make zink work. +This should be merged with the above change for later releases. +--- + src/gallium/frontends/dri/kopper.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/gallium/frontends/dri/kopper.c b/src/gallium/frontends/dri/kopper.c +index 54273647cc1..cfb9bfeae46 100644 +--- a/src/gallium/frontends/dri/kopper.c ++++ b/src/gallium/frontends/dri/kopper.c +@@ -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, + }; +-- +2.17.1 + diff --git a/package/mesa3d/Config.in b/package/mesa3d/Config.in index e21bbbe3..35ccc2b3 100644 --- a/package/mesa3d/Config.in +++ b/package/mesa3d/Config.in @@ -277,6 +277,14 @@ config BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_VIRGL virgl is the 3D acceleration backend for the virtio-gpu shipping with qemu. +config BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_PVR + bool "Gallium pvr driver" + depends on BR2_PACKAGE_IMG_GPU_POWERVR + select BR2_PACKAGE_MESA3D_GALLIUM_DRIVER + select BR2_PACKAGE_MESA3D_OPENGL_EGL + help + pvr is the 3D acceleration backend for Imagination PowerVR GPUs + config BR2_PACKAGE_MESA3D_VDPAU bool "Gallium VDPAU state tracker" depends on BR2_PACKAGE_XORG7 diff --git a/package/mesa3d/mesa3d.hash b/package/mesa3d/mesa3d.hash deleted file mode 100644 index e4de997f..00000000 --- a/package/mesa3d/mesa3d.hash +++ /dev/null @@ -1,5 +0,0 @@ -# From https://lists.freedesktop.org/archives/mesa-announce/2023-January/000703.html -sha256 37a1ddaf03f41919ee3c89c97cff41e87de96e00e9d3247959cc8279d8294593 mesa-22.3.4.tar.xz -sha512 6af340153244d3e95d0e155a45d6db134335654d62590797ae0ef6ba44c2ccfe91ebf95f70ff82c67cee108ac35536767b1f6848d6d1129f52eb9e8414ee321d mesa-22.3.4.tar.xz -# License -sha256 a00275a53178e2645fb65be99a785c110513446a5071ff2c698ed260ad917d75 docs/license.rst diff --git a/package/mesa3d/mesa3d.mk b/package/mesa3d/mesa3d.mk index 36b71515..765afc4d 100644 --- a/package/mesa3d/mesa3d.mk +++ b/package/mesa3d/mesa3d.mk @@ -5,7 +5,7 @@ ################################################################################ # When updating the version, please also update mesa3d-headers -MESA3D_VERSION = 22.3.4 +MESA3D_VERSION = 22.3.5 MESA3D_SOURCE = mesa-$(MESA3D_VERSION).tar.xz MESA3D_SITE = https://archive.mesa3d.org MESA3D_LICENSE = MIT, SGI, Khronos @@ -92,11 +92,11 @@ MESA3D_CONF_OPTS += \ -Dgallium-xa=disabled endif -ifeq ($(BR2_ARM_CPU_HAS_NEON),y) -MESA3D_CONF_OPTS += -Dgallium-vc4-neon=auto -else -MESA3D_CONF_OPTS += -Dgallium-vc4-neon=disabled -endif +#ifeq ($(BR2_ARM_CPU_HAS_NEON),y) +#MESA3D_CONF_OPTS += -Dgallium-vc4-neon=auto +#else +#MESA3D_CONF_OPTS += -Dgallium-vc4-neon=disabled +#endif # Drivers @@ -118,6 +118,7 @@ MESA3D_GALLIUM_DRIVERS-$(BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_TEGRA) += tegra MESA3D_GALLIUM_DRIVERS-$(BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_V3D) += v3d MESA3D_GALLIUM_DRIVERS-$(BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_VC4) += vc4 MESA3D_GALLIUM_DRIVERS-$(BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_VIRGL) += virgl +MESA3D_GALLIUM_DRIVERS-$(BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_PVR) += pvr # Vulkan Drivers MESA3D_VULKAN_DRIVERS-$(BR2_PACKAGE_MESA3D_VULKAN_DRIVER_INTEL) += intel @@ -130,6 +131,9 @@ MESA3D_CONF_OPTS += \ -Dshared-glapi=enabled \ -Dgallium-drivers=$(subst $(space),$(comma),$(MESA3D_GALLIUM_DRIVERS-y)) \ -Dgallium-extra-hud=true +ifeq ($(BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_PVR),y) +MESA3D_DEPENDENCIES += img-gpu-powervr +endif endif ifeq ($(BR2_PACKAGE_MESA3D_VULKAN_DRIVER),) diff --git a/package/python-sip/python-sip.mk b/package/python-sip/python-sip.mk index 3e015fa1..5d52a1c6 100644 --- a/package/python-sip/python-sip.mk +++ b/package/python-sip/python-sip.mk @@ -22,7 +22,7 @@ define HOST_PYTHON_SIP_BUILD_CMDS endef define HOST_PYTHON_SIP_INSTALL_CMDS - $(HOST_MAKE_ENV) $(HOST_CONFIGURE_OPTS) $(MAKE) install -C $(@D) + $(HOST_MAKE_ENV) $(HOST_CONFIGURE_OPTS) $(MAKE1) install -C $(@D) endef define PYTHON_SIP_CONFIGURE_CMDS @@ -43,7 +43,7 @@ define PYTHON_SIP_BUILD_CMDS endef define PYTHON_SIP_INSTALL_TARGET_CMDS - $(TARGET_MAKE_ENV) $(TARGET_CONFIGURE_OPTS) $(MAKE) install -C $(@D) + $(TARGET_MAKE_ENV) $(TARGET_CONFIGURE_OPTS) $(MAKE1) install -C $(@D) endef $(eval $(generic-package)) diff --git a/package/qt5/qt5base/qt5base.mk b/package/qt5/qt5base/qt5base.mk index efa0e16e..d41b186c 100644 --- a/package/qt5/qt5base/qt5base.mk +++ b/package/qt5/qt5base/qt5base.mk @@ -194,6 +194,10 @@ QT5BASE_DEPENDENCIES += xlib_libXext endif else QT5BASE_CONFIGURE_OPTS += -no-xcb +ifeq ($(BR2_PACKAGE_QT5WAYLAND),y) +QT5BASE_CONFIGURE_OPTS += -xkbcommon +QT5BASE_DEPENDENCIES += libxkbcommon +endif endif ifeq ($(BR2_PACKAGE_QT5BASE_OPENGL_DESKTOP),y) diff --git a/package/qt5/qt5wayland/0002-add-WL_EGL_PLATFORM-define.patch b/package/qt5/qt5wayland/0002-add-WL_EGL_PLATFORM-define.patch new file mode 100644 index 00000000..91de6ef8 --- /dev/null +++ b/package/qt5/qt5wayland/0002-add-WL_EGL_PLATFORM-define.patch @@ -0,0 +1,13 @@ +diff --git a/src/hardwareintegration/compositor/wayland-egl/wayland-egl.pri b/src/hardwareintegration/compositor/wayland-egl/wayland-egl.pri +index e20c680..e1f8de8 100644 +--- a/src/hardwareintegration/compositor/wayland-egl/wayland-egl.pri ++++ b/src/hardwareintegration/compositor/wayland-egl/wayland-egl.pri +@@ -3,6 +3,8 @@ INCLUDEPATH += $$PWD + QMAKE_USE_PRIVATE += egl wayland-server wayland-egl + + QT += egl_support-private ++#WL_EGL_PLATFORM or __GBM__ or USE_X11 default which will compile crash ++QMAKE_CXXFLAGS += -DWL_EGL_PLATFORM + + SOURCES += \ + $$PWD/waylandeglclientbufferintegration.cpp diff --git a/package/tinyalsa/tinyalsa.mk b/package/tinyalsa/tinyalsa.mk index b5c39e35..15502791 100644 --- a/package/tinyalsa/tinyalsa.mk +++ b/package/tinyalsa/tinyalsa.mk @@ -9,6 +9,6 @@ TINYALSA_SITE = $(call github,tinyalsa,tinyalsa,v$(TINYALSA_VERSION)) TINYALSA_LICENSE = BSD-3-Clause TINYALSA_LICENSE_FILES = NOTICE TINYALSA_INSTALL_STAGING = YES -TINYALSA_CONF_OPTS = -Ddocs=disabled -Dexamples=disabled -Dutils=disabled +TINYALSA_CONF_OPTS = -Ddocs=disabled -Dexamples=disabled $(eval $(meson-package)) diff --git a/package/udev/udev.mk b/package/udev/udev.mk index d70d13eb..05b35b21 100644 --- a/package/udev/udev.mk +++ b/package/udev/udev.mk @@ -4,9 +4,10 @@ # ################################################################################ -# Required by default rules +# Required by default rules for input devices define UDEV_USERS - - input -1 * - - - Input device group + - - render -1 * - - - DRI rendering nodes - - kvm -1 * - - - kvm nodes endef diff --git a/package/unrar/unrar.mk b/package/unrar/unrar.mk index fee9fb75..ed2fd1ea 100644 --- a/package/unrar/unrar.mk +++ b/package/unrar/unrar.mk @@ -12,7 +12,7 @@ UNRAR_LICENSE_FILES = license.txt UNRAR_CPE_ID_VENDOR = rarlab define UNRAR_BUILD_CMDS - $(TARGET_MAKE_ENV) $(MAKE) CXX="$(TARGET_CXX)" STRIP="/bin/true" \ + $(TARGET_MAKE_ENV) $(MAKE1) CXX="$(TARGET_CXX)" STRIP="/bin/true" \ CXXFLAGS="$(TARGET_CXXFLAGS) -pthread" \ LDFLAGS="$(TARGET_LDFLAGS) -pthread" -C $(@D) endef diff --git a/package/wayland/0001-build-the-wayland-scanner-is-not-always-required.patch b/package/wayland/0001-build-the-wayland-scanner-is-not-always-required.patch new file mode 100644 index 00000000..817463e2 --- /dev/null +++ b/package/wayland/0001-build-the-wayland-scanner-is-not-always-required.patch @@ -0,0 +1,44 @@ +From d58695c5a49e3279cd45037b3219c1387c91868c Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Wed, 18 May 2022 12:14:56 +0100 +Subject: [PATCH] build: the wayland scanner is not always required + +The Wayland Scanner is only needed if the libraries or tests are +being built. + +In the IMG DDK build system, Wayland is built twice, once for the build +machine, and once for the host. The build machine version only builds +the Wayland Scanner which is used to build the host version. Both builds +use a cross build definition file, and so are cross builds. + +Without this change, it is not possible to build Wayland Scanner for the +build machine, unless a Wayland Scanner is already installed. + +The indentation within the new "if" block hasn't been altered to minimise +the diff. +--- + src/meson.build | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/meson.build b/src/meson.build +index a8a1d2b..ed35ea9 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -77,12 +77,14 @@ if get_option('scanner') + endif + endif + ++if get_option('libraries') or get_option('tests') + if meson.is_cross_build() or not get_option('scanner') + scanner_dep = dependency('wayland-scanner', native: true, version: meson.project_version()) + wayland_scanner_for_build = find_program(scanner_dep.get_variable(pkgconfig: 'wayland_scanner')) + else + wayland_scanner_for_build = wayland_scanner + endif ++endif + + if get_option('libraries') + # wayland libraries +-- +2.25.1 + diff --git a/package/weston/0001-backend-drm-disable-bo-geometry-out-of-bounds-messag.patch b/package/weston/0001-backend-drm-disable-bo-geometry-out-of-bounds-messag.patch new file mode 100644 index 00000000..b8d96e0a --- /dev/null +++ b/package/weston/0001-backend-drm-disable-bo-geometry-out-of-bounds-messag.patch @@ -0,0 +1,29 @@ +From bd538014822c7291d54268cf9ce335adc7ab3fe2 Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Tue, 4 Sep 2018 14:59:09 +0100 +Subject: [PATCH 1/5] backend-drm: disable "bo geometry out of bounds" message + +The message was being printed repeatedly whilst running an opaque +windowed application, because the application wasn't within the +framebuffer dimension limits. +--- + libweston/backend-drm/fb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libweston/backend-drm/fb.c b/libweston/backend-drm/fb.c +index ba0c177e..3c664779 100644 +--- a/libweston/backend-drm/fb.c ++++ b/libweston/backend-drm/fb.c +@@ -306,7 +306,9 @@ drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf, + fb->width > backend->max_width || + backend->min_height > fb->height || + fb->height > backend->max_height) { ++#if 0 + weston_log("bo geometry out of bounds\n"); ++#endif + goto err_free; + } + +-- +2.34.1 + diff --git a/package/weston/0001-tests-Add-dependency-on-screenshooter-client-protocol.patch b/package/weston/0001-tests-Add-dependency-on-screenshooter-client-protocol.patch deleted file mode 100644 index 92721538..00000000 --- a/package/weston/0001-tests-Add-dependency-on-screenshooter-client-protocol.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 2ac6b6b084a877adde64db7faff2ed22eb3ea97a Mon Sep 17 00:00:00 2001 -From: Daniel Stone -Date: Tue, 8 Feb 2022 22:39:42 +0000 -Subject: [PATCH] tests: Add dependency on screenshooter client protocol - -Given that the test-helper code relies on the screenshooter protocol, -make sure it's available for us to build, and the dependency ensures we -build in order. - -Fixes: #588 - -Signed-off-by: Daniel Stone - -[Retrieved from: -https://gitlab.freedesktop.org/wayland/weston/-/commit/2ac6b6b084a877adde64db7faff2ed22eb3ea97a] -Signed-off-by: Fabrice Fontaine ---- - tests/meson.build | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tests/meson.build b/tests/meson.build -index 2d464ddcc..222091cd1 100644 ---- a/tests/meson.build -+++ b/tests/meson.build -@@ -29,8 +29,9 @@ lib_test_client = static_library( - 'weston-test-client-helper.c', - 'weston-test-fixture-compositor.c', - weston_test_client_protocol_h, -- weston_screenshooter_protocol_c, - weston_test_protocol_c, -+ weston_screenshooter_client_protocol_h, -+ weston_screenshooter_protocol_c, - viewporter_client_protocol_h, - viewporter_protocol_c, - 'color_util.h', --- -GitLab - diff --git a/package/weston/0002-meson-fix-failure-to-find-libudev-when-linking-the-c.patch b/package/weston/0002-meson-fix-failure-to-find-libudev-when-linking-the-c.patch new file mode 100644 index 00000000..ef262e92 --- /dev/null +++ b/package/weston/0002-meson-fix-failure-to-find-libudev-when-linking-the-c.patch @@ -0,0 +1,33 @@ +From 5c81f9112267d282e54967ffd1d0dc65d5c328e4 Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Thu, 28 Mar 2019 12:58:10 +0000 +Subject: [PATCH 2/5] meson: fix failure to find libudev when linking the + compositor + +The compositor links against libinput, which in turn is linked against +libudev. When the compositor is linked, it has a dependency on libinput, +but not libudev. Whilst this is correct, it means the linker won't be +able to find libudev if the library is in a non-standard place (i.e. +a place where the linker wouldn't normally look). + +Workaround the problem by adding libudev as a dependency for the +compositor. +--- + compositor/meson.build | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/compositor/meson.build b/compositor/meson.build +index 8a54ea99..11a6c59b 100644 +--- a/compositor/meson.build ++++ b/compositor/meson.build +@@ -17,6 +17,7 @@ deps_weston = [ + dep_libevdev, + dep_libdl, + dep_threads, ++ dependency('libudev'), + ] + + if get_option('xwayland') +-- +2.34.1 + diff --git a/package/weston/0003-libweston-reduce-checks-for-dmabufs-with-DRM-modifie.patch b/package/weston/0003-libweston-reduce-checks-for-dmabufs-with-DRM-modifie.patch new file mode 100644 index 00000000..f54578f5 --- /dev/null +++ b/package/weston/0003-libweston-reduce-checks-for-dmabufs-with-DRM-modifie.patch @@ -0,0 +1,63 @@ +From c2d5452a2aefd42f7786b1e9b86ded1a664427f7 Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Thu, 15 Apr 2021 19:30:02 +0100 +Subject: [PATCH 3/5] libweston: reduce checks for dmabufs with DRM modifiers + +If the buffer associated with a dmabuf has a DRM modifier, then +checking the stride and stride*height against the size of the +dambuf may not make sense, so skip the check. + +IMG lossy framebuffers have a smaller size than that of the +equivalent linear framebuffer. +--- + libweston/linux-dmabuf.c | 33 ++++++++++++++++++--------------- + 1 file changed, 18 insertions(+), 15 deletions(-) + +diff --git a/libweston/linux-dmabuf.c b/libweston/linux-dmabuf.c +index 21de498d..6d1c3ee4 100644 +--- a/libweston/linux-dmabuf.c ++++ b/libweston/linux-dmabuf.c +@@ -244,22 +244,25 @@ params_create_common(struct wl_client *client, + goto err_out; + } + +- if (buffer->attributes.offset[i] + buffer->attributes.stride[i] > size) { +- wl_resource_post_error(params_resource, +- ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, +- "invalid stride %i for plane %i", +- buffer->attributes.stride[i], i); +- goto err_out; +- } ++ if (buffer->attributes.modifier[i] == DRM_FORMAT_MOD_INVALID || ++ buffer->attributes.modifier[i] == DRM_FORMAT_MOD_LINEAR) { ++ if (buffer->attributes.offset[i] + buffer->attributes.stride[i] > size) { ++ wl_resource_post_error(params_resource, ++ ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, ++ "invalid stride %i for plane %i", ++ buffer->attributes.stride[i], i); ++ goto err_out; ++ } + +- /* Only valid for first plane as other planes might be +- * sub-sampled according to fourcc format */ +- if (i == 0 && +- buffer->attributes.offset[i] + buffer->attributes.stride[i] * height > size) { +- wl_resource_post_error(params_resource, +- ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, +- "invalid buffer stride or height for plane %i", i); +- goto err_out; ++ /* Only valid for first plane as other planes might be ++ * sub-sampled according to fourcc format */ ++ if (i == 0 && ++ buffer->attributes.offset[i] + buffer->attributes.stride[i] * height > size) { ++ wl_resource_post_error(params_resource, ++ ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS, ++ "invalid buffer stride or height for plane %i", i); ++ goto err_out; ++ } + } + } + +-- +2.34.1 + diff --git a/package/weston/0004-tests-test-client-depends-on-libudev.patch b/package/weston/0004-tests-test-client-depends-on-libudev.patch new file mode 100644 index 00000000..f8629afa --- /dev/null +++ b/package/weston/0004-tests-test-client-depends-on-libudev.patch @@ -0,0 +1,25 @@ +From 7ac15e8dfb0d51f14919cb956d0894772f70429d Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Sat, 12 Jun 2021 16:50:01 +0100 +Subject: [PATCH 4/5] tests: test-client depends on libudev + +Source file weston-test-fixture-compositor.c includes libudev.h. +--- + tests/meson.build | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/meson.build b/tests/meson.build +index d8e96e77..195366bb 100644 +--- a/tests/meson.build ++++ b/tests/meson.build +@@ -43,6 +43,7 @@ lib_test_client = static_library( + dep_libexec_weston, + dep_pixman, + dependency('cairo'), ++ dependency('libudev'), + ], + install: false, + ) +-- +2.34.1 + diff --git a/package/weston/0005-backend-drm-allow-linear-framebuffers-if-no-KMS-modi.patch b/package/weston/0005-backend-drm-allow-linear-framebuffers-if-no-KMS-modi.patch new file mode 100644 index 00000000..a56f6b91 --- /dev/null +++ b/package/weston/0005-backend-drm-allow-linear-framebuffers-if-no-KMS-modi.patch @@ -0,0 +1,53 @@ +From 8d40edf61573ad5b36b79536f491c2fc1418e907 Mon Sep 17 00:00:00 2001 +From: Brendan King +Date: Wed, 20 Apr 2022 11:56:50 +0000 +Subject: [PATCH 5/5] backend-drm: allow linear framebuffers if no KMS modifier + support + +If KMS doesn't support modifiers, but a framebuffer is supplied via +a dmabuf with a linear modifier, assume the buffer is compatible with +KMS. This scenario can occur when different drivers are used for the +GPU and KMS, and the GPU driver supports modifiers. + +Some platforms used internally by IMG, such as the Acer R13 Chromebook, +have KMS drivers that don't support modifiers. Without this change, +applications such as weston-simple-egl cannot keep up with vsync. +This problem didn't occur with older versions of Weston (e.g, 9.0.0). + +This change can be dropped for platforms where KMS supports modifiers. + +The change that prompted this one was: + + commit 567cc92797846081506ccb36e6af99884a8b6cf2 + Author: Leandro Ribeiro + Date: Wed Apr 21 11:44:53 2021 -0300 + + backend-drm: add DRM_FORMAT_MOD_INVALID to modifier sets when no + modifiers are supported +--- + libweston/backend-drm/fb.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/libweston/backend-drm/fb.c b/libweston/backend-drm/fb.c +index 3c664779..c59e0a99 100644 +--- a/libweston/backend-drm/fb.c ++++ b/libweston/backend-drm/fb.c +@@ -489,6 +489,15 @@ drm_fb_compatible_with_plane(struct drm_fb *fb, struct drm_plane *plane) + + if (weston_drm_format_has_modifier(fmt, fb->modifier)) + return true; ++ ++ /* KMS doesn't support modifiers, but we've been sent a dmabuf ++ * with a linear modifier. This can happen if different drivers ++ * are used for the GPU and KMS, and the GPU driver supports ++ * modifiers. Assume this is valid combination. */ ++ if (fb->modifier == DRM_FORMAT_MOD_LINEAR && ++ weston_drm_format_has_modifier(fmt, DRM_FORMAT_MOD_INVALID)) ++ return true; ++ + } + + drm_debug(b, "\t\t\t\t[%s] not placing view on %s: " +-- +2.34.1 + diff --git a/package/weston/0006-weston-set-default-compositor-to-gpu.patch b/package/weston/0006-weston-set-default-compositor-to-gpu.patch new file mode 100644 index 00000000..768dfd75 --- /dev/null +++ b/package/weston/0006-weston-set-default-compositor-to-gpu.patch @@ -0,0 +1,27 @@ +From fa39466071e3ddfc7b3f8e4062332778a76fcf5c Mon Sep 17 00:00:00 2001 +From: dengbo +Date: Wed, 27 Dec 2023 20:45:49 +0800 +Subject: [PATCH] weston: set default compositor to gpu + +Workaround: +spacemit drm has bug to assign multi planes to display. +--- + libweston/backend-drm/state-propose.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libweston/backend-drm/state-propose.c b/libweston/backend-drm/state-propose.c +index 7b350aa..ecc6575 100644 +--- a/libweston/backend-drm/state-propose.c ++++ b/libweston/backend-drm/state-propose.c +@@ -1097,7 +1097,7 @@ drm_assign_planes(struct weston_output *output_base, void *repaint_data) + struct drm_plane_state *plane_state; + struct weston_paint_node *pnode; + struct weston_plane *primary = &output_base->compositor->primary_plane; +- enum drm_output_propose_state_mode mode = DRM_OUTPUT_PROPOSE_STATE_PLANES_ONLY; ++ enum drm_output_propose_state_mode mode = DRM_OUTPUT_PROPOSE_STATE_RENDERER_ONLY; + + drm_debug(b, "\t[repaint] preparing state for output %s (%lu)\n", + output_base->name, (unsigned long) output_base->id); +-- +2.34.1 + diff --git a/package/weston/run_weston.sh b/package/weston/run_weston.sh new file mode 100644 index 00000000..23dfcd7c --- /dev/null +++ b/package/weston/run_weston.sh @@ -0,0 +1,6 @@ +export EGL_LOG_LEVEL=debug +export MESA_LOADER_DRIVER_OVERRIDE=pvr +export XDG_RUNTIME_DIR=/root +export QT_QPA_PLATFORM_PLUGIN_PATH=/usr/lib/qt/plugins/platforms +export QT_QPA_PLATFORM=wayland +weston --log=/var/log/weston --tty=1 --idle-time=0 diff --git a/package/weston/weston.hash b/package/weston/weston.hash deleted file mode 100644 index d58ca1ef..00000000 --- a/package/weston/weston.hash +++ /dev/null @@ -1,4 +0,0 @@ -# From https://lists.freedesktop.org/archives/wayland-devel/2022-June/042260.html -sha256 8a9e52506a865a7410981b04f8341b89b84106db8531ab1f9fdd37b5dc034115 weston-10.0.1.tar.xz -sha512 688d843096a95b463161b98e85ca3443b31ba2ee49fc8d456a2780cc96f576e9d097054e9f361997a66e9cc8373cf29e406a742dae3884b3b50b26acf1710c8c weston-10.0.1.tar.xz -sha256 fdb65868f65d0fbdb05c2d3b779e10ce9969fa0c4b9262ba4f260e87086ab860 COPYING diff --git a/package/weston/weston.ini b/package/weston/weston.ini new file mode 100644 index 00000000..1fa07eaa --- /dev/null +++ b/package/weston/weston.ini @@ -0,0 +1,10 @@ +[core] +shell=desktop-shell.so +xwayland=false +backend=drm-backend.so +require-input=false +[shell] +startup-animation=none +[keyboard] +[output] +mode=640x480 diff --git a/package/weston/weston.mk b/package/weston/weston.mk index 01f84178..6ef505b0 100644 --- a/package/weston/weston.mk +++ b/package/weston/weston.mk @@ -4,9 +4,9 @@ # ################################################################################ -WESTON_VERSION = 10.0.1 -WESTON_SITE = https://gitlab.freedesktop.org/wayland/weston/-/releases/$(WESTON_VERSION)/downloads -WESTON_SOURCE = weston-$(WESTON_VERSION).tar.xz +WESTON_VERSION = 10.0.3 +WESTON_SITE = https://gitlab.freedesktop.org/wayland/weston/-/archive/$(WESTON_VERSION) +WESTON_SOURCE = weston-$(WESTON_VERSION).tar.bz2 WESTON_LICENSE = MIT WESTON_LICENSE_FILES = COPYING WESTON_CPE_ID_VENDOR = wayland @@ -187,4 +187,12 @@ else WESTON_CONF_OPTS += -Ddemo-clients=false endif +define WESTON_INSTALL_CONF_ON_TARGET + mkdir -p $(TARGET_DIR)/etc/xdg + $(INSTALL) -D -m 0644 package/weston/weston.ini $(TARGET_DIR)/etc/xdg/weston/weston.ini + $(INSTALL) -D -m 0755 package/weston/run_weston.sh $(TARGET_DIR)/root/run_weston.sh +endef + +WESTON_POST_INSTALL_TARGET_HOOKS += WESTON_INSTALL_CONF_ON_TARGET + $(eval $(meson-package)) diff --git a/package/wqy-zenhei/0001-fix-Having-multiple-values-in-test-isn-t-supported-a.patch b/package/wqy-zenhei/0001-fix-Having-multiple-values-in-test-isn-t-supported-a.patch new file mode 100644 index 00000000..d5ebe602 --- /dev/null +++ b/package/wqy-zenhei/0001-fix-Having-multiple-values-in-test-isn-t-supported-a.patch @@ -0,0 +1,29 @@ +From 4fabbe9144f13dd7e270d0d1e5ab4c3c32d00c27 Mon Sep 17 00:00:00 2001 +From: max +Date: Mon, 22 Jan 2024 11:24:15 +0800 +Subject: [PATCH] fix: Having multiple values in isn't supported and may + not work as expected + +--- + 44-wqy-zenhei.conf | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/44-wqy-zenhei.conf b/44-wqy-zenhei.conf +index 5744827..5b70987 100644 +--- a/44-wqy-zenhei.conf ++++ b/44-wqy-zenhei.conf +@@ -6,7 +6,11 @@ + + + WenQuanYi Zen Hei ++ ++ + 文泉驿正黑 ++ ++ + 文泉驛正黑 + + false +-- +2.25.1 + diff --git a/toolchain/Config.in b/toolchain/Config.in index b3cbec83..70bea538 100644 --- a/toolchain/Config.in +++ b/toolchain/Config.in @@ -744,10 +744,15 @@ config BR2_TOOLCHAIN_GCC_AT_LEAST_12 bool select BR2_TOOLCHAIN_GCC_AT_LEAST_11 +config BR2_TOOLCHAIN_GCC_AT_LEAST_13 + bool + select BR2_TOOLCHAIN_GCC_AT_LEAST_12 + # This order guarantees that the highest version is set, as kconfig # stops affecting a value on the first matching default. config BR2_TOOLCHAIN_GCC_AT_LEAST string + default "13" if BR2_TOOLCHAIN_GCC_AT_LEAST_13 default "12" if BR2_TOOLCHAIN_GCC_AT_LEAST_12 default "11" if BR2_TOOLCHAIN_GCC_AT_LEAST_11 default "10" if BR2_TOOLCHAIN_GCC_AT_LEAST_10 diff --git a/toolchain/toolchain-external/Config.in b/toolchain/toolchain-external/Config.in index c1c159cb..333b7942 100644 --- a/toolchain/toolchain-external/Config.in +++ b/toolchain/toolchain-external/Config.in @@ -8,6 +8,9 @@ choice # Kept toolchains sorted by architecture in order to use some toolchain # as default choice +#riscv64 default +source "toolchain/toolchain-external/toolchain-external-jdsk-riscv64/Config.in" + # Aarch64 (use ARM toolchain by default) source "toolchain/toolchain-external/toolchain-external-arm-aarch64/Config.in" source "toolchain/toolchain-external/toolchain-external-linaro-aarch64/Config.in" @@ -112,6 +115,9 @@ config BR2_TOOLCHAIN_EXTERNAL_PREFIX # The toolchain Config.in.options must define # BR2_PACKAGE_PROVIDES_TOOLCHAIN_EXTERNAL and BR2_TOOLCHAIN_EXTERNAL_PREFIX +#riscv64 default +source "toolchain/toolchain-external/toolchain-external-jdsk-riscv64/Config.in.options" + # Aarch64 source "toolchain/toolchain-external/toolchain-external-arm-aarch64/Config.in.options" source "toolchain/toolchain-external/toolchain-external-linaro-aarch64/Config.in.options" diff --git a/toolchain/toolchain-external/toolchain-external-custom/Config.in.options b/toolchain/toolchain-external/toolchain-external-custom/Config.in.options index e9a9c1c2..a4309c54 100644 --- a/toolchain/toolchain-external/toolchain-external-custom/Config.in.options +++ b/toolchain/toolchain-external/toolchain-external-custom/Config.in.options @@ -46,6 +46,10 @@ choice Set to the gcc version that is used by your external toolchain. +config BR2_TOOLCHAIN_EXTERNAL_GCC_13 + bool "13.x" + select BR2_TOOLCHAIN_GCC_AT_LEAST_13 + config BR2_TOOLCHAIN_EXTERNAL_GCC_12 bool "12.x" select BR2_TOOLCHAIN_GCC_AT_LEAST_12 diff --git a/toolchain/toolchain-external/toolchain-external-jdsk-riscv64/Config.in b/toolchain/toolchain-external/toolchain-external-jdsk-riscv64/Config.in new file mode 100755 index 00000000..70406dde --- /dev/null +++ b/toolchain/toolchain-external/toolchain-external-jdsk-riscv64/Config.in @@ -0,0 +1,19 @@ +config BR2_TOOLCHAIN_EXTERNAL_JDSK_RISCV64 + bool "spacemit riscv64 v0.1.5" + depends on BR2_riscv + depends on BR2_HOSTARCH = "x86_64" || BR2_HOSTARCH = "x86" + select BR2_TOOLCHAIN_EXTERNAL_GLIBC + select BR2_TOOLCHAIN_HAS_SSP + select BR2_INSTALL_LIBSTDCPP + select BR2_TOOLCHAIN_HEADERS_AT_LEAST_5_10 + select BR2_TOOLCHAIN_GCC_AT_LEAST_7 + select BR2_TOOLCHAIN_GCC_AT_LEAST_8 + select BR2_TOOLCHAIN_GCC_AT_LEAST_9 + select BR2_TOOLCHAIN_GCC_AT_LEAST_10 + select BR2_TOOLCHAIN_GCC_AT_LEAST_11 + select BR2_TOOLCHAIN_GCC_AT_LEAST_12 + select BR2_TOOLCHAIN_HAS_FORTRAN + select BR2_TOOLCHAIN_HAS_OPENMP + help + Toolchain for the riscv64 architecture, from + https://www.spacemit.com diff --git a/toolchain/toolchain-external/toolchain-external-jdsk-riscv64/Config.in.options b/toolchain/toolchain-external/toolchain-external-jdsk-riscv64/Config.in.options new file mode 100755 index 00000000..bf3df9c4 --- /dev/null +++ b/toolchain/toolchain-external/toolchain-external-jdsk-riscv64/Config.in.options @@ -0,0 +1,9 @@ +if BR2_TOOLCHAIN_EXTERNAL_JDSK_RISCV64 + +config BR2_TOOLCHAIN_EXTERNAL_PREFIX + default "riscv64-unknown-linux-gnu" + +config BR2_PACKAGE_PROVIDES_TOOLCHAIN_EXTERNAL + default "toolchain-external-jdsk-riscv64" + +endif diff --git a/toolchain/toolchain-external/toolchain-external-jdsk-riscv64/toolchain-external-jdsk-riscv64.hash b/toolchain/toolchain-external/toolchain-external-jdsk-riscv64/toolchain-external-jdsk-riscv64.hash new file mode 100755 index 00000000..14bc3c44 --- /dev/null +++ b/toolchain/toolchain-external/toolchain-external-jdsk-riscv64/toolchain-external-jdsk-riscv64.hash @@ -0,0 +1,2 @@ +# Locally calculated +sha256 1cb203988954a8e373865f937ca3c80064f37ab5dafb4a494ceb8710fb8fbe42 spacemit-gcc-linux-glibc-x86_64-jdsk-v0.1.5-20230324T022642.tar.gz diff --git a/toolchain/toolchain-external/toolchain-external-jdsk-riscv64/toolchain-external-jdsk-riscv64.mk b/toolchain/toolchain-external/toolchain-external-jdsk-riscv64/toolchain-external-jdsk-riscv64.mk new file mode 100755 index 00000000..da71d771 --- /dev/null +++ b/toolchain/toolchain-external/toolchain-external-jdsk-riscv64/toolchain-external-jdsk-riscv64.mk @@ -0,0 +1,16 @@ +################################################################################ +# +# toolchain-external-linaro-aarch64 +# +################################################################################ + +TOOLCHAIN_EXTERNAL_JDSK_RISCV64_VERSION = v0.1.5-20230324T022642 +TOOLCHAIN_EXTERNAL_JDSK_RISCV64_SITE = http://lnode1.dc.com:20000/software/toolchain + +ifeq ($(HOSTARCH),x86) +TOOLCHAIN_EXTERNAL_JDSK_RISCV64_SOURCE = spacemit-gcc-linux-glibc-x86_64-jdsk-$(TOOLCHAIN_EXTERNAL_JDSK_RISCV64_VERSION).tar.gz +else +TOOLCHAIN_EXTERNAL_JDSK_RISCV64_SOURCE = spacemit-gcc-linux-glibc-x86_64-jdsk-$(TOOLCHAIN_EXTERNAL_JDSK_RISCV64_VERSION).tar.gz +endif + +$(eval $(toolchain-external-package))