HLSL++

repository·master·Indexed 22 days ago

https://github.com/redorav/hlslpp

A header-only C++ math library that mirrors HLSL shading language syntax, featuring swizzling, native types, and common math functions. It supports multiple SIMD backends including SSE, AVX, AVX2, AVX512, NEON, and WASM, with a scalar fallback via HLSLPP_SCALAR. The library includes an interop namespace for C++ structs compatible with GPU constant buffers. The repository also contains a Premake extension module for configuring Xbox 360 XDK build projects.

Tokens
1.6K
Snippets
5
Records
7
Agent score
28%

What's inside hlslpp

  1. Ensure C++ and Shader memory compatibility with interop types

    master

    Because HLSL++ internal types use SIMD vectors, they may have different alignment/layout requirements than what a shader expects in a constant buffer.

    To create C++ structs that are safely compatible with GPU constant buffers, use the hlslpp::interop namespace. These classes do not assume SIMD alignment and follow standard HLSL packing rules.

    Example of a compatible struct:

    struct alignas(16) MyData
    {
      hlslpp::interop::float4 data0;
      hlslpp::interop::float3 data1;
      float data2;
      hlslpp::interop::float3x4 data3;
    };

    Always ensure you add necessary padding and alignment (e.g., using alignas) to respect shader layout rules.

  2. Use HLSL++ syntax and features in C++

    master

    HLSL++ provides a C++ interface that mirrors HLSL shading language syntax, including swizzling, native types, and common math functions.

    Key Capabilities:

    • Swizzling: Access components using .x, .y, .z, .w or .r, .g, .b, .a. Supports swizzling of swizzles (e.g., foo.wx = bar.yx).
    • Constructors: Create vectors and matrices using HLSL-style constructors like float4(1, 2, 3, 4) or combined constructors like float4(vec2, vec2).
    • Matrix Operations: Use mul(matrix, vector) for transformations and access static methods for common matrices like float4x4::identity() or float4x4::perspective().
    • Extended Types: Supports float8 for wide SIMD registers and quaternion types.
    • Data Packing: Use functions like pack_float4_rgba8_unorm and unpack_rgba8_unorm_float4 for efficient data handling.
    • Pointer Interop: Overloaded & operator on individual swizzle members (e.g., &foo.x) allows passing component addresses to libraries like ImGui.
    // Native types and Swizzling
    float4 foo4 = float4(1, 2, 3, 4);
    float3 bar3 = foo4.xzy;
    
    // HLSL functions
    float2 logFoo2 = log(bar3.xz);
    
    // Swizzle of swizzle
    foo4.wx = logFoo2.yx;
    
    // Combined constructors
    float4 baz4 = float4(logFoo2, foo4.zz);
    
    // Matrices and transformations
    float4x4 fooMatrix4x4 = float4x4( 1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1);
    float4 myTransformedVector = mul(fooMatrix4x4, baz4);
    
    // Data packing
    uint rgba8Packed     = pack_float4_rgba8_unorm(foo4);
    float4 rgba8Unpacked = unpack_rgba8_unorm_float4(rgba8Packed);
  3. Configure an Xbox 360 project in Premake

    master

    Once the module is imported, you can target the Xbox 360 platform by setting the system to "xbox360". You can use specific Xbox 360 properties to configure the build, such as the output executable name, Title ID, base address, and profiling settings. It is recommended to wrap these settings in a platform filter to ensure they only apply to your Xbox 360 configuration.

    workspace "MyWorkspace"
    	configurations { "Debug", "Release" }
    	
    	platforms { "MyXbox360Config" }
    	
    	filter { "platforms:MyXbox360Config" }
    		system("xbox360")
    	
    		-- Xbox360-specific properties
    		xexoutput("test_output.xex")
    		titleid("0x1234567")
    		baseaddress("0x88000000")
    		inlineassembly("true")
    		prescheduling("true")
    		callattributedprofiling("callcap")
  4. Install and import the Xbox 360 module

    master

    To use this module, clone or download the repository to a location accessible by Premake. In your project's Premake script, import the module using the require function with the path to the xbox360 file within the module directory.

    require("premake-xbox360/xbox360")
  5. Install and include HLSL++ in your project

    master

    HLSL++ is a header-only math library. To use it, add the library's include directory to your project's include paths. Depending on your needs, choose one of the following inclusion strategies:

    • Fast iteration (easiest): Include the single header hlsl++.h. This is convenient but can increase compile times.
    • Optimized compile times: Include specific headers for vectors and matrices:
      • #include "hlsl++/vector_float.h"
      • #include "hlsl++/matrix_float.h"
    • Type-only usage: If you only need type information (e.g., in header files) without using functions, include the _type.h variants:
      • #include "hlsl++/vector_float_type.h"
      • #include "hlsl++/quaternion_type.h"

    Important Notes:

    • Windows Users: If you are using <windows.h>, you must #define NOMINMAX before including it to prevent conflicts with min and max macros.
    • Scalar Fallback: To force a scalar implementation (useful for embedded platforms without SIMD or for performance testing), define HLSLPP_SCALAR globally.
    // Quickest way
    #include "hlsl++.h"
    
    // For better compile times
    #include "hlsl++/vector_float.h"
    #include "hlsl++/matrix_float.h"
    
    // For type information only
    #include "hlsl++/vector_float_type.h"
    #include "hlsl++/quaternion_type.h"
  6. Supported Platforms and SIMD backends

    master

    HLSL++ is a cross-platform library supporting various SIMD instruction sets:

    • x86/x64 (PC, PS4/5, Xbox): SSE, AVX, AVX2, AVX512
    • ARM (Android, Mac M1/M2, iOS, Switch): NEON
    • Web: WASM
    • Fallback: If no SIMD is available, you can use the scalar implementation by defining HLSLPP_SCALAR globally.