yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// d3d11-helper-functions.h 2#pragma once 3 4#include "../../../source/core/slang-list.h" 5#include "d3d11-base.h" 6#include "slang-gfx.h" 7 8namespace gfx 9{ 10 11using namespace Slang ; 12 13namespace d3d11 14{ 15/// Contextual data and operations required when binding shader objects to the pipeline state 16struct BindingContext 17{ 18// One key service that the `BindingContext` provides is abstracting over 19// the difference between the D3D11 compute and graphics/rasteriation pipelines. 20// D3D11 has distinct operations for, e.g., `CSSetShaderResources` 21// for compute vs. `VSSetShaderResources` and `PSSetShaderResources` 22// for rasterization. 23// 24// The context type provides simple operations for setting each class 25// of resource/sampler, which will be overridden in derived types. 26// 27// TODO: These operations should really support binding multiple resources/samplers 28// in one call, so that we can eventually make more efficient use of the API. 29// 30// TODO: We could reasonably also just store the bound resources into 31// lcoal arrays like we are doing for UAVs, and remove the pipeline-specific 32// virtual functions. However, doing so would seemingly eliminate any 33// chance of avoiding redundant binding work when binding changes are 34// made for a root shader object. 35// 36virtual void setCBV (UINT index ,ID3D11Buffer * buffer )= 0 ; 37virtual void setSRV (UINT index ,ID3D11ShaderResourceView * srv )= 0 ; 38virtual void setSampler (UINT index ,ID3D11SamplerState * sampler )= 0 ; 39 40// Unordered Access Views (UAVs) are a somewhat special case in that 41// the D3D11 API requires them to all be set at once, rather than one 42// at a time. To support this, we will keep a local array of the UAVs 43// that have been bound (up to the maximum supported by D3D 11.0) 44// 45void setUAV (UINT index ,ID3D11UnorderedAccessView * uav ) 46 { 47uavs [index ]= uav ; 48 49// We will also track the total number of UAV slots that will 50// need to be bound (including any gaps that might occur due 51// to either explicit bindings or RTV bindings that conflict 52// with the `u` registers for fragment shaders). 53// 54if (uavCount <=index ) 55 { 56uavCount = index + 1 ; 57 } 58 } 59 60/// The values bound for any UAVs 61ID3D11UnorderedAccessView * uavs [D3D11_PS_CS_UAV_REGISTER_COUNT ]; 62 63/// The number of entries in `uavs` that need to be considered when binding to the pipeline 64UINT uavCount = 0 ; 65 66/// The D3D11 device that we are using for binding 67DeviceImpl * device = nullptr ; 68 69/// The D3D11 device context that we are using for binding 70ID3D11DeviceContext * context = nullptr ; 71 72/// Initialize a binding context for binding to the given `device` and `context` 73BindingContext (DeviceImpl * device ,ID3D11DeviceContext * context ) 74 :device (device ),context (context ) 75 { 76memset (uavs ,0 ,sizeof (uavs )); 77 } 78}; 79 80/// A `BindingContext` for binding to the compute pipeline 81struct ComputeBindingContext :BindingContext 82{ 83/// Initialize a binding context for binding to the given `device` and `context` 84ComputeBindingContext (DeviceImpl * device ,ID3D11DeviceContext * context ) 85 :BindingContext (device ,context ) 86 { 87 } 88 89void setCBV (UINT index ,ID3D11Buffer * buffer )SLANG_OVERRIDE 90 { 91context -> CSSetConstantBuffers (index ,1 ,& buffer ); 92 } 93 94void setSRV (UINT index ,ID3D11ShaderResourceView * srv )SLANG_OVERRIDE 95 { 96context -> CSSetShaderResources (index ,1 ,& srv ); 97 } 98 99void setSampler (UINT index ,ID3D11SamplerState * sampler )SLANG_OVERRIDE 100 { 101context -> CSSetSamplers (index ,1 ,& sampler ); 102 } 103}; 104 105/// A `BindingContext` for binding to the graphics/rasterization pipeline 106struct GraphicsBindingContext :BindingContext 107{ 108/// Initialize a binding context for binding to the given `device` and `context` 109GraphicsBindingContext (DeviceImpl * device ,ID3D11DeviceContext * context ) 110 :BindingContext (device ,context ) 111 { 112 } 113 114// TODO: The operations here are only dealing with vertex and fragment 115// shaders for now. We should eventually extend them to handle HS/DS/GS 116// bindings. (We might want to skip those stages depending on whether 117// the associated program uses them at all). 118// 119// TODO: If we support cases where different stages might use distinct 120// entry-point parameters, we might need to support some modes where 121// a "stage mask" is passed in that applies to the bindings. 122// 123void setCBV (UINT index ,ID3D11Buffer * buffer )SLANG_OVERRIDE 124 { 125context -> VSSetConstantBuffers (index ,1 ,& buffer ); 126context -> PSSetConstantBuffers (index ,1 ,& buffer ); 127 } 128 129void setSRV (UINT index ,ID3D11ShaderResourceView * srv )SLANG_OVERRIDE 130 { 131context -> VSSetShaderResources (index ,1 ,& srv ); 132context -> PSSetShaderResources (index ,1 ,& srv ); 133 } 134 135void setSampler (UINT index ,ID3D11SamplerState * sampler )SLANG_OVERRIDE 136 { 137context -> VSSetSamplers (index ,1 ,& sampler ); 138context -> PSSetSamplers (index ,1 ,& sampler ); 139 } 140}; 141 142// In order to bind shader parameters to the correct locations, we need to 143// be able to describe those locations. Most shader parameters will 144// only consume a single type of D3D11-visible regsiter (e.g., a `t` 145// register for a txture, or an `s` register for a sampler), and scalar 146// integers suffice for these cases. 147// 148// In more complex cases we might be binding an entire "sub-object" like 149// a parameter block, an entry point, etc. For the general case, we need 150// to be able to represent a composite offset that includes offsets for 151// each of the register classes known to D3D11. 152 153/// A "simple" binding offset that records an offset in CBV/SRV/UAV/Sampler slots 154struct SimpleBindingOffset 155{ 156uint32_t cbv = 0 ; 157uint32_t srv = 0 ; 158uint32_t uav = 0 ; 159uint32_t sampler = 0 ; 160 161/// Create a default (zero) offset 162SimpleBindingOffset () {} 163 164/// Create an offset based on offset information in the given Slang `varLayout` 165SimpleBindingOffset (slang ::VariableLayoutReflection * varLayout ) 166 { 167if (varLayout ) 168 { 169cbv = (uint32_t )varLayout -> getOffset (SLANG_PARAMETER_CATEGORY_CONSTANT_BUFFER ); 170srv = (uint32_t )varLayout -> getOffset (SLANG_PARAMETER_CATEGORY_SHADER_RESOURCE ); 171uav = (uint32_t )varLayout -> getOffset (SLANG_PARAMETER_CATEGORY_UNORDERED_ACCESS ); 172sampler = (uint32_t )varLayout -> getOffset (SLANG_PARAMETER_CATEGORY_SAMPLER_STATE ); 173 } 174 } 175 176/// Create an offset based on size/stride information in the given Slang `typeLayout` 177SimpleBindingOffset (slang ::TypeLayoutReflection * typeLayout ) 178 { 179if (typeLayout ) 180 { 181cbv = (uint32_t )typeLayout -> getSize (SLANG_PARAMETER_CATEGORY_CONSTANT_BUFFER ); 182srv = (uint32_t )typeLayout -> getSize (SLANG_PARAMETER_CATEGORY_SHADER_RESOURCE ); 183uav = (uint32_t )typeLayout -> getSize (SLANG_PARAMETER_CATEGORY_UNORDERED_ACCESS ); 184sampler = (uint32_t )typeLayout -> getSize (SLANG_PARAMETER_CATEGORY_SAMPLER_STATE ); 185 } 186 } 187 188/// Add any values in the given `offset` 189void operator += (SimpleBindingOffset const & offset ) 190 { 191cbv += offset .cbv ; 192srv += offset .srv ; 193uav += offset .uav ; 194sampler += offset .sampler ; 195 } 196}; 197 198// While a "simple" binding offset representation will work in many cases, 199// once we need to deal with layout for programs with interface-type parameters 200// that have been statically specialized, we also need to track the offset 201// for where to bind any "pending" data that arises from the process of static 202// specialization. 203// 204// In order to conveniently track both the "primary" and "pending" offset information, 205// we will define a more complete `BindingOffset` type that combines simple 206// binding offsets for the primary and pending parts. 207 208/// A representation of the offset at which to bind a shader parameter or sub-object 209struct BindingOffset :SimpleBindingOffset 210{ 211// Offsets for "primary" data are stored directly in the `BindingOffset` 212// via the inheritance from `SimpleBindingOffset`. 213 214/// Offset for any "pending" data 215SimpleBindingOffset pending ; 216 217/// Create a default (zero) offset 218BindingOffset () {} 219 220/// Create an offset from a simple offset 221explicit BindingOffset (SimpleBindingOffset const & offset ) 222 :SimpleBindingOffset (offset ) 223 { 224 } 225 226/// Create an offset based on offset information in the given Slang `varLayout` 227BindingOffset (slang ::VariableLayoutReflection * varLayout ) 228 :SimpleBindingOffset (varLayout ),pending (varLayout -> getPendingDataLayout ()) 229 { 230 } 231 232/// Create an offset based on size/stride information in the given Slang `typeLayout` 233BindingOffset (slang ::TypeLayoutReflection * typeLayout ) 234 :SimpleBindingOffset (typeLayout ),pending (typeLayout -> getPendingDataTypeLayout ()) 235 { 236 } 237 238/// Add any values in the given `offset` 239void operator += (SimpleBindingOffset const & offset ) {SimpleBindingOffset ::operator += (offset ); } 240 241/// Add any values in the given `offset` 242void operator += (BindingOffset const & offset ) 243 { 244SimpleBindingOffset ::operator += (offset ); 245pending += offset .pending ; 246 } 247}; 248 249bool isSupportedNVAPIOp (IUnknown * dev ,uint32_t op ); 250 251D3D11_BIND_FLAG calcResourceFlag (ResourceState state ); 252int _calcResourceBindFlags (ResourceStateSet allowedStates ); 253int _calcResourceAccessFlags (MemoryType memType ); 254 255D3D11_FILTER_TYPE translateFilterMode (TextureFilteringMode mode ); 256D3D11_FILTER_REDUCTION_TYPE translateFilterReduction (TextureReductionOp op ); 257D3D11_TEXTURE_ADDRESS_MODE translateAddressingMode (TextureAddressingMode mode ); 258D3D11_COMPARISON_FUNC translateComparisonFunc (ComparisonFunc func ); 259 260D3D11_STENCIL_OP translateStencilOp (StencilOp op ); 261D3D11_FILL_MODE translateFillMode (FillMode mode ); 262D3D11_CULL_MODE translateCullMode (CullMode mode ); 263bool isBlendDisabled (AspectBlendDesc const & desc ); 264bool isBlendDisabled (TargetBlendDesc const & desc ); 265D3D11_BLEND_OP translateBlendOp (BlendOp op ); 266D3D11_BLEND translateBlendFactor (BlendFactor factor ); 267D3D11_COLOR_WRITE_ENABLE translateRenderTargetWriteMask (RenderTargetWriteMaskT mask ); 268 269void initSrvDesc ( 270IResource ::Type resourceType , 271const ITextureResource ::Desc & textureDesc , 272DXGI_FORMAT pixelFormat , 273D3D11_SHADER_RESOURCE_VIEW_DESC & descOut ); 274}// namespace d3d11 275 276Result SLANG_MCALL getD3D11Adapters (List < AdapterInfo >& outAdapters ); 277 278Result SLANG_MCALL createD3D11Device (const IDevice ::Desc * desc ,IDevice ** outDevice ); 279 280}// namespace gfx