DieHard Wolfers Forum Index DieHard Wolfers
A Wolfenstein 3d Fan Community


  Hosted by: MCS & Areyep.com - Designed by: BrotherTank

Original Yahoo Forum - Die Hard Archives

AReyeP HomepageAreyep Homepage DieHard Wolfenstein BunkerDieHard Wolfenstein Bunker Log inLog in RegisterRegister Banlist FAQFAQ Search ForumsSearch

  Username:    Password:      Remember me       

Vulkan
Page 1 of 1
DieHard Wolfers Forum Index -> Howling Wolfers View Previous TopicRefresh this PageAdd Topic to your Browser FavoritesSearch ForumsPrint this TopicE-mail TopicGoto Page BottomView Next Topic
Post new topicReply to topic
Author Message
Matthew
DieHard Officer
DieHard Officer


Joined: 02 Jul 2007
Last Visit: 12 Aug 2019

Topics: 102
Posts: 506

usa.gif

PostPosted: Sat Aug 18, 2018 10:39 pm
   Subject: Vulkan
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Next PostGoto Bottom of Posts

I have started writing a test program that uses Vulkan.

Recently, SDL added support for Vulkan through the WSI extensions. (It is also possible to display a Vulkan image with an OpenGL window; unlike with OpenGL, the core Vulkan API is independent of the window system.)

The Vulkan support is not mentioned in the SDL documentation. To figure out how to use it, I had to examine the SDL source code.



This is what I've written so far:

::: CODE :::
#include <cstdlib>
#include <cstdint>

#define VK_NO_STDINT_H
#define VK_USE_PLATFORM_WIN32_KHR
#define VK_NO_PROTOTYPES

#include "vulkan/vulkan.h"

#define SDL_MAIN_HANDLED

#include "SDL2/SDL.h"
#include "SDL2/SDL_vulkan.h"



SDL_Window *Window;

PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
PFN_vkCreateInstance vkCreateInstance;
PFN_vkDestroyInstance vkDestroyInstance;
PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
PFN_vkCreateDevice vkCreateDevice;
PFN_vkDestroyDevice vkDestroyDevice;
PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;

VkInstance Instance;
VkPhysicalDevice PhysicalDevice;
uint32_t QueueFamilyIndex;
VkDevice Device;
VkSurfaceKHR Surface;



inline void Error(const char *Message)
{
    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", Message, nullptr);
    exit(1);
}

void Init();

void Quit();



void Init()
{
    uint32_t NumInstanceExtensions = 0;

    const char *DeviceExtensions[] =
    {
        "VK_KHR_swapchain"
    };

    uint32_t PhysicalDeviceCount = 0;

    const float QueuePriority = 1.0f;
    VkDeviceQueueCreateInfo DeviceQueueCreateInfo;
    const VkDeviceCreateInfo DeviceCreateInfo
    {
        VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
        nullptr,
        0,
        1,
        &DeviceQueueCreateInfo,
        0,
        nullptr,
        1,
        DeviceExtensions,
        nullptr
    };

    if (SDL_InitSubSystem(SDL_INIT_VIDEO))
        Error("Failed to initialize SDL");

    Window = SDL_CreateWindow(nullptr, 0, 0, 1920, 1080, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS | SDL_WINDOW_VULKAN);
    if (!Window)
        Error("Failed to create SDL window");

    vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_Vulkan_GetVkGetInstanceProcAddr();
    if (!vkGetInstanceProcAddr)
        Error("Failed to get address of \"vkGetInstanceProdAddr\"");

    vkCreateInstance = (PFN_vkCreateInstance)vkGetInstanceProcAddr(nullptr, "vkCreateInstance");
    if (!vkCreateInstance)
        Error("Failed to get address of \"vkCreateInstance\"");

    if (!SDL_Vulkan_GetInstanceExtensions(Window, &NumInstanceExtensions, nullptr))
        Error("Failed to get Vulkan instance extensions");
    {
        const char *InstanceExtensions[NumInstanceExtensions];
        const VkInstanceCreateInfo InstanceCreateInfo =
        {
            VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
            nullptr,
            0,
            nullptr,
            0,
            nullptr,
            NumInstanceExtensions,
            InstanceExtensions
        };

        if (!SDL_Vulkan_GetInstanceExtensions(Window, &NumInstanceExtensions, InstanceExtensions))
            Error("Failed to get Vulkan instance extensions");

        if (vkCreateInstance(&InstanceCreateInfo, nullptr, &Instance) != VK_SUCCESS)
            Error("Failed to create Vulkan instance");
    }

#define VKINSTANCEPROC(p) p = (PFN_##p)vkGetInstanceProcAddr(Instance, #p); \
    if (!p) \
        Error("Failed to get address of \""#p"\"");

    VKINSTANCEPROC(vkDestroyInstance)
    VKINSTANCEPROC(vkEnumeratePhysicalDevices)
    VKINSTANCEPROC(vkGetPhysicalDeviceQueueFamilyProperties)
    VKINSTANCEPROC(vkCreateDevice)
    VKINSTANCEPROC(vkDestroyDevice)
    VKINSTANCEPROC(vkDestroySurfaceKHR)

#undef VKINSTANCEPROC

    if (vkEnumeratePhysicalDevices(Instance, &PhysicalDeviceCount, nullptr) != VK_SUCCESS)
        Error("Failed to enumerate physical devices");
    {
        VkPhysicalDevice PhysicalDevices[PhysicalDeviceCount];
        if (vkEnumeratePhysicalDevices(Instance, &PhysicalDeviceCount, PhysicalDevices) != VK_SUCCESS)
            Error("Failed to enumerate physical devices");

        for (VkPhysicalDevice *pdp = PhysicalDevices; pdp != PhysicalDevices + PhysicalDeviceCount; pdp++)
        {
            uint32_t QueueFamilyPropertyCount = 0;
            vkGetPhysicalDeviceQueueFamilyProperties(*pdp, &QueueFamilyPropertyCount, nullptr);
            {
                VkQueueFamilyProperties QueueFamilyProperties[QueueFamilyPropertyCount];
                vkGetPhysicalDeviceQueueFamilyProperties(*pdp, &QueueFamilyPropertyCount, QueueFamilyProperties);
                for (uint32_t qfpp = 0; qfpp < QueueFamilyPropertyCount; qfpp++)
                    if (QueueFamilyProperties[qfpp].queueFlags & VK_QUEUE_GRAPHICS_BIT)
                    {
                        PhysicalDevice = *pdp;
                        QueueFamilyIndex = qfpp;
                        goto createdevice;
                    }
            }
        }
        Error("Failed to find a suitable physical device");
    }

createdevice:
    DeviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
    DeviceQueueCreateInfo.pNext = nullptr;
    DeviceQueueCreateInfo.flags = 0;
    DeviceQueueCreateInfo.queueFamilyIndex = QueueFamilyIndex;
    DeviceQueueCreateInfo.queueCount = 1;
    DeviceQueueCreateInfo.pQueuePriorities = &QueuePriority;
    if (vkCreateDevice(PhysicalDevice, &DeviceCreateInfo, nullptr, &Device) != VK_SUCCESS)
        Error("Failed to create device");

    if (!SDL_Vulkan_CreateSurface(Window, Instance, &Surface))
        Error("Failed to create Vulkan surface");
}

void Quit()
{
    vkDestroySurfaceKHR(Instance, Surface, nullptr);

    SDL_DestroyWindow(Window);

    vkDestroyDevice(Device, nullptr);

    vkDestroyInstance(Instance, nullptr);

    SDL_Quit();
}

int main(int argc, char *argv[])
{
    Init();

    atexit(Quit);

    return 0;
}




This just sets up an SDL window and creates a Vulkan instance and a Vulkan device. Actually rendering anything will be much more difficult. Smile

One thing I've noticed: With all of the Vulkan tutorials I've seen, and most C/C++ code in general, they use "malloc" or "new" to allocate arrays whose size needs to be queried. This allocates it as heap memory. It is poor practice to use heap memory for data that is only used within a single function and not expected to take up a large amount of space. Stack memory should be used.

As I did in this code, the proper way of doing that is to use automatic arrays. Why does most C/C++ code do that type of thing using heap memory? Do programmers just not know any better?


Last edited by Matthew on Thu Aug 15, 2019 6:16 pm; edited 4 times in total
AlumiuN
DieHard Wolfer
DieHard Wolfer


Joined: 29 Nov 2007
Last Visit: 8:13 ago.

Topics: 40
Posts: 2612
Location: Christchurch, New Zealand
newzealand.gif

PostPosted: Sat Aug 18, 2018 11:54 pm
   Subject: Re: Vulkan
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

You can use SDL without using its window manager (so you could use Vulkan with it before), but having better integration for it is nice.

On the subject of people not using automatic arrays, I suspect it may be because compiler support for it was either poor or nonexistent for an awful lot of C's (and IIRC some of C++'s) lifespan. These days it's also usually not a problem if it uses heap memory instead of stack memory, so whatever the programmer finds easiest to implement is probably the best choice for them.
Matthew
DieHard Officer
DieHard Officer


Joined: 02 Jul 2007
Last Visit: 12 Aug 2019

Topics: 102
Posts: 506

usa.gif

PostPosted: Sun Aug 19, 2018 1:59 am
   Subject: Vulkan
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

I actually started working on this in April 2017, but have been stalled on it because of problems in my personal life. I now am working on it again.

I originally was writing it so it was going to use SDL and WSI without SDL integration, since SDL didn't support it at the time. But then SDL added support for it, so I'm using it.

When I actually implement Vulkan support in games, I may have to use OpenGL for the window system, because it seems that nVidia 3D Vision does not support Vulkan, even though WSI supports multi-view output. nVidia 3D Vision's driver support is terrible; even OpenGL is barely supported on consumer GPUs.

As I mentioned recently, I am planning to create a rendering engine that will render Wolf3D's game world using GPU rendering. It will use Vulkan.

When I mentioned that, you said that there is no point in using Vulkan with a game as primitive as Wolf3D.

Actually, even with Wolf3D, there are some advantages to using Vulkan.

For example, it would allow all the static geometry on the level to be rendered with a single command buffer submission.

Vulkan also recently added support for multi-view rendering to the core API, which is still not officially supported in OpenGL. With games that I've added stereoscopic rendering support to with OpenGL, there is a large drop in framerate when the game is played with stereoscopic rendering.

Regarding automatic arrays, why would there be issues with a compiler? All you have to do is declare the array at the start of a code block enclosed in braces. With modern compilers, you don't even have to do that, but it is still a good idea.

It is easier and simpler than allocating and freeing heap memory.
Tricob
Moderator
<B>Moderator</B>


Joined: 14 Mar 2005
Last Visit: 0:16 ago.

Topics: 167
Posts: 8413
Location: Neo-traditions, Inc.
usa.gif

PostPosted: Sun Aug 19, 2018 2:03 pm
   Subject: Re: Vulkan
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Do you have links to demos that use Vulkan and its features? I'm sure users will more interested in this addition if they know exactly what it does ... myself included.
Matthew
DieHard Officer
DieHard Officer


Joined: 02 Jul 2007
Last Visit: 12 Aug 2019

Topics: 102
Posts: 506

usa.gif

PostPosted: Sun Aug 19, 2018 6:47 pm
   Subject: Vulkan
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Vulkan is a graphics API which is a successor to OpenGL.

It is an open, cross-platform alternative to the DirectX 12 graphics API. DirectX 12 has a huge limitation: It only is supported by Windows 10. Smile

It was originally developed from AMD's Mantle graphics API.

Everything about it is described in the specification:

https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html

Good luck trying to understand it. Smile

What I am planning to do is create a Vulkan renderer for Wolf4SDL. This will render the game world using GPU rendering.

Of course this can also be done with OpenGL. But OpenGL is outdated, inefficient, and a mess to use.

I actually was originally planning to do this many years ago. In 2013, before I got my new computer, Wolf4SDL was slow. I was planning to create an OpenGL 3.3 renderer so it would run fast.

After I got my new computer, I decided that wasn't necessary. But since them, I've added an advanced AI system that is very performance intensive.
Robbbert
Bring 'em On
Bring 'em On


Joined: 23 Jan 2018
Last Visit: 23 Apr 2019

Topics: 10
Posts: 105

australia.gif

PostPosted: Wed Aug 22, 2018 1:24 am
   Subject: Re: Vulkan
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

If your requirement for extra memory is within a single function, you can use alloca. It will free itself at the end of the function.
You must not try freeing it yourself, because a crash will occur.
AlumiuN
DieHard Wolfer
DieHard Wolfer


Joined: 29 Nov 2007
Last Visit: 8:13 ago.

Topics: 40
Posts: 2612
Location: Christchurch, New Zealand
newzealand.gif

PostPosted: Wed Aug 22, 2018 6:03 am
   Subject: Re: Vulkan
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

Robbbert wrote:
If your requirement for extra memory is within a single function, you can use alloca. It will free itself at the end of the function.
You must not try freeing it yourself, because a crash will occur.


You should never have to use alloca. Both the variant of C used in the original DOS codebase and basically any semi-modern C++ compiler allow variable length arrays, and for anything else (IIRC) a normal declaration will work fine.
Matthew
DieHard Officer
DieHard Officer


Joined: 02 Jul 2007
Last Visit: 12 Aug 2019

Topics: 102
Posts: 506

usa.gif

PostPosted: Tue Jul 30, 2019 2:55 am
   Subject: Vulkan
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

I have started working on this again. (I've updated the code in my original post.)

I originally was using the original "mingw32"; I recently switched to "mingw32-w64".

When I tried to compile it with "mingw32-w64", there were two issues:



* The object file "vulkan-1.lib", which is included with the LunarG Vulkan SDK, does not work with "mingw32-w64". It does not recognize the file format. It is a Microsoft Visual Studio object file. "mingw32" supports MSVS object files. Does "mingw32-w64" not support them?

* Unlike "mingw32", "mingw32-w64" does not have the Windows libraries put together into a single library ("libmingw32"). "libmingw32" has the Windows entry point; the other libraries have to be included separately. To get SDL to work with "mingw32-w64", I had to do Google searches to find which libraries had the functions that were listed in linker errors. Is there anywhere that lists the Windows libraries that SDL requires?



To address the first issue, I changed it so that it loads the Vulkan procedures at runtime. This is better, anyway. The Vulkan specification states that procedures that use a specified device may contain dispatch code if they aren't loaded specifically for that device.
AlumiuN
DieHard Wolfer
DieHard Wolfer


Joined: 29 Nov 2007
Last Visit: 8:13 ago.

Topics: 40
Posts: 2612
Location: Christchurch, New Zealand
newzealand.gif

PostPosted: Tue Jul 30, 2019 4:04 am
   Subject: Re: Vulkan
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

I don't know what version of mingw-w64 you have, but mine has mingw32.lib still.
Matthew
DieHard Officer
DieHard Officer


Joined: 02 Jul 2007
Last Visit: 12 Aug 2019

Topics: 102
Posts: 506

usa.gif

PostPosted: Tue Jul 30, 2019 1:09 pm
   Subject: Vulkan
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

AlumiuN wrote:
I don't know what version of mingw-w64 you have, but mine has mingw32.lib still.


I'm using TDM-GCC-64. The libraries were last modified on June 25, 2015.

It doesn't have "lib" files, only "a" files. It has "libmingw32.a", but it does not contain the Windows libraries; they are in separate files.

Another thing I've discovered: "SDLmain" causes issues with mingw-w64. Normally, it is not necessary to include "libmingw32", because MinGW links to it automatically. But "SDLmain" breaks that. See this discussion for details.

Do you think it would be a good idea to not use SDLmain? I have removed it from this project.

SDL 1 used it to inject initialization code, a terrible idea. With SDL 2, all it does is abstract the entry point. There is no need for that; all compilers I know of use "main" by default.
Matthew
DieHard Officer
DieHard Officer


Joined: 02 Jul 2007
Last Visit: 12 Aug 2019

Topics: 102
Posts: 506

usa.gif

PostPosted: Mon Aug 12, 2019 3:01 am
   Subject: Vulkan
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Bottom of Posts

Here's another thing I've learned: With C/C++ macros, "##" can be used to concatenate macro arguments without spacing.

I already knew that "#" can be used to encapsulate a macro argument in a string, but I didn't know about "##".

In the Vulkan header files, this is used to define handle types with a macro with a single argument.

Vulkan applications can use it to load each procedure with a macro with a single argument.

This is not possible to do with OpenGL, because it uses macros with uppercase letters for the function pointer types.

With my modified version of OpenGlide, it has to prefix each Glide procedure with an underscore, because MSVS does that automatically, but MinGW doesn't. Many years ago, I tried to find a way of doing that with a macro, but couldn't, so I created a header file with dozens of macros, one for each Glide procedure. I'll change it to use this soon.
Display posts from previous:   
Post new topicReply to topic Time synchronized with the forum server time
DieHard Wolfers Forum Index -> Howling Wolfers View Previous TopicRefresh this PageAdd Topic to your Browser FavoritesSearch ForumsPrint this TopicE-mail TopicGoto Page TopView Next Topic
Page 1 of 1
Jump to:  

Related topics
 Topics   Replies   Views   Last Post 
No new posts Girlfriends & styles
Author: Reactor
101 19118 Wed Dec 14, 2005 9:51 am
monkapotomus View latest post
No new posts Quake 3 source released!!
Author: ChiefRebelAngel
9 3472 Thu Dec 01, 2005 7:57 pm
monkapotomus View latest post
No new posts Cookie is a good "sometimes" food!
Author: Ringman
1 1937 Fri Sep 23, 2005 2:38 pm
ChiefRebelAngel View latest post
This topic is locked: you cannot edit posts or make replies. "The-Rooms"
Author: Guest
12 220 Wed Sep 21, 2005 9:20 am
BrotherTank View latest post
No new posts Midi-version of "Der Königgrätzer". Does that even
Author: Metal Overlord
0 2682 Sun Jul 24, 2005 9:05 am
Metal Overlord View latest post
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
   You cannot delete your posts in this forum
You cannot vote in polls in this forum


Copyright ©2003-2008 DieHard Wolfers
A Modified subBunker Theme by BrotherTank
Powered by phpBB © 2001, 2005 phpBB Group