mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
panvk: Use multiple sampler planes and one texture descriptor per plane
Multiple sampler planes (one for luma, one for chroma) are needed to support CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT. Multiple texture descriptors (one per plane) are needed for the downsampling in nir_vk_lower_ycbcr_tex() to work in panvk. Signed-off-by: Rebecca Mckeever <rebecca.mckeever@collabora.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32563>
This commit is contained in:
parent
45657fb70f
commit
cdf24f067e
9 changed files with 343 additions and 110 deletions
|
|
@ -37,6 +37,17 @@ struct panvk_descriptor_set_binding_layout {
|
|||
VkDescriptorBindingFlags flags;
|
||||
unsigned desc_count;
|
||||
unsigned desc_idx;
|
||||
|
||||
/* if textures are present, maximum number of planes required per texture;
|
||||
* 0 otherwise
|
||||
*/
|
||||
unsigned textures_per_desc;
|
||||
|
||||
/* if samplers are present, maximum number of planes required per sampler;
|
||||
* 0 otherwise
|
||||
*/
|
||||
unsigned samplers_per_desc;
|
||||
|
||||
struct panvk_sampler **immutable_samplers;
|
||||
};
|
||||
|
||||
|
|
@ -66,30 +77,72 @@ to_panvk_descriptor_set_layout(const struct vk_descriptor_set_layout *layout)
|
|||
static inline const uint32_t
|
||||
panvk_get_desc_stride(const struct panvk_descriptor_set_binding_layout *layout)
|
||||
{
|
||||
/* One descriptor for the sampler, and one for the texture. */
|
||||
return layout->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ? 2 : 1;
|
||||
/* One descriptor for each sampler plane, and one for each texture. */
|
||||
return layout->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
|
||||
? layout->textures_per_desc + layout->samplers_per_desc : 1;
|
||||
}
|
||||
|
||||
struct panvk_subdesc_info {
|
||||
VkDescriptorType type;
|
||||
uint8_t plane;
|
||||
};
|
||||
|
||||
#define IMPLICIT_SUBDESC_TYPE (VkDescriptorType)-1
|
||||
#define NO_SUBDESC (struct panvk_subdesc_info){ \
|
||||
.type = IMPLICIT_SUBDESC_TYPE, \
|
||||
}
|
||||
#define TEX_SUBDESC(__plane) (struct panvk_subdesc_info){ \
|
||||
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, \
|
||||
.plane = __plane, \
|
||||
}
|
||||
#define SAMPLER_SUBDESC(__plane) (struct panvk_subdesc_info){ \
|
||||
.type = VK_DESCRIPTOR_TYPE_SAMPLER, \
|
||||
.plane = __plane, \
|
||||
}
|
||||
|
||||
static inline struct panvk_subdesc_info
|
||||
get_tex_subdesc_info(VkDescriptorType type, uint8_t plane)
|
||||
{
|
||||
return (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
|
||||
? TEX_SUBDESC(plane) : NO_SUBDESC;
|
||||
}
|
||||
|
||||
static inline struct panvk_subdesc_info
|
||||
get_sampler_subdesc_info(VkDescriptorType type, uint8_t plane)
|
||||
{
|
||||
return (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
|
||||
? SAMPLER_SUBDESC(plane) : NO_SUBDESC;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
get_subdesc_idx(const struct panvk_descriptor_set_binding_layout *layout,
|
||||
struct panvk_subdesc_info subdesc)
|
||||
{
|
||||
assert((subdesc.type == IMPLICIT_SUBDESC_TYPE) ||
|
||||
(layout->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
|
||||
(subdesc.type == VK_DESCRIPTOR_TYPE_SAMPLER ||
|
||||
subdesc.type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)));
|
||||
|
||||
uint32_t subdesc_idx = 0;
|
||||
|
||||
/* In case of combined image-sampler, we put the texture first. */
|
||||
if (subdesc.type == VK_DESCRIPTOR_TYPE_SAMPLER)
|
||||
subdesc_idx += layout->textures_per_desc +
|
||||
MIN2(subdesc.plane, layout->samplers_per_desc - 1);
|
||||
else if (subdesc.type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
|
||||
subdesc_idx += MIN2(subdesc.plane, layout->textures_per_desc - 1);
|
||||
|
||||
return subdesc_idx;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
panvk_get_desc_index(const struct panvk_descriptor_set_binding_layout *layout,
|
||||
uint32_t elem, VkDescriptorType type)
|
||||
uint32_t elem, struct panvk_subdesc_info subdesc)
|
||||
{
|
||||
assert(layout->type == type ||
|
||||
(layout->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
|
||||
(type == VK_DESCRIPTOR_TYPE_SAMPLER ||
|
||||
type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)));
|
||||
|
||||
assert(!vk_descriptor_type_is_dynamic(layout->type));
|
||||
|
||||
uint32_t desc_idx =
|
||||
layout->desc_idx + elem * panvk_get_desc_stride(layout);
|
||||
|
||||
/* In case of combined image-sampler, we put the texture first. */
|
||||
if (layout->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
|
||||
type == VK_DESCRIPTOR_TYPE_SAMPLER)
|
||||
desc_idx++;
|
||||
|
||||
return desc_idx;
|
||||
return layout->desc_idx + elem * panvk_get_desc_stride(layout) +
|
||||
get_subdesc_idx(layout, subdesc);
|
||||
}
|
||||
|
||||
#endif /* PANVK_VX_DESCRIPTOR_SET_LAYOUT_H */
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "pan_texture.h"
|
||||
|
||||
#include "genxml/gen_macros.h"
|
||||
#include "panvk_image.h"
|
||||
|
||||
struct panvk_priv_bo;
|
||||
|
||||
|
|
@ -29,7 +30,7 @@ struct panvk_image_view {
|
|||
|
||||
struct {
|
||||
union {
|
||||
struct mali_texture_packed tex;
|
||||
struct mali_texture_packed tex[PANVK_MAX_PLANES];
|
||||
struct {
|
||||
struct mali_texture_packed tex;
|
||||
struct mali_texture_packed other_aspect_tex;
|
||||
|
|
|
|||
|
|
@ -14,9 +14,15 @@
|
|||
|
||||
#include "vk_sampler.h"
|
||||
|
||||
/* We use 2 sampler planes for YCbCr conversion with different filters for
|
||||
* the Y and CbCr components.
|
||||
*/
|
||||
#define PANVK_MAX_DESCS_PER_SAMPLER 2
|
||||
|
||||
struct panvk_sampler {
|
||||
struct vk_sampler vk;
|
||||
struct mali_sampler_packed desc;
|
||||
struct mali_sampler_packed descs[PANVK_MAX_DESCS_PER_SAMPLER];
|
||||
uint8_t desc_count;
|
||||
};
|
||||
|
||||
VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_sampler, vk.base, VkSampler,
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ fill_textures(struct panvk_cmd_buffer *cmdbuf, struct pan_fb_info *fbinfo,
|
|||
cmdbuf->state.gfx.render.color_attachments.iviews[i];
|
||||
|
||||
if (iview)
|
||||
textures[i] = iview->descs.tex;
|
||||
textures[i] = iview->descs.tex[0];
|
||||
else
|
||||
textures[i] = (struct mali_texture_packed){0};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,23 +35,23 @@
|
|||
|
||||
static void *
|
||||
get_desc_slot_ptr(struct panvk_descriptor_set *set, uint32_t binding,
|
||||
uint32_t elem, VkDescriptorType type)
|
||||
uint32_t elem, struct panvk_subdesc_info subdesc)
|
||||
{
|
||||
const struct panvk_descriptor_set_binding_layout *binding_layout =
|
||||
&set->layout->bindings[binding];
|
||||
|
||||
uint32_t offset = panvk_get_desc_index(binding_layout, elem, type);
|
||||
uint32_t offset = panvk_get_desc_index(binding_layout, elem, subdesc);
|
||||
|
||||
assert(offset < set->layout->desc_count);
|
||||
|
||||
return (char *)set->descs.host + offset * PANVK_DESCRIPTOR_SIZE;
|
||||
}
|
||||
|
||||
#define write_desc(set, binding, elem, desc, type) \
|
||||
#define write_desc(set, binding, elem, desc, subdesc) \
|
||||
do { \
|
||||
static_assert(sizeof(*(desc)) == PANVK_DESCRIPTOR_SIZE, \
|
||||
"wrong descriptor size"); \
|
||||
void *__dst = get_desc_slot_ptr(set, binding, elem, type); \
|
||||
void *__dst = get_desc_slot_ptr(set, binding, elem, subdesc); \
|
||||
memcpy(__dst, (desc), PANVK_DESCRIPTOR_SIZE); \
|
||||
} while (0)
|
||||
|
||||
|
|
@ -66,19 +66,22 @@ write_sampler_desc(struct panvk_descriptor_set *set,
|
|||
if (binding_layout->immutable_samplers && !write_immutable)
|
||||
return;
|
||||
|
||||
const struct mali_sampler_packed *sampler_desc;
|
||||
struct panvk_sampler *sampler;
|
||||
|
||||
if (binding_layout->immutable_samplers) {
|
||||
sampler_desc = &binding_layout->immutable_samplers[elem]->desc;
|
||||
sampler = binding_layout->immutable_samplers[elem];
|
||||
} else {
|
||||
struct panvk_sampler *sampler = panvk_sampler_from_handle(
|
||||
sampler = panvk_sampler_from_handle(
|
||||
pImageInfo ? pImageInfo->sampler : VK_NULL_HANDLE);
|
||||
|
||||
sampler_desc = sampler ? &sampler->desc : NULL;
|
||||
}
|
||||
|
||||
if (sampler_desc)
|
||||
write_desc(set, binding, elem, sampler_desc, VK_DESCRIPTOR_TYPE_SAMPLER);
|
||||
if (!sampler)
|
||||
return;
|
||||
|
||||
for (uint8_t plane = 0; plane < sampler->desc_count; plane++) {
|
||||
write_desc(set, binding, elem, &sampler->descs[plane],
|
||||
get_sampler_subdesc_info(binding_layout->type, plane));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -89,14 +92,19 @@ write_image_view_desc(struct panvk_descriptor_set *set,
|
|||
if (pImageInfo && pImageInfo->imageView != VK_NULL_HANDLE) {
|
||||
VK_FROM_HANDLE(panvk_image_view, view, pImageInfo->imageView);
|
||||
|
||||
uint8_t plane_count = vk_format_get_plane_count(view->vk.format);
|
||||
for (uint8_t plane = 0; plane < plane_count; plane++) {
|
||||
struct panvk_subdesc_info subdesc = get_tex_subdesc_info(type, plane);
|
||||
#if PAN_ARCH <= 7
|
||||
if (type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
|
||||
write_desc(set, binding, elem, &view->descs.img_attrib_buf, type);
|
||||
else
|
||||
write_desc(set, binding, elem, &view->descs.tex, type);
|
||||
if (type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
|
||||
write_desc(set, binding, elem, &view->descs.img_attrib_buf,
|
||||
NO_SUBDESC);
|
||||
else
|
||||
write_desc(set, binding, elem, &view->descs.tex[plane], subdesc);
|
||||
#else
|
||||
write_desc(set, binding, elem, &view->descs.tex, type);
|
||||
write_desc(set, binding, elem, &view->descs.tex[plane], subdesc);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -116,7 +124,7 @@ write_buffer_desc(struct panvk_descriptor_set *set,
|
|||
.size = range,
|
||||
};
|
||||
|
||||
write_desc(set, binding, elem, &desc, type);
|
||||
write_desc(set, binding, elem, &desc, NO_SUBDESC);
|
||||
} else {
|
||||
struct {
|
||||
struct mali_uniform_buffer_packed ubo;
|
||||
|
|
@ -128,7 +136,7 @@ write_buffer_desc(struct panvk_descriptor_set *set,
|
|||
cfg.entries = DIV_ROUND_UP(range, 16);
|
||||
}
|
||||
|
||||
write_desc(set, binding, elem, &padded_desc, type);
|
||||
write_desc(set, binding, elem, &padded_desc, NO_SUBDESC);
|
||||
}
|
||||
#else
|
||||
struct mali_buffer_packed desc;
|
||||
|
|
@ -137,7 +145,7 @@ write_buffer_desc(struct panvk_descriptor_set *set,
|
|||
cfg.address = panvk_buffer_gpu_ptr(buffer, info->offset);
|
||||
cfg.size = range;
|
||||
}
|
||||
write_desc(set, binding, elem, &desc, type);
|
||||
write_desc(set, binding, elem, &desc, NO_SUBDESC);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -170,11 +178,12 @@ write_buffer_view_desc(struct panvk_descriptor_set *set,
|
|||
|
||||
#if PAN_ARCH <= 7
|
||||
if (type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
|
||||
write_desc(set, binding, elem, &view->descs.img_attrib_buf, type);
|
||||
write_desc(set, binding, elem, &view->descs.img_attrib_buf,
|
||||
NO_SUBDESC);
|
||||
else
|
||||
write_desc(set, binding, elem, &view->descs.tex, type);
|
||||
write_desc(set, binding, elem, &view->descs.tex, NO_SUBDESC);
|
||||
#else
|
||||
write_desc(set, binding, elem, &view->descs.tex, type);
|
||||
write_desc(set, binding, elem, &view->descs.tex, NO_SUBDESC);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -242,6 +251,8 @@ panvk_per_arch(CreateDescriptorPool)(
|
|||
if (!vk_descriptor_type_is_dynamic(pCreateInfo->pPoolSizes[i].type)) {
|
||||
const struct panvk_descriptor_set_binding_layout layout = {
|
||||
.type = pCreateInfo->pPoolSizes[i].type,
|
||||
.textures_per_desc = PANVK_MAX_PLANES,
|
||||
.samplers_per_desc = PANVK_MAX_DESCS_PER_SAMPLER,
|
||||
};
|
||||
desc_count += panvk_get_desc_stride(&layout) *
|
||||
pCreateInfo->pPoolSizes[i].descriptorCount;
|
||||
|
|
@ -307,8 +318,14 @@ desc_set_write_immutable_samplers(struct panvk_descriptor_set *set,
|
|||
array_size = variable_count;
|
||||
|
||||
for (uint32_t j = 0; j < array_size; j++) {
|
||||
write_desc(set, b, j, &layout->bindings[b].immutable_samplers[j]->desc,
|
||||
VK_DESCRIPTOR_TYPE_SAMPLER);
|
||||
struct panvk_sampler *sampler =
|
||||
layout->bindings[b].immutable_samplers[j];
|
||||
for (uint8_t plane = 0; plane < sampler->desc_count; plane++) {
|
||||
write_desc(set, b, j,
|
||||
&sampler->descs[plane],
|
||||
get_sampler_subdesc_info(layout->bindings[b].type,
|
||||
plane));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -459,12 +476,12 @@ panvk_per_arch(descriptor_set_write)(struct panvk_descriptor_set *set,
|
|||
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
for (uint32_t j = 0; j < write->descriptorCount; j++) {
|
||||
write_image_view_desc(set, write->pImageInfo + j, write->dstBinding,
|
||||
write->dstArrayElement + j,
|
||||
write->descriptorType);
|
||||
write_sampler_desc(set, write->pImageInfo + j, write->dstBinding,
|
||||
write->dstArrayElement + j,
|
||||
write_immutable_samplers);
|
||||
write_image_view_desc(set, write->pImageInfo + j, write->dstBinding,
|
||||
write->dstArrayElement + j,
|
||||
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -536,10 +553,10 @@ panvk_descriptor_set_copy(const VkCopyDescriptorSet *copy)
|
|||
for (uint32_t i = 0; i < copy->descriptorCount; i++) {
|
||||
void *dst = get_desc_slot_ptr(dst_set, copy->dstBinding,
|
||||
copy->dstArrayElement + i,
|
||||
dst_binding_layout->type);
|
||||
NO_SUBDESC);
|
||||
const void *src = get_desc_slot_ptr(src_set, copy->srcBinding,
|
||||
copy->srcArrayElement + i,
|
||||
src_binding_layout->type);
|
||||
NO_SUBDESC);
|
||||
|
||||
memcpy(dst, src,
|
||||
PANVK_DESCRIPTOR_SIZE *
|
||||
|
|
@ -609,12 +626,11 @@ panvk_per_arch(descriptor_set_write_template)(
|
|||
for (uint32_t j = 0; j < entry->array_count; j++) {
|
||||
const VkDescriptorImageInfo *info =
|
||||
data + entry->offset + j * entry->stride;
|
||||
write_image_view_desc(set, info, entry->binding,
|
||||
entry->array_element + j, entry->type);
|
||||
write_sampler_desc(set, info, entry->binding,
|
||||
entry->array_element + j,
|
||||
write_immutable_samplers);
|
||||
write_image_view_desc(set, info, entry->binding,
|
||||
entry->array_element + j,
|
||||
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "vk_format.h"
|
||||
#include "vk_log.h"
|
||||
#include "vk_util.h"
|
||||
#include "vk_ycbcr_conversion.h"
|
||||
|
||||
#include "util/bitset.h"
|
||||
|
||||
|
|
@ -30,18 +31,55 @@
|
|||
#define PANVK_MAX_DESCS_PER_SET (1 << 24)
|
||||
|
||||
static bool
|
||||
binding_has_immutable_samplers(const VkDescriptorSetLayoutBinding *binding)
|
||||
is_texture(VkDescriptorType type)
|
||||
{
|
||||
switch (binding->descriptorType) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
switch (type) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
return binding->pImmutableSamplers != NULL;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
is_sampler(VkDescriptorType type)
|
||||
{
|
||||
switch (type) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
binding_has_immutable_samplers(const VkDescriptorSetLayoutBinding *binding)
|
||||
{
|
||||
return is_sampler(binding->descriptorType) &&
|
||||
binding->pImmutableSamplers != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
set_immutable_sampler(struct panvk_descriptor_set_binding_layout *binding_layout,
|
||||
uint32_t index, struct panvk_sampler *sampler)
|
||||
{
|
||||
binding_layout->immutable_samplers[index] = sampler;
|
||||
if (!sampler->vk.ycbcr_conversion)
|
||||
return;
|
||||
|
||||
binding_layout->textures_per_desc =
|
||||
MAX2(vk_format_get_plane_count(sampler->vk.ycbcr_conversion->state.format),
|
||||
binding_layout->textures_per_desc);
|
||||
binding_layout->samplers_per_desc =
|
||||
MAX2(sampler->desc_count, binding_layout->samplers_per_desc);
|
||||
}
|
||||
|
||||
VkResult
|
||||
panvk_per_arch(CreateDescriptorSetLayout)(
|
||||
VkDevice _device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
|
||||
|
|
@ -119,6 +157,11 @@ panvk_per_arch(CreateDescriptorSetLayout)(
|
|||
}
|
||||
|
||||
binding_layout->desc_count = binding->descriptorCount;
|
||||
if (is_texture(binding_layout->type))
|
||||
binding_layout->textures_per_desc = 1;
|
||||
|
||||
if (is_sampler(binding_layout->type))
|
||||
binding_layout->samplers_per_desc = 1;
|
||||
|
||||
if (binding_has_immutable_samplers(binding)) {
|
||||
binding_layout->immutable_samplers = samplers;
|
||||
|
|
@ -126,7 +169,7 @@ panvk_per_arch(CreateDescriptorSetLayout)(
|
|||
for (uint32_t j = 0; j < binding->descriptorCount; j++) {
|
||||
VK_FROM_HANDLE(panvk_sampler, sampler,
|
||||
binding->pImmutableSamplers[j]);
|
||||
binding_layout->immutable_samplers[j] = sampler;
|
||||
set_immutable_sampler(binding_layout, j, sampler);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -160,7 +203,23 @@ panvk_per_arch(CreateDescriptorSetLayout)(
|
|||
sizeof(layout->bindings[b].flags));
|
||||
_mesa_blake3_update(&hash_ctx, &layout->bindings[b].desc_count,
|
||||
sizeof(layout->bindings[b].desc_count));
|
||||
/* Immutable samplers are ignored for now */
|
||||
_mesa_blake3_update(&hash_ctx, &layout->bindings[b].textures_per_desc,
|
||||
sizeof(layout->bindings[b].textures_per_desc));
|
||||
_mesa_blake3_update(&hash_ctx, &layout->bindings[b].samplers_per_desc,
|
||||
sizeof(layout->bindings[b].samplers_per_desc));
|
||||
|
||||
if (layout->bindings[b].immutable_samplers != NULL) {
|
||||
for (uint32_t i = 0; i < layout->bindings[b].desc_count; i++) {
|
||||
const struct panvk_sampler *sampler =
|
||||
layout->bindings[b].immutable_samplers[i];
|
||||
|
||||
/* We zalloc the object, so it's safe to hash the whole thing */
|
||||
if (sampler != NULL && sampler->vk.ycbcr_conversion != NULL)
|
||||
_mesa_blake3_update(&hash_ctx,
|
||||
&sampler->vk.ycbcr_conversion->state,
|
||||
sizeof(sampler->vk.ycbcr_conversion->state));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_mesa_blake3_final(&hash_ctx, layout->vk.blake3);
|
||||
|
|
@ -188,8 +247,28 @@ panvk_per_arch(GetDescriptorSetLayoutSupport)(
|
|||
continue;
|
||||
}
|
||||
|
||||
unsigned textures_per_desc = is_texture(type) ? 1 : 0;
|
||||
unsigned samplers_per_desc = is_sampler(type) ? 1 : 0;
|
||||
if (binding_has_immutable_samplers(binding)) {
|
||||
for (uint32_t j = 0; j < binding->descriptorCount; j++) {
|
||||
VK_FROM_HANDLE(panvk_sampler, sampler,
|
||||
binding->pImmutableSamplers[j]);
|
||||
if (!sampler->vk.ycbcr_conversion)
|
||||
continue;
|
||||
|
||||
textures_per_desc =
|
||||
MAX2(vk_format_get_plane_count(
|
||||
sampler->vk.ycbcr_conversion->state.format),
|
||||
textures_per_desc);
|
||||
samplers_per_desc =
|
||||
MAX2(sampler->desc_count, samplers_per_desc);
|
||||
}
|
||||
}
|
||||
|
||||
const struct panvk_descriptor_set_binding_layout layout = {
|
||||
.type = type,
|
||||
.textures_per_desc = textures_per_desc,
|
||||
.samplers_per_desc = samplers_per_desc,
|
||||
};
|
||||
|
||||
desc_count += panvk_get_desc_stride(&layout) * binding->descriptorCount;
|
||||
|
|
|
|||
|
|
@ -113,17 +113,22 @@ prepare_tex_descs(struct panvk_image_view *view)
|
|||
if (pview.format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
|
||||
pview.format = PIPE_FORMAT_Z32_FLOAT;
|
||||
|
||||
uint32_t plane_count = vk_format_get_plane_count(view->vk.format);
|
||||
uint32_t tex_payload_size =
|
||||
GENX(panfrost_estimate_texture_payload_size)(&pview);
|
||||
|
||||
struct panvk_pool_alloc_info alloc_info = {
|
||||
#if PAN_ARCH == 6
|
||||
.alignment = pan_alignment(SURFACE_WITH_STRIDE),
|
||||
#elif PAN_ARCH == 7
|
||||
.alignment = pan_alignment(MULTIPLANAR_SURFACE),
|
||||
.alignment = (plane_count > 1)
|
||||
? pan_alignment(MULTIPLANAR_SURFACE)
|
||||
: pan_alignment(SURFACE_WITH_STRIDE),
|
||||
#else
|
||||
.alignment = pan_alignment(PLANE),
|
||||
.alignment = pan_alignment(PLANE) * (plane_count > 1 ? 2 : 1),
|
||||
#endif
|
||||
|
||||
.size = GENX(panfrost_estimate_texture_payload_size)(&pview) *
|
||||
(can_preload_other_aspect ? 2 : 1),
|
||||
.size = tex_payload_size * (can_preload_other_aspect ? 2 : plane_count),
|
||||
};
|
||||
|
||||
view->mem = panvk_pool_alloc_mem(&dev->mempools.rw, alloc_info);
|
||||
|
|
@ -135,7 +140,25 @@ prepare_tex_descs(struct panvk_image_view *view)
|
|||
.cpu = panvk_priv_mem_host_addr(view->mem),
|
||||
};
|
||||
|
||||
GENX(panfrost_new_texture)(&pview, &view->descs.tex, &ptr);
|
||||
if (plane_count > 1) {
|
||||
memset(pview.planes, 0, sizeof(pview.planes));
|
||||
|
||||
for (uint32_t plane = 0; plane < plane_count; plane++) {
|
||||
VkFormat plane_format =
|
||||
vk_format_get_plane_format(view->vk.view_format, plane);
|
||||
|
||||
/* We need a per-plane pview. */
|
||||
pview.planes[0] = view->pview.planes[plane];
|
||||
pview.format = vk_format_to_pipe_format(plane_format);
|
||||
|
||||
GENX(panfrost_new_texture)(&pview, &view->descs.tex[plane], &ptr);
|
||||
|
||||
ptr.cpu += tex_payload_size;
|
||||
ptr.gpu += tex_payload_size;
|
||||
}
|
||||
} else {
|
||||
GENX(panfrost_new_texture)(&pview, &view->descs.tex[0], &ptr);
|
||||
}
|
||||
|
||||
if (!can_preload_other_aspect)
|
||||
return VK_SUCCESS;
|
||||
|
|
@ -158,8 +181,8 @@ prepare_tex_descs(struct panvk_image_view *view)
|
|||
assert(!"Invalid format");
|
||||
}
|
||||
|
||||
ptr.cpu += alloc_info.size / 2;
|
||||
ptr.gpu += alloc_info.size / 2;
|
||||
ptr.cpu += tex_payload_size;
|
||||
ptr.gpu += tex_payload_size;
|
||||
|
||||
GENX(panfrost_new_texture)(&pview, &view->descs.zs.other_aspect_tex, &ptr);
|
||||
return VK_SUCCESS;
|
||||
|
|
|
|||
|
|
@ -110,8 +110,8 @@ struct desc_id {
|
|||
struct {
|
||||
uint32_t binding;
|
||||
uint32_t set : 4;
|
||||
uint32_t subdesc : 1;
|
||||
uint32_t pad : 27;
|
||||
uint32_t subdesc : 3;
|
||||
uint32_t pad : 25;
|
||||
};
|
||||
uint64_t ht_key;
|
||||
};
|
||||
|
|
@ -119,12 +119,15 @@ struct desc_id {
|
|||
|
||||
#if PAN_ARCH <= 7
|
||||
static enum panvk_bifrost_desc_table_type
|
||||
desc_type_to_table_type(VkDescriptorType type, unsigned subdesc_idx)
|
||||
desc_type_to_table_type(
|
||||
const struct panvk_descriptor_set_binding_layout *binding_layout,
|
||||
unsigned subdesc_idx)
|
||||
{
|
||||
switch (type) {
|
||||
switch (binding_layout->type) {
|
||||
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
||||
return subdesc_idx == 1 ? PANVK_BIFROST_DESC_TABLE_SAMPLER
|
||||
: PANVK_BIFROST_DESC_TABLE_TEXTURE;
|
||||
return subdesc_idx >= MAX2(1, binding_layout->textures_per_desc)
|
||||
? PANVK_BIFROST_DESC_TABLE_SAMPLER
|
||||
: PANVK_BIFROST_DESC_TABLE_TEXTURE;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
||||
|
|
@ -143,27 +146,15 @@ desc_type_to_table_type(VkDescriptorType type, unsigned subdesc_idx)
|
|||
#endif
|
||||
|
||||
static uint32_t
|
||||
get_subdesc_idx(const struct panvk_descriptor_set_binding_layout *bind_layout,
|
||||
VkDescriptorType subdesc_type)
|
||||
{
|
||||
if (bind_layout->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
|
||||
assert(subdesc_type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
|
||||
subdesc_type == VK_DESCRIPTOR_TYPE_SAMPLER);
|
||||
return subdesc_type == VK_DESCRIPTOR_TYPE_SAMPLER ? 1 : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
shader_desc_idx(uint32_t set, uint32_t binding, VkDescriptorType subdesc_type,
|
||||
shader_desc_idx(uint32_t set, uint32_t binding,
|
||||
struct panvk_subdesc_info subdesc,
|
||||
const struct lower_desc_ctx *ctx)
|
||||
{
|
||||
const struct panvk_descriptor_set_layout *set_layout =
|
||||
get_set_layout(set, ctx);
|
||||
const struct panvk_descriptor_set_binding_layout *bind_layout =
|
||||
&set_layout->bindings[binding];
|
||||
uint32_t subdesc_idx = get_subdesc_idx(bind_layout, subdesc_type);
|
||||
uint32_t subdesc_idx = get_subdesc_idx(bind_layout, subdesc);
|
||||
|
||||
/* On Valhall, all non-dynamic descriptors are accessed directly through
|
||||
* their set. The vertex attribute table always comes first, so we always
|
||||
|
|
@ -193,7 +184,7 @@ shader_desc_idx(uint32_t set, uint32_t binding, VkDescriptorType subdesc_type,
|
|||
} else if (bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
|
||||
map = &ctx->desc_info.dyn_ssbos;
|
||||
} else {
|
||||
uint32_t table = desc_type_to_table_type(bind_layout->type, src.subdesc);
|
||||
uint32_t table = desc_type_to_table_type(bind_layout, src.subdesc);
|
||||
|
||||
assert(table < PANVK_BIFROST_DESC_TABLE_COUNT);
|
||||
map = &ctx->desc_info.others[table];
|
||||
|
|
@ -300,7 +291,7 @@ build_res_index(nir_builder *b, uint32_t set, uint32_t binding,
|
|||
&set_layout->bindings[binding];
|
||||
uint32_t array_size = bind_layout->desc_count;
|
||||
nir_address_format addr_fmt = addr_format_for_type(bind_layout->type, ctx);
|
||||
uint32_t desc_idx = shader_desc_idx(set, binding, bind_layout->type, ctx);
|
||||
uint32_t desc_idx = shader_desc_idx(set, binding, NO_SUBDESC, ctx);
|
||||
|
||||
switch (addr_fmt) {
|
||||
#if PAN_ARCH <= 7
|
||||
|
|
@ -524,7 +515,14 @@ load_resource_deref_desc(nir_builder *b, nir_deref_instr *deref,
|
|||
get_set_layout(set, ctx);
|
||||
const struct panvk_descriptor_set_binding_layout *bind_layout =
|
||||
&set_layout->bindings[binding];
|
||||
unsigned subdesc_idx = get_subdesc_idx(bind_layout, subdesc_type);
|
||||
struct panvk_subdesc_info subdesc =
|
||||
subdesc_type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
|
||||
? get_tex_subdesc_info(bind_layout->type, 0)
|
||||
: subdesc_type == VK_DESCRIPTOR_TYPE_SAMPLER
|
||||
? get_sampler_subdesc_info(bind_layout->type, 0)
|
||||
: NO_SUBDESC;
|
||||
|
||||
unsigned subdesc_idx = get_subdesc_idx(bind_layout, subdesc);
|
||||
|
||||
assert(index_ssa == NULL || index_imm == 0);
|
||||
if (index_ssa == NULL)
|
||||
|
|
@ -677,12 +675,24 @@ load_img_samples(nir_builder *b, nir_deref_instr *deref,
|
|||
}
|
||||
|
||||
static uint32_t
|
||||
get_desc_array_stride(const struct panvk_descriptor_set_binding_layout *layout)
|
||||
get_desc_array_stride(const struct panvk_descriptor_set_binding_layout *layout,
|
||||
VkDescriptorType type)
|
||||
{
|
||||
if (PAN_ARCH >= 9)
|
||||
return panvk_get_desc_stride(layout);
|
||||
|
||||
/* On Bifrost, descriptors are copied from the sets to the final
|
||||
* descriptor tables which are per-type, making the stride one in
|
||||
* this context. */
|
||||
return PAN_ARCH >= 9 ? panvk_get_desc_stride(layout) : 1;
|
||||
* descriptor tables which are per-type. For combined image-sampler,
|
||||
* the stride is {textures/samplers}_per_desc in this context;
|
||||
* otherwise the stride is one. */
|
||||
switch(type) {
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
return layout->textures_per_desc;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
return layout->samplers_per_desc;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -722,9 +732,14 @@ lower_tex(nir_builder *b, nir_tex_instr *tex, const struct lower_desc_ctx *ctx)
|
|||
return true;
|
||||
}
|
||||
|
||||
uint32_t plane = 0;
|
||||
int sampler_src_idx =
|
||||
nir_tex_instr_src_index(tex, nir_tex_src_sampler_deref);
|
||||
if (sampler_src_idx >= 0) {
|
||||
nir_def *plane_ssa = nir_steal_tex_src(tex, nir_tex_src_plane);
|
||||
plane =
|
||||
plane_ssa ? nir_src_as_uint(nir_src_for_ssa(plane_ssa)) : 0;
|
||||
|
||||
nir_deref_instr *deref = nir_src_as_deref(tex->src[sampler_src_idx].src);
|
||||
nir_tex_instr_remove_src(tex, sampler_src_idx);
|
||||
|
||||
|
|
@ -736,10 +751,12 @@ lower_tex(nir_builder *b, nir_tex_instr *tex, const struct lower_desc_ctx *ctx)
|
|||
get_set_layout(set, ctx);
|
||||
const struct panvk_descriptor_set_binding_layout *bind_layout =
|
||||
&set_layout->bindings[binding];
|
||||
uint32_t desc_stride = get_desc_array_stride(bind_layout);
|
||||
struct panvk_subdesc_info subdesc =
|
||||
get_sampler_subdesc_info(bind_layout->type, plane);
|
||||
uint32_t desc_stride = get_desc_array_stride(bind_layout, subdesc.type);
|
||||
|
||||
tex->sampler_index =
|
||||
shader_desc_idx(set, binding, VK_DESCRIPTOR_TYPE_SAMPLER, ctx) +
|
||||
shader_desc_idx(set, binding, subdesc, ctx) +
|
||||
index_imm * desc_stride;
|
||||
|
||||
if (index_ssa != NULL) {
|
||||
|
|
@ -767,10 +784,12 @@ lower_tex(nir_builder *b, nir_tex_instr *tex, const struct lower_desc_ctx *ctx)
|
|||
get_set_layout(set, ctx);
|
||||
const struct panvk_descriptor_set_binding_layout *bind_layout =
|
||||
&set_layout->bindings[binding];
|
||||
uint32_t desc_stride = get_desc_array_stride(bind_layout);
|
||||
struct panvk_subdesc_info subdesc =
|
||||
get_tex_subdesc_info(bind_layout->type, plane);
|
||||
uint32_t desc_stride = get_desc_array_stride(bind_layout, subdesc.type);
|
||||
|
||||
tex->texture_index =
|
||||
shader_desc_idx(set, binding, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, ctx) +
|
||||
shader_desc_idx(set, binding, subdesc, ctx) +
|
||||
index_imm * desc_stride;
|
||||
|
||||
if (index_ssa != NULL) {
|
||||
|
|
@ -798,7 +817,7 @@ get_img_index(nir_builder *b, nir_deref_instr *deref,
|
|||
bind_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
|
||||
bind_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
|
||||
|
||||
unsigned img_offset = shader_desc_idx(set, binding, bind_layout->type, ctx);
|
||||
unsigned img_offset = shader_desc_idx(set, binding, NO_SUBDESC, ctx);
|
||||
|
||||
if (index_ssa == NULL) {
|
||||
return nir_imm_int(b, img_offset + index_imm);
|
||||
|
|
@ -879,15 +898,17 @@ lower_descriptors_instr(nir_builder *b, nir_instr *instr, void *data)
|
|||
|
||||
static void
|
||||
record_binding(struct lower_desc_ctx *ctx, unsigned set, unsigned binding,
|
||||
VkDescriptorType subdesc_type, uint32_t max_idx)
|
||||
struct panvk_subdesc_info subdesc, uint32_t max_idx)
|
||||
{
|
||||
const struct panvk_descriptor_set_layout *set_layout = ctx->set_layouts[set];
|
||||
const struct panvk_descriptor_set_binding_layout *binding_layout =
|
||||
&set_layout->bindings[binding];
|
||||
uint32_t subdesc_idx = get_subdesc_idx(binding_layout, subdesc_type);
|
||||
uint32_t subdesc_idx = get_subdesc_idx(binding_layout, subdesc);
|
||||
uint32_t desc_stride = panvk_get_desc_stride(binding_layout);
|
||||
uint32_t max_desc_stride = MAX2(
|
||||
binding_layout->samplers_per_desc + binding_layout->textures_per_desc, 1);
|
||||
|
||||
assert(desc_stride == 1 || desc_stride == 2);
|
||||
assert(desc_stride >= 1 && desc_stride <= max_desc_stride);
|
||||
ctx->desc_info.used_set_mask |= BITFIELD_BIT(set);
|
||||
|
||||
/* On valhall, we only record dynamic bindings, others are accessed directly
|
||||
|
|
@ -931,7 +952,7 @@ record_binding(struct lower_desc_ctx *ctx, unsigned set, unsigned binding,
|
|||
ctx->desc_info.dyn_ssbos.count += desc_count_diff;
|
||||
} else {
|
||||
uint32_t table =
|
||||
desc_type_to_table_type(binding_layout->type, subdesc_idx);
|
||||
desc_type_to_table_type(binding_layout, subdesc_idx);
|
||||
|
||||
assert(table < PANVK_BIFROST_DESC_TABLE_COUNT);
|
||||
ctx->desc_info.others[table].count += desc_count_diff;
|
||||
|
|
@ -969,7 +990,7 @@ fill_copy_descs_for_binding(struct lower_desc_ctx *ctx, unsigned set,
|
|||
map = &ctx->desc_info.dyn_ssbos;
|
||||
} else {
|
||||
uint32_t dst_table =
|
||||
desc_type_to_table_type(binding_layout->type, subdesc_idx);
|
||||
desc_type_to_table_type(binding_layout, subdesc_idx);
|
||||
|
||||
assert(dst_table < PANVK_BIFROST_DESC_TABLE_COUNT);
|
||||
map = &ctx->desc_info.others[dst_table];
|
||||
|
|
@ -1069,17 +1090,28 @@ collect_tex_desc_access(nir_builder *b, nir_tex_instr *tex,
|
|||
struct lower_desc_ctx *ctx)
|
||||
{
|
||||
bool recorded = false;
|
||||
uint32_t plane = 0;
|
||||
int sampler_src_idx =
|
||||
nir_tex_instr_src_index(tex, nir_tex_src_sampler_deref);
|
||||
if (sampler_src_idx >= 0) {
|
||||
int plane_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_plane);
|
||||
if (plane_src_idx >= 0)
|
||||
plane = nir_src_as_uint(tex->src[plane_src_idx].src);
|
||||
|
||||
nir_deref_instr *deref = nir_src_as_deref(tex->src[sampler_src_idx].src);
|
||||
|
||||
uint32_t set, binding, index_imm, max_idx;
|
||||
nir_def *index_ssa;
|
||||
get_resource_deref_binding(deref, &set, &binding, &index_imm, &index_ssa,
|
||||
&max_idx);
|
||||
const struct panvk_descriptor_set_layout *set_layout =
|
||||
ctx->set_layouts[set];
|
||||
const struct panvk_descriptor_set_binding_layout *binding_layout =
|
||||
&set_layout->bindings[binding];
|
||||
struct panvk_subdesc_info subdesc =
|
||||
get_sampler_subdesc_info(binding_layout->type, plane);
|
||||
|
||||
record_binding(ctx, set, binding, VK_DESCRIPTOR_TYPE_SAMPLER, max_idx);
|
||||
record_binding(ctx, set, binding, subdesc, max_idx);
|
||||
recorded = true;
|
||||
}
|
||||
|
||||
|
|
@ -1091,9 +1123,14 @@ collect_tex_desc_access(nir_builder *b, nir_tex_instr *tex,
|
|||
nir_def *index_ssa;
|
||||
get_resource_deref_binding(deref, &set, &binding, &index_imm, &index_ssa,
|
||||
&max_idx);
|
||||
const struct panvk_descriptor_set_layout *set_layout =
|
||||
ctx->set_layouts[set];
|
||||
const struct panvk_descriptor_set_binding_layout *binding_layout =
|
||||
&set_layout->bindings[binding];
|
||||
struct panvk_subdesc_info subdesc =
|
||||
get_tex_subdesc_info(binding_layout->type, plane);
|
||||
|
||||
record_binding(ctx, set, binding, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
max_idx);
|
||||
record_binding(ctx, set, binding, subdesc, max_idx);
|
||||
recorded = true;
|
||||
}
|
||||
|
||||
|
|
@ -1113,7 +1150,7 @@ collect_intr_desc_access(nir_builder *b, nir_intrinsic_instr *intrin,
|
|||
|
||||
/* TODO: walk the reindex chain from load_vulkan_descriptor() to try and
|
||||
* guess the max index. */
|
||||
record_binding(ctx, set, binding, ~0, UINT32_MAX);
|
||||
record_binding(ctx, set, binding, NO_SUBDESC, UINT32_MAX);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1129,7 +1166,7 @@ collect_intr_desc_access(nir_builder *b, nir_intrinsic_instr *intrin,
|
|||
|
||||
get_resource_deref_binding(deref, &set, &binding, &index_imm, &index_ssa,
|
||||
&max_idx);
|
||||
record_binding(ctx, set, binding, ~0, max_idx);
|
||||
record_binding(ctx, set, binding, NO_SUBDESC, max_idx);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "vk_format.h"
|
||||
#include "vk_log.h"
|
||||
#include "vk_ycbcr_conversion.h"
|
||||
|
||||
static enum mali_mipmap_mode
|
||||
panvk_translate_sampler_mipmap_mode(VkSamplerMipmapMode mode)
|
||||
|
|
@ -185,7 +186,7 @@ panvk_per_arch(CreateSampler)(VkDevice _device,
|
|||
if (!sampler)
|
||||
return panvk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
STATIC_ASSERT(sizeof(sampler->desc) >= pan_size(SAMPLER));
|
||||
STATIC_ASSERT(sizeof(sampler->descs[0]) >= pan_size(SAMPLER));
|
||||
|
||||
VkFormat fmt;
|
||||
VkClearColorValue border_color =
|
||||
|
|
@ -195,10 +196,27 @@ panvk_per_arch(CreateSampler)(VkDevice _device,
|
|||
panvk_afbc_reswizzle_border_color(&border_color, fmt);
|
||||
#endif
|
||||
|
||||
panvk_sampler_fill_desc(pCreateInfo, &sampler->desc, border_color,
|
||||
sampler->desc_count = 1;
|
||||
panvk_sampler_fill_desc(pCreateInfo, &sampler->descs[0], border_color,
|
||||
pCreateInfo->minFilter, pCreateInfo->magFilter,
|
||||
sampler->vk.reduction_mode);
|
||||
|
||||
/* In order to support CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT,
|
||||
* we need multiple sampler planes: at minimum we will need one for
|
||||
* luminance (the default), and one for chroma.
|
||||
*/
|
||||
if (sampler->vk.ycbcr_conversion) {
|
||||
const VkFilter chroma_filter =
|
||||
sampler->vk.ycbcr_conversion->state.chroma_filter;
|
||||
if (pCreateInfo->magFilter != chroma_filter ||
|
||||
pCreateInfo->minFilter != chroma_filter) {
|
||||
sampler->desc_count = 2;
|
||||
panvk_sampler_fill_desc(pCreateInfo, &sampler->descs[1],
|
||||
border_color, chroma_filter, chroma_filter,
|
||||
sampler->vk.reduction_mode);
|
||||
}
|
||||
}
|
||||
|
||||
*pSampler = panvk_sampler_to_handle(sampler);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue