Files
UnrealEngineUWP/Engine/Shaders/Public/BindlessResources.ush
christopher waters 1e01768e33 Bindless shader parameters
- Adding support for bindless resources/samplers. The loose resources have to be wrapped in a macro that generates an index and proxy resource when bindless is enabled. Reflection has to parse these differently from other resources since they're parsed as uint parameters. The runtime also has to bind these differently since they end up needing to find their real resource in the binding data and then update a constant buffer.
- To assist in conversions, the shader compiler will detect if a shader is compiled with both bindless and non-bindless resources/samplers and will emit errors if that is the case.
- Adding support for bindless Uniform Buffer resources/samplers. Because Uniform Buffers aren't per-shader, they'll always update their constants with the bindless indices of their resources.
- Adding more flags to FShaderCodePackedResourceCounts required changing all the array initializations to individual parameters since not all the new flags are used everywhere.
- No shaders have been configured to support bindless resources/samplers. Yet.

#jira UE-139616
#rb zach.bethel, arciel.rekman
#preflight 6282b8ec44349a6581a21a39

[CL 20250348 by christopher waters in ue5-main branch]
2022-05-17 16:30:48 -04:00

92 lines
2.5 KiB
Plaintext

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Platform.ush"
#ifndef ENABLE_BINDLESS_RESOURCES
#define ENABLE_BINDLESS_RESOURCES 0
#endif
#ifndef ENABLE_BINDLESS_SAMPLERS
#define ENABLE_BINDLESS_SAMPLERS 0
#endif
// Indices can always be used as-is. This is important for things like Uniform Buffer layouts.
#define DEFINE_RESOURCE_INDEX(Name) uint BindlessResource_##Name
#define DEFINE_SAMPLER_INDEX(Name) uint BindlessSampler_##Name
//
#if ENABLE_BINDLESS_RESOURCES && PLATFORM_SUPPORTS_BINDLESS
#define DEFINE_RESOURCE_VARIABLE(Type, Name) \
Type GetBindlessResource##Name() \
{ \
return GetResourceFromHeap(Type, BindlessResource_##Name); \
}
#define GET_RESOURCE(Name) GetBindlessResource##Name()
#define DEFINE_RESOURCE(Type, Name) \
DEFINE_RESOURCE_INDEX(Name); \
DEFINE_RESOURCE_VARIABLE(Type, Name); \
static const Type Name = GET_RESOURCE(Name);
#else
#define DEFINE_RESOURCE_VARIABLE(Type, Name) Type Name
#define DEFINE_RESOURCE(Type, Name) Type Name
#define GET_RESOURCE(Name) Name
#endif
#if ENABLE_BINDLESS_SAMPLERS && PLATFORM_SUPPORTS_BINDLESS
#define DEFINE_SAMPLER_VARIABLE(Type, Name) \
Type GetBindlessSampler##Name() \
{ \
return GetSamplerFromHeap(Type, BindlessSampler_##Name); \
}
#define GET_SAMPLER(Name) GetBindlessSampler##Name()
#define DEFINE_SAMPLER(Type, Name) \
DEFINE_SAMPLER_INDEX(Name); \
DEFINE_SAMPLER_VARIABLE(Type, Name); \
static const Type Name = GET_SAMPLER(Name);
#else
#define DEFINE_SAMPLER_VARIABLE(Type, Name) Type Name
#define DEFINE_SAMPLER(Type, Name) Type Name
#define GET_SAMPLER(Name) Name
#endif
/*
// Uniform buffers will do:
cbuffer UniformBuffer_MyUniformBuffer
{
DEFINE_RESOURCE_INDEX(MyUniformBuffer_MyTexture);
DEFINE_SAMPLER_INDEX(MyUniformBuffer_MySampler);
};
DEFINE_RESOURCE_VARIABLE(Texture2D, MyUniformBuffer_MyTexture);
DEFINE_SAMPLER_VARIABLE(SamplerState, MyUniformBuffer_MySampler);
static const struct
{
Texture2D MyTexture;
SamplerState MySampler;
}
MyUniformBuffer = { GET_RESOURCE(MyUniformBuffer_MyTexture), GET_SAMPLER(MyUniformBuffer_MySampler) };
{ // No wrappers necessary to use
MyUniformBuffer.MyTexture.Sample(MyUniformBuffer.MySampler, ...);
}
// Normal uses will look like:
DEFINE_RESOURCE(Texture2D, MyTexture);
DEFINE_SAMPLER(SamplerState, MySampler);
{ // No wrappers necessary to use
MyTexture.Sample(MySampler, ...);
}
*/