6 Commits

Author SHA1 Message Date
marfrit 7708744eb2 mesa-panvk-bifrost: r5 -> r6 — advertise VK_EXT_legacy_dithering on Bifrost
Backports Mesa main's unconditional flip of VK_EXT_legacy_dithering.
Pure-software composition; no new HW path. vk_render_pass already gates
on enabled_features.legacyDithering and panvk_vX_blend + pan_format
already plumb the dithered BLEND descriptor (BFMT2 table has MALI_BLEND_AU
encodings for RGB565/RGB5A1/RGBA4/RGB10A2 on PAN_ARCH 7). Our r5 base
just hadn't picked up the cherry-pick.

Phase 7 verify on ohm (PineTab2 / RK3566 / Mali-G52 r1 MC1) with a
locally-built r6 lib at /tmp/r6_test_lib/:

  Feature advertisement:
    r5: VK_EXT_legacy_dithering not in extension list, legacyDithering=false
    r6: VK_EXT_legacy_dithering rev 2 advertised, legacyDithering=true

  dEQP subsets (delta):
    dEQP-VK.api.*.legacy_dithering*    r5/r6 both:  2 P / 0 F (identical)
    dEQP-VK.renderpass.dithering.*     r5/r6 both:  0 P / 0 F / 94 NS (identical)
    dEQP-VK.renderpass2.dithering.*    r5/r6 both:  0 P / 0 F / 94 NS (identical)

  Net: zero regressions, advertisement-only delta as expected.

Second-model review (per bugfix-process step 4) traced the full code
path through vk_render_pass + panvk_vX_cmd_draw + panvk_vX_blend +
pan_format BFMT2. No interaction with our r1 nullDescriptor (disjoint
paths). Mesa upstream marks ext DONE for panvk in docs/features.txt.

ARM's own libmali r51p0 driver (BXODROIDN2PL, 2024-08) lists
VK_EXT_legacy_dithering in its Vulkan extension string table,
confirming the feature is shipped by ARM for Mali-G52-class hardware.

Follow-up out of scope: the 94 renderpass-dithering tests show as
NotSupported on both r5 and r6 — there's a separate panvk-side
prereq the dEQP harness checks (likely a specific format-feature
combination). Worth investigating in a future iteration.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 00:23:40 +02:00
marfrit 5d97cf15d6 Merge pull request 'chromium-fourier: bump to 148.0.7778.178, add Debian recipe' (#93) from claude-noether/marfrit-packages:noether/chromium-fourier-148 into main
Reviewed-on: marfrit/marfrit-packages#93
2026-05-24 19:46:13 +00:00
marfrit 58f67d4b2c chromium-fourier: bump to 148.0.7778.178, add Debian recipe
Arch: version 147→148, drop enable_nacl (removed upstream), fix
nv12-external-oes patch context for 148 (base/numerics/safe_conversions.h
include removed upstream). Header comment updated: native build fiction →
cross-compile reality.

Debian: new build-deb.sh that assembles .deb from pre-built artifacts
on CT 220 (data). Same binary artifacts as the Arch package, launcher at
/usr/bin/chromium-fourier (no Conflicts with stock chromium on Debian).

Both packages published to packages.reauktion.de:
- Arch: marfrit/aarch64/chromium-fourier 1:148.0.7778.178-1
- Debian: trixie+bookworm/main/arm64 chromium-fourier 1:148.0.7778.178-1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-24 09:45:30 +02:00
marfrit 685f85c22e Merge pull request 'mesa-panvk-bifrost: r4 -> r5 — advertise fragmentStoresAndAtomics on Bifrost (closes panvk-bifrost#2)' (#92) from claude-noether/marfrit-packages:noether/mesa-panvk-bifrost-r5 into main
Reviewed-on: marfrit/marfrit-packages#92
2026-05-23 12:19:10 +00:00
marfrit 6896853544 mesa-panvk-bifrost: r4 -> r5 — advertise fragmentStoresAndAtomics on Bifrost
Backports Mesa main's unconditional flip of .fragmentStoresAndAtomics
to true in src/panfrost/vulkan/panvk_vX_physical_device.c. Closes
the Dawn-WebGPU adapter rejection at PhysicalDeviceVk.cpp:250 that
caused brave-vulkan to fall back to the SwiftShader CPU adapter on
PineTab2/Mali-G52, per marfrit/panvk-bifrost#2.

Phase 7 verify on ohm (PineTab2, RK3566, Mali-G52 r1 MC1) with a
locally-built r5 lib installed to /tmp/r5_test_lib/:

  dEQP-VK.glsl.atomic_operations.*:
    r4:  48 pass /   0 fail / 992 NotSupported  (1040 total)
    r5:  80 pass /   0 fail / 960 NotSupported  (1040 total)
    delta: +32 newly-passing, zero new failures

  dEQP-VK.image.store.*:
    r4: 2772 pass /  0 fail / 238 NotSupported  (3010 total)
    r5: 2772 pass /  0 fail / 238 NotSupported  (3010 total)
    delta: identical (image.store is independent of the flag)

The disjunction with instance->force_enable_shader_atomics is kept as
a documented kill-switch even though the compiler folds it away —
it leaves the DRI option pan_force_enable_shader_atomics semantically
wired for future rebases or downstream debugging.

Patch reviewed via 2nd-model pass (per bugfix-process step 4):
recommended keeping the disjunction (applied), Bifrost-only-vs-unconditional
left unconditional to match upstream (applied), pre-ship CTS subset
(applied with results above).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 14:04:44 +02:00
marfrit fd56eca3cb Merge pull request 'mesa-panvk-bifrost{,-video}: fix url= to real Gitea repo' (#91) from claude-noether/marfrit-packages:noether/panvk-bifrost-url-fix into main
Reviewed-on: marfrit/marfrit-packages#91
2026-05-23 03:18:37 +00:00
8 changed files with 330 additions and 11 deletions
+5 -6
View File
@@ -8,13 +8,13 @@
# NEXT.md alongside this PKGBUILD for the full rationale and the
# validation log on PineTab2 (RK3566).
#
# Multi-arch: builds natively on x86_64 and aarch64. The x86_64 path
# is primarily a development / CI host; the runtime target audience is
# aarch64. The two patches are architecture-independent.
# Cross-compiled from x86_64 using chromium's bundled clang (upstream
# LLVM doesn't ship clang 23+ yet; chromium's internal fork is required).
# Runtime target is aarch64. The three patches are architecture-independent.
pkgname=chromium-fourier
pkgver=147.0.7727.116
pkgrel=2
pkgver=148.0.7778.178
pkgrel=1
epoch=1
pkgdesc='Chromium with V4L2VDA HW video decode unlocked for mainline Linux Wayland on Rockchip'
arch=('aarch64' 'x86_64')
@@ -150,7 +150,6 @@ build() {
'symbol_level=0'
'is_cfi=false'
'treat_warnings_as_errors=false'
'enable_nacl=false'
'enable_widevine=false'
# System toolchain (clang/lld from pacman)
@@ -73,16 +73,15 @@ diff --git a/ui/ozone/common/native_pixmap_egl_binding.cc b/ui/ozone/common/nati
index 31877f4459..6855c1093e 100644
--- a/ui/ozone/common/native_pixmap_egl_binding.cc
+++ b/ui/ozone/common/native_pixmap_egl_binding.cc
@@ -6,10 +6,13 @@
@@ -6,9 +6,12 @@
#include <array>
+#include "base/containers/flat_map.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
+#include "base/no_destructor.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
+#include "base/synchronization/lock.h"
#include "ui/gfx/linux/drm_util_linux.h"
#include "ui/gl/gl_bindings.h"
@@ -0,0 +1,50 @@
From: marfrit-packages noether <claude-noether@reauktion.de>
Subject: [PATCH] panvk: report fragmentStoresAndAtomics = true on Bifrost
Backports Mesa main's unconditional advertisement of
fragmentStoresAndAtomics for panvk (snapshot ref: src/panfrost/vulkan/
panvk_vX_physical_device.c at commit-time 2026-05-06; the line reads
`.fragmentStoresAndAtomics = true,` on main with no PAN_ARCH gate).
Motivation: Chromium Dawn's WebGPU initializer in
third_party/dawn/src/dawn/native/vulkan/PhysicalDeviceVk.cpp:250
unconditionally rejects any Vulkan adapter that doesn't advertise this
feature, causing Dawn to fall back to the SwiftShader CPU adapter
on PineTab2 / RK3566 / Mali-G52 r1 MC1 (PAN_ARCH 7). With this patch the
device advertises true, satisfying Dawn's gate. Tracked at
https://git.reauktion.de/marfrit/panvk-bifrost/issues/2.
The disjunction with `instance->force_enable_shader_atomics` is
preserved as a kill-switch: in compiler terms it's dead code
(`true || X == true`), but it leaves the DRI option
`pan_force_enable_shader_atomics` semantically wired so future
rebases or downstream debugging can see the link to the runtime knob.
Caveat: the existing DRI option's description in src/util/driconf.h
still labels this as "may not work reliably and is for debug purposes
only". Mesa main's choice to ship it as default-on for all panvk
architectures (including Bifrost, which is non-conformant per the
PAN_I_WANT_A_BROKEN_VULKAN_DRIVER gate) reflects an upstream judgment
that the practical risk is acceptable. Verify-before-ship for this
package: dEQP-VK.glsl.atomic_operations.* + dEQP-VK.image.store.*
deltas vs the r4 baseline must show no new fails. Pass counts may rise
(tests that previously NotSupported now run); the load-bearing line is
the Failed column staying at zero.
---
src/panfrost/vulkan/panvk_vX_physical_device.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/panfrost/vulkan/panvk_vX_physical_device.c b/src/panfrost/vulkan/panvk_vX_physical_device.c
--- a/src/panfrost/vulkan/panvk_vX_physical_device.c
+++ b/src/panfrost/vulkan/panvk_vX_physical_device.c
@@ -280,8 +280,7 @@
.vertexPipelineStoresAndAtomics =
(PAN_ARCH >= 13 && instance->enable_vertex_pipeline_stores_atomics) ||
instance->force_enable_shader_atomics,
- .fragmentStoresAndAtomics =
- (PAN_ARCH >= 10) || instance->force_enable_shader_atomics,
+ .fragmentStoresAndAtomics = true || instance->force_enable_shader_atomics,
.shaderTessellationAndGeometryPointSize = false,
.shaderImageGatherExtended = true,
.shaderStorageImageExtendedFormats = true,
@@ -0,0 +1,51 @@
From: marfrit-packages noether <claude-noether@reauktion.de>
Subject: [PATCH] panvk: advertise VK_EXT_legacy_dithering on Bifrost
Backports Mesa main's flip — vanilla 26.0.6 doesn't have the extension
in the panvk advertisement list; main does (line 172 / 647 on snapshot
617da94, 2026-05-06).
VK_EXT_legacy_dithering exposes the classic OpenGL-style dithering
behavior to Vulkan apps. Pure-software composition; no new HW path.
ARM's own libmali driver release r51p0 (BXODROIDN2PL, Aug 2024) lists
this extension in its Vulkan implementation for ODROID-N2 boards
using the same Mali-G52 architecture family — confirms ARM ships it
for Mali-G52-class hardware.
Consumer benefit: dithering matters for low-bit-depth framebuffers
(RGB565 / RGB5A1 — common on portable / battery-saving renders)
where banding is visible. DXVK / vkd3d-proton both opt in when
available.
Verify-before-ship: vulkaninfo lists the extension and
VkPhysicalDeviceLegacyDitheringFeaturesEXT.legacyDithering == true.
Cross-refs:
- marfrit/panvk-bifrost research/r6_r7_mali_g52_feature_audit_2026-05-24.md
- ARM blob r51p0 strings dump (in-blob extension confirmed)
---
src/panfrost/vulkan/panvk_vX_physical_device.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/panfrost/vulkan/panvk_vX_physical_device.c b/src/panfrost/vulkan/panvk_vX_physical_device.c
--- a/src/panfrost/vulkan/panvk_vX_physical_device.c
+++ b/src/panfrost/vulkan/panvk_vX_physical_device.c
@@ -156,6 +156,7 @@
.EXT_image_drm_format_modifier = true,
.EXT_image_robustness = true,
.EXT_index_type_uint8 = true,
+ .EXT_legacy_dithering = true,
.EXT_line_rasterization = true,
.EXT_load_store_op_none = true,
.EXT_non_seamless_cube_map = true,
@@ -552,6 +553,9 @@
/* VK_EXT_multisampled_render_to_single_sampled */
.multisampledRenderToSingleSampled = true,
+
+ /* VK_EXT_legacy_dithering */
+ .legacyDithering = true,
};
}
+31 -1
View File
@@ -30,7 +30,7 @@
pkgname=mesa-panvk-bifrost
_mesaver=26.0.6
pkgver=26.0.6.r4
pkgver=26.0.6.r6
pkgrel=1
pkgdesc="Patched Mesa libvulkan_panfrost.so exposing Bifrost-gen Mali to Vulkan apps (panvk-bifrost campaign)"
arch=('aarch64')
@@ -81,6 +81,8 @@ source=(
"0002-panvk-expose-vulkan-1.1-1.2-on-bifrost.patch"
"0003-panvk-bifrost-vk-ext-transform-feedback.patch"
"0004-panvk-bifrost-xfb-primitive-decomposition.patch"
"0005-panvk-bifrost-fragment-stores-atomics.patch"
"0006-panvk-bifrost-legacy-dithering.patch"
"brave-vulkan"
"icd.json"
)
@@ -92,6 +94,8 @@ sha256sums=(
'SKIP'
'SKIP'
'SKIP'
'SKIP'
'SKIP'
)
prepare() {
@@ -127,6 +131,27 @@ prepare() {
# Phase-doc context: ~/src/panvk-bifrost/iter17/phase{0,1,2,4,5,6,8}_*.md.
patch -p1 < "${srcdir}/0004-panvk-bifrost-xfb-primitive-decomposition.patch"
# r5 (2026-05-23): advertise .fragmentStoresAndAtomics = true on Bifrost
# to satisfy Chromium Dawn's WebGPU init gate
# (third_party/dawn/src/dawn/native/vulkan/PhysicalDeviceVk.cpp:250).
# Backports Mesa main's unconditional flip (same line as on main as of
# 2026-05-06). Disjunction with instance->force_enable_shader_atomics
# is preserved as a documented kill-switch even though the compiler
# folds it away. Closes marfrit/panvk-bifrost#2.
# Verify-before-ship: dEQP-VK.glsl.atomic_operations.* and
# dEQP-VK.image.store.* show no new Failed vs r4 baseline.
patch -p1 < "${srcdir}/0005-panvk-bifrost-fragment-stores-atomics.patch"
# r6 (2026-05-25): advertise VK_EXT_legacy_dithering. Backports Mesa
# main's unconditional flip. Pure-software composition; vk_render_pass
# already gates on enabled_features.legacyDithering and panvk_vX_blend
# + pan_format already plumb the dithered BLEND descriptor (BFMT2 table
# has MALI_BLEND_AU encodings for RGB565/RGB5A1/RGBA4/RGB10A2 on
# PAN_ARCH 7). Closes the EXT_legacy_dithering gap surfaced by
# marfrit/panvk-bifrost research/r6_r7_*. ARM blob r51p0 confirms the
# extension as Mali-G52-architecture supported.
patch -p1 < "${srcdir}/0006-panvk-bifrost-legacy-dithering.patch"
# Sanity-check the patches landed.
grep -q "KHR_robustness2 = true," src/panfrost/vulkan/panvk_vX_physical_device.c
grep -q "EXT_robustness2 = true," src/panfrost/vulkan/panvk_vX_physical_device.c
@@ -138,6 +163,11 @@ prepare() {
test -f src/panfrost/vulkan/jm/panvk_vX_cmd_xfb.c
# iter17 sanity: pan_nir_lower_xfb call site has been replaced; new file present.
grep -q "panvk_per_arch(nir_lower_xfb)" src/panfrost/vulkan/panvk_vX_shader.c
# r5 sanity: fragmentStoresAndAtomics = true patch landed
grep -q "fragmentStoresAndAtomics = true ||" src/panfrost/vulkan/panvk_vX_physical_device.c
# r6 sanity: VK_EXT_legacy_dithering advertised
grep -q '\.EXT_legacy_dithering = true,' src/panfrost/vulkan/panvk_vX_physical_device.c
grep -q '\.legacyDithering = true,' src/panfrost/vulkan/panvk_vX_physical_device.c
grep -q "xfb_topology" src/panfrost/vulkan/panvk_shader.h
grep -q "panvk_xfb_topology" src/panfrost/vulkan/panvk_shader.h
test -f src/panfrost/vulkan/panvk_vX_xfb_lower.c
+150
View File
@@ -0,0 +1,150 @@
#!/bin/bash
# Package pre-built chromium-fourier artifacts into a .deb.
#
# Chromium can't be compiled natively on any available aarch64 runner
# (clang version wall — chromium requires its internal clang fork).
# The build is cross-compiled on CT 220 (data, x86_64 Ryzen 7).
# This script expects the build artifacts to exist at BUILD_DIR
# (default: fetched from CT 220 via SSH).
#
# Sibling Arch package: ../../arch/chromium-fourier/PKGBUILD
set -euo pipefail
PKGVER=148.0.7778.178
EPOCH=1
PKGREL=1
ARCH=arm64
HERE=$(dirname "$(readlink -f "$0")")
export SOURCE_DATE_EPOCH=1779854400 # 2026-05-24 09:00 UTC
BUILD_DIR="${BUILD_DIR:-}"
work=$(mktemp -d)
trap "rm -rf $work" EXIT
if [ -z "$BUILD_DIR" ]; then
echo "BUILD_DIR not set — fetching artifacts from CT 220 on data..."
BUILD_DIR="$work/artifacts"
mkdir -p "$BUILD_DIR"
ssh root@data "pct exec 220 -- tar -cf - -C /build/chromium/src/out/Default \
chrome chrome_crashpad_handler \
libEGL.so libGLESv2.so libvk_swiftshader.so libvulkan.so.1 \
vk_swiftshader_icd.json \
chrome_100_percent.pak chrome_200_percent.pak resources.pak \
v8_context_snapshot.bin snapshot_blob.bin icudtl.dat \
locales/" | tar -xf - -C "$BUILD_DIR"
fi
ROOT="$work/pkgroot"
install -Dm755 "$BUILD_DIR/chrome" "$ROOT/usr/lib/chromium/chromium"
install -Dm755 "$BUILD_DIR/chrome_crashpad_handler" "$ROOT/usr/lib/chromium/chrome_crashpad_handler"
for so in libEGL.so libGLESv2.so libvk_swiftshader.so libvulkan.so.1; do
[ -f "$BUILD_DIR/$so" ] && install -Dm755 "$BUILD_DIR/$so" "$ROOT/usr/lib/chromium/$so"
done
for icd in "$BUILD_DIR"/*_icd.json; do
[ -f "$icd" ] && install -Dm644 "$icd" "$ROOT/usr/lib/chromium/$(basename "$icd")"
done
for f in chrome_100_percent.pak chrome_200_percent.pak resources.pak \
v8_context_snapshot.bin snapshot_blob.bin icudtl.dat; do
[ -f "$BUILD_DIR/$f" ] && install -Dm644 "$BUILD_DIR/$f" "$ROOT/usr/lib/chromium/$f"
done
if [ -d "$BUILD_DIR/locales" ]; then
install -dm755 "$ROOT/usr/lib/chromium/locales"
cp -r "$BUILD_DIR/locales/"* "$ROOT/usr/lib/chromium/locales/"
fi
install -dm755 "$ROOT/usr/bin"
cat > "$ROOT/usr/bin/chromium-fourier" <<'LAUNCHER'
#!/bin/bash
USER_HANDLES_VULKAN=0
for arg in "$@"; do
case "$arg" in
--use-vulkan*|--enable-features=*Vulkan*|--disable-features=*Vulkan*|--use-angle=vulkan*)
USER_HANDLES_VULKAN=1
break
;;
esac
done
vulkan_default=()
if [ "$USER_HANDLES_VULKAN" = 0 ]; then
vulkan_default=(--disable-features=Vulkan)
fi
exec /usr/lib/chromium/chromium \
--ozone-platform=wayland \
--use-gl=angle --use-angle=gles \
--enable-features=AcceleratedVideoDecoder \
"${vulkan_default[@]}" \
"$@"
LAUNCHER
chmod 0755 "$ROOT/usr/bin/chromium-fourier"
mkdir -p "$ROOT/usr/share/doc/chromium-fourier" "$ROOT/DEBIAN"
install -Dm644 "$HERE/debian/copyright" \
"$ROOT/usr/share/doc/chromium-fourier/copyright"
install -Dm644 "$HERE/debian/changelog" \
"$ROOT/usr/share/doc/chromium-fourier/changelog.Debian"
gzip -9 -n "$ROOT/usr/share/doc/chromium-fourier/changelog.Debian"
ISIZE=$(du -sk "$ROOT" | awk '{print $1}')
cat > "$ROOT/DEBIAN/control" <<EOF
Package: chromium-fourier
Version: ${EPOCH}:${PKGVER}-${PKGREL}
Section: web
Priority: optional
Architecture: ${ARCH}
Installed-Size: ${ISIZE}
Depends: libasound2,
libatk-bridge2.0-0,
libatk1.0-0,
libcairo2,
libcups2,
libdbus-1-3,
libdrm2,
libexpat1,
libfontconfig1,
libfreetype6,
libgbm1,
libglib2.0-0,
libgtk-3-0,
libnspr4,
libnss3,
libpango-1.0-0,
libpulse0,
libva2,
libwayland-client0,
libx11-6,
libxcb1,
libxkbcommon0,
libpipewire-0.3-0,
fonts-liberation,
v4l-utils
Provides: www-browser
Conflicts: chromium
Maintainer: Markus Fritsche <mfritsche@reauktion.de>
Homepage: https://www.chromium.org/
Description: Chromium with V4L2 HW video decode for Rockchip (Wayland + mainline)
Chromium ${PKGVER} with three patches enabling V4L2 hardware video
decoding on mainline Linux / Wayland for Rockchip SoCs (RK3566 hantro,
RK3588 VDPU381).
.
Cross-compiled from x86_64 using chromium's bundled clang (upstream
LLVM cannot compile chromium). Runtime target is aarch64.
.
Patches: enable-v4l2-decoder-default, wayland-allow-direct-egl-gles2,
nv12-external-oes-on-modifier-external-only.
.
Launcher at /usr/bin/chromium-fourier defaults to Wayland + ANGLE/GLES
with Vulkan disabled (panvk on RK3566 breaks V4L2 dispatch).
EOF
DEB_OUT="chromium-fourier_${EPOCH}%3a${PKGVER}-${PKGREL}_${ARCH}.deb"
dpkg-deb --root-owner-group --build "$ROOT" "$HERE/$DEB_OUT"
echo "built: $HERE/$DEB_OUT"
+8
View File
@@ -0,0 +1,8 @@
chromium-fourier (1:148.0.7778.178-1) trixie; urgency=medium
* Chromium 148.0.7778.178 with V4L2 HW decode patches for Rockchip.
* Cross-compiled from x86_64 using chromium's bundled clang.
* Three fourier patches: enable-v4l2-decoder-default,
wayland-allow-direct-egl-gles2, nv12-external-oes-on-modifier-external-only.
-- Markus Fritsche <mfritsche@reauktion.de> Sat, 24 May 2026 09:00:00 +0200
+32
View File
@@ -0,0 +1,32 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Chromium
Upstream-Contact: chromium-dev@chromium.org
Source: https://www.chromium.org/
Files: *
Copyright: The Chromium Authors
License: BSD-3-Clause
Files: debian/*
Copyright: 2026 Markus Fritsche <mfritsche@reauktion.de>
License: BSD-3-Clause
License: BSD-3-Clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
.
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.