From c710287143734ab6f708dbdf54fe9a46134ae402 Mon Sep 17 00:00:00 2001 From: Jens Koenen <koenen@vr.rwth-aachen.de> Date: Thu, 27 Oct 2022 17:34:53 +0200 Subject: [PATCH] Started allocating the input images for the NvEnc encoder. --- src/encoder/encoder.hpp | 4 +- src/encoder/nvidia_encoder.cpp | 406 ++++++++++++++++++++++++++++++- src/encoder/nvidia_encoder.hpp | 27 +- src/encoder/vulkan_encoder.cpp | 2 +- src/encoder/vulkan_encoder.hpp | 2 +- src/headset/emulated_headset.cpp | 2 +- src/headset/remote_headset.cpp | 2 +- src/vr_application.cpp | 9 + 8 files changed, 432 insertions(+), 22 deletions(-) diff --git a/src/encoder/encoder.hpp b/src/encoder/encoder.hpp index a766aed1..91b8db81 100644 --- a/src/encoder/encoder.hpp +++ b/src/encoder/encoder.hpp @@ -13,7 +13,7 @@ setup_device_for_encoder(...); //During creation and submission of a frame - Encoder::Ptr encoder = make_encoder(); + Encoder::Ptr encoder = make_encoder(...); encoder->create(...); @@ -59,7 +59,7 @@ public: virtual ~Encoder() = default; //NOTE: The parameter input_buffers defines how many input images the encoder should provide. - virtual bool create(lava::device_ptr device, const lava::renderer& renderer, const glm::uvec2& size, uint32_t input_buffers) = 0; + virtual bool create(lava::instance& instance, lava::device_ptr device, const lava::renderer& renderer, const glm::uvec2& size, uint32_t input_buffers) = 0; virtual void destroy() = 0; //NOTE: The following functions should be thread safe. diff --git a/src/encoder/nvidia_encoder.cpp b/src/encoder/nvidia_encoder.cpp index 45abd910..99e13714 100644 --- a/src/encoder/nvidia_encoder.cpp +++ b/src/encoder/nvidia_encoder.cpp @@ -1,22 +1,38 @@ #include "nvidia_encoder.hpp" -#include <cuda.h> - -#if defined(__unix__) +#if defined(_WIN32) + #include <windows.h> + #include <vulkan/vulkan_win32.h> +#elif defined(__unix__) #include <dlfcn.h> +#else + #error "Not implemented for this platform!" #endif typedef NVENCSTATUS(NVENCAPI* NvEncodeAPICreateInstance_Type)(NV_ENCODE_API_FUNCTION_LIST*); -bool NvidiaEncoder::create(lava::device_ptr device, const lava::renderer& renderer, const glm::uvec2& size, uint32_t input_buffers) +bool NvidiaEncoder::create(lava::instance& instance, lava::device_ptr device, const lava::renderer& renderer, const glm::uvec2& size, uint32_t input_buffers) { - cuInit(0); + if (!this->create_context(device)) + { + return false; + } if (!this->load_library()) { return false; } + if (!this->create_session()) + { + return false; + } + + if (!this->create_input_buffers(instance, device, size, input_buffers)) + { + return false; + } + return false; } @@ -85,21 +101,88 @@ uint32_t NvidiaEncoder::get_frame_rate() const return this->frame_rate; } +bool NvidiaEncoder::create_context(lava::device_ptr device) +{ + VkPhysicalDeviceIDProperties physical_device_id; + physical_device_id.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; + physical_device_id.pNext = nullptr; + + VkPhysicalDeviceProperties2 physical_device_properties; + physical_device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + physical_device_properties.pNext = &physical_device_id; + + vkGetPhysicalDeviceProperties2(device->get_physical_device()->get(), &physical_device_properties); + + int32_t device_count = 0; + + if (cuDeviceGetCount(&device_count) != CUDA_SUCCESS) + { + lava::log()->error("Can't get cuda device count!"); + + return false; + } + + for (uint32_t index = 0; index < device_count; index++) + { + CUdevice device_handle; + CUuuid device_id; + + if (cuDeviceGet(&device_handle, index) != CUDA_SUCCESS) + { + lava::log()->error("Can't get cuda device handle!"); + + return false; + } + + if (cuDeviceGetUuid(&device_id, device_handle) != CUDA_SUCCESS) + { + lava::log()->error("Can't get cuda device identifier!"); + + return false; + } + + if (memcmp(device_id.bytes, physical_device_id.deviceUUID, sizeof(device_id.bytes)) != 0) + { + continue; + } + + this->cuda_device = device_handle; + + if(cuCtxCreate(&this->cuda_context, 0, this->cuda_device) != CUDA_SUCCESS) + { + lava::log()->error("Can't create cuda context!"); + + return false; + } + + return true; + } + + lava::log()->error("Can't find matching cuda device!"); + + return false; +} + +void NvidiaEncoder::destroy_context() +{ + +} + bool NvidiaEncoder::load_library() { #if defined(_WIN32) #if defined(_WIN64) - this->library_handle = LoadLibrary("nvEncodeAPI64.dll"); + this->nvenc_library = LoadLibrary("nvEncodeAPI64.dll"); #else - this->library_handle = LoadLibrary("nvEncodeAPI.dll"); + this->nvenc_library = LoadLibrary("nvEncodeAPI.dll"); #endif #elif defined(__unix__) - this->library_handle = dlopen("libnvidia-encode.so.1", RTLD_LAZY); + this->nvenc_library = dlopen("libnvidia-encode.so.1", RTLD_LAZY); #else #error "Not implemented for this platform!" #endif - if (this->library_handle == nullptr) + if (this->nvenc_library == nullptr) { lava::log()->error("Can't load library!"); @@ -109,9 +192,9 @@ bool NvidiaEncoder::load_library() NvEncodeAPICreateInstance_Type NvEncodeAPICreateInstance = nullptr; #if defined(_WIN32) - NvEncodeAPICreateInstance = (NvEncodeAPICreateInstance_Type)GetProcAddress((HMODULE) this->library_handle, "NvEncodeAPICreateInstance"); + NvEncodeAPICreateInstance = (NvEncodeAPICreateInstance_Type)GetProcAddress((HMODULE)this->nvenc_library, "NvEncodeAPICreateInstance"); #elif defined(__unix__) - NvEncodeAPICreateInstance = (NvEncodeAPICreateInstance_Type)dlsym((HMODULE) this->library_handle, "NvEncodeAPICreateInstance"); + NvEncodeAPICreateInstance = (NvEncodeAPICreateInstance_Type)dlsym((HMODULE)this->nvenc_library, "NvEncodeAPICreateInstance"); #else #error "Not implemented for this platform!" #endif @@ -123,9 +206,9 @@ bool NvidiaEncoder::load_library() return false; } - this->function_list.version = NV_ENCODE_API_FUNCTION_LIST_VER; + this->nvenc_functions.version = NV_ENCODE_API_FUNCTION_LIST_VER; - if (NvEncodeAPICreateInstance(&this->function_list) != NV_ENC_SUCCESS) + if (NvEncodeAPICreateInstance(&this->nvenc_functions) != NV_ENC_SUCCESS) { lava::log()->error("Can't create function list!"); @@ -140,12 +223,309 @@ void NvidiaEncoder::unload_library() } +bool NvidiaEncoder::create_session() +{ + NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS session_parameters; + session_parameters.version = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER; + session_parameters.deviceType = NV_ENC_DEVICE_TYPE_CUDA; + session_parameters.device = (void*)this->cuda_context; + session_parameters.reserved = 0; + session_parameters.apiVersion = NVENCAPI_VERSION; + memset(session_parameters.reserved1, 0, sizeof(session_parameters.reserved1)); + memset(session_parameters.reserved2, 0, sizeof(session_parameters.reserved2)); + + if (this->nvenc_functions.nvEncOpenEncodeSessionEx(&session_parameters, &this->nvenc_session) != NV_ENC_SUCCESS) + { + lava::log()->error("Can't create nvenc session!"); + + return false; + } + + if (!this->check_encode_support(NV_ENC_CODEC_H264_GUID)) + { + lava::log()->error("Codec not supported!"); + + return false; + } + + + return true; + + + if (!this->check_profile_support(NV_ENC_H264_PROFILE_HIGH_GUID)) + { + lava::log()->error("Profile not supported!"); + + return false; + } + + if (!this->check_preset_support(NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID)) + { + lava::log()->error("Preset not supported!"); + + return false; + } + + NV_ENC_INITIALIZE_PARAMS init_parameters; + /*init_parameters.version = NV_ENC_INITIALIZE_PARAMS_VER; /**< [in]: Struct version. Must be set to ::NV_ENC_INITIALIZE_PARAMS_VER. */ + /*init_parameters.encodeGUID; /**< [in]: Specifies the Encode GUID for which the encoder is being created. ::NvEncInitializeEncoder() API will fail if this is not set, or set to unsupported value. */ + /*init_parameters.presetGUID; /**< [in]: Specifies the preset for encoding. If the preset GUID is set then , the preset configuration will be applied before any other parameter. */ + /*init_parameters.encodeWidth; /**< [in]: Specifies the encode width. If not set ::NvEncInitializeEncoder() API will fail. */ + /*init_parameters.encodeHeight; /**< [in]: Specifies the encode height. If not set ::NvEncInitializeEncoder() API will fail. */ + /*init_parameters.darWidth; /**< [in]: Specifies the display aspect ratio Width. */ + /*init_parameters.darHeight; /**< [in]: Specifies the display aspect ratio height. */ + /*init_parameters.frameRateNum; /**< [in]: Specifies the numerator for frame rate used for encoding in frames per second ( Frame rate = frameRateNum / frameRateDen ). */ + /*init_parameters.frameRateDen; /**< [in]: Specifies the denominator for frame rate used for encoding in frames per second ( Frame rate = frameRateNum / frameRateDen ). */ + /*init_parameters.enableEncodeAsync; /**< [in]: Set this to 1 to enable asynchronous mode and is expected to use events to get picture completion notification. */ + /*init_parameters.enablePTD; /**< [in]: Set this to 1 to enable the Picture Type Decision is be taken by the NvEncodeAPI interface. */ + /*init_parameters.reportSliceOffsets : 1; /**< [in]: Set this to 1 to enable reporting slice offsets in ::_NV_ENC_LOCK_BITSTREAM. NV_ENC_INITIALIZE_PARAMS::enableEncodeAsync must be set to 0 to use this feature. Client must set this to 0 if NV_ENC_CONFIG_H264::sliceMode is 1 on Kepler GPUs */ + /*init_parameters.enableSubFrameWrite : 1; /**< [in]: Set this to 1 to write out available bitstream to memory at subframe intervals. + If enableSubFrameWrite = 1, then the hardware encoder returns data as soon as a slice has completed encoding. + This results in better encoding latency, but the downside is that the application has to keep polling via a call to nvEncLockBitstream API continuously to see if any encoded slice data is available. + Use this mode if you feel that the marginal reduction in latency from sub-frame encoding is worth the increase in complexity due to CPU-based polling. */ + /*init_parameters.enableExternalMEHints : 1; /**< [in]: Set to 1 to enable external ME hints for the current frame. For NV_ENC_INITIALIZE_PARAMS::enablePTD=1 with B frames, programming L1 hints is optional for B frames since Client doesn't know internal GOP structure. + NV_ENC_PIC_PARAMS::meHintRefPicDist should preferably be set with enablePTD=1. */ + /*init_parameters.enableMEOnlyMode : 1; /**< [in]: Set to 1 to enable ME Only Mode .*/ + /*init_parameters.enableWeightedPrediction : 1; /**< [in]: Set this to 1 to enable weighted prediction. Not supported if encode session is configured for B-Frames (i.e. NV_ENC_CONFIG::frameIntervalP > 1 or preset >=P3 when tuningInfo = ::NV_ENC_TUNING_INFO_HIGH_QUALITY or + tuningInfo = ::NV_ENC_TUNING_INFO_LOSSLESS. This is because preset >=p3 internally enables B frames when tuningInfo = ::NV_ENC_TUNING_INFO_HIGH_QUALITY or ::NV_ENC_TUNING_INFO_LOSSLESS). */ + /*init_parameters.enableOutputInVidmem : 1; /**< [in]: Set this to 1 to enable output of NVENC in video memory buffer created by application. This feature is not supported for HEVC ME only mode. */ + /*init_parameters.reservedBitFields : 26; /**< [in]: Reserved bitfields and must be set to 0 */ + /*init_parameters.privDataSize; /**< [in]: Reserved private data buffer size and must be set to 0 */ + /*init_parameters.privData; /**< [in]: Reserved private data buffer and must be set to NULL */ + /*init_parameters.encodeConfig; /**< [in]: Specifies the advanced codec specific structure. If client has sent a valid codec config structure, it will override parameters set by the NV_ENC_INITIALIZE_PARAMS::presetGUID parameter. If set to NULL the NvEncodeAPI interface will use the NV_ENC_INITIALIZE_PARAMS::presetGUID to set the codec specific parameters. + Client can also optionally query the NvEncodeAPI interface to get codec specific parameters for a presetGUID using ::NvEncGetEncodePresetConfig() API. It can then modify (if required) some of the codec config parameters and send down a custom config structure as part of ::_NV_ENC_INITIALIZE_PARAMS. + Even in this case client is recommended to pass the same preset guid it has used in ::NvEncGetEncodePresetConfig() API to query the config structure; as NV_ENC_INITIALIZE_PARAMS::presetGUID. This will not override the custom config structure but will be used to determine other Encoder HW specific parameters not exposed in the API. */ + /*init_parameters.maxEncodeWidth; /**< [in]: Maximum encode width to be used for current Encode session. + Client should allocate output buffers according to this dimension for dynamic resolution change. If set to 0, Encoder will not allow dynamic resolution change. */ + /*init_parameters.maxEncodeHeight; /**< [in]: Maximum encode height to be allowed for current Encode session. + Client should allocate output buffers according to this dimension for dynamic resolution change. If set to 0, Encode will not allow dynamic resolution change. */ + /*init_parameters.maxMEHintCountsPerBlock[2]; /**< [in]: If Client wants to pass external motion vectors in NV_ENC_PIC_PARAMS::meExternalHints buffer it must specify the maximum number of hint candidates per block per direction for the encode session. + The NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[0] is for L0 predictors and NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[1] is for L1 predictors. + This client must also set NV_ENC_INITIALIZE_PARAMS::enableExternalMEHints to 1. */ + /*init_parameters.tuningInfo; /**< [in]: Tuning Info of NVENC encoding(TuningInfo is not applicable to H264 and HEVC meonly mode). */ + /*init_parameters.bufferFormat; /**< [in]: Specifies input buffer format. Client should set input buffer format only when D3D12 interface type is used. */ + /*init_parameters.reserved[287]; /**< [in]: Reserved and must be set to 0 */ + /*init_parameters.reserved2[64]; /**< [in]: Reserved and must be set to NULL */ + + if (this->nvenc_functions.nvEncInitializeEncoder(&this->nvenc_session, &init_parameters) != NV_ENC_SUCCESS) + { + lava::log()->error("Can't init nvenc session!"); + + return false; + } + + return true; +} + +void NvidiaEncoder::destroy_session() +{ + +} + +bool NvidiaEncoder::create_input_buffers(lava::instance& instance, lava::device_ptr device, const glm::uvec2& size, uint32_t input_buffers) +{ + PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32HandleKHR_Func = (PFN_vkGetMemoryWin32HandleKHR) vkGetInstanceProcAddr(instance.get(), "vkGetMemoryWin32HandleKHR"); + + if (vkGetMemoryWin32HandleKHR_Func == nullptr) + { + return false; + } + + for (uint32_t index = 0; index < input_buffers; index++) + { + VkExternalMemoryImageCreateInfo export_image_info; + export_image_info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO; + export_image_info.pNext = nullptr; + export_image_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT; + + VkImageCreateInfo image_info; + image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_info.pNext = &export_image_info; + image_info.flags = 0; + image_info.imageType = VK_IMAGE_TYPE_2D; + image_info.format = VK_FORMAT_R8G8B8A8_SRGB; + image_info.extent.width = size.x; + image_info.extent.height = size.y; + image_info.extent.depth = 1; + image_info.mipLevels = 1; + image_info.arrayLayers = 1; + image_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_info.tiling = VK_IMAGE_TILING_OPTIMAL; + image_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; + image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + image_info.queueFamilyIndexCount = 0; + image_info.pQueueFamilyIndices = nullptr; + image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + VkImage image = VK_NULL_HANDLE; + + if (vkCreateImage(device->get(), &image_info, nullptr, &image) != VK_SUCCESS) + { + lava::log()->error("Can't create input image!"); + + return false; + } + + VkMemoryRequirements memory_requirements; + vkGetImageMemoryRequirements(device->get(), image, &memory_requirements); + + VkPhysicalDeviceMemoryProperties memory_properties; + vkGetPhysicalDeviceMemoryProperties(device->get_physical_device()->get(), &memory_properties); + + bool memory_found = false; + uint32_t memory_index = 0; + VkMemoryPropertyFlags memory_flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + + for (uint32_t index = 0; index < memory_properties.memoryTypeCount; index++) + { + if ((memory_requirements.memoryTypeBits & (1 << index)) == 0) + { + continue; + } + + if ((memory_properties.memoryTypes[index].propertyFlags & memory_flags) == 0) + { + continue; + } + + memory_found = true; + memory_index = index; + + break; + } + + if (!memory_found) + { + return false; + } + + VkExportMemoryAllocateInfo export_info; + export_info.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO; + export_info.pNext = nullptr; + export_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT; + + VkMemoryAllocateInfo allocation_info; + allocation_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocation_info.pNext = &export_info; + allocation_info.allocationSize = memory_requirements.size; + allocation_info.memoryTypeIndex = memory_index; + + VkDeviceMemory device_memory = VK_NULL_HANDLE; + + if (vkAllocateMemory(device->get(), &allocation_info, nullptr, &device_memory) != VK_SUCCESS) + { + return false; + } + + if (vkBindImageMemory(device->get(), image, device_memory, 0) != VK_SUCCESS) + { + return false; + } + + VkMemoryGetWin32HandleInfoKHR memory_info; + memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR; + memory_info.pNext = nullptr; + memory_info.memory = device_memory; + memory_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT; + + HANDLE memory_handle; + + if (vkGetMemoryWin32HandleKHR_Func(device->get(), &memory_info, &memory_handle) != VK_SUCCESS) + { + return false; + } + + CUDA_EXTERNAL_MEMORY_HANDLE_DESC external_memory_description; + external_memory_description.type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32; + external_memory_description.handle.win32.handle = memory_handle; + external_memory_description.handle.win32.name = nullptr; + external_memory_description.size = memory_requirements.size; + external_memory_description.flags = 0; + memset(external_memory_description.reserved, 0, sizeof(external_memory_description.reserved)); + + CUexternalMemory external_memory; + + if (cuImportExternalMemory(&external_memory, &external_memory_description) != CUDA_SUCCESS) + { + return false; + } + + //cuExternalMemoryGetMappedMipmappedArray(); + + this->nvenc_functions.nvEncRegisterResource() + + //TODO:!!!!!!! + } + + return true; +} + +void NvidiaEncoder::destroy_input_buffers() +{ + +} + +bool NvidiaEncoder::check_encode_support(GUID identifier) const +{ + uint32_t guid_count = 0; + + if (this->nvenc_functions.nvEncGetEncodeGUIDCount(this->nvenc_session, &guid_count) != NV_ENC_SUCCESS) + { + return false; + } + + std::vector<GUID> guid_list; + guid_list.resize(guid_count); + + if(this->nvenc_functions.nvEncGetEncodeGUIDs(this->nvenc_session, guid_list.data(), guid_count, &guid_count) != NV_ENC_SUCCESS) + { + return false; + } + + for (const GUID& guid : guid_list) + { + if (memcmp(&guid, &identifier, sizeof(guid)) == 0) + { + return true; + } + } + + return false; +} + +bool NvidiaEncoder::check_profile_support(GUID identifier) const +{ + + return false; +} + +bool NvidiaEncoder::check_preset_support(GUID identifier) const +{ + + return false; +} + +bool NvidiaEncoder::check_format_support(NV_ENC_BUFFER_FORMAT format) const +{ + + return false; +} + bool setup_instance_for_nvidia_encoder(lava::frame_config& config) { + if(cuInit(0) != CUDA_SUCCESS) + { + lava::log()->error("Can't init cuda!"); + + return false; + } + return true; } bool setup_device_for_nvidia_encoder(lava::device::create_param& parameters) { + parameters.extensions.push_back(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME); + return true; } \ No newline at end of file diff --git a/src/encoder/nvidia_encoder.hpp b/src/encoder/nvidia_encoder.hpp index 278a52cc..a6fd078b 100644 --- a/src/encoder/nvidia_encoder.hpp +++ b/src/encoder/nvidia_encoder.hpp @@ -6,6 +6,7 @@ #include <memory> #include <cstdint> +#include <cuda.h> #include <nvEncodeAPI.h> #include "encoder.hpp" @@ -18,7 +19,7 @@ public: public: NvidiaEncoder() = default; - bool create(lava::device_ptr device, const lava::renderer& renderer, const glm::uvec2& size, uint32_t input_buffers); + bool create(lava::instance& instance, lava::device_ptr device, const lava::renderer& renderer, const glm::uvec2& size, uint32_t input_buffers); void destroy(); bool encode(VkCommandBuffer command_buffer, lava::renderer& renderer, lava::image::ptr image, VkImageLayout image_layout, OnEncodeComplete function); @@ -38,9 +39,23 @@ public: uint32_t get_frame_rate() const; private: + bool create_context(lava::device_ptr device); + void destroy_context(); + bool load_library(); void unload_library(); + bool create_session(); + void destroy_session(); + + bool create_input_buffers(lava::instance& instance, lava::device_ptr device, const glm::uvec2& size, uint32_t input_buffers); + void destroy_input_buffers(); + + bool check_encode_support(GUID identifier) const; + bool check_profile_support(GUID identifier) const; + bool check_preset_support(GUID identifier) const; + bool check_format_support(NV_ENC_BUFFER_FORMAT format) const; + private: OnEncodeError on_encoder_error; @@ -51,8 +66,14 @@ private: uint32_t frame_rate = 90; private: - void* library_handle = nullptr; - NV_ENCODE_API_FUNCTION_LIST function_list; + CUdevice cuda_device; + CUcontext cuda_context; + + void* nvenc_library = nullptr; + void* nvenc_session = nullptr; + NV_ENCODE_API_FUNCTION_LIST nvenc_functions; + + std::vector<VkImage> input_buffers; }; bool setup_instance_for_nvidia_encoder(lava::frame_config& config); diff --git a/src/encoder/vulkan_encoder.cpp b/src/encoder/vulkan_encoder.cpp index b11d8b5e..cde326d0 100644 --- a/src/encoder/vulkan_encoder.cpp +++ b/src/encoder/vulkan_encoder.cpp @@ -2,7 +2,7 @@ #include <array> #include <vk_video/vulkan_video_codecs_common.h> -bool VulkanEncoder::create(lava::device_ptr device, const lava::renderer& renderer, const glm::uvec2& size, uint32_t frame_count) +bool VulkanEncoder::create(lava::instance& instance, lava::device_ptr device, const lava::renderer& renderer, const glm::uvec2& size, uint32_t frame_count) { //Get the default graphics queue of lava for querey ownership transiations this->default_queue = renderer.get_queue(); diff --git a/src/encoder/vulkan_encoder.hpp b/src/encoder/vulkan_encoder.hpp index 78a18994..8311ee3c 100644 --- a/src/encoder/vulkan_encoder.hpp +++ b/src/encoder/vulkan_encoder.hpp @@ -77,7 +77,7 @@ public: public: VulkanEncoder() = default; - bool create(lava::device_ptr device, const lava::renderer& renderer, const glm::uvec2& size, uint32_t input_buffers); + bool create(lava::instance& instance, lava::device_ptr device, const lava::renderer& renderer, const glm::uvec2& size, uint32_t input_buffers); void destroy(); bool encode(VkCommandBuffer command_buffer, lava::renderer& renderer, lava::image::ptr image, VkImageLayout image_layout, OnEncodeComplete function); diff --git a/src/headset/emulated_headset.cpp b/src/headset/emulated_headset.cpp index 61fd3c7e..ff651832 100644 --- a/src/headset/emulated_headset.cpp +++ b/src/headset/emulated_headset.cpp @@ -11,7 +11,7 @@ bool EmulatedHeadset::on_create() { //DEBUG!! Encoder::Ptr encoder = make_encoder(ENCODER_TYPE_NVIDIA); - encoder->create(this->get_application()->get_device(), this->get_application()->get_renderer(), glm::uvec2(1920, 1080), 4); + encoder->create(this->get_application()->get_instance(), this->get_application()->get_device(), this->get_application()->get_renderer(), glm::uvec2(1920, 1080), 4); lava::camera& camera = this->get_application()->get_camera(); diff --git a/src/headset/remote_headset.cpp b/src/headset/remote_headset.cpp index 22bda66a..69d56eec 100644 --- a/src/headset/remote_headset.cpp +++ b/src/headset/remote_headset.cpp @@ -456,7 +456,7 @@ bool RemoteHeadset::create_encoders() lava::renderer& renderer = this->get_application()->get_renderer(); uint32_t frame_count = this->get_application()->get_frame_count(); - if (!encoder->create(device, renderer, this->resolution, frame_count)) + if (!encoder->create(this->get_application()->get_instance(), device, renderer, this->resolution, frame_count)) { return false; } diff --git a/src/vr_application.cpp b/src/vr_application.cpp index e4f7dec5..6d69a72d 100644 --- a/src/vr_application.cpp +++ b/src/vr_application.cpp @@ -3,6 +3,9 @@ #include <iostream> #include <imgui.h> +//DEBUG!!!!!!!!!!!!!!!! +#include "encoder/encoder.hpp" + bool VRApplication::setup(lava::name name, argh::parser cmd_line) { if (!this->command_parser.parse_command(cmd_line)) @@ -24,6 +27,9 @@ bool VRApplication::setup(lava::name name, argh::parser cmd_line) config.log.debug = true; config.debug.validation = false; + //DEBUG!!!!!!!!!!!!!!!! + setup_instance_for_encoder(ENCODER_TYPE_NVIDIA, config); + if (!this->headset->on_setup_instance(config)) { std::cout << "Error during headset setup instance!" << std::endl; @@ -46,6 +52,9 @@ bool VRApplication::setup(lava::name name, argh::parser cmd_line) this->app->manager.on_create_param = [this](lava::device::create_param& parameters) { + //DEBUG!!!!!!!!!!!!!!!! + setup_device_for_encoder(ENCODER_TYPE_NVIDIA, parameters); + if (!this->headset->on_setup_device(parameters)) { lava::log()->error("Error during headset setup device!"); -- GitLab