Positional arguments? Im my C++? It's more likely than you think!

This commit is contained in:
mittorn 2024-10-15 01:30:40 +03:00
parent 9639c4c990
commit 50eca7e379
2 changed files with 74 additions and 120 deletions

View file

@ -102,98 +102,70 @@ struct ComputeApplication {
void ImportVaapiImage(VulkanTexture &texture0, VulkanTexture &texture1, int fd, uint64_t mod, uint32_t size, uint32_t offset, uint32_t pitch1, uint32_t pitch2, bool p010)
{
VkImageCreateInfo imageCreateInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.format = p010?VK_FORMAT_R16_UNORM:VK_FORMAT_R8_UNORM;
imageCreateInfo.extent = { WIDTH, HEIGHT, 1 };
imageCreateInfo.mipLevels = 1;
imageCreateInfo.arrayLayers = 1;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageCreateInfo.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;//VK_IMAGE_TILING_LINEAR;
// todo: do we need SAMPLED?
imageCreateInfo.usage = VK_IMAGE_USAGE_STORAGE_BIT;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
// external image stuff
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //PREINITIALIZED;
VkExternalMemoryImageCreateInfo extInfo = {VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO};
extInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
imageCreateInfo.pNext = &extInfo;
VkImageDrmFormatModifierExplicitCreateInfoEXT drmModInfo = {VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT};
VkSubresourceLayout layout = {0};
layout.rowPitch = pitch1;
drmModInfo.drmFormatModifierPlaneCount = 1;
drmModInfo.drmFormatModifier = mod;
drmModInfo.pPlaneLayouts = &layout;
extInfo.pNext = &drmModInfo;
StructureChain layout{$M(VkSubresourceLayout{0},$(rowPitch) = pitch1)};
StructureChain iinfo{
Wr(VkImageCreateInfo{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO},
S(imageType,VK_IMAGE_TYPE_2D),
S(format,p010?VK_FORMAT_R16_UNORM:VK_FORMAT_R8_UNORM),
S(extent, imageCreateInfo.extent),
S(mipLevels, 1),
S(arrayLayers, 1),
S(samples,VK_SAMPLE_COUNT_1_BIT),
S(tiling,VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT),
S(usage, VK_IMAGE_USAGE_STORAGE_BIT),
S(sharingMode, VK_SHARING_MODE_EXCLUSIVE)
$M(VkImageCreateInfo{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO},
$(imageType) = VK_IMAGE_TYPE_2D,
$(format) = p010?VK_FORMAT_R16_UNORM:VK_FORMAT_R8_UNORM,
$(extent) = VkExtent3D{ WIDTH, HEIGHT, 1 },
$(mipLevels) = 1,
$(arrayLayers)= 1,
$(samples) =VK_SAMPLE_COUNT_1_BIT,
$(tiling) = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
$(usage) = VK_IMAGE_USAGE_STORAGE_BIT,
$(sharingMode) = VK_SHARING_MODE_EXCLUSIVE
),
Wr(VkExternalMemoryImageCreateInfo{VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO},
S(handleTypes, VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)
$M(VkExternalMemoryImageCreateInfo{VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO},
$(handleTypes) = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT
),
Wr(VkImageDrmFormatModifierExplicitCreateInfoEXT{VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT},
S(drmFormatModifierPlaneCount,1),
S(drmFormatModifier, mod),
S(pPlaneLayouts, &layout))
};
//VkExternalMemoryImageCreateInfo{VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO}
//};
//auto a = StructureWrapper(VkExternalMemoryImageCreateInfo{}, Setter(&VkExternalMemoryImageCreateInfo::handleTypes,VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT));
//StructureWrapper<VkExternalMemoryImageCreateInfo> aaa{};
//&decltype(aaa)::Setter3::handleTypes;
//auto a = StructureWrapper1(VkExternalMemoryImageCreateInfo{},
//Setter4([](auto *a){
//return &decltype(*a)::handleTypes;
// },VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT));
$M(VkImageDrmFormatModifierExplicitCreateInfoEXT{VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT},
$(drmFormatModifierPlaneCount) = 1,
$(drmFormatModifier) = mod,
$(pPlaneLayouts) = &layout
)
};
VK_CHECK_RESULT(vkCreateImage(dev.device, &iinfo, NULL, &texture0.image)); // create image.
imageCreateInfo.format = p010?VK_FORMAT_R16G16_UNORM:VK_FORMAT_R8G8_UNORM;
imageCreateInfo.extent = { WIDTH/2, HEIGHT/2, 1 };
layout.offset = 0;//2088960;
layout.rowPitch = pitch2;
VK_CHECK_RESULT(vkCreateImage(dev.device, &imageCreateInfo, NULL, &texture1.image)); // create image.
$F(iinfo,$(format) = p010?VK_FORMAT_R16G16_UNORM:VK_FORMAT_R8G8_UNORM, $(extent) = VkExtent3D{ WIDTH/2, HEIGHT/2, 1 });
$F(layout,$(offset) = 0, $(rowPitch) = pitch2 );
VK_CHECK_RESULT(vkCreateImage(dev.device, &iinfo, NULL, &texture1.image)); // create image.
VkMemoryRequirements memoryRequirements;
vkGetImageMemoryRequirements(dev.device, texture0.image, &memoryRequirements);
VkImportMemoryFdInfoKHR importInfo = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR};
importInfo.handleType =VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
importInfo.fd = fd;
VkMemoryFdPropertiesKHR fdProps = {VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR};
PFN_vkGetMemoryFdPropertiesKHR vkGetMemoryFdProperties = (PFN_vkGetMemoryFdPropertiesKHR)vkGetInstanceProcAddr(context.instance, "vkGetMemoryFdPropertiesKHR");
vkGetMemoryFdProperties(dev.device,VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, fd, &fdProps);
VkMemoryAllocateInfo allocateInfo = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
allocateInfo.allocationSize = size;//memoryRequirements.size; // specify required memory.
allocateInfo.pNext = &importInfo;
StructureChain ainfo{
$M(VkMemoryAllocateInfo{VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO},
$(allocationSize) = size //memoryRequirements.size; // specify required memory.
),
$M(VkImportMemoryFdInfoKHR{VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR},
$(handleType) = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
$(fd) = fd
)
};
dev.GetMemoryType(memoryRequirements.memoryTypeBits & fdProps.memoryTypeBits, 0, &allocateInfo.memoryTypeIndex);//VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
VK_CHECK_RESULT(vkAllocateMemory(dev.device, &allocateInfo, NULL, &texture0.device_memory)); // allocate memory on device.
dev.GetMemoryType(memoryRequirements.memoryTypeBits & fdProps.memoryTypeBits, 0, &ainfo.memoryTypeIndex);//VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
VK_CHECK_RESULT(vkAllocateMemory(dev.device, &ainfo, NULL, &texture0.device_memory)); // allocate memory on device.
// Now associate that allocated memory with the buffer. With that, the buffer is backed by actual memory.
VK_CHECK_RESULT(vkBindImageMemory(dev.device, texture0.image, texture0.device_memory, 0));
VK_CHECK_RESULT(vkBindImageMemory(dev.device, texture1.image, texture0.device_memory, offset));
texture0.image_layout = VK_IMAGE_LAYOUT_UNDEFINED;
texture0.width = WIDTH;
texture0.height = HEIGHT;
texture0.mip_levels = 1;
texture0.layer_count = 1;
texture1.image_layout = VK_IMAGE_LAYOUT_UNDEFINED;
texture1.width = WIDTH/2;
texture1.height = HEIGHT/2;
texture1.mip_levels = 1;
texture1.layer_count = 1;
$F(texture0,
$(image_layout) = VK_IMAGE_LAYOUT_UNDEFINED,
$(width) = WIDTH,
$(height) = HEIGHT,
$(mip_levels) = 1,
$(layer_count) = 1
);
$F(texture1,
$(image_layout) = VK_IMAGE_LAYOUT_UNDEFINED,
$(width) = WIDTH/2,
$(height) = HEIGHT/2,
$(mip_levels) = 1,
$(layer_count) = 1
);
texture0.CreateImageView(dev.device, p010?VK_FORMAT_R16_UNORM:VK_FORMAT_R8_UNORM);
texture1.CreateImageView(dev.device, p010?VK_FORMAT_R16G16_UNORM:VK_FORMAT_R8G8_UNORM);
}

View file

@ -51,8 +51,7 @@ const bool enableValidationLayers = true;
} \
}
// wrapper for chains with pNext
template <typename T, typename... Ts>
struct StructureChain : T, StructureChain<Ts...>
{
@ -68,66 +67,49 @@ struct StructureChain<T> : T
StructureChain(const T &t) : T(t){}
};
// Positional arguments? Im my C++? It's more likely than you think!
template<typename T>
struct SetterFunc;
template<typename T, typename V>
struct Setter2
struct SetterVal // keeps val reference and SetterFunc wrapper
{
V T::*ptr;
const SetterFunc<T> &func;
const V &val;
template <typename T1>
Setter2(V T::*p, T1 v) : ptr(p), val(v){}
SetterVal(const SetterFunc<T> &f, const V &v) : func(f), val(v){}
};
template<typename T, typename V>
struct Setter5
template<typename T>
struct SetterFunc // keeps member pointer getter, wrapper for user-provided lambda
{
V T::*ptr;
const V &val;
template <typename T1>
Setter5(V T::*p, T1 v) : ptr(p), val(v){}
};
template<typename T, typename V>
struct SetterPair: T
{
const V &val;
SetterPair(const T &data, const V &v)
: T(data), val(v)
const T &func;
SetterFunc(const T &data)
: func(data)
{}
template <typename V>
SetterVal<T,V> operator() (const V &v) {return SetterVal(*this,v);}
template <typename V>
SetterVal<T,V> operator= (const V &v) {return SetterVal(*this,v);}
};
#define S(k,v) SetterPair([](auto a){return &decltype(a)::k;},v)
// macro wrapper for building positional argument setters
// todo: remove extra unused copy
#define $(k) SetterFunc([](auto a){return &decltype(a)::k;})
template <typename T, typename... Ts>
T Wr(T t, Ts... ts)
void $F(T &t, const Ts&... ts) // fills all SetterVal's member pointers with it's values
{
T t1 = t;
auto filler = [](T &t, const auto &arg){
auto T::*ptr = arg(t);
t.*ptr = arg.val;
t.*arg.func.func(t) = arg.val;
};
(filler(t,ts),...);
}
// wrapper for inline constructors with FillStructure
template <typename T, typename... Ts>
T $M(T t, const Ts&... ts)
{
$F(t, ts...);
return t;
}
template <typename T>
struct StructureWrapper
{
template<typename V>
struct Setter1
{
V T::*ptr;
const V &val;
template <typename T1>
Setter1(V T::*p, T1 v) : ptr(p), val(v){}
};
struct Setter3: T{};
};
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
struct VulkanContext
{