Skip to content

Commit ac52f87

Browse files
Custom types v2 (#48)
* Support auto-creation of textures as output * Update resourceview * Fix up all custom types so they function correctly in terms of dimensions * Start improving the custom types * Rock solid not dimension locked thread id arg! * Improved all custom types + make them not locked to dimensions * Add grid to main namespace * Fix call dimensionality check * Fix texture tests * Update SlangPy->0.19.3, SGL->0.12.4 --------- Co-authored-by: Benedikt Bitterli <[email protected]>
1 parent 903531a commit ac52f87

21 files changed

+409
-113
lines changed

docs/changelog.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
Changelog
22
---------
33

4+
**Version 0.19.3**
5+
- Update SGL -> 0.12.4
6+
- Significant improvements to generator types
7+
- Support textures as output type
8+
49
**Version 0.19.2**
510
- Update SGL -> 0.12.3
611
- Better error messages during generation

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "slangpy"
7-
version = "0.19.2"
7+
version = "0.19.3"
88
authors = [
99
{name = "Chris Cummings", email = "[email protected]"},
1010
{name = "Benedikt Bitterli", email = "[email protected]"},
@@ -17,7 +17,7 @@ requires-python = ">=3.9"
1717
dependencies = [
1818
"typing_extensions",
1919
"numpy",
20-
"nv-sgl==0.12.3"
20+
"nv-sgl==0.12.4"
2121
]
2222

2323
[tool.pyright]

requirements-dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
typing_extensions
22
numpy
3-
nv-sgl == 0.12.3
3+
nv-sgl == 0.12.4
44

55
pre-commit
66
pytest

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
typing_extensions
22
numpy
3-
nv-sgl == 0.12.3
3+
nv-sgl == 0.12.4

slangpy/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
# Bring all shared types into the top level namespace
1212
from .types import *
1313

14+
# Bring tested experimental types into top level namespace
15+
from .experimental.gridarg import grid
16+
1417
# Slangpy reflection system
1518
from . import reflection
1619

slangpy/bindings/boundvariable.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,10 +354,15 @@ def _apply_implicit_vectorization(self, context: BindContext):
354354
self.vector_mapping.as_tuple())+1
355355
else:
356356
self.call_dimensionality = 0
357+
elif self.python.match_call_shape:
358+
self.call_dimensionality = -1
357359
else:
358360
assert self.vector_type is not None
359361
self.call_dimensionality = self.python.resolve_dimensionality(
360362
context, self, self.vector_type)
363+
if self.call_dimensionality is not None and self.call_dimensionality < 0:
364+
raise BoundVariableException(
365+
f"Could not resolve dimensionality for {self.path}", self)
361366

362367
def finalize_mappings(self, context: BindContext):
363368
"""
@@ -369,6 +374,9 @@ def finalize_mappings(self, context: BindContext):
369374
self._finalize_mappings(context)
370375

371376
def _finalize_mappings(self, context: BindContext):
377+
if self.call_dimensionality == -1:
378+
self.call_dimensionality = context.call_dimensionality
379+
372380
if context.options['strict_broadcasting'] and self.children is None and not self.explicitly_vectorized:
373381
if self.call_dimensionality != 0 and self.call_dimensionality != context.call_dimensionality:
374382
raise BoundVariableException(

slangpy/builtin/resourceview.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,18 @@ def _get_or_create_python_type(layout: SlangProgramLayout, value: Any):
1212
assert isinstance(value, ResourceView)
1313
if isinstance(value.resource, Texture):
1414
if value.type == ResourceViewType.shader_resource:
15-
return get_or_create_python_texture_type(layout, value.resource, ResourceUsage.shader_resource)
15+
usage = ResourceUsage.shader_resource
1616
elif value.type == ResourceViewType.unordered_access:
17-
return get_or_create_python_texture_type(layout, value.resource, ResourceUsage.unordered_access)
17+
usage = ResourceUsage.unordered_access
1818
else:
1919
raise ValueError(f"Unsupported resource view type {value.type}")
20+
desc = value.resource.desc
21+
return get_or_create_python_texture_type(layout,
22+
desc.format,
23+
desc.type,
24+
usage,
25+
value.resource.array_size,
26+
desc.sample_count)
2027
else:
2128
raise ValueError(f"Unsupported resource view resource {value.resource}")
2229

slangpy/builtin/texture.py

Lines changed: 85 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,23 @@
55
from slangpy.backend import TypeReflection
66

77
from slangpy.backend import (FormatType, ResourceType, ResourceUsage, Sampler,
8-
Texture, get_format_info)
8+
Texture, Format, get_format_info)
99
from slangpy.bindings import (PYTHON_SIGNATURES, PYTHON_TYPES, Marshall,
1010
BindContext, BoundVariable, BoundVariableRuntime,
11-
CodeGenBlock)
12-
from slangpy.reflection.reflectiontypes import SamplerStateType, SlangProgramLayout, SlangType, TextureType
11+
CodeGenBlock, ReturnContext)
12+
from slangpy.reflection.reflectiontypes import SamplerStateType, SlangProgramLayout, SlangType, TextureType, VectorType, ArrayType, ScalarType
13+
from typing import Optional
14+
15+
16+
SCALARTYPE_TO_TEXTURE_FORMAT = {
17+
TypeReflection.ScalarType.float32: (Format.r32_float, Format.rg32_float, Format.rgb32_float, Format.rgba32_float),
18+
TypeReflection.ScalarType.float16: (Format.r16_float, Format.rg16_float, None, Format.rgba16_float),
19+
TypeReflection.ScalarType.uint32: (Format.r32_uint, Format.rg32_uint, Format.rgb32_uint, Format.rgba32_uint),
20+
TypeReflection.ScalarType.uint16: (Format.r16_unorm, Format.rg16_unorm, None, Format.rgba16_unorm),
21+
TypeReflection.ScalarType.uint8: (Format.r8_unorm, Format.rg8_unorm, None, Format.rgba8_unorm),
22+
TypeReflection.ScalarType.int16: (Format.r16_snorm, Format.rg16_snorm, None, Format.rgba16_snorm),
23+
TypeReflection.ScalarType.int8: (Format.r8_snorm, Format.rg8_snorm, None, Format.rgba8_snorm),
24+
}
1325

1426

1527
def has_uav(usage: ResourceUsage):
@@ -22,7 +34,7 @@ def prefix(usage: ResourceUsage):
2234

2335
class TextureMarshall(NativeTextureMarshall):
2436

25-
def __init__(self, layout: SlangProgramLayout, resource_shape: TypeReflection.ResourceShape, element_type: SlangType, usage: ResourceUsage):
37+
def __init__(self, layout: SlangProgramLayout, resource_shape: TypeReflection.ResourceShape, element_type: SlangType, format: Format, usage: ResourceUsage):
2638
tex_type = ""
2739
tex_dims = 0
2840

@@ -65,7 +77,7 @@ def __init__(self, layout: SlangProgramLayout, resource_shape: TypeReflection.Re
6577
self.slang_type: 'SlangType'
6678
self.slang_element_type: 'SlangType'
6779

68-
super().__init__(st, element_type, resource_shape, usage, tex_dims)
80+
super().__init__(st, element_type, resource_shape, format, usage, tex_dims)
6981

7082
def reduce_type(self, context: BindContext, dimensions: int):
7183
return super().reduce_type(context, dimensions)
@@ -144,57 +156,106 @@ def gen_calldata(self, cgb: CodeGenBlock, context: BindContext, binding: 'BoundV
144156
f"Texture {name} has invalid dimensionality {binding.call_dimensionality}")
145157

146158

147-
def get_or_create_python_texture_type(layout: SlangProgramLayout, resource: Texture, usage: ResourceUsage):
159+
def get_or_create_python_texture_type(layout: SlangProgramLayout, format: Format, type: ResourceType, usage: ResourceUsage, array_size: int, sample_count: int):
148160

149161
# Translate format into slang scalar type + channel count, which allows
150162
# us to build the element type of the texture.
151-
fmt_info = get_format_info(resource.desc.format)
163+
fmt_info = get_format_info(format)
152164
if fmt_info.type in [FormatType.float, FormatType.unorm, FormatType.snorm, FormatType.unorm_srgb]:
153165
scalar_type = TypeReflection.ScalarType.float32
154166
elif fmt_info.type == FormatType.uint:
155167
scalar_type = TypeReflection.ScalarType.uint32
156168
elif fmt_info.type == FormatType.sint:
157169
scalar_type = TypeReflection.ScalarType.int32
158170
else:
159-
raise ValueError(f"Unsupported format {resource.desc.format}")
171+
raise ValueError(f"Unsupported format {format}")
160172
element_type = layout.vector_type(scalar_type, fmt_info.channel_count)
161173

162174
# Translate resource type + array size into a slang resource shape.
163175
resource_shape = TypeReflection.ResourceShape.none
164-
if resource.array_size == 1:
165-
if resource.desc.type == ResourceType.texture_1d:
176+
if array_size == 1:
177+
if type == ResourceType.texture_1d:
166178
resource_shape = TypeReflection.ResourceShape.texture_1d
167-
elif resource.desc.type == ResourceType.texture_2d:
168-
if resource.desc.sample_count == 1:
179+
elif type == ResourceType.texture_2d:
180+
if sample_count == 1:
169181
resource_shape = TypeReflection.ResourceShape.texture_2d
170182
else:
171183
resource_shape = TypeReflection.ResourceShape.texture_2d_multisample
172-
elif resource.desc.type == ResourceType.texture_3d:
184+
elif type == ResourceType.texture_3d:
173185
resource_shape = TypeReflection.ResourceShape.texture_3d
174-
elif resource.desc.type == ResourceType.texture_cube:
186+
elif type == ResourceType.texture_cube:
175187
resource_shape = TypeReflection.ResourceShape.texture_cube
176188
else:
177-
raise ValueError(f"Unsupported texture type {resource.desc.type}")
189+
raise ValueError(f"Unsupported texture type {type}")
178190
else:
179-
if resource.desc.type == ResourceType.texture_1d:
191+
if type == ResourceType.texture_1d:
180192
resource_shape = TypeReflection.ResourceShape.texture_1d_array
181-
elif resource.desc.type == ResourceType.texture_2d:
182-
if resource.desc.sample_count == 1:
193+
elif type == ResourceType.texture_2d:
194+
if sample_count == 1:
183195
resource_shape = TypeReflection.ResourceShape.texture_2d_array
184196
else:
185197
resource_shape = TypeReflection.ResourceShape.texture_2d_multisample_array
186-
elif resource.desc.type == ResourceType.texture_cube:
198+
elif type == ResourceType.texture_cube:
187199
resource_shape = TypeReflection.ResourceShape.texture_cube_array
188200
else:
189-
raise ValueError(f"Unsupported texture type {resource.desc.type}")
201+
raise ValueError(f"Unsupported texture type {type}")
202+
203+
return TextureMarshall(layout, resource_shape, element_type, format, usage)
204+
205+
206+
def slang_type_to_texture_format(st: SlangType) -> Optional[Format]:
207+
if isinstance(st, VectorType) or isinstance(st, ArrayType):
208+
assert st.element_type
209+
210+
num_channels = st.shape[0]
211+
channel_type = st.element_type
212+
else:
213+
num_channels = 1
214+
channel_type = st
190215

191-
return TextureMarshall(layout, resource_shape, element_type, usage)
216+
if not isinstance(channel_type, ScalarType):
217+
return None
218+
if num_channels == 0 or num_channels > 4:
219+
return None
220+
221+
scalar = channel_type.slang_scalar_type
222+
if scalar not in SCALARTYPE_TO_TEXTURE_FORMAT:
223+
return None
224+
225+
return SCALARTYPE_TO_TEXTURE_FORMAT[scalar][num_channels - 1]
192226

193227

194228
def _get_or_create_python_type(layout: SlangProgramLayout, value: Any):
195-
assert isinstance(value, Texture)
196-
usage = value.desc.usage
197-
return get_or_create_python_texture_type(layout, value, usage)
229+
if isinstance(value, Texture):
230+
desc = value.desc
231+
return get_or_create_python_texture_type(layout,
232+
desc.format,
233+
desc.type,
234+
desc.usage,
235+
value.array_size,
236+
desc.sample_count)
237+
elif isinstance(value, ReturnContext):
238+
format = slang_type_to_texture_format(value.slang_type)
239+
if format is None:
240+
raise ValueError(f"Can't create output texture: Slang type "
241+
f"\"{value.slang_type.full_name}\" can't be used as a texel type")
242+
243+
dim = value.bind_context.call_dimensionality
244+
if dim == 1:
245+
tex_type = ResourceType.texture_1d
246+
elif dim == 2:
247+
tex_type = ResourceType.texture_2d
248+
elif dim == 3:
249+
tex_type = ResourceType.texture_3d
250+
else:
251+
raise ValueError(
252+
"Can't create output texture: Call dimensionality has to be 1D, 2D or 3D")
253+
254+
usage = ResourceUsage.unordered_access | ResourceUsage.shader_resource
255+
256+
return get_or_create_python_texture_type(layout, format, tex_type, usage, 1, 1)
257+
else:
258+
raise ValueError(f"Type {type(value)} is unsupported for TextureMarshall")
198259

199260

200261
PYTHON_TYPES[Texture] = _get_or_create_python_type

slangpy/slang/callidarg.slang

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
22
implementing slangpy;
33

4-
public struct CallIdArg<let N : int> {
5-
public typealias T = vector<uint, N>;
6-
public void load(ContextND<N> context, out T value) {
4+
public struct CallIdArg {
5+
6+
public void load<let N : int>(ContextND<N> context, out vector<uint,N> value) {
77
var t = context.call_id;
88
for (int i = 0; i < N; i++) {
99
value[i] = t[i];
1010
}
1111
}
12-
public void load(ContextND<1> context, out uint value) {
13-
value = context.call_id[0];
14-
}
12+
1513
}

slangpy/slang/core.slang

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,17 @@ namespace impl
372372

373373
// A python int can be passed to any slang integer scalar type
374374
extension<T : __BuiltinIntegerType> T : IConvertibleFrom<int> {}
375+
375376
// A python float can be passed to any slang float scalar type
376377
extension<T : __BuiltinFloatingPointType> T : IConvertibleFrom<float> {}
378+
377379
// A python array can be passed to any slang array of the same length, as
378380
// long as their element types can be safely passed
379381
extension<S, T : IConvertibleFrom<S>, let N : int, ArrT : ISizedArray<T, N>> ArrT : IConvertibleFrom<Array<S, N>> {}
380382

383+
// A vector is convertible to another vector of the same length who's element types are convertible
384+
extension<S, T : IConvertibleFrom<S>, let N : int> vector<T,N> : IConvertibleFrom<vector<S, N>> {}
385+
381386
// This function allows us to check if type A is convertible to type B.
382387
// We attempt to specialize allowedConversionWitness with types [A, B]
383388
// If it succeeds, the interface requirements are satisfied.

0 commit comments

Comments
 (0)