Making it easier to work with shaders



Linux Build Status Windows Build Status

Slang is a shading language that makes it easier to build and maintain large shader codebases in a modular and extensible fashion, while also maintaining the highest possible performance on modern GPUs and graphics APIs. Slang is based on years of collaboration between researchers at NVIDIA, Carnegie Mellon University, and Stanford.

Key Features

The Slang system is designed to provide developers of real-time graphics applications with the services they need when working with shader code.

  • Slang is backwards-compatible with most existing HLSL code. It is possible to start taking advantage of Slang's benefits without rewriting or porting your shader codebase.

  • The Slang compiler can generate code for a wide variety of targets and APIs: D3D12, Vulkan, D3D11, OpenGL, CUDA, and CPU. Slang code can be broadly portable, but still take advantage of the unique features of each platform.

  • Parameter blocks (exposed as ParameterBlock<T>) provide a first-class language feature for grouping related shader parameters and specifying that they should be passed to the GPU as a coherent block. Parameter blocks make it easy for applications to use the most efficient parameter-binding model of each API, such as descriptor tables/sets in D3D12/Vulkan.

  • Generics and interfaces allow shader specialization to be expressed cleanly without resort to preprocessor techniques or string-pasting. Unlike C++ templates, Slang's generics are checked ahead of time and don't produce cascading error messages that are difficult to diagnose. The same generic shader can be specialized for a variety of different types to produce specialized code ahead of time, or on the fly, completely under application control.

  • Slang provides a module system that can be used to logically organize code and benefit from separate compilation. Slang modules can be compiled offline to a custom IR (with optional obfuscation) and then linked at runtime to generate DXIL, SPIR-V etc.

  • Rather than require tedious explicit register and layout specifications on each shader parameter, Slang supports completely automate and deterministic assignment of binding locations to parameter. You can write simple and clean code and still get the deterministic layout your application wants.

  • For applications that want it, Slang provides full reflection information about the parameters of your shader code, with a consistent API across all target platforms and graphics APIs. Unlike some other compilers, Slang does not reorder or drop shader parameters based on how they are used, so you can always see the full picture.

Getting Started

If you want to try out the Slang language without installing anything, a fast and simple way is to use the Shader Playground.

The fastest way to get started using Slang in your own development is to use a pre-built binary package, available through GitHub releases. There are packages built for 32- and 64-bit Windows, as well as 64-bit Ubuntu. Each binary release includes the command-line slangc compiler, a shared library for the compiler, and the slang.h header.

If you would like to build Slang from source, please consult the build instructions.


The Slang project provides a variety of different documentation, but most users would be well served starting with the User's Guide.

We also provide a few examples of how to integrate Slang into a rendering application.


If you'd like to contribute to the project, we are excited to have your input. The following guidelines should be observed by contributors:

  • Please follow the contributor Code of Conduct.
  • Bugs reports and feature requests should go through the GitHub issue tracker
  • Changes should ideally come in as small pull requests on top of master, coming from your own personal fork of the project
  • Large features that will involve multiple contributors or a long development time should be discussed in issues, and broken down into smaller pieces that can be implemented and checked in in stages


The Slang project has been used for production applications and large shader codebases, but it is still under active development. Support is currently focused on the platforms (Windows, Linux) and target APIs (Direct3D 12, Vulkan) where Slang is used most heavily. Users who are looking for support on other platforms or APIs should coordinate with the development team via the issue tracker to make sure that their use case(s) can be supported.


The Slang code itself is under the MIT license (see LICENSE).

Builds of the core Slang tools depend on the following projects, either automatically or optionally, which may have their own licenses:

Slang releases may include slang-llvm which includes LLVM under the license:

  • llvm (Apache 2.0 License with LLVM exceptions)

Some of the tests and example programs that build with Slang use the following projects, which may have their own licenses:

  • glm (MIT)
  • stb_image and stb_image_write from the stb collection of single-file libraries (Public Domain)
  • tinyobjloader (MIT)
  • Fix ARM64 detection for MSVC

    Fix ARM64 detection for MSVC

    Small one to fix ARM64 not being detected correctly for MSVC building for windows ARM64.

    Would be awesome to see windows arm64 binaries attached to releases as well, but I wasn't sure what needed to change to make that happen.

    opened by englercj 14
  • Poor performance when reading float4x4 uniform with dynamic array index

    Poor performance when reading float4x4 uniform with dynamic array index

    This may or may not be an issue of Slang, but I have observed a strange performance issue in my shader that is probably worth noting here.

    On Vulkan, I defined a uniform float4x4 array in my shader code (in this case, the lightMatrix for cascaded shadow maps), and as long as I am accessing the array in a loop, the performance drops dramatically (from ~200fps to 20fps), even after I changed loop to do nothing else but accessing the data.

    The performance issue is solved by manually unrolling the loop, and make sure the shader is only using constants as indices into the array. I also tried to just define float4 arrays, and construct a float4x4 by manually loading 4 float4s, but that doesn't seem to work either. However, the same issue does not exist for float4x3 arrays.

    Note that it does not matter whether the code is actually executed or not, the existence of such code causes the slow down of entire pixel shader execution, even if the access is in a branch that is never executed.

    I feel that this may have something to do with row_major, and if that is the case, then we definitely should generate code to handle all input fetching ourselves (as we discussed last time).

    opened by csyonghe 13
  • Do uniforms have incorrect

    Do uniforms have incorrect "set" index in Spirv?


    I was trying slang for a while and noticed for SPIRV (and GLSL) the ParameterBlock is converted to a uniform with set=1 decorator. Shouldn't that be set=0?

    Input: shader.slang:

    struct UBOData {
        float4x4 model;
        float4x4 view;
        float4x4 proj;
    ParameterBlock<UBOData> ubo;

    GLSL output:

    layout(binding = 0, set = 1)
    layout(std140) uniform _S1
        UBOData_0 ubo_0;

    Shouldn't set be 0? Same with SPIRV's disassembly: OpDecorate %_ DescriptorSet 1

    I am trying to run some vulkan code, and my pipeline layout has only 1 descriptor set which is set 0. Is there any specific reason to go with set 1?

    Ran on Slang binary: v0.10.32

    kind:bug scenario:cross compilation area:reflection 
    opened by vasumahesh1 13
  • Hitting

    The issue reproduces with the compute shader from Falcor on the latest:

    Any write to a UAV of the pattern:

    uavTexture[coord] = foo;

    fails with this error.

    kind:bug area:semantic checking 
    opened by zbethel 13
  • API for compiling entry point sets

    API for compiling entry point sets

    Proposing the following API:

    struct Value
        int valueType;
        char * stringValue;
        int intValue;
        float floatValue;
    struct EntryPointSet
         const char * name;
         SlangProfileID vsProfile, psProfile, hsProfile, gsProfile, dsProfile;
         int specializationArgumentCount;
         Value ** arguments;
    int spAddEntryPointSet(compileRequest, EntryPointSet entryPointSet);
    SLANG_API char const* spGetEntryPointSetSource(
            SlangCompileRequest*    request,
            int                     entryPointSetIndex,
            SlangStage       stage);
    SLANG_API char const* spGetEntryPointSetCode(
            SlangCompileRequest*    request,
            int                     entryPointSetIndex,
            SlangStage       stage);

    When a compile request gets executed, it will compile the entry points defined in an entry point set using the corresponding profiles. The compiled code can be retrieved via spGetEntryPointSetSource and spGetEntryPointSetCode functions. spGetEntryPointSetSource returns null if the corresponding stage is not defined by the entry point set.

    kind:enhancement kind:design area:API 
    opened by csyonghe 10
  • Vector comparison returns wrong type

    Vector comparison returns wrong type

    Vector comparison operators such as operator ==(float3, float3) should return bool3, which shouldn't be allowed directly as if condition or in branching(x?y:z) expressions.

    Currently Slang does not issue any diagnostic message when source code does this, and generates invalid HLSL/GLSL that fails downstream compilation.

    opened by csyonghe 9
  • Float operation is in 16 bit precision?

    Float operation is in 16 bit precision?

    Hi, In slang shader I write:

    float computeRoot(float b, float c, int2 uv)
        float d = b * b - 4 * c;
        gDebugTexture[uv] = float4(b*b,4*c,d,0);
        return d;

    upon inspecting in renderdoc, the input of b = 0.016f; c = 0.00006f; I would expect b*b = 0.000256f, 4 * c = 0.00024, and d = 0.000016f; But in renderdoc it actually shows that gDebugTexture[uv] = ( 0.00026, 0.00026, 0, 0). Which means that b*b is calculated into 0.00026 with the same value as 4 * c becoming 0.00026. In turns the d becomes 0.

    This doesn't seems to be executing at 32 bit floating point precision. Looks more like half floating point precision. If I look at the spir-v code in renderdoc, i don't see any converting into half floating point.

    Any idea why this is happening?


    kind:question target:glsl scenario:cross compilation 
    opened by KaChen-Dex 8
  • Using associatedtypes from global generic type parameter does not work

    Using associatedtypes from global generic type parameter does not work

    //TEST(compute):COMPARE_COMPUTE:-xslang -use-ir
    //TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out
    //TEST_INPUT:type AssocImpl
    RWStructuredBuffer<float> outputBuffer;
    interface IBase
        float getVal();
    interface IAssoc
        associatedtype TBase : IBase;
    struct BaseImpl : IBase
        float getVal() { return 1.0; }
    struct AssocImpl : IAssoc
        typedef BaseImpl TBase;
    __generic_param T : IAssoc;
    [numthreads(4, 1, 1)]
    void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
        uint tid = dispatchThreadID.x;
        T.TBase base;
        float rs = base.getVal();
        outputBuffer[tid] = rs;

    Output HLSL contains FuncType = /*unhandled case*/

    opened by csyonghe 8
  • Support `static` methods

    Support `static` methods

    To express entry point functions in a entry-point-set struct, we need to be able to define the entry point functions as static methods of a struct type.

    For example, we should be able to compile:

    struct EPS
          static VSOut vsMain(VSIn vsIn) {}
          static FSOut fsMain(VSOut vsOut) {}
    kind:enhancement area:ir area:semantic checking 
    opened by csyonghe 8
  • Generate GLSL bindings for separate texture/sampler objects

    Generate GLSL bindings for separate texture/sampler objects

    To support OpenGL applications, Slang needs to have a story for generating GLSL bindings of separate texture / sampler objects.

    While it is relatively easier to just add support for combined texture/sampler objects for all targets, it feels limiting since it forces developers who wish to target OpenGL to author shader code using only combined texture/samplers.

    Ideally, I should be able to write the following code:

    Texture2D tex1;
    Texture2D tex2;
    SamplerState samplerState;
    void func()
        vec4 v1 = tex1.Sample(samplerState, uv);
        vec4 v2 = tex2.Sample(samplerState, uv);

    Slang should generate the following GLSL:

    layout(binding = 0) sampler2D tex1;
    layout(binding = 1) sampler2D tex2;

    And provide the following reflection data:

    tex1: type = texture2D,  binding = 0
    tex2: type = texture2D, binding = 1
    samplerState: type = sampler, binding = {0, 1} // this sampler is used at texture unit 0 and 1

    There is one case that we cannot easily handle: when the shader code samples one Texture2D object with two different sampler objects, it actually needs two different sampler2D declarations in GLSL, and need to tell the host to setup two different combined texture/samplers and bind them to the pipeline. I don't see a easy way to do this without adding complexity to the reflection API and the host logic. So it might be helpful for the compiler to just emit error message when this happens.

    kind:enhancement target:glsl scenario:cross compilation 
    opened by csyonghe 8
  • No type conformances are found when placed in other modules

    No type conformances are found when placed in other modules

    The documentation for loadModule() states:

    Executing loadModule("MyShaders") in host C++ code is similar to using import MyShaders in Slang code. The session will search for a matching module (usually in a file called MyShaders.slang) and will load and compile it (if it hasn’t been done already).

    Now I'm trying to create an interface and place a struct conforming to that interface in a different (potentially generated) file, and load it with loadModule(). I have created a sample reproducing the issue:


    interface IMaterial
        float4 sample(float2 texCoord);
    ParameterBlock<IMaterial> gMaterial;


    import Mat;
    struct SimpleMaterial : IMaterial
        float4 sample(float2 texCoord)
            return float4(1, 0, 1, 1);


    import Mat;
    float4 fragmentMain(float2 texCoord)
        return gMaterial.sample(texCoord);


    #include <slang.h>
    #include <slang-com-ptr.h>
    #include <map>
    #include <array>
    struct ShaderCreateInfo
        std::string mainModule;
        std::vector<std::string> additionalModules;
        std::string name; // Debug info
        std::string entryPoint;
        std::vector<const char*> typeParameter;
        std::map<const char*, const char*> defines;
    int main()
        ShaderCreateInfo createInfo =
            .mainModule = "shaders.slang",
            .additionalModules = { "Simple" },
            .name = "TestCompile",
            .entryPoint = "fragmentMain",
            .typeParameter = { "SimpleMaterial" }
        thread_local Slang::ComPtr<slang::IGlobalSession> globalSession;
        slang::SessionDesc sessionDesc;
        sessionDesc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
        sessionDesc.flags = 0;
        std::vector<slang::PreprocessorMacroDesc> macros;
        for(auto define : createInfo.defines)    
                .name = define.first,
                .value = define.second
        sessionDesc.preprocessorMacroCount = macros.size();
        sessionDesc.preprocessorMacros =;
        slang::TargetDesc vulkan;
        vulkan.profile = globalSession->findProfile("glsl_vk");
        vulkan.format = SLANG_SPIRV;
        sessionDesc.targetCount = 1;
        sessionDesc.targets = &vulkan;
        std::array<const char*, 3> searchPaths = {"shaders/", "shaders/lib/", "shaders/generated/"};
        sessionDesc.searchPaths =;
        sessionDesc.searchPathCount = searchPaths.size();
        Slang::ComPtr<slang::ISession> session;
        globalSession->createSession(sessionDesc, session.writeRef());
        Slang::ComPtr<slang::IBlob> diagnostics;
        std::vector<slang::IComponentType*> modules;
        Slang::ComPtr<slang::IEntryPoint> entrypoint;
        for (auto moduleName : createInfo.additionalModules)
            modules.push_back(session->loadModule(moduleName.c_str(), diagnostics.writeRef()));
                std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
        slang::IModule* mainModule = session->loadModule(createInfo.mainModule.c_str(), diagnostics.writeRef());
            std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
        mainModule->findEntryPointByName(createInfo.entryPoint.c_str(), entrypoint.writeRef());
        Slang::ComPtr<slang::IComponentType> moduleComposition;
        session->createCompositeComponentType(, modules.size(), moduleComposition.writeRef(), diagnostics.writeRef());
            std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
        //slang::ProgramLayout* reflection = moduleComposition->getLayout(0, diagnostics.writeRef());
        //    std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
        //std::vector<slang::SpecializationArg> specialization;
        //for(auto typeArg : createInfo.typeParameter)
        //    specialization.push_back(slang::SpecializationArg::fromType(reflection->findTypeByName(typeArg)));
        //Slang::ComPtr<slang::IComponentType> specializedComponent;
        //moduleComposition->specialize(, specialization.size(), specializedComponent.writeRef(), diagnostics.writeRef());
        //    std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
        Slang::ComPtr<slang::IBlob> kernelBlob;
            std::cout << (const char*)diagnostics->getBufferPointer() << std::endl;
        return 0;

    Running this gives me the following error

    shaders/Mat.slang(1): error 50100: No type conformances are found for interface 'IMaterial'. Code generation for current target requires at least one implementation type present in the linkage. interface IMaterial ^~~~~~~~~

    Notice that the code for creating a specialized Component is commented out, as it gives me different error:

    (0): error 38025: expected 0 specialization arguments (1 provided)

    This hints that the ParameterBuffer is not recognized as a type parameter so I tried explicitly introducing it in Mat.slang:

    type_param TMaterial : IMaterial;
    ParameterBuffer<TMaterial> gMaterial;

    This still gives the error about no specialization arguments being expected, and crashes the kernel code generation entirely at lowerCallToInterfaceMethod() in file slang-ir-lower-generic-call.cpp:285

    I guess I'm using the API incorrectly, so help would be much appreciated. Thanks in advance.

    opened by Dynamitos 7
  • Multi-block reverse-mode autodiff

    Multi-block reverse-mode autodiff

    Added support for multiple blocks resulting from conditional control flow. Restructured the unzip and transposition passes to achieve this.

    The current strategy is to create a uint 'control' variable for every block that holds an index identifying the previous executed block. The primal blocks assign the appropriate index (which is then checked by the reverse-mode differential blocks)

    For now, we only support IRIfElse, but support can be extended for switch-case statements.

    Also fixed minor issues with the intermediates-splitting logic that arose as a result of multiple blocks.

    opened by saipraveenb25 0
  • Internal error around interface inheritance

    Internal error around interface inheritance

    Note! This may/may not be a problem in current Slang, but can be shown on 0.24.20 in shader playground

    Take the following code...

    RWStructuredBuffer<float> outputBuffer;
    interface IA
        int doThing(int a);
    interface IB : IA
        int anotherThing(int a);
    struct Struct : IB
        int doThing(int a) { return a + 1; }
        int anotherThing(int a) { return a * a; }
    int doThing<B : IB>(B b, int c)
        return b.doThing(c) + b.anotherThing(c);
    [numthreads(4, 1, 1)]
    void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
    	uint tid = dispatchThreadID.x;
        Struct s;
        int v = doThing(s, int(tid));
    	float inVal = float(tid + v);
    	outputBuffer[tid] = inVal;

    Will cause an internal error with

    (0): error 99999: Slang compilation aborted due to an exception of class Slang::InternalError: assert failure: The key does not exists in dictionary.

    It may(?) be of interest that if you replace

    int doThing<B : IB>(B b, int c)


    int doThing(IB b, int c) 

    Then compilation completes without problem.

    Note: have confirmed the problem occurs on 0.24.8 where the problem was originally reported.

    opened by jsmall-nvidia 0
  • Use SPIR-V opcode names rather than numbers

    Use SPIR-V opcode names rather than numbers

    WIP: I think there are still a few in *.meta.slang that my awk script didn't catch.

    Besides the noise the changes are in:

    • source/slang/slang-emit-spirv.cpp
    • tools/slang-lookup-generator/lookup-generator-main.cpp (This is a small program which extracts the spirv (or extinst) opnames from the json files in spirv-headers and generates a lookup table for them).
    • premake5.lua
    opened by expipiplus1 0
  • struct forward declarations  and non-inline method definitions

    struct forward declarations and non-inline method definitions

    Hi, I am moving code from a DXC compiled base to Slang. I ran into the following problems making porting the shader code an issue for code readability.

    1. struct forward declarations not working
    2. non-inline method definitions are not working

    The following is valid DXC code that does not compile using Slang:

    struct PSInput
    	float4 color : COLOR;
    class SDR;
    class SDR
        float4 do_smth();
    float4 SDR::do_smth()
        return float4(1.0, 0.0, 1.0, 1.0);
    float4 PSMain(PSInput input) : SV_TARGET
        const SDR sdr;
    	return sdr.do_smth();//input.color;

    Is this by design? With a larger shader code base I find it very important to have a good overview of struct interfaces and data members and the implementation details separate.

    opened by chrislu 1
  • Shader debugging via RenderDoc

    Shader debugging via RenderDoc

    I'm trying to debug the execution of one of my fragment shaders using RenderDoc, but I can't seem to deduce the required incantation to make slangc produce debug output. I have added the -g3, -O0, and "-Xglslang gVS" args to no avail.

    Does slang not support source-level debugging or am I just missing something?

    Thank you.

    opened by NickDriscoll 9
A modern-day Boss Key software tool. Switch instantly from work to play & play to work with Bosky.

Bosky By: Seanpm2001, Bosky-dev Et; Al. Top Read this article in a different language Sorted by: A-Z Sorting options unavailable ( af Afrika

Sean P. Myrick V19.1.7.2 2 Sep 10, 2022
SKSE plugin for replacing Skyrim SE shaders at launch.

Plugin for SSE Parallax Shader Fix. Requirements CMake Add this to your PATH PowerShell Vcpkg Add the environment variable VCPKG_ROOT with the value a

null 8 Nov 30, 2022
Hydrogen is a tiny GDI Malware, with some bytebeat music, many payloads and some shaders

Hydrogen is a tiny GDI Malware, with some bytebeat music, many payloads and some shaders

Leo Lezury 28 Nov 12, 2022
LLVM IR and optimizer for shaders, including front-end adapters for GLSL and SPIR-V and back-end adapter for GLSL

Licensing LunarGLASS is available via a three clause BSD-style open source license. Goals The primary goals of the LunarGLASS project are: Reduce the

LunarG, Inc. 153 Dec 8, 2022
⚔️ A tool for cross compiling shaders. Convert between GLSL, HLSL, Metal Shader Language, or older versions of GLSL.

A cross compiler for shader languages. Convert between SPIR-V, GLSL / GLSL ES, HLSL, Metal Shader Language, or older versions of a given language. Cross Shader wraps glslang and SPIRV-Cross, exposing a simpler interface to transpile shaders.

Alain Galvan 207 Dec 30, 2022
yariv.h is a single C/C++ header to encode and decode SPIR-V shaders into a more compressed form I've called YARI-V.

YARI-V yariv.h is a single C/C++ header to encode and decode SPIR-V shaders into a more compressed form I've called YARI-V. YARI-V is an alternative e

Neil Henning 31 Dec 8, 2022
A collection of post-processing shaders written for ReShade.

ReShade FX shaders This repository aims to collect post-processing shaders written in the ReShade FX shader language. Installation Download this repos

null 784 Dec 30, 2022
A collection of osl shaders

This is a collection of osl shaders that I have found. This collection is intended for use with a version of blender that has been compiled with osl

Shane Ambler 301 Dec 25, 2022
Step-by-step guide through the abstract and complex universe of Fragment Shaders.

The Book of Shaders by Patricio Gonzalez Vivo and Jen Lowe This is a gentle step-by-step guide through the abstract and complex universe of Fragment S

Patricio Gonzalez Vivo 4.9k Jan 2, 2023
dump and replace shaders of any OpenGL or Vulkan application

deshade deshade is a library that allows you to dump and replace the shaders of any OpenGL or Vulkan application, which includes: GL2 + extensions, GL

Dale Weiler 25 Aug 10, 2022
ApeX is a static library for C++ software. Originally it was created to make C++ studying easier,

ApeX is a static library for C++ software. Originally it was created to make C++ studying easier, so it has functions to complete common tasks with just one line of code. But who knows, maybe this library will get bigger some day

null 0 Jan 18, 2022
A single file, single function, header to make notifications on the PS4 easier

Notifi Synopsis Adds a single function notifi(). It functions like printf however the first arg is the image to use (NULL and any invalid input should

Al Azif 9 Oct 4, 2022
Seam is a pin-based node editor for OpenFrameworks that makes prototyping visual systems easier and faster.

seam Seam is a pin-based node editor for openFrameworks built using: openFrameworks Dear ImGui the node editor extension for ImGui It is heavily WIP,

Austin Clifton 2 Jan 2, 2022
A simple program to make your life a little easier when you evaluate the Rush exercises at 42.

Rush exercise number A simple program to make your life a little easier when you evaluate the Rush exercises at 42. Usage Run make to generate the exe

Edmar Paulino 3 Feb 7, 2022
This is the source code for for the Plugin GAS Associate, that is supposed to make your life easier while using Unreal's Gameplay Ability System.

GASAssociate Description: This is the source code for for the Plugin GAS Associate, that is supposed to make your life easier while using Unreal's Gam

Malik Sahab 22 Dec 14, 2022
making dwm as beautiful as possible

chadwm (Initial look) (empty workspaces have their color greyed out) NOTE: This is vanilla dwm bar (status2d patch for setting colors) not dwmblocks o

null 1k Dec 31, 2022
✨ Your best friend when it comes to making your output beautiful ✨

?? Fadey ✨ Your best friend when it comes to making your output beautiful ✨ ?? Content: About Requirements Installation Features Performance Shoutout

Fluffy 3 Nov 29, 2021
This repository is for my coding practice, making a text editor from scratch in C.

text-editor-practice This repository will contain my coding practice, making a text editor from scratch. I based this practice from this wonderful res

null 2 Dec 13, 2021
Making dwm as beautiful as possible!

chadwm (Initial look) (empty workspaces have their color greyed out) NOTE: This is vanilla dwm bar (status2d patch for setting colors) not dwmblocks o

null 1k Dec 31, 2022