154 auto physical_device =
m_backend->get_context().get_physical_device();
156 vk::SamplerCreateInfo sampler_info {};
165 auto properties = physical_device.getProperties();
166 sampler_info.anisotropyEnable = VK_TRUE;
167 sampler_info.maxAnisotropy = std::min(
169 properties.limits.maxSamplerAnisotropy);
171 sampler_info.anisotropyEnable = VK_FALSE;
172 sampler_info.maxAnisotropy = 1.0F;
177 sampler_info.unnormalizedCoordinates = VK_FALSE;
179 sampler_info.compareEnable = VK_FALSE;
180 sampler_info.compareOp = vk::CompareOp::eAlways;
184 ? vk::SamplerMipmapMode::eLinear
185 : vk::SamplerMipmapMode::eNearest;
186 sampler_info.minLod = 0.0F;
187 sampler_info.maxLod = VK_LOD_CLAMP_NONE;
188 sampler_info.mipLodBias = 0.0F;
190 sampler_info.mipmapMode = vk::SamplerMipmapMode::eNearest;
191 sampler_info.minLod = 0.0F;
192 sampler_info.maxLod = 0.0F;
193 sampler_info.mipLodBias = 0.0F;
197 vk::Sampler sampler =
device.createSampler(sampler_info);
199 "Created sampler: mag={}, min={}, aniso={}",
200 vk::to_string(sampler_info.magFilter),
201 vk::to_string(sampler_info.minFilter),
202 sampler_info.maxAnisotropy);
204 }
catch (
const vk::SystemError& e) {
206 "Failed to create sampler: {}", e.what());
214 hash ^= std::hash<int> {}(
static_cast<int>(config.
mag_filter)) << 0;
215 hash ^= std::hash<int> {}(
static_cast<int>(config.
min_filter)) << 4;
216 hash ^= std::hash<int> {}(
static_cast<int>(config.
address_mode_u)) << 8;
217 hash ^= std::hash<int> {}(
static_cast<int>(config.
address_mode_v)) << 12;
218 hash ^= std::hash<int> {}(
static_cast<int>(config.
address_mode_w)) << 16;
221 hash ^= std::hash<int> {}(
static_cast<int>(config.
border_color)) << 28;
282 if (src_width == 0 || src_height == 0 || dst_width == 0 || dst_height == 0) {
293 const auto place = [&plan, filter](
294 vk::Rect2D
src, vk::Rect2D
dst,
bool flip_x =
false,
bool flip_y =
false) {
296 .
src =
src, .dst =
dst, .filter = filter, .flip_x = flip_x, .flip_y = flip_y });
299 const auto region = [](int32_t x, int32_t y, uint32_t
width, uint32_t
height) {
300 return vk::Rect2D { vk::Offset2D { x, y }, vk::Extent2D {
width,
height } };
303 const auto centered = [](uint32_t outer, uint32_t inner) {
304 return static_cast<int32_t
>((outer - inner) / 2);
307 const auto extent = [](
double value, uint32_t limit) {
308 return std::clamp(
static_cast<uint32_t
>(std::lround(
value)), 1U, limit);
311 const auto sw =
static_cast<double>(src_width);
312 const auto sh =
static_cast<double>(src_height);
313 const auto dw =
static_cast<double>(dst_width);
314 const auto dh =
static_cast<double>(dst_height);
319 place(region(0, 0, src_width, src_height), region(0, 0, dst_width, dst_height));
323 const double scale = std::min(dw / sw, dh / sh);
324 const uint32_t w = extent(sw * scale, dst_width);
325 const uint32_t
h = extent(sh * scale, dst_height);
327 place(region(0, 0, src_width, src_height),
328 region(centered(dst_width, w), centered(dst_height,
h), w,
h));
333 const double scale = std::max(dw / sw, dh / sh);
334 const uint32_t w = extent(dw / scale, src_width);
335 const uint32_t
h = extent(dh / scale, src_height);
337 place(region(centered(src_width, w), centered(src_height,
h), w,
h),
338 region(0, 0, dst_width, dst_height));
343 const uint32_t w = std::min(src_width, dst_width);
344 const uint32_t
h = std::min(src_height, dst_height);
346 place(region(centered(src_width, w), centered(src_height,
h), w,
h),
347 region(centered(dst_width, w), centered(dst_height,
h), w,
h));
357 for (uint32_t y = 0; y < dst_height; y += src_height, ++row) {
358 const uint32_t
h = std::min(src_height, dst_height - y);
359 const bool flip_y = mirrored && (row % 2 == 1);
362 for (uint32_t x = 0; x < dst_width; x += src_width, ++column) {
363 const uint32_t w = std::min(src_width, dst_width - x);
364 const bool flip_x = mirrored && (column % 2 == 1);
366 place(region(flip_x ?
static_cast<int32_t
>(src_width - w) : 0,
367 flip_y ?
static_cast<int32_t
>(src_height -
h) : 0, w,
h),
368 region(
static_cast<int32_t
>(x),
static_cast<int32_t
>(y), w,
h),
static FitPlan plan_fit(uint32_t src_width, uint32_t src_height, uint32_t dst_width, uint32_t dst_height, FitMode mode=FitMode::STRETCH, FilterMode filter=FilterMode::LINEAR)
Work out how a source extent maps onto a destination extent.