vkQueueSubmit blocks when using timeline semaphores - c++

I need to run a function on CPU between two GPU batches. For this I use timeline semaphores. As far as I know, vkQueueSubmit does not block. However, it blocks when I submit these GPU batches:
uint64_t host_wait = timeline;
uint64_t host_signal = ++timeline;
uint64_t wait0 = timeline;
uint64_t signal0 = ++timeline;
uint64_t wait1 = timeline;
uint64_t signal1 = ++timeline;
VkPipelineStageFlags wait_mask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
VkTimelineSemaphoreSubmitInfo sp_submit0 = {
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
.waitSemaphoreValueCount = 1,
.pWaitSemaphoreValues = &wait0,
.signalSemaphoreValueCount = 1,
.pSignalSemaphoreValues = &signal0,
};
VkSubmitInfo submit0 = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = &sp_submit0,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &timeline_semaphore,
.pWaitDstStageMask = &wait_mask,
.signalSemaphoreCount = 1,
.pSignalSemaphores = &timeline_semaphore,
};
VkTimelineSemaphoreSubmitInfo sp_submit1 = {
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
.waitSemaphoreValueCount = 1,
.pWaitSemaphoreValues = &wait1,
.signalSemaphoreValueCount = 1,
.pSignalSemaphoreValues = &signal1,
};
VkSubmitInfo submit1 = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = &sp_submit1,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &timeline_semaphore,
.pWaitDstStageMask = &wait_mask,
.commandBufferCount = 1,
.pCommandBuffers = &command_buffer,
.signalSemaphoreCount = 1,
.pSignalSemaphores = &timeline_semaphore,
};
VkSubmitInfo infos[2] = { submit0, submit1 };
vkQueueSubmit(queue, 2, infos, fence);
// here vkQueueSubmit blocks the thread
WaitSemaphore(timeline_semaphore, host_wait);
some_function();
SignalSemaphore(timeline_semaphore, host_signal);
It is blocking for seconds without return, I think this is something like a deadlock. In the debugger, I saw SleepEx function call from vkQueueSubmit: vk_icdGetInstanceProcAddrSG -> ... -> SleepEx.
But vkQueueSubmit does not block in this sample (combined batch):
uint64_t host_wait = timeline;
uint64_t host_signal = ++timeline;
uint64_t wait1 = timeline;
uint64_t signal1 = ++timeline;
VkPipelineStageFlags wait_mask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
VkTimelineSemaphoreSubmitInfo sp_submit1 = {
.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
.waitSemaphoreValueCount = 1,
.pWaitSemaphoreValues = &wait1,
.signalSemaphoreValueCount = 1,
.pSignalSemaphoreValues = &signal1,
};
VkSubmitInfo submit1 = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = &sp_submit1,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &timeline_semaphore,
.pWaitDstStageMask = &wait_mask,
.commandBufferCount = 1,
.pCommandBuffers = &command_buffer,
.signalSemaphoreCount = 1,
.pSignalSemaphores = &timeline_semaphore,
};
VkSubmitInfo infos[1] = { submit1 };
vkQueueSubmit(queue, 1, infos, fence);
WaitSemaphore(timeline_semaphore, host_wait);
some_function();
SignalSemaphore(timeline_semaphore, host_signal);
Why vkQueueSubmit blocks in the first code sample? What are the possible causes of this problem?
I use Vulkan 1.2 (SDK 1.2.135) on Windows 10 and Radeon RX 570 (driver 20.4.2).
EDIT: When I add a command buffer to submit0, vkQueueSubmit will not block. Is it a bug in the driver?

Doing something odd like submitting a batch with no work is far more likely to be the cause.
The spec doesn’t have performance requirements. The fact that something is legal does not make it a good idea. Broadly speaking, if there are two ways to do a thing, do it the obvious way. And sending an empty batch isn’t exactly obvious
https://community.khronos.org/t/vkqueuesubmit-blocks-when-using-timeline-semaphores/105704/2

Related

Vulkan queue waiting on semaphore that can't be signaled

It seems I have had invalid code for a while but the validation layers were silent. After updating my sdk to the latest version I started getting this error:
Message ID name: VUID-vkQueuePresentKHR-pWaitSemaphores-03268
Message: [ VUID-vkQueuePresentKHR-pWaitSemaphores-03268 ] Object: 0x55b4b87478f0 (Name = Selected logical device : Type = 3) | VkQueue 0x55b4b8224020[Main queue] is waiting on VkSemaphore 0x110000000011[Render Finished Semaphore: 0] that has no way to be signaled. The Vulkan spec states: All elements of the pWaitSemaphores member of pPresentInfo must reference a semaphore signal operation that has been submitted for execution and any semaphore signal operations on which it depends (if any) must have also been submitted for execution. (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkQueuePresentKHR-pWaitSemaphores-03268)
Severity: VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT
This happens inside of my main draw loop and it's the only validation layer error in my code. If I never call the code that is responsible for surface presentation. I get no errors.
I am sure the place where I am doing things wrong is here:
void DisplayTarget::StartPass(uint target_num, bool should_clear,
VulkanImage* external_depth)
{
auto device = h_interface->GetDevice();
auto result = device.acquireNextImageKHR(
*swap_chain,
std::numeric_limits<uint64_t>::max(),
*img_available_sems[current_frame],
nullptr,
&active_image_index);
if(result != vk::Result::eSuccess)
Log::RecordLog("Failed to acquire image");
}
vk::Result DisplayTarget::EndPass()
{
auto device = h_interface->GetDevice();
auto cmd_buff = h_interface->GetCmdBuffer();
auto graphics_queue = h_interface->GetQueue();
device.waitForFences(
1,
&*in_flight_fences[current_frame],
VK_TRUE,
std::numeric_limits<uint64_t>::max());
vk::Semaphore wait_semaphores[] = {*img_available_sems[current_frame]};
vk::PipelineStageFlags wait_stages[] = {
vk::PipelineStageFlagBits::eColorAttachmentOutput};
vk::Semaphore signal_semaphores[] = {*render_finished_sems[current_frame]};
vk::SubmitInfo submit_info(
1, wait_semaphores, wait_stages, 1, &cmd_buff, 1, signal_semaphores);
device.resetFences(1, &*in_flight_fences[current_frame]);
auto result =
graphics_queue.submit(1, &submit_info, *in_flight_fences[current_frame]);
if(result != vk::Result::eSuccess)
Log::RecordLog("Failed to submit draw command buffer!");
graphics_queue.waitIdle();
device.waitIdle();
vk::SwapchainKHR swap_chains[] = {*swap_chain};
vk::PresentInfoKHR present_info = {};
present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = signal_semaphores;
present_info.swapchainCount = 1;
present_info.pSwapchains = swap_chains;
present_info.pImageIndices = &active_image_index;
result = graphics_queue.presentKHR(&present_info);
current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT;
return result;
}
Currently they are called consecutively:
display.StartPass();
display.EndPass();
To get things working I have tried both commenting parts of these 2 functions out or changing the order in which things are called, but either the error persists or I get different validation errors.
I also tried signaling the semaphore directly:
vk::SemaphoreSignalInfo semaphore_info = {};
semaphore_info.semaphore = *render_finished_sems[current_frame];
semaphore_info.value = 0;
device.signalSemaphore(semaphore_info);
But all I managed is to cause a segmentation fault
The error was the order of operations. This is wrong:
graphics_queue.waitIdle();
device.waitIdle();
vk::SwapchainKHR swap_chains[] = {*swap_chain};
vk::PresentInfoKHR present_info = {};
present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = signal_semaphores;
present_info.swapchainCount = 1;
present_info.pSwapchains = swap_chains;
present_info.pImageIndices = &active_image_index;
result = graphics_queue.presentKHR(&present_info);
current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT;
This is the correct use:
vk::SwapchainKHR swap_chains[] = {*swap_chain};
vk::PresentInfoKHR present_info = {};
present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = signal_semaphores;
present_info.swapchainCount = 1;
present_info.pSwapchains = swap_chains;
present_info.pImageIndices = &active_image_index;
result = graphics_queue.presentKHR(&present_info);
current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT;
graphics_queue.waitIdle();
device.waitIdle();

Vulkan timeline semaphore extension cannot be enabled

I've been at this for a better part of today and I'm at the end of my wits.
I'm running Vulkan SDK 1.2.131.2
I have a RTX 2080 Ti.
I have Windows 10 Education, version 1909, build 18363.657.
I'm using Vulkan.hpp instead of Vulkan.h directly.
Here is where I specify the API version I use:
appInfo.apiVersion = VK_API_VERSION_1_2;
This is the relevant part of the code that creates the device:
// bla bla
const std::vector<const char*> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME,
VK_NV_RAY_TRACING_EXTENSION_NAME
};
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
m_logicalDevice = m_physicalDevice.createDeviceUnique(deviceCreateInfo);
I use the following validation layers:
"VK_LAYER_LUNARG_api_dump"
"VK_LAYER_KHRONOS_validation"
This is how I later try to create a timeline semaphore:
vk::UniqueSemaphore VulkanContext::createTimelineSemaphore(const uint32_t initialValue) const {
vk::SemaphoreTypeCreateInfo timelineCreateInfo;
timelineCreateInfo.semaphoreType = vk::SemaphoreType::eTimeline;
timelineCreateInfo.initialValue = initialValue;
vk::SemaphoreCreateInfo createInfo;
createInfo.pNext = &timelineCreateInfo;
return m_logicalDevice->createSemaphoreUnique(createInfo);
}
I get the following error:
vkCreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore) returns VkResultVkCreateSemaphore: timelineSemaphore feature is not enabled, can not create timeline semaphores The Vulkan spec states: If the timelineSemaphore feature is not enabled, semaphoreType must not equal VK_SEMAPHORE_TYPE_TIMELINE (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSemaphoreTypeCreateInfo-timelineSemaphore-03252)
This is even more infuriating because timeline semaphores are supposed to be part of the core Vulkan 1.2, but I get the same error even if I ommit it from the extension list. Swapchain extension does work and I haven't had the time to verify that ray tracing extension is enabled.
It gets even more stupid because the next message tells me this:
VK_SUCCESS (0):
device: VkDevice = 0000023AA29BD8B0
pCreateInfo: const VkSemaphoreCreateInfo* = 0000008D145ED538:
sType: VkStructureType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO (9)
pNext: VkSemaphoreTypeCreateInfo = 0000008D145ED4F8:
sType: VkStructureType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO (1000207002)
pNext: const void* = NULL
semaphoreType: VkSemaphoreType = VK_SEMAPHORE_TYPE_TIMELINE (1)
initialValue: uint64_t = 0
flags: VkSemaphoreCreateFlags = 0
pAllocator: const VkAllocationCallbacks* = NULL
pSemaphore: VkSemaphore* = AA989B000000001E
I have no idea if this creates the timeline semaphore or just creates a normal binary one.
When I later use it to submit to a transfer queue:
vk::CommandBufferBeginInfo beginInfo;
transferCmdBuffer->begin(beginInfo);
object->recordUploadToGPU(*transferCmdBuffer);
transferCmdBuffer->end();
vk::TimelineSemaphoreSubmitInfo timelineSubmitInfo;
timelineSubmitInfo.signalSemaphoreValueCount = 1;
timelineSubmitInfo.pSignalSemaphoreValues = &signalValue;
vk::SubmitInfo submitInfo;
submitInfo.pNext = &timelineSubmitInfo;
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &signalSemaphore;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &*transferCmdBuffer;
vkCtx.m_transferQueue.submit(submitInfo, nullptr);
I get this error here:
vkQueueSubmit(queue, submitCount, pSubmits, fence) returns VkResultVkQueueSubmit: VkQueue 0x23aa2539500[] contains timeline sempahore VkSemaphore 0xaa989b000000001e[] that sets its wait value with a margin greater than maxTimelineSemaphoreValueDifference The Vulkan spec states: For each element of pSignalSemaphores created with a VkSemaphoreType of VK_SEMAPHORE_TYPE_TIMELINE the corresponding element of VkTimelineSemaphoreSubmitInfo::pSignalSemaphoreValues must have a value which does not differ from the current value of the semaphore or the value of any outstanding semaphore wait or signal operation on that semaphore by more than maxTimelineSemaphoreValueDifference. (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSubmitInfo-pSignalSemaphores-03244)
And just to be futher mocked, this is the next line:
VK_SUCCESS (0):
queue: VkQueue = 0000023AA2539500
submitCount: uint32_t = 1
pSubmits: const VkSubmitInfo* = 0000008D145ED370
pSubmits[0]: const VkSubmitInfo = 0000008D145ED370:
sType: VkStructureType = VK_STRUCTURE_TYPE_SUBMIT_INFO (4)
pNext: VkTimelineSemaphoreSubmitInfo = 0000008D145ED318:
sType: VkStructureType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO (1000207003)
pNext: const void* = NULL
waitSemaphoreValueCount: uint32_t = 0
pWaitSemaphoreValues: const uint64_t* = NULL
signalSemaphoreValueCount: uint32_t = 1
pSignalSemaphoreValues: const uint64_t* = 0000008D145ED740
pSignalSemaphoreValues[0]: const uint64_t = 1
waitSemaphoreCount: uint32_t = 0
pWaitSemaphores: const VkSemaphore* = NULL
pWaitDstStageMask: const VkPipelineStageFlags* = NULL
commandBufferCount: uint32_t = 1
pCommandBuffers: const VkCommandBuffer* = 0000008D145EF408
pCommandBuffers[0]: const VkCommandBuffer = 0000023AA9CEC8E0
signalSemaphoreCount: uint32_t = 1
pSignalSemaphores: const VkSemaphore* = 0000008D145EF430
pSignalSemaphores[0]: const VkSemaphore = AA989B000000001E
fence: VkFence = 0000000000000000
I've also tried with VK_API_VERSION_1_1 and VK_API_VERSION_1_0, both with and without enabling the extension explicitly, none of them work.
The dumps are from the VK_LAYER_LUNARG_api_dump validation layer, while VK_LAYER_KHRONOS_validation validation layer is the one spewing out the errors. They seem to disagree.
So, what gives?
In what way am I stupid today?
EDIT:
Here is an example that you should be able to run yourself. I think I made it as minimal as I can:
#include <vulkan/vulkan.hpp>
#include <iostream>
VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData) {
std::cerr << pCallbackData->pMessage << std::endl;
return VK_FALSE;
};
int main() {
vk::ApplicationInfo appInfo;
appInfo.apiVersion = VK_API_VERSION_1_2;
vk::InstanceCreateInfo instanceCreateInfo;
instanceCreateInfo.pApplicationInfo = &appInfo;
std::vector<const char*> extensions;
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
instanceCreateInfo.ppEnabledExtensionNames = extensions.data();
const std::vector<const char*> validationLayers = {
"VK_LAYER_LUNARG_api_dump",
"VK_LAYER_KHRONOS_validation"
};
instanceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
instanceCreateInfo.ppEnabledLayerNames = validationLayers.data();
vk::DebugUtilsMessengerCreateInfoEXT debugCreateInfo;
debugCreateInfo.messageSeverity =
vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError;
debugCreateInfo.messageType =
vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance;
debugCreateInfo.pfnUserCallback = debugCallback;
instanceCreateInfo.pNext = &debugCreateInfo;
vk::Instance m_instance = vk::createInstance(instanceCreateInfo);
vk::DispatchLoaderDynamic m_loader = vk::DispatchLoaderDynamic(m_instance, vkGetInstanceProcAddr);
vk::DebugUtilsMessengerEXT m_debugMessenger = m_instance.createDebugUtilsMessengerEXT(debugCreateInfo, nullptr, m_loader);
vk::PhysicalDevice m_physicalDevice = m_instance.enumeratePhysicalDevices()[0];
std::vector<vk::DeviceQueueCreateInfo> queueCreateInfos;
vk::DeviceQueueCreateInfo queueInfo;
queueInfo.queueFamilyIndex = 0;
queueInfo.queueCount = 1;
queueCreateInfos.push_back(queueInfo);
vk::PhysicalDeviceFeatures deviceFeatures;
vk::DeviceCreateInfo deviceCreateInfo;
deviceCreateInfo.pQueueCreateInfos = queueCreateInfos.data();
deviceCreateInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
deviceCreateInfo.pEnabledFeatures = &deviceFeatures;
// This part can be omitted from here...
const std::vector<const char*> deviceExtensions = {
VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME
};
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
// ...to here. It doesn't work either way.
vk::Device m_logicalDevice = m_physicalDevice.createDevice(deviceCreateInfo);
vk::SemaphoreTypeCreateInfo timelineCreateInfo;
timelineCreateInfo.semaphoreType = vk::SemaphoreType::eTimeline;
timelineCreateInfo.initialValue = 0;
vk::SemaphoreCreateInfo semaphoreCreateInfo;
semaphoreCreateInfo.pNext = &timelineCreateInfo;
m_logicalDevice.createSemaphore(semaphoreCreateInfo);
}
The feature needs to be enabled explicitly as well:
vk::PhysicalDeviceVulkan12Features features;
features.timelineSemaphore = true;
vk::DeviceCreateInfo deviceCreateInfo;
deviceCreateInfo.pNext = &features;

MFXVideoDECODE_Init fail with MFX_ERR_MEMORY_ALLOC

I'm trying to use intel-media-sdk decoder for h.264 videos. Here is my code for initializing decoder :
mfxStatus decoder::initDecoder(HWND window, mfxBitstream *Header) {
mfxStatus sts = MFX_ERR_NONE;
mfxVersion ver = { { 0, 1 } };
mfxVideoParam mfxVideoParams;
mfxFrameAllocator mfxAllocator;
mfxFrameAllocResponse mfxResponse;
sts = m_mfxSession.Init(MFX_IMPL_AUTO_ANY, &ver); //sts = MFX_ERR_NONE
if (sts == MFX_ERR_NONE) {
sts = m_mfxSession.SetHandle(MFX_HANDLE_DIRECT3D_DEVICE_MANAGER9,
m_renderer.initD3d(GetIntelDeviceAdapterNum(), window)); //sts = MFX_ERR_NONE
if (sts == MFX_ERR_NONE) {
mfxAllocator.pthis = m_mfxSession;
sts = m_mfxSession.SetFrameAllocator(&mfxAllocator); //sts = MFX_ERR_NONE
if (sts == MFX_ERR_NONE) {
MFXVideoDECODE mfxDEC(m_mfxSession);
m_mfxVideoDecode = mfxDEC;
memset(&mfxVideoParams, 0, sizeof(mfxVideoParams));
mfxVideoParams.mfx.CodecId = MFX_CODEC_AVC;
mfxVideoParams.IOPattern = MFX_IOPATTERN_OUT_VIDEO_MEMORY;
sts = m_mfxVideoDecode.DecodeHeader(Header, &mfxVideoParams); //sts = MFX_ERR_NONE
if (sts == MFX_ERR_NONE) {
memset(&m_mfxRequest, 0, sizeof(m_mfxRequest));
sts = m_mfxVideoDecode.QueryIOSurf(&mfxVideoParams, &m_mfxRequest); //sts = MFX_ERR_NONE
if (sts == MFX_ERR_NONE) {
sts = m_renderer.allocSurfaces(mfxAllocator.pthis, &m_mfxRequest, &mfxResponse);
if (sts == MFX_ERR_NONE) {
m_pmfxSurfaces = new mfxFrameSurface1 *[m_mfxRequest.NumFrameSuggested];
for (int i = 0; i < m_mfxRequest.NumFrameSuggested; i++) {
m_pmfxSurfaces[i] = new mfxFrameSurface1;
memset(m_pmfxSurfaces[i], 0, sizeof(mfxFrameSurface1));
memcpy(&(m_pmfxSurfaces[i]->Info), &(mfxVideoParams.mfx.FrameInfo), sizeof(mfxFrameInfo));
// MID (memory id) represents one video NV12 surface
m_pmfxSurfaces[i]->Data.MemId = mfxResponse.mids[i];
};
sts = m_mfxVideoDecode.Init(&mfxVideoParams); //sts = MFX_ERR_MEMORY_ALLOC
}
}
}
}
}
}
return sts;
}
So as you can see MFXVideoDECODE::Init(mfxVideoParam*) (which internally calls MFXVideoDECODE_Init) returns MFX_ERR_MEMORY_ALLOC and the strange thing here is in this document it says this function does not have this return value.
Here is some debug information about mfxVideoParams :
AllocId = 0, AsyncDepth = 0, IOPattern = 16, mfx.CodecId = 541283905,
mfx.CodecProfile = 77, mfx.CodecLevel = 30, vpp.In.FourCC = 842094158,
vpp.In.Width = 864, vpp.In.Height = 480, vpp.In.CropW = 854,
vpp.In.CropH = 480, vpp.In.BufferSize = 31458144, vpp.In.AspectRatioW
= 1, vpp.In.AspectRatioH = 1, vpp.In.PicStruct = 1, vpp.In.ChromaFormat = 1
Here is Some member data definition in header which used here :
MFXVideoSession m_mfxSession;
MFXVideoDECODE m_mfxVideoDecode;
mfxFrameAllocRequest m_mfxRequest;
mfxFrameSurface1** m_pmfxSurfaces;
And Here is some information about my current working device that might relate to this problem:
Operating System : Windows 8.1
Processor : Intel(R) Core(TM) i5-3470 CPU # 3.20GHZ
System type : 64-bit operating system, x64-based processor
Installed memory (RAM) : 8.00 GB
And finally to reproduce the exact same situation I downloaded video named big_buck_bunny_1080p_h264.mov from this site and then extracted it with ffmpeg to h264 and used it in my program.
You need to initialize mfxFrameAlocator callback functions (Alloc, Free, GetHDL, ...) with proper functions.
for example :
//static member
mfxStatus decoder::gethdl(mfxHDL pthis, mfxMemId mid, mfxHDL* handle)
{
pthis; // To avoid warning for this unused parameter
if (handle == 0) return MFX_ERR_INVALID_HANDLE;
*handle = mid;
return MFX_ERR_NONE;
}
mfxStatus decoder::initDecoder(HWND window, mfxBitstream *Header) {
//blah blah
mfxAllocator.pthis = m_mfxSession;
mfxAllocator.GetHDL = gethdl;
//define for these too
//mfxAllocator.Alloc = alloc;
//mfxAllocator.Free = free;
//mfxAllocator.Lock = lock;
//mfxAllocator.Unlock = unlock;
//rest of your code
}

Access violation from vkCreateGraphicsPipelines

I'm running into an access violation on this piece of Vulkan API.
VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.billboard);
The error is:
Exception thrown at 0x00007FFB8BEDB276 (amdvlk64.dll) in 3Dfunctionvisualizer.exe: 0xC0000005: Access violation reading location 0x000000000000004C.
All other relevant code, as far as I can tell:
VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {};
pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
VkResult err = vkCreatePipelineCache(device, &pipelineCacheCreateInfo, nullptr, &pipelineCache);
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
vkTools::initializers::pipelineInputAssemblyStateCreateInfo(
VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
0,
VK_FALSE);
VkPipelineRasterizationStateCreateInfo rasterizationState =
vkTools::initializers::pipelineRasterizationStateCreateInfo(
VK_POLYGON_MODE_FILL,
VK_CULL_MODE_BACK_BIT,
VK_FRONT_FACE_CLOCKWISE,
0);
VkPipelineColorBlendAttachmentState blendAttachmentState =
vkTools::initializers::pipelineColorBlendAttachmentState(
0xf,
VK_FALSE);
VkPipelineColorBlendStateCreateInfo colorBlendState =
vkTools::initializers::pipelineColorBlendStateCreateInfo(
1,
&blendAttachmentState);
VkPipelineDepthStencilStateCreateInfo depthStencilState =
vkTools::initializers::pipelineDepthStencilStateCreateInfo(
VK_TRUE,
VK_TRUE,
VK_COMPARE_OP_LESS_OR_EQUAL);
VkPipelineViewportStateCreateInfo viewportState =
vkTools::initializers::pipelineViewportStateCreateInfo(1, 1, 0);
VkPipelineMultisampleStateCreateInfo multisampleState =
vkTools::initializers::pipelineMultisampleStateCreateInfo(
VK_SAMPLE_COUNT_1_BIT,
0);
std::vector<VkDynamicState> dynamicStateEnables = {
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR,
VK_DYNAMIC_STATE_LINE_WIDTH
};
VkPipelineDynamicStateCreateInfo dynamicState =
vkTools::initializers::pipelineDynamicStateCreateInfo(
dynamicStateEnables.data(),
dynamicStateEnables.size(),
0);
std::array<VkPipelineShaderStageCreateInfo, 3> shaderStages;
shaderStages[0] = loadShader("./../data/shaders/3DVisualizer/billboard.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
shaderStages[1] = loadShader("./../data/shaders/3DVisualizer/billboard.geom.spv", VK_SHADER_STAGE_GEOMETRY_BIT);
shaderStages[2] = loadShader("./../data/shaders/3DVisualizer/billboard.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
VkGraphicsPipelineCreateInfo pipelineCreateInfo =
vkTools::initializers::pipelineCreateInfo(
pipelineLayout,
renderPass,
0);
pipelineCreateInfo.pVertexInputState = &vertices.billboard.inputState;
pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
pipelineCreateInfo.pRasterizationState = &rasterizationState;
pipelineCreateInfo.pColorBlendState = &colorBlendState;
pipelineCreateInfo.pMultisampleState = &multisampleState;
pipelineCreateInfo.pViewportState = &viewportState;
pipelineCreateInfo.pDepthStencilState = &depthStencilState;
pipelineCreateInfo.pDynamicState = &dynamicState;
pipelineCreateInfo.stageCount = 3;
pipelineCreateInfo.pStages = shaderStages.data();
pipelineCreateInfo.renderPass = renderPass;
The device and pipelineCache are both set by the superclass, which was written by Sascha Willems and works for all of the examples he has created, so I don't expect the problem would be there. However, that really only leaves pipelineCreateInfo or pipelines.billboard as the potential source of the error.
Both of those are dealt with in the (almost exact) same way as the examples by Sascha in his examples, so I'm at a loss here.
EDIT: I found the problem. I had failed to specify the binding point for the sampler in my shader.

the content of pointer changed when passed to the function

I am using C++ to do my work. The following is the problem I am confulsed.
typedef struct netHandler {
int m_iFd;
poll_event_t* m_pPollEvent;
epoll_event m_Event;
void* m_pConn;
} netHandler_t;
Here is my struct. When the program running. I set a breakpoint in the following place:
connection_t* conn = geneConnection(idenfication, fd, handler);
And before step into this funcition, I record the handler's content.
p *(netHandler_t *) 0x2aaaac000960
$2 = {m_iFd = 9, m_pPollEvent = 0x2aaaac000930, m_Event =
{events = 1, data = {ptr = 0x2aaaac000960, fd = -1409283744, u32 = 2885683552, u64 = 46912518490464}},
m_pConn = 0x60d010}
Then I step into the geneConnection function. The content changed.
p *(netHandler_t *) 0x2aaaac000960
$3 = {m_iFd = 9, m_pPollEvent = 0xac00093000000000, m_Event =
{events = 10922, data = {ptr = 0xac00096000000001, fd = 1, u32 = 1, u64 = 12393916482445115393}},
m_pConn = 0x2aaa}
That's like the struct was shrifted.
connection_t* geneConnection(long iden, int sendfd, netHandler_t* handler);
This is the declare of geneConnection. I don't understand why this happened. When I change this function to inline type. The content of handler would not changed.