Skip to content

Instantly share code, notes, and snippets.

@rygorous
rygorous / gist:6f96cc21292cc704f53ef77e5b4be519
Created May 22, 2025 02:25
Oodle Texture BC7RD "preserve extremes" constraint validation
//===================================================================
// constraint validation for preserve extremes mode
// Cold part of are_endpoitns_permitted: the actual constraint validation
static RADNOINLINE bool are_endpoints_permitted_cold(const BC7BlockState & st, const bc7rd_blockinfo& info)
{
const BC7Flags flags = info.flags;
if (st.mode <= 3)
{
@rygorous
rygorous / gist:52cc2a23a73813d645581046dced27fd
Created May 22, 2025 00:15
Oodle Texture "preserve extremes" rules
{
BC7Flags flags = in_flags;
// Preserve extremes mode.
//
// This mode preserves values of 0 and 255 in the alpha channel exactly. In general,
// we can do this in any one channel, but restricting this to alpha makes the interface
// simpler, is consistent with what we do for BC3, and doesn't seem like a signfiicant
// limitation for the user.
//
uint EvenBitMask = 0x55555555u;
uint HighIndexBit = PackedIndices >> 1;
float NumWeight1 = float(countbits(EvenBitMask & ~HighIndexBit & PackedIndices));
float NumWeight2 = float(countbits(EvenBitMask & HighIndexBit & ~PackedIndices));
float NumWeight3 = float(countbits(EvenBitMask & HighIndexBit & PackedIndices));
// with NV LOP3: 1 shift, 3 LOP3, 3 pop count, 3 int->float = 10 insns total for 16 pixels
// without: 1 shift, 2 NOT, 5 AND, 3 pop count, 3 int->float = 14 insns total for 16 pixels
@rygorous
rygorous / rr_dds.h
Created March 7, 2025 01:45
rr_dds loader/writer
//===================================================
// Oodle2 DDS Tool
// (C) Copyright 1994-2022 Epic Games Tools LLC
//===================================================
#ifndef RR_DDS_INCLUDED
#define RR_DDS_INCLUDED
#include <stdint.h>
#include <stddef.h>
@rygorous
rygorous / main.rs
Created March 2, 2025 04:42
Base64 fixed point test
use bit_set::BitSet;
use std::mem;
// Vanilla RFC 4648
const ALPHABET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// URL-safe RFC 4648
//const ALPHABET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
const COUNT: usize = 1usize << 24; // 3 bytes worth suffices for this test
fn lookup(index: u32) -> u32 {
@rygorous
rygorous / bc7rd_chart_example.html
Created January 2, 2025 09:46
Example run with a BC7 RD plot diff
<!DOCTYPE html>
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style>
body { background: #fff; margin: 10px; font: 12pt Calibri,Arial,Helvetica,sans-serif; }
h1 { font-size: 18pt; margin: .5em 0 .5em 0; }
h2 { font-size: 16pt; margin: .5em 0 .5em 0; }
canvas { margin: auto; }
table { border-spacing: 0; }
table.rdresult tbody tr:nth-child(even) { background: #eee; }
@rygorous
rygorous / rdchart_template_prefix.html
Created January 2, 2025 09:40
RD chart template for Oodle Texture eval
<!DOCTYPE html>
<html>
<head>
<style>
body { background: #fff; margin: 10px; font: 12pt Calibri,Arial,Helvetica,sans-serif; }
h1 { font-size: 18pt; margin: .5em 0 .5em 0; }
h2 { font-size: 16pt; margin: .5em 0 .5em 0; }
canvas { margin: auto; }
table { border-spacing: 0; }
table.rdresult tbody tr:nth-child(even) { background: #eee; }
@rygorous
rygorous / main.cpp
Created December 24, 2024 15:07
Direct UNORM/SNORM conversion test program
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
static uint32_t float_to_bits(float x)
{
uint32_t u;
memcpy(&u, &x, sizeof(x));
return u;
// ep1 - ep0 >= 0: four-interpolated color mode
// ep1 - ep0 < 0: six-interpolated-color mode
//
// we want to avoid ep0 = ep1 in general (because it gives us no useful
// interpolated values). That means in four-interp mode we want ep1 - ep0 > 0,
// and in six-interp mode we want ep1 - ep0 < 0. If they're identical or
// have the wrong sign, we need to fix it!
int ep_diff = ((ep1_int - ep0_int) ^ target_sign) - target_sign;
if (ep_diff <= 0)
{
template <int t_nbits>
static inline void quant_endpoint_with_pbit(U8 *deq0, U8 *deq1, int val)
{
const int expanded_nbits = t_nbits + 1;
const U32 range = 1u << expanded_nbits;
const U32 recip255 = 0x8081; // enough bits for our value range
const int postscale = (0x10000 >> t_nbits) + (0x10000 >> (t_nbits*2 + 1));
// The reconstruction here adds the pbit as the lowest bit and then reconstructs
// it as a (nbits+1)-bit value to float, i.e. (quant*2 + pbit) / (range - 1).