drfrag666 / gzdoom

GZDoom adds an OpenGL renderer to the ZDoom source port.
http://gzdoom.drdteam.org
GNU General Public License v3.0
73 stars 15 forks source link

Is Vulkan renderer supposed to be working with LZDoom? #20

Closed vanfanel closed 3 years ago

vanfanel commented 3 years ago

Hi there!

I have just build LZDoom from current GIT on my Pi4, which has a working Vulkan MESA implementation (many other games work with it). Looking at CMakeLists.txt, it seems that VULKAN support is enabled by default.

However, if I lauch LZDoom, and change the video renderer to "vulkan", and launch it again, I get:

At least OpenGL 3.3 is required...

So, is VULKAN supposed to be working? Also, I believe VULKAN's vid_rendermode value in lzdoom.ini is 4, right?

drfrag666 commented 3 years ago

You mean the master branch? Yes, but it's vid_preferbackend 1.

vanfanel commented 3 years ago

@drfrag666 I mean the master branch in this LZDoom fork, yes. I have tried manually setting vid_preferbackend to 1 in lzdoom.ini, but it still tries to use the OpenGL 3.3 renderer. As I said, I have activated the Vulkan renderer on the menu, with the same results. So what am I missing, please?

drfrag666 commented 3 years ago

Try adding +vid_preferbackend 1 on the command line. And does it work with GZDoom? I think it's pretty much the same code tough.

drfrag666 commented 3 years ago

If Vulkan fails it will fall back to OpenGL, probably your card doesn't support Vulkan properly.

alexey-lysiuk commented 3 years ago

Put a breakpoint at the following line, and check if Priv::window is not null. If it is, you can call SDL_GetError() in debugger to get more info. https://github.com/drfrag666/gzdoom/blob/007b3b11643e0fd7169e8a2fef3ddb94e6238c7b/src/common/platform/posix/sdl/sdlglvideo.cpp#L435

If breakpoint isn't hit, check SDL2 library loading at the following line. https://github.com/drfrag666/gzdoom/blob/007b3b11643e0fd7169e8a2fef3ddb94e6238c7b/src/common/platform/posix/sdl/sdlglvideo.cpp#L422

vanfanel commented 3 years ago

@alexey-lysiuk

This is what happens when I pass the +vid_preferbackend 1 parameter:

Thread 1 "lzdoom" hit Breakpoint 1, SDLVideo::SDLVideo (this=0x555d9da910)
    at /home/pi/src/gzdoom/src/common/platform/posix/sdl/sdlglvideo.cpp:431
431             if (Priv::vulkanEnabled)
(gdb) n
433                     Priv::CreateWindow(Priv::VulkanWindowFlag | SDL_WINDOW_HIDDEN);
(gdb) n
435                     if (Priv::window == nullptr)
(gdb) n
441             if (Priv::softpolyEnabled)
(gdb)
449     }
(gdb) n
gl_CreateVideo () at /home/pi/src/gzdoom/src/common/platform/posix/sdl/sdlglvideo.cpp:505
505     }
(gdb) n
I_InitGraphics () at /home/pi/src/gzdoom/src/common/platform/posix/sdl/hardware.cpp:82
82              if (Video == NULL)
(gdb) 
84      }
(gdb) 
V_Init2 () at /home/pi/src/gzdoom/src/common/rendering/v_video.cpp:386
386             Video->SetResolution(); // this only fails via exceptions.
(gdb) 
Selecting SoftPoly backend...
Changing the video backend requires a restart for LZDoom.

Unsupported OpenGL version.
At least OpenGL 3.3 is required to run LZDoom.
Falling back to SoftPoly for next run.

[Thread 0x7ff62880d0 (LWP 12894) exited]
[Thread 0x7ff6a890d0 (LWP 12893) exited]
free(): invalid pointer

The Pi4 supports Vulkan and it's certified for it: https://www.raspberrypi.org/blog/vulkan-update-were-conformant/

Other Vulkan games, like vkQuake, vkQuake3, etc... work here, so it doesn't seem to be a problem with the platform itself.

alexey-lysiuk commented 3 years ago

Where is the exception thrown exactly? catch throw in GDB should help to figure this out.

vanfanel commented 3 years ago

@alexey-lysiuk after catch throw it seems that the exception is thrown here:


Thread 1 "lzdoom" hit Catchpoint 2 (exception thrown), 0x0000007ff7a3fb68 in __cxa_throw ()
   from /usr/lib/aarch64-linux-gnu/libstdc++.so.6
(gdb) bt
#0  0x0000007ff7a3fb68 in __cxa_throw () from /usr/lib/aarch64-linux-gnu/libstdc++.so.6
#1  0x0000005555b5e5f4 in VulkanError (text=0x55562a3d48 "No Vulkan device supports the minimum requirements of this application")
    at /home/pi/src/gzdoom/src/common/rendering/vulkan/system/vk_device.h:119
#2  0x0000005555b5af5c in VulkanDevice::SelectPhysicalDevice (this=0x555d260f00)
    at /home/pi/src/gzdoom/src/common/rendering/vulkan/system/vk_device.cpp:172
#3  0x0000005555b5a9a8 in VulkanDevice::VulkanDevice (this=0x555d260f00)
    at /home/pi/src/gzdoom/src/common/rendering/vulkan/system/vk_device.cpp:82
#4  0x00000055559cf664 in SDLVideo::CreateFrameBuffer (this=0x555df54b30)
    at /home/pi/src/gzdoom/src/common/platform/posix/sdl/sdlglvideo.cpp:469
#5  0x000000555606c4b4 in IVideo::SetResolution (this=0x555df54b30) at /home/pi/src/gzdoom/src/common/rendering/v_video.cpp:310
#6  0x000000555606c7ec in V_Init2 () at /home/pi/src/gzdoom/src/common/rendering/v_video.cpp:386
#7  0x0000005555c08dd8 in D_DoomMain_Internal () at /home/pi/src/gzdoom/src/d_main.cpp:3613
#8  0x0000005555c09304 in GameMain () at /home/pi/src/gzdoom/src/d_main.cpp:3720
#9  0x00000055559cd5ac in main (argc=3, argv=0x7ffffff628) at /home/pi/src/gzdoom/src/common/platform/posix/sdl/i_main.cpp:194

I am puzzled because (appart from the Pi4 working fine with the likes of vQuake, vQuaye3, rtc) I don't see any call to KMSDRM_Vulkan_CreateSurface(), which means you are not using SDL2 calls to create the Vulkan surface, are you? On the Pi, the optimum way to display graphics for low-latency gaming is using Vulkan with the VK_KHR_display extension, which is what I do in SDL2 here: https://github.com/libsdl-org/SDL/blob/b55b11af88f9d02f438a8593b1e2194dbf9f305b/src/video/kmsdrm/SDL_kmsdrmvulkan.c#L180

dpjudas commented 3 years ago

The "No Vulkan device supports the minimum requirements of this application" message means that while it did detect a vulkan device, the device did not support the feature set required. Those requirements are:

VkPhysicalDeviceFeatures.samplerAnisotropy must be true, VkPhysicalDeviceFeatures.fragmentStoresAndAtomics must be true, VkPhysicalDeviceFeatures.depthClamp must be true, and the VK_KHR_SWAPCHAIN_EXTENSION_NAME extension must be supported.

The question is, which of those does the Pi4 not support?

vanfanel commented 3 years ago

@dpjudas

I set a bp on VulkanDevice::CheckRequiredFeatures since that's where you seem to be testing for VK features, and I see this:

(gdb) p f.samplerAnisotropy 
$2 = 1
(gdb) p f.fragmentStoresAndAtomics
$3 = 1
(gdb) p f.depthClamp
$4 = 0

I don't even know what depthClamp is, to be honest. So, no Vulkan LZDoom for the Pi4? I mean.. no way around the apparent lack of that feature?

drfrag666 commented 3 years ago

The Vulkan code is the same as in GZDoom. I don't know if anyone is running Vulkan on the Pi4.

dpjudas commented 3 years ago

The depth clamp (it's the feature provided by glEnable(GL_DEPTH_CLAMP) in OpenGL) is used for portals. GZDoom should be able to run without it, although portals will then have visual glitches.

If you just want to test things, you could remove the check for depthClamp. There may be a need to check if the feature is available when depthClamp is enabled if you remove the check though. Knowing Vulkan it will probably be an undefined behavior to set depthClamp to true in the pipeline if it's not requested on device creation.

vanfanel commented 3 years ago

@dpjudas I tried to remove the check, and I get this:

Using video driver KMSDRM
Vulkan device: V3D 4.2
Vulkan device type: integrated gpu                                                                                                    
Vulkan version: 1.0.155 (api) 21.0.99 (driver)
Max. texture size: 4096
Max. uniform buffer range: 134217728
Min. uniform buffer offset alignment: 32
Resolution: 640 x 480
[New Thread 0x7ff05e70d0 (LWP 881)]

Thread 1 "lzdoom" received signal SIGSEGV, Segmentation fault.
0x0000007ff4da81e4 in v3dv_CreateImageView () from /usr/local/lib/aarch64-linux-gnu/libvulkan_broadcom.so
(gdb) bt
#0  0x0000007ff4da81e4 in v3dv_CreateImageView () from /usr/local/lib/aarch64-linux-gnu/libvulkan_broadcom.so
#1  0x0000005555b8a2b4 in ImageViewBuilder::create (this=0x7fffffda98, device=0x555d25f050)
    at /home/pi/src/gzdoom/src/common/rendering/vulkan/system/vk_builders.h:481
#2  0x0000005555baa1c4 in VkRenderBuffers::CreateSceneNormal (this=0x555c410740, width=640, height=480, 
    samples=VK_SAMPLE_COUNT_1_BIT) at /home/pi/src/gzdoom/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp:222
#3  0x0000005555ba9b70 in VkRenderBuffers::CreateScene (this=0x555c410740, width=640, height=480, samples=VK_SAMPLE_COUNT_1_BIT)
    at /home/pi/src/gzdoom/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp:129
#4  0x0000005555ba97e0 in VkRenderBuffers::BeginFrame (this=0x555c410740, width=640, height=480, sceneWidth=640, sceneHeight=480)
    at /home/pi/src/gzdoom/src/common/rendering/vulkan/renderer/vk_renderbuffers.cpp:78
#5  0x0000005555b752c8 in VulkanFrameBuffer::BeginFrame (this=0x5557d918b0)
    at /home/pi/src/gzdoom/src/common/rendering/vulkan/system/vk_framebuffer.cpp:564
#6  0x0000005555c00588 in D_Display () at /home/pi/src/gzdoom/src/d_main.cpp:1065
#7  0x0000005555c01504 in D_DoomLoop () at /home/pi/src/gzdoom/src/d_main.cpp:1343
#8  0x0000005555c080a4 in D_DoomMain_Internal () at /home/pi/src/gzdoom/src/d_main.cpp:3690
#9  0x0000005555c082f4 in GameMain () at /home/pi/src/gzdoom/src/d_main.cpp:3720
#10 0x00000055559cd5ac in main (argc=3, argv=0x7ffffff628) at /home/pi/src/gzdoom/src/common/platform/posix/sdl/i_main.cpp:194

So I guess it's not enough and it's trying to use something that doesn't exist, right?

My guess is that, as I said, you are not using the X11-less VK extension, as SDL2 does.

alexey-lysiuk commented 3 years ago

So I guess it's not enough and it's trying to use something that doesn't exist, right?

It crashes inside Vulkan driver's implementation of vkCreateImageView() function. You can set vk_debug CVAR to 1, and if the implementation has validation layers, it may report something useful.

My guess is that, as I said, you are not using the X11-less VK extension, as SDL2 does.

GZDoom uses extensions reported by SDL_Vulkan_GetInstanceExtensions() function.

vanfanel commented 3 years ago

@alexey-lysiuk

I got this after doing export vk_debug=1:


*** Fatal Error ***
Address not mapped to object (signal 11)
Address: 0x1

Let me insist on SDL2 Vulkan code: you are using SDL_Vulkan_GetInstanceExtensions() to get the available extensions, but you should also use SDL_Vulkan_CreateSurface() to let SDL2 create the surface using the right functions (the surface creation is different if you don't use X11, etc).

This is how SDL2 manages Vulkan surface creation WITHOUT X11: https://github.com/libsdl-org/SDL/blob/07ba13b7a9eb6bd53dae6849ce6ca4977304dd65/src/video/kmsdrm/SDL_kmsdrmvulkan.c#L180 You are not doing anything like that on GZDoom, so it can't work outside X11.

vkQuake3 uses SDL_Vulkan_CreateSurface(), and it works fine on the Pi4 with X11 and without X11, etc. Please look at: https://github.com/suijingfeng/vkQuake3/blob/38062bbf16565425341d686d2f54d40e5305f93b/code/renderer_vulkan/vk_create_window_SDL.c#L353

It's better for you too, since it makes the code simpler as you don't have to create the Vulkan surface yourself.

alexey-lysiuk commented 3 years ago

That fatal error message doesn’t tell me anything without a backtrace.

Regarding surface creation, SDL_Vulkan_CreateSurface() is used indeed. Honestly, I don’t know why you keep asking such questions instead of debugging related code.

Vulkan renderer works for me when running GZDoom on Ubuntu 20.04 x64 with open source Intel and proprietary NVIDIA drivers. If something doesn’t work for you, you need to debug it in order to find the problem.

vanfanel commented 3 years ago

@alexey-lysiuk

I see no errors at all while debugging functions in that block. Please ask for whatever you want me to look in there: all Vulkan calls there seem to return success.

I have however been debugging ImageViewBuilder::create that is where the v3dv_CreateImageView()segfault is caused.

The segfault is caused by the vkCreateImageView() call, and only happens the 6th time that ImageViewBuilder::create is run.

This is the state of the parameters passed to vkCreateImageView(), just before the call that causes the segfault:

Thread 1 "lzdoom" hit Breakpoint 1, ImageViewBuilder::create (this=0x7fffffda88, device=0x555d218a00)
    at /home/pi/src/gzdoom/src/common/rendering/vulkan/system/vk_builders.h:481
481             VkResult result = vkCreateImageView(device->device, &viewInfo, nullptr, &view);
(gdb) p device
$1 = (VulkanDevice *) 0x555d218a00
(gdb) p *device
$2 = {AvailableLayers = std::vector of length 0, capacity 0, Extensions = std::vector of length 7, capacity 7 = {{
      extensionName = "VK_KHR_display", '\000' <repeats 241 times>, specVersion = 23}, {
      extensionName = "VK_KHR_external_memory_capabilities", '\000' <repeats 220 times>, specVersion = 1}, {
      extensionName = "VK_KHR_get_physical_device_properties2", '\000' <repeats 217 times>, specVersion = 1}, {
      extensionName = "VK_KHR_get_surface_capabilities2", '\000' <repeats 223 times>, specVersion = 1}, {
      extensionName = "VK_KHR_surface", '\000' <repeats 241 times>, specVersion = 25}, {
      extensionName = "VK_EXT_debug_report", '\000' <repeats 236 times>, specVersion = 9}, {
      extensionName = "VK_EXT_debug_utils", '\000' <repeats 237 times>, specVersion = 1}}, 
  EnabledExtensions = std::vector of length 2, capacity 2 = {0x7ff7f83a18 "VK_KHR_surface", 0x7ff7f83a28 "VK_KHR_display"}, 
  OptionalExtensions = std::vector of length 1, capacity 1 = {0x55562a3360 "VK_EXT_swapchain_colorspace"}, 
  EnabledValidationLayers = std::vector of length 0, capacity 0, UsedDeviceFeatures = {robustBufferAccess = 0, 
    fullDrawIndexUint32 = 0, imageCubeArray = 0, independentBlend = 0, geometryShader = 0, tessellationShader = 0, 
    sampleRateShading = 0, dualSrcBlend = 0, logicOp = 0, multiDrawIndirect = 0, drawIndirectFirstInstance = 0, depthClamp = 0, 
    depthBiasClamp = 0, fillModeNonSolid = 0, depthBounds = 0, wideLines = 0, largePoints = 0, alphaToOne = 0, multiViewport = 0, 
    samplerAnisotropy = 1, textureCompressionETC2 = 0, textureCompressionASTC_LDR = 0, textureCompressionBC = 0, 
    occlusionQueryPrecise = 0, pipelineStatisticsQuery = 0, vertexPipelineStoresAndAtomics = 0, fragmentStoresAndAtomics = 1, 
    shaderTessellationAndGeometryPointSize = 0, shaderImageGatherExtended = 0, shaderStorageImageExtendedFormats = 0, 
    shaderStorageImageMultisample = 0, shaderStorageImageReadWithoutFormat = 0, shaderStorageImageWriteWithoutFormat = 0, 
    shaderUniformBufferArrayDynamicIndexing = 0, shaderSampledImageArrayDynamicIndexing = 0, 
    shaderStorageBufferArrayDynamicIndexing = 0, shaderStorageImageArrayDynamicIndexing = 0, shaderClipDistance = 1, 
    shaderCullDistance = 0, shaderFloat64 = 0, shaderInt64 = 0, shaderInt16 = 0, shaderResourceResidency = 0, 
    shaderResourceMinLod = 0, sparseBinding = 0, sparseResidencyBuffer = 0, sparseResidencyImage2D = 0, sparseResidencyImage3D = 0, 
    sparseResidency2Samples = 0, sparseResidency4Samples = 0, sparseResidency8Samples = 0, sparseResidency16Samples = 0, 
    sparseResidencyAliased = 0, variableMultisampleRate = 0, inheritedQueries = 0}, 
  EnabledDeviceExtensions = std::vector of length 1, capacity 1 = {0x55562a3380 "VK_KHR_swapchain"}, 
  OptionalDeviceExtensions = std::vector of length 3, capacity 3 = {0x55562a3398 "VK_EXT_hdr_metadata", 
    0x55562a2d88 "VK_KHR_dedicated_allocation", 0x55562a2da8 "VK_KHR_get_memory_requirements2"}, PhysicalDevice = {
    Device = 0x555dbff540, Extensions = std::vector of length 6, capacity 6 = {{
        extensionName = "VK_KHR_external_memory", '\000' <repeats 233 times>, specVersion = 1}, {
--Type <RET> for more, q to quit, c to continue without paging--
        extensionName = "VK_KHR_external_memory_fd", '\000' <repeats 230 times>, specVersion = 1}, {
        extensionName = "VK_KHR_maintenance1", '\000' <repeats 236 times>, specVersion = 2}, {
        extensionName = "VK_KHR_swapchain", '\000' <repeats 239 times>, specVersion = 68}, {
        extensionName = "VK_EXT_external_memory_dma_buf", '\000' <repeats 225 times>, specVersion = 1}, {
        extensionName = "VK_EXT_private_data", '\000' <repeats 236 times>, specVersion = 1}}, 
    QueueFamilies = std::vector of length 1, capacity 1 = {{queueFlags = 7, queueCount = 1, timestampValidBits = 64, 
        minImageTransferGranularity = {width = 1, height = 1, depth = 1}}}, Properties = {apiVersion = 4194459, 
      driverVersion = 88080385, vendorID = 5348, deviceID = 42, deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, 
      deviceName = "V3D 4.2", '\000' <repeats 248 times>, pipelineCacheUUID = "@\252\070\n\005\350\233\247\252\212\256\n[\357z\207", 
      limits = {maxImageDimension1D = 4096, maxImageDimension2D = 4096, maxImageDimension3D = 4096, maxImageDimensionCube = 4096, 
        maxImageArrayLayers = 2048, maxTexelBufferElements = 268435456, maxUniformBufferRange = 134217728, 
        maxStorageBufferRange = 134217728, maxPushConstantsSize = 128, maxMemoryAllocationCount = 236836, 
        maxSamplerAllocationCount = 65536, bufferImageGranularity = 256, sparseAddressSpaceSize = 0, maxBoundDescriptorSets = 16, 
        maxPerStageDescriptorSamplers = 16, maxPerStageDescriptorUniformBuffers = 12, maxPerStageDescriptorStorageBuffers = 12, 
        maxPerStageDescriptorSampledImages = 16, maxPerStageDescriptorStorageImages = 4, maxPerStageDescriptorInputAttachments = 4, 
        maxPerStageResources = 128, maxDescriptorSetSamplers = 96, maxDescriptorSetUniformBuffers = 72, 
        maxDescriptorSetUniformBuffersDynamic = 8, maxDescriptorSetStorageBuffers = 72, maxDescriptorSetStorageBuffersDynamic = 36, 
        maxDescriptorSetSampledImages = 96, maxDescriptorSetStorageImages = 24, maxDescriptorSetInputAttachments = 4, 
        maxVertexInputAttributes = 16, maxVertexInputBindings = 16, maxVertexInputAttributeOffset = 4294967295, 
        maxVertexInputBindingStride = 4294967295, maxVertexOutputComponents = 64, maxTessellationGenerationLevel = 0, 
        maxTessellationPatchSize = 0, maxTessellationControlPerVertexInputComponents = 0, 
        maxTessellationControlPerVertexOutputComponents = 0, maxTessellationControlPerPatchOutputComponents = 0, 
        maxTessellationControlTotalOutputComponents = 0, maxTessellationEvaluationInputComponents = 0, 
        maxTessellationEvaluationOutputComponents = 0, maxGeometryShaderInvocations = 0, maxGeometryInputComponents = 0, 
        maxGeometryOutputComponents = 0, maxGeometryOutputVertices = 0, maxGeometryTotalOutputComponents = 0, 
        maxFragmentInputComponents = 64, maxFragmentOutputAttachments = 4, maxFragmentDualSrcAttachments = 0, 
        maxFragmentCombinedOutputResources = 20, maxComputeSharedMemorySize = 16384, maxComputeWorkGroupCount = {65535, 65535, 
          65535}, maxComputeWorkGroupInvocations = 256, maxComputeWorkGroupSize = {256, 256, 256}, subPixelPrecisionBits = 6, 
        subTexelPrecisionBits = 8, mipmapPrecisionBits = 8, maxDrawIndexedIndexValue = 16777215, maxDrawIndirectCount = 2147483647, 
--Type <RET> for more, q to quit, c to continue without paging--
        maxSamplerLodBias = 14, maxSamplerAnisotropy = 16, maxViewports = 1, maxViewportDimensions = {4096, 4096}, 
        viewportBoundsRange = {-8192, 8191}, viewportSubPixelBits = 0, minMemoryMapAlignment = 4096, 
        minTexelBufferOffsetAlignment = 256, minUniformBufferOffsetAlignment = 32, minStorageBufferOffsetAlignment = 32, 
        minTexelOffset = -8, maxTexelOffset = 7, minTexelGatherOffset = -8, maxTexelGatherOffset = 7, minInterpolationOffset = -0.5, 
        maxInterpolationOffset = 0.5, subPixelInterpolationOffsetBits = 6, maxFramebufferWidth = 4096, maxFramebufferHeight = 4096, 
        maxFramebufferLayers = 256, framebufferColorSampleCounts = 5, framebufferDepthSampleCounts = 5, 
        framebufferStencilSampleCounts = 5, framebufferNoAttachmentsSampleCounts = 5, maxColorAttachments = 4, 
        sampledImageColorSampleCounts = 5, sampledImageIntegerSampleCounts = 5, sampledImageDepthSampleCounts = 5, 
        sampledImageStencilSampleCounts = 5, storageImageSampleCounts = 1, maxSampleMaskWords = 1, timestampComputeAndGraphics = 1, 
        timestampPeriod = 1, maxClipDistances = 8, maxCullDistances = 0, maxCombinedClipAndCullDistances = 8, 
        discreteQueuePriorities = 2, pointSizeRange = {0, 512}, lineWidthRange = {1, 32}, pointSizeGranularity = 0, 
        lineWidthGranularity = 0, strictLines = 1, standardSampleLocations = 0, optimalBufferCopyOffsetAlignment = 32, 
        optimalBufferCopyRowPitchAlignment = 32, nonCoherentAtomSize = 256}, sparseProperties = {residencyStandard2DBlockShape = 0, 
        residencyStandard2DMultisampleBlockShape = 0, residencyStandard3DBlockShape = 0, residencyAlignedMipSize = 0, 
        residencyNonResidentStrict = 0}}, Features = {robustBufferAccess = 1, fullDrawIndexUint32 = 0, imageCubeArray = 1, 
      independentBlend = 1, geometryShader = 0, tessellationShader = 0, sampleRateShading = 1, dualSrcBlend = 0, logicOp = 1, 
      multiDrawIndirect = 0, drawIndirectFirstInstance = 1, depthClamp = 0, depthBiasClamp = 0, fillModeNonSolid = 1, 
      depthBounds = 0, wideLines = 1, largePoints = 1, alphaToOne = 1, multiViewport = 0, samplerAnisotropy = 1, 
      textureCompressionETC2 = 1, textureCompressionASTC_LDR = 0, textureCompressionBC = 0, occlusionQueryPrecise = 1, 
      pipelineStatisticsQuery = 0, vertexPipelineStoresAndAtomics = 1, fragmentStoresAndAtomics = 1, 
      shaderTessellationAndGeometryPointSize = 0, shaderImageGatherExtended = 0, shaderStorageImageExtendedFormats = 1, 
      shaderStorageImageMultisample = 0, shaderStorageImageReadWithoutFormat = 0, shaderStorageImageWriteWithoutFormat = 0, 
      shaderUniformBufferArrayDynamicIndexing = 0, shaderSampledImageArrayDynamicIndexing = 0, 
      shaderStorageBufferArrayDynamicIndexing = 0, shaderStorageImageArrayDynamicIndexing = 0, shaderClipDistance = 1, 
      shaderCullDistance = 0, shaderFloat64 = 0, shaderInt64 = 0, shaderInt16 = 0, shaderResourceResidency = 0, 
      shaderResourceMinLod = 0, sparseBinding = 0, sparseResidencyBuffer = 0, sparseResidencyImage2D = 0, 
      sparseResidencyImage3D = 0, sparseResidency2Samples = 0, sparseResidency4Samples = 0, sparseResidency8Samples = 0, 
      sparseResidency16Samples = 0, sparseResidencyAliased = 0, variableMultisampleRate = 0, inheritedQueries = 1}, 
    MemoryProperties = {memoryTypeCount = 1, memoryTypes = {{propertyFlags = 7, heapIndex = 0}, {propertyFlags = 0, heapIndex = 0}, {
--Type <RET> for more, q to quit, c to continue without paging--
          propertyFlags = 0, heapIndex = 0}, {propertyFlags = 0, heapIndex = 0}, {propertyFlags = 0, heapIndex = 0}, {
          propertyFlags = 0, heapIndex = 3072}, {propertyFlags = 0, heapIndex = 144}, {propertyFlags = 0, heapIndex = 1571501184}, {
          propertyFlags = 85, heapIndex = 0}, {propertyFlags = 0, heapIndex = 0} <repeats 14 times>, {propertyFlags = 0, 
          heapIndex = 3216}, {propertyFlags = 0, heapIndex = 144}, {propertyFlags = 0, heapIndex = 1571500880}, {propertyFlags = 85, 
          heapIndex = 1571501264}, {propertyFlags = 85, heapIndex = 1551897024}, {propertyFlags = 85, heapIndex = 1551897472}, {
          propertyFlags = 85, heapIndex = 1571503184}, {propertyFlags = 85, heapIndex = 0}, {propertyFlags = 0, heapIndex = 0}}, 
      memoryHeapCount = 1, memoryHeaps = {{size = 970082304, flags = 1}, {size = 0, flags = 0}, {size = 0, flags = 0}, {size = 0, 
          flags = 0}, {size = 0, flags = 0}, {size = 289, flags = 1571550160}, {size = 549613591288, flags = 0}, {size = 0, 
          flags = 0}, {size = 0, flags = 0}, {size = 0, flags = 0}, {size = 0, flags = 0}, {size = 0, flags = 0}, {size = 0, 
          flags = 0}, {size = 0, flags = 144}, {size = 144, flags = 1571501344}, {size = 366643722560, flags = 0}}}}, 
  DebugLayerActive = false, instance = 0x555e5ae5a0, surface = 0x555d3f8d90, device = 0x555dcbfcb0, allocator = 0x555d25ef80, 
  graphicsQueue = 0x555dcc0200, presentQueue = 0x555dcc0200, graphicsFamily = 0, presentFamily = 0, graphicsTimeQueries = true, 
  debugMessenger = 0x0}
(gdb) p viewInfo
$3 = {sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, pNext = 0x0, flags = 0, image = 0x555d48c260, 
  viewType = VK_IMAGE_VIEW_TYPE_2D, format = VK_FORMAT_A2R10G10B10_UNORM_PACK32, components = {r = VK_COMPONENT_SWIZZLE_IDENTITY, 
    g = VK_COMPONENT_SWIZZLE_IDENTITY, b = VK_COMPONENT_SWIZZLE_IDENTITY, a = VK_COMPONENT_SWIZZLE_IDENTITY}, subresourceRange = {
    aspectMask = 1, baseMipLevel = 0, levelCount = 1, baseArrayLayer = 0, layerCount = 1}}
(gdb) p view
$4 = (VkImageView) 0x555d2167d0
(gdb) p *view
$5 = <incomplete type>

After that, it comes the VkResult result = vkCreateImageView(device->device, &viewInfo, nullptr, &view); that causes the segfault. Do you see anything strange there?

alexey-lysiuk commented 3 years ago

Number of times vkCreateImageView() is called may vary, so it doesn't really matter. What does matter is a backtrace (aka callstack). Is the one from this comment correct? I would like to be sure that VkRenderBuffers::CreateSceneNormal() is responsible for a faulty call.

vk_debug I mentioned before is a console variable, not environment one. Set it to true with +vk_debug 1 command line option, or in a config file.

Also, may I ask you to post output of vulkaninfo tool?

dpjudas commented 3 years ago

Based on the call stack of the crash point, the problem seems to be that either the vulkan driver has a faulty VK_FORMAT_A2R10G10B10_UNORM_PACK32 image format implementation or doesn't support this image format at all.

I couldn't quickly find where it states in the vulkan spec what formats are required to support (if any). It may be that gzdoom needs to call vkGetPhysicalDeviceFormatProperties on every VK_FORMAT that it intends to use to figure out if it can be used at all?

You can check if it indeed is a problem with this format by using a different one. Replace VK_FORMAT_A2R10G10B10_UNORM_PACK32 with VK_FORMAT_R8G8B8A8_UNORM in the following locations:

src\common\rendering\vulkan\renderer\vk_renderbuffers.cpp(215): builder.setFormat(VK_FORMAT_A2R10G10B10_UNORM_PACK32); src\common\rendering\vulkan\renderer\vk_renderbuffers.cpp(221): viewbuilder.setImage(SceneNormal.Image.get(), VK_FORMAT_A2R10G10B10_UNORM_PACK32); src\common\rendering\vulkan\renderer\vk_renderpass.cpp(284): VkFormat drawBufferFormats[] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A2R10G10B10_UNORM_PACK32 };

dpjudas commented 3 years ago

Okay, I found the place in the spec where it lists the required formats to support and VK_FORMAT_A2R10G10B10_UNORM_PACK32 is indeed not among them. So that's what the problem is.

dpjudas commented 3 years ago

I created a PR with those changes to GZDoom: https://github.com/coelckers/gzdoom/pull/1359

drfrag666 commented 3 years ago

Merged.

vanfanel commented 3 years ago

Boots on the Pi4 now. Looks fine until a game is started: then screen appears totally garbled (except for HUD, which looks fine).

Am I the only person trying this on a Pi4 in Vulkan mode?

dpjudas commented 3 years ago

I didn't test it as I don't own a Pi4. My PR was purely based on the issues that were identified by your initial debugging (the missing depthclamp support and the image creation crash) and fixing those things to be in line with the vulkan spec.

Is there no validation layer (vk_debug 1) for the pi4? I can only repeat what alexy said: this requires active debugging from someone with the device and the interest to figure out where things go wrong. Garbled output of only the 3D scene indicates it could be a problem with the vertex format, or the uniform buffers, or more. It's hard to say for sure.

madame-rachelle commented 3 years ago

Works fine for me on GZDoom. It is slow, however, and requires you to enter vid_scalemode 1 in the console.

It works fine outside of a few glitches. gl_dither_bpc is broken and portal support is iffy, but otherwise I have not had any issues with it.

However, it is extremely slow and that is to be expected with the Pi. I'm sure you'll have to disable a lot of shaders to get it running at a decent speed. At 768x400 using X11 I got 15 fps. It was magnitudes slower at any higher resolution.

drfrag666 commented 3 years ago

But did it work before dpjudas' PR? I suspect @vanfanel is not using the latest driver.

madame-rachelle commented 3 years ago

For me? No it did not.

vanfanel commented 3 years ago

@drfrag666 I am using the latest driver here. I wouldn't report anything without building and installing latest libDRM and MESA.

drfrag666 commented 3 years ago

The garbled screen could be due to the different default light mode then. I dunno, try setting gl_lightmode to 3.

vanfanel commented 3 years ago

I have built current GIT version to try @drfrag666 suggestion, and now I see this exception being thrown:


Thread 1 "lzdoom" hit Catchpoint 2 (exception thrown), 0x0000007ff7a3db68 in __cxa_throw ()
   from /usr/lib/aarch64-linux-gnu/libstdc++.so.6
(gdb) bt
#0  0x0000007ff7a3db68 in __cxa_throw () from /usr/lib/aarch64-linux-gnu/libstdc++.so.6
#1  0x0000005555b3f9e4 in VulkanError (text=0x5556291578 "Could not create vulkan surface")
    at /home/pi/src/gzdoom/src/common/rendering/vulkan/system/vk_device.h:119
#2  0x0000005555b3c920 in VulkanDevice::CreateSurface (this=0x555d1749d0)
    at /home/pi/src/gzdoom/src/common/rendering/vulkan/system/vk_device.cpp:268
#3  0x0000005555b3bda0 in VulkanDevice::VulkanDevice (this=0x555d1749d0)
    at /home/pi/src/gzdoom/src/common/rendering/vulkan/system/vk_device.cpp:81
#4  0x00000055559b9430 in SDLVideo::CreateFrameBuffer (this=0x555e28cc20)
    at /home/pi/src/gzdoom/src/common/platform/posix/sdl/sdlglvideo.cpp:469
#5  0x0000005556055d34 in IVideo::SetResolution (this=0x555e28cc20) at /home/pi/src/gzdoom/src/common/rendering/v_video.cpp:310
#6  0x000000555605606c in V_Init2 () at /home/pi/src/gzdoom/src/common/rendering/v_video.cpp:386
#7  0x0000005555be9e34 in D_DoomMain_Internal () at /home/pi/src/gzdoom/src/d_main.cpp:3587
#8  0x0000005555bea370 in GameMain () at /home/pi/src/gzdoom/src/d_main.cpp:3694
#9  0x00000055559b734c in main (argc=3, argv=0x7ffffff628) at /home/pi/src/gzdoom/src/common/platform/posix/sdl/i_main.cpp:194

It wasn't happening before. Any idea on what has changed?

madame-rachelle commented 3 years ago

That means you are running on a system that does not support Vulkan, and no one bothered to put in a try{}catch{} to handle the VulkanError exceptions.

vanfanel commented 3 years ago

Ah, got it working. Even if fullscreen is activated, LZDoom tries to create a 1024x576 window, which Vulkan can't do outside X11 (Vulkan window sizes outside the X server are limited to the available physical monitor resolutions), so after setting win_w=1280 and win_h=720, things work.

Now, even in-game graphics look good! :) I think this is "debugged" now to run on a Pi4! Thanks!

vanfanel commented 3 years ago

That means you are running on a system that does not support Vulkan, and no one bothered to put in a try{}catch{} to handle the VulkanError exceptions.

Well, no. Vulkan works fine here, thanks :) Explanation is on my previous post, but just in case: size of the Vulkan SDL2 windows on the KMSDRM backend is limited to the available video modes. Once that's sorted, LZDoom now works on the Pi4 using Vulkan.

madame-rachelle commented 3 years ago

It threw an unhandled exception which is a bug which still needs to be fixed. It should error out gracefully with the message instead of forcing you to dig the message out of a backtrace.