Skip to content

Commit

Permalink
+ Added a bunch of ResourceFlags w.r.t image filtering. Note that onl…
Browse files Browse the repository at this point in the history
…y ImageFilterNearest and ImageFilterLinear are fully implemented right now
  • Loading branch information
harrand committed Oct 11, 2022
1 parent 318d168 commit 5d723e5
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 27 deletions.
6 changes: 5 additions & 1 deletion demo/gl/tz_dynamic_triangle_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,11 @@ int main()
{
.format = tz::gl::ImageFormat::RGBA32,
.dimensions = {2u, 2u},
.access = tz::gl::ResourceAccess::DynamicVariable
.access = tz::gl::ResourceAccess::DynamicVariable,
.flags =
{
tz::gl::ResourceFlag::ImageFilterLinear
}
}
)
);
Expand Down
10 changes: 9 additions & 1 deletion src/tz/gl/api/resource.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@ namespace tz::gl
/// - Indicates that the buffer should be treated as a hardware index buffer. It will act as a bespoke non-shader-resource buffer that must store indices encoded as `unsigned int[]`. Can only be applied to buffer resources.
IndexBuffer,
/// - Indicates that the image can be used as an ImageOutput for another renderer. Can only be applied to image resources.
RendererOutput
RendererOutput,
/// - Indicates that when doing min/mag on the image, the value of the nearest texel to the texcoord is retrieved.
ImageFilterNearest,
/// - Indicates that when doing min/mag on the image, the value of the weighted average of the nearest texels is retrieved.
ImageFilterLinear,
/// - Indicates that the chosen mip will have the closest match of size to the texture pixel.
ImageMipNearest,
/// - Indicates that a mip computed from the weighted average of the next and previous mip will be chosen.
ImageMipLinear,
};

using ResourceFlags = tz::EnumField<ResourceFlag>;
Expand Down
19 changes: 17 additions & 2 deletions src/tz/gl/impl/frontend/ogl2/component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,29 @@ namespace tz::gl
{
tz_assert(this->resource->get_type() == ResourceType::Image, "ImageComponent was provided a resource which was not an ImageResource. Please submit a bug report.");
const ImageResource* img_res = static_cast<const ImageResource*>(this->resource);
ogl2::LookupFilter filter = ogl2::LookupFilter::Nearest;
#if TZ_DEBUG
if(img_res->get_flags().contains({ResourceFlag::ImageFilterNearest, ResourceFlag::ImageFilterLinear}))
{
tz_error("ResourceFlags included both ImageFilterNearest and ImageFilterLinear, which are mutually exclusive. Please submit a bug report.");
}
#endif
if(img_res->get_flags().contains(ResourceFlag::ImageFilterNearest))
{
filter = ogl2::LookupFilter::Nearest;
}
if(img_res->get_flags().contains(ResourceFlag::ImageFilterLinear))
{
filter = ogl2::LookupFilter::Linear;
}
return
{{
.format = to_ogl2(img_res->get_format()),
.dimensions = img_res->get_dimensions(),
.sampler =
{
.min_filter = ogl2::LookupFilter::Nearest,
.mag_filter = ogl2::LookupFilter::Nearest,
.min_filter = filter,
.mag_filter = filter,
.address_mode_s = ogl2::AddressMode::ClampToEdge,
.address_mode_t = ogl2::AddressMode::ClampToEdge,
.address_mode_r = ogl2::AddressMode::ClampToEdge
Expand Down
57 changes: 42 additions & 15 deletions src/tz/gl/impl/frontend/vk2/renderer.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "tz/gl/impl/backend/vk2/sampler.hpp"
#if TZ_VULKAN
#include "tz/gl/impl/backend/vk2/tz_vulkan.hpp"
#include "tz/gl/impl/frontend/vk2/device.hpp"
Expand All @@ -22,28 +23,52 @@ namespace tz::gl
AssetStorageCommon<IResource>(info.get_resources()),
components(),
image_component_views(),
basic_sampler(vk2::SamplerInfo
{
.device = &ldev,
.min_filter = vk2::LookupFilter::Nearest,
.mag_filter = vk2::LookupFilter::Nearest,
.mipmap_mode = vk2::MipLookupFilter::Nearest,
.address_mode_u = vk2::SamplerAddressMode::ClampToEdge,
.address_mode_v = vk2::SamplerAddressMode::ClampToEdge,
.address_mode_w = vk2::SamplerAddressMode::ClampToEdge,
}),
samplers(),
descriptor_layout(vk2::DescriptorLayout::null()),
descriptor_pool(vk2::DescriptorPool::null()),
descriptors(),
frame_in_flight_count(frame_in_flight_count)
{
auto resources = info.get_resources();
TZ_PROFZONE("Vulkan Frontend - RendererVulkan ResourceStorage Create", TZ_PROFCOL_YELLOW);
this->samplers.reserve(this->count());

auto get_fitting_sampler = [&ldev](const IResource& res) -> vk2::SamplerInfo
{
vk2::LookupFilter filter = vk2::LookupFilter::Nearest;
vk2::MipLookupFilter mip_filter = vk2::MipLookupFilter::Nearest;
#if TZ_DEBUG
if(res.get_flags().contains({ResourceFlag::ImageFilterNearest, ResourceFlag::ImageFilterLinear}))
{
tz_error("ImageResource contained both ResourceFlags ImageFilterNearest and ImageFilterLinear, which are mutually exclusive. Please submit a bug report.");
}
#endif // TZ_DEBUG
if(res.get_flags().contains(ResourceFlag::ImageFilterNearest))
{
filter = vk2::LookupFilter::Nearest;
}
else if(res.get_flags().contains(ResourceFlag::ImageFilterLinear))
{
filter = vk2::LookupFilter::Linear;
}

return
{
.device = &ldev,
.min_filter = filter,
.mag_filter = filter,
.mipmap_mode = mip_filter,
.address_mode_u = vk2::SamplerAddressMode::ClampToEdge,
.address_mode_v = vk2::SamplerAddressMode::ClampToEdge,
.address_mode_w = vk2::SamplerAddressMode::ClampToEdge
};
};

auto resources = info.get_resources();
std::vector<bool> buffer_id_to_variable_access;
std::vector<bool> buffer_id_to_descriptor_visibility;
std::size_t encountered_reference_count = 0;

auto retrieve_resource_metadata = [this, &buffer_id_to_variable_access, &buffer_id_to_descriptor_visibility](IComponent* cmp)
auto retrieve_resource_metadata = [this, &buffer_id_to_variable_access, &buffer_id_to_descriptor_visibility, get_fitting_sampler](IComponent* cmp)
{
IResource* res = cmp->get_resource();
switch(res->get_type())
Expand All @@ -66,6 +91,8 @@ namespace tz::gl
break;
case ResourceType::Image:
{
this->samplers.emplace_back(get_fitting_sampler(*res));

auto* img = static_cast<ImageComponentVulkan*>(cmp);
// We will need to create an image view. Let's get that out-of-the-way-now.
vk2::Image& underlying_image = img->vk_get_image();
Expand Down Expand Up @@ -222,7 +249,7 @@ namespace tz::gl
AssetStorageCommon<IResource>(static_cast<AssetStorageCommon<IResource>&&>(move)),
components(std::move(move.components)),
image_component_views(std::move(move.image_component_views)),
basic_sampler(std::move(move.basic_sampler)),
samplers(std::move(move.samplers)),
descriptor_layout(std::move(move.descriptor_layout)),
descriptor_pool(std::move(move.descriptor_pool)),
descriptors(std::move(move.descriptors)),
Expand All @@ -238,7 +265,7 @@ namespace tz::gl
{
std::swap(this->components, rhs.components);
std::swap(this->image_component_views, rhs.image_component_views);
std::swap(this->basic_sampler, rhs.basic_sampler);
std::swap(this->samplers, rhs.samplers);
std::swap(this->descriptor_layout, rhs.descriptor_layout);
std::swap(this->descriptor_pool, rhs.descriptor_pool);
std::swap(this->descriptors, rhs.descriptors);
Expand Down Expand Up @@ -359,7 +386,7 @@ namespace tz::gl
{
set_edit.set_image(descriptor_buffer_count,
{
.sampler = &this->basic_sampler,
.sampler = &this->samplers[j],
.image_view = &this->image_component_views[j]
}, j);
}
Expand Down
4 changes: 2 additions & 2 deletions src/tz/gl/impl/frontend/vk2/renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ namespace tz::gl
std::vector<tz::MaybeOwnedPtr<IComponent>> components;
/// An ImageView for each ImageResource that was passed to the constructor. These are views referring to the corresponding ImageComponent to said resource.
std::vector<vk2::ImageView> image_component_views;
/// Hard-coded sampler info. This might need to be editable in the future, but for now the user has no control over this. Care must be taken to ensure that other graphics API frontends sample images in the same way.
vk2::Sampler basic_sampler;
// A unique sampler for every single image. There is no duplicate checking, so there may be redundant samplers in here. However, it's not trivial to fix this because we use combined image sampling - to use separate image and samplers requires shader source changes, which means big tzslc changes for vulkan only. Looks like it could end up changing syntax so we avoid this for the time being.
std::vector<vk2::Sampler> samplers;
/// Vulkan Descriptor Set layout, which matches the layout of the provided buffer and image resources. Note that buffer resources get their own binding, but all image resources are a single descriptor array.
vk2::DescriptorLayout descriptor_layout;
/// Storage for DescriptorSets.
Expand Down
10 changes: 5 additions & 5 deletions src/tz/gl/resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ namespace tz::gl
return this->access;
}

const ResourceFlags& Resource::get_flags() const
{
return this->flags;
}

std::span<const std::byte> Resource::data() const
{
if(this->mapped_resource_data.has_value())
Expand Down Expand Up @@ -52,11 +57,6 @@ namespace tz::gl
this->mapped_resource_data = mapped_resource_data;
}

const ResourceFlags& Resource::get_flags() const
{
return this->flags;
}

std::unique_ptr<IResource> BufferResource::unique_clone() const
{
return std::make_unique<BufferResource>(*this);
Expand Down
2 changes: 1 addition & 1 deletion src/tz/gl/resource.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ namespace tz::gl
// IResource
virtual ResourceType get_type() const final;
virtual ResourceAccess get_access() const final;
virtual const ResourceFlags& get_flags() const final;
virtual std::span<const std::byte> data() const final;
virtual std::span<std::byte> data() final;

void resize_data(std::size_t new_size);
protected:
Resource(ResourceAccess access, std::vector<std::byte> resource_data, std::size_t initial_alignment_offset, ResourceType type, ResourceFlags flags = {});
virtual void set_mapped_data(std::span<std::byte> mapped_resource_data) override;
virtual const ResourceFlags& get_flags() const final;
private:
ResourceAccess access;
std::vector<std::byte> resource_data;
Expand Down

0 comments on commit 5d723e5

Please sign in to comment.