diff --git a/src/sgl/device/python/resource.cpp b/src/sgl/device/python/resource.cpp index 42248ff0..e1ef568b 100644 --- a/src/sgl/device/python/resource.cpp +++ b/src/sgl/device/python/resource.cpp @@ -217,9 +217,28 @@ SGL_PY_EXPORT(device_resource) nb::sgl_enum(m, "ResourceViewType"); + nb::sgl_enum(m, "TextureAspect"); + + nb::class_(m, "BufferRange", D(SubresourceRange)) + .def(nb::init<>()) + .def_ro("offset", &BufferRange::offset, D_NA(BufferRange, offset)) + .def_ro("size", &BufferRange::size, D_NA(BufferRange, size)) + .def("__repr__", &BufferRange::to_string, D_NA(BufferRange, to_string)); + + nb::class_(m, "SubresourceRange", D(SubresourceRange)) + .def(nb::init<>()) + .def_ro("texture_aspect", &SubresourceRange::texture_aspect, D_NA(SubresourceRange, texture_aspect)) + .def_ro("mip_level", &SubresourceRange::mip_level, D_NA(SubresourceRange, mip_level)) + .def_ro("mip_count", &SubresourceRange::mip_count, D_NA(SubresourceRange, mip_count)) + .def_ro("base_array_layer", &SubresourceRange::base_array_layer, D_NA(SubresourceRange, base_array_layer)) + .def_ro("layer_count", &SubresourceRange::layer_count, D_NA(SubresourceRange, layer_count)) + .def("__repr__", &SubresourceRange::to_string, D_NA(SubresourceRange, to_string)); + nb::class_(m, "ResourceView", D(ResourceView)) .def_prop_ro("type", &ResourceView::type, D(ResourceView, type)) - .def_prop_ro("resource", &ResourceView::resource, D(ResourceView, resource)); + .def_prop_ro("resource", &ResourceView::resource, D(ResourceView, resource)) + .def_prop_ro("buffer_range", &ResourceView::buffer_range, D_NA(ResourceView, buffer_range)) + .def_prop_ro("subresource_range", &ResourceView::subresource_range, D_NA(ResourceView, subresource_range)); nb::class_(m, "BufferDesc", D(BufferDesc)) .def(nb::init<>()) diff --git a/src/sgl/device/resource.cpp b/src/sgl/device/resource.cpp index 43c4e068..cf2ea75a 100644 --- a/src/sgl/device/resource.cpp +++ b/src/sgl/device/resource.cpp @@ -258,15 +258,14 @@ std::string ResourceView::to_string() const "ResourceView(\n" " type = {},\n" " format = {},\n" - " buffer_range = (offset={}, size={}),\n" - // " subresource_range = {},\n" + " buffer_range = {},\n" + " subresource_range = {},\n" " resource = {}\n" ")", m_desc.type, m_desc.format, - m_desc.buffer_range.offset, - m_desc.buffer_range.size, - // m_desc.subresource_range, + m_desc.buffer_range.to_string(), + m_desc.subresource_range.to_string(), string::indent(m_resource ? m_resource->to_string() : "null") ); } diff --git a/src/sgl/device/resource.h b/src/sgl/device/resource.h index 03671d5d..ad30a0d6 100644 --- a/src/sgl/device/resource.h +++ b/src/sgl/device/resource.h @@ -192,6 +192,8 @@ struct BufferRange { uint64_t size{ALL}; auto operator<=>(const BufferRange&) const = default; + + std::string to_string() const { return fmt::format("BufferRange(offset={}, size={}", offset, size); } }; enum class TextureAspect : uint32_t { @@ -205,6 +207,22 @@ enum class TextureAspect : uint32_t { plane2 = static_cast(gfx::TextureAspect::Plane2), depth_stencil = depth | stencil, }; +SGL_ENUM_INFO( + TextureAspect, + { + {TextureAspect::default_, "default_"}, + {TextureAspect::color, "color"}, + {TextureAspect::depth, "depth"}, + {TextureAspect::stencil, "stencil"}, + {TextureAspect::meta_data, "meta_data"}, + {TextureAspect::plane0, "plane0"}, + {TextureAspect::plane1, "plane1"}, + {TextureAspect::plane2, "plane2"}, + {TextureAspect::depth_stencil, "depth_stencil"}, + + } +); +SGL_ENUM_REGISTER(TextureAspect); struct SubresourceRange { static constexpr uint32_t ALL = std::numeric_limits::max(); @@ -220,6 +238,18 @@ struct SubresourceRange { uint32_t layer_count{ALL}; // For cube maps, this is a multiple of 6. auto operator<=>(const SubresourceRange&) const = default; + + std::string to_string() const + { + return fmt::format( + "SubresourceRange(texture_aspect={}, mip_level={}, mip_count={}, base_array_layer={}, layer_count={}", + texture_aspect, + mip_level, + mip_count, + base_array_layer, + layer_count + ); + } }; struct ResourceViewDesc { diff --git a/src/sgl/device/tests/test_texture_access.py b/src/sgl/device/tests/test_texture_access.py index 427da991..22a0a617 100644 --- a/src/sgl/device/tests/test_texture_access.py +++ b/src/sgl/device/tests/test_texture_access.py @@ -158,10 +158,22 @@ def test_shader_read_write_texture( device.link_program([module], [module.entry_point("copy_color")]) ) + srv = src_tex.get_srv(mip) + assert srv.subresource_range.base_array_layer == 0 + assert srv.subresource_range.layer_count == 1 + assert srv.subresource_range.mip_level == mip + assert srv.subresource_range.mip_count == src_tex.mip_count - mip + + uav = dest_tex.get_uav(mip) + assert uav.subresource_range.base_array_layer == 0 + assert uav.subresource_range.layer_count == 1 + assert uav.subresource_range.mip_level == mip + assert uav.subresource_range.mip_count == dest_tex.mip_count - mip + copy_kernel.dispatch( [src_tex.width, src_tex.height, src_tex.depth], - src=src_tex.get_srv(mip), - dest=dest_tex.get_uav(mip), + src=srv, + dest=uav, ) else: @@ -171,11 +183,10 @@ def test_shader_read_write_texture( void copy_color( uint{dims} tid: SV_DispatchThreadID, Texture{dims}DArray src, - RWTexture{dims}DArray dest, - uniform uint slice + RWTexture{dims}DArray dest ) {{ - uint{dims+1} idx = uint{dims+1}(tid, slice); + uint{dims+1} idx = uint{dims+1}(tid, 0); dest[idx] = src[idx]; }} """ @@ -187,11 +198,20 @@ def test_shader_read_write_texture( device.link_program([module], [module.entry_point("copy_color")]) ) for i in range(0, slices): + srv = src_tex.get_srv(mip_level=mip, base_array_layer=i, layer_count=1) + assert srv.subresource_range.base_array_layer == i + assert srv.subresource_range.layer_count == 1 + assert srv.subresource_range.mip_level == mip + assert srv.subresource_range.mip_count == src_tex.mip_count - mip + + uav = dest_tex.get_uav(mip_level=mip, base_array_layer=i, layer_count=1) + assert uav.subresource_range.base_array_layer == i + assert uav.subresource_range.layer_count == 1 + assert uav.subresource_range.mip_level == mip + assert uav.subresource_range.mip_count == dest_tex.mip_count - mip + copy_kernel.dispatch( - [src_tex.width, src_tex.height, src_tex.depth], - src=src_tex.get_srv(mip), - dest=dest_tex.get_uav(mip), - slice=i, + [src_tex.width, src_tex.height, src_tex.depth], src=srv, dest=uav ) # Read back data and compare