yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

kaizhangNVImplement parameter block to slang-gfx for Metal backend (#6577)ac0dc491e

master
4.1 KiB139 linesraw
1// metal-helper-functions.h
2#pragma once
3#include "metal-base.h"
4
5namespace gfx
6{
7using namespace Slang;
8namespace metal
9{
10
11/// A "simple" binding offset that records an offset in buffer/texture/sampler slots
12struct BindingOffset
13{
14    uint32_t buffer = 0;
15    uint32_t texture = 0;
16    uint32_t sampler = 0;
17
18    /// Create a default (zero) offset
19    BindingOffset() = default;
20
21    /// Create an offset based on offset information in the given Slang `varLayout`
22    BindingOffset(slang::VariableLayoutReflection* varLayout)
23    {
24        if (varLayout)
25        {
26            buffer = (uint32_t)varLayout->getOffset(SLANG_PARAMETER_CATEGORY_METAL_BUFFER);
27            texture = (uint32_t)varLayout->getOffset(SLANG_PARAMETER_CATEGORY_METAL_TEXTURE);
28            sampler = (uint32_t)varLayout->getOffset(SLANG_PARAMETER_CATEGORY_METAL_SAMPLER);
29        }
30    }
31
32    /// Create an offset based on size/stride information in the given Slang `typeLayout`
33    BindingOffset(slang::TypeLayoutReflection* typeLayout)
34    {
35        if (typeLayout)
36        {
37            buffer = (uint32_t)typeLayout->getSize(SLANG_PARAMETER_CATEGORY_METAL_BUFFER);
38            texture = (uint32_t)typeLayout->getSize(SLANG_PARAMETER_CATEGORY_METAL_TEXTURE);
39            sampler = (uint32_t)typeLayout->getSize(SLANG_PARAMETER_CATEGORY_METAL_SAMPLER);
40        }
41    }
42
43    /// Add any values in the given `offset`
44    void operator+=(BindingOffset const& offset)
45    {
46        buffer += offset.buffer;
47        texture += offset.texture;
48        sampler += offset.sampler;
49    }
50};
51
52/// Contextual data and operations required when binding shader objects to the pipeline state
53struct BindingContext
54{
55    DeviceImpl* device = nullptr;
56    virtual void setBuffer(MTL::Buffer* buffer, NS::UInteger index) = 0;
57    virtual void setTexture(MTL::Texture* texture, NS::UInteger index) = 0;
58    virtual void setSampler(MTL::SamplerState* sampler, NS::UInteger index) = 0;
59    virtual void useResources(
60        MTL::Resource const** resources,
61        NS::UInteger count,
62        MTL::ResourceUsage usage) = 0;
63};
64
65struct ComputeBindingContext : public BindingContext
66{
67    MTL::ComputeCommandEncoder* encoder;
68
69    Result init(DeviceImpl* device, MTL::ComputeCommandEncoder* encoder)
70    {
71        this->device = device;
72        this->encoder = encoder;
73        return SLANG_OK;
74    }
75
76    void setBuffer(MTL::Buffer* buffer, NS::UInteger index) override
77    {
78        encoder->setBuffer(buffer, 0, index);
79    }
80
81    void setTexture(MTL::Texture* texture, NS::UInteger index) override
82    {
83        encoder->setTexture(texture, index);
84    }
85
86    void setSampler(MTL::SamplerState* sampler, NS::UInteger index) override
87    {
88        encoder->setSamplerState(sampler, index);
89    }
90
91    void useResources(MTL::Resource const** resources, NS::UInteger count, MTL::ResourceUsage usage)
92        override
93    {
94        encoder->useResources(resources, count, usage);
95    }
96};
97
98struct RenderBindingContext : public BindingContext
99{
100    MTL::RenderCommandEncoder* encoder;
101
102    Result init(DeviceImpl* device, MTL::RenderCommandEncoder* encoder)
103    {
104        this->device = device;
105        this->encoder = encoder;
106        return SLANG_OK;
107    }
108
109    void setBuffer(MTL::Buffer* buffer, NS::UInteger index) override
110    {
111        encoder->setVertexBuffer(buffer, 0, index);
112        encoder->setFragmentBuffer(buffer, 0, index);
113    }
114
115    void setTexture(MTL::Texture* texture, NS::UInteger index) override
116    {
117        encoder->setVertexTexture(texture, index);
118        encoder->setFragmentTexture(texture, index);
119    }
120
121    void setSampler(MTL::SamplerState* sampler, NS::UInteger index) override
122    {
123        encoder->setVertexSamplerState(sampler, index);
124        encoder->setFragmentSamplerState(sampler, index);
125    }
126
127    void useResources(MTL::Resource const** resources, NS::UInteger count, MTL::ResourceUsage usage)
128        override
129    {
130        encoder->useResources(resources, count, usage);
131    }
132};
133
134} // namespace metal
135
136Result SLANG_MCALL getMetalAdapters(List<AdapterInfo>& outAdapters);
137Result SLANG_MCALL createMetalDevice(const IDevice::Desc* desc, IDevice** outRenderer);
138
139} // namespace gfx