Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions code/components/glue/src/ConnectToNative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1038,7 +1038,6 @@ static InitFunction initFunction([] ()
{
static bool done = ([]
{
#ifdef GTA_FIVE
std::thread([]
{
UiDone();
Expand All @@ -1051,7 +1050,6 @@ static InitFunction initFunction([] ()
SetForegroundWindow(hWnd);
})
.detach();
#endif

MarkNuiLoaded();

Expand Down
73 changes: 8 additions & 65 deletions code/components/glue/src/GtaNui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,73 +643,14 @@ fwRefContainer<GITexture> GtaNuiInterface::CreateTextureFromShareHandle(HANDLE s

if (texRef)
{
rage::sga::Driver_Destroy_Texture(texRef);
rage::sga::Driver_Destroy_Texture(texRef);

// Vulkan API magic time (copy/pasted from samples on GH)
VkDevice device = (VkDevice)GetGraphicsDriverHandle();

VkExtent3D Extent = { width, height, 1 };

VkExternalMemoryImageCreateInfo ExternalMemoryImageCreateInfo = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO };
ExternalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
VkImageCreateInfo ImageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
ImageCreateInfo.pNext = &ExternalMemoryImageCreateInfo;
ImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
ImageCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
ImageCreateInfo.extent = Extent;
ImageCreateInfo.mipLevels = 1;
ImageCreateInfo.arrayLayers = 1;
ImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
ImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
ImageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
ImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
ImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

VkPhysicalDevice physicalDevice = GetVulkanPhysicalHandle();

VkImage Image;
VkResult result = vkCreateImage(device, &ImageCreateInfo, nullptr, &Image);

if (result != VK_SUCCESS)
{
FatalError("Failed to create a Vulkan image. VkResult: %s", ResultToString(result));
}

VkMemoryRequirements MemoryRequirements;
vkGetImageMemoryRequirements(device, Image, &MemoryRequirements);

VkMemoryDedicatedAllocateInfo MemoryDedicatedAllocateInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO };
MemoryDedicatedAllocateInfo.image = Image;
VkImportMemoryWin32HandleInfoKHR ImportMemoryWin32HandleInfo = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR };
ImportMemoryWin32HandleInfo.pNext = &MemoryDedicatedAllocateInfo;
ImportMemoryWin32HandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
ImportMemoryWin32HandleInfo.handle = shareHandle;
VkMemoryAllocateInfo MemoryAllocateInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
MemoryAllocateInfo.pNext = &ImportMemoryWin32HandleInfo;
MemoryAllocateInfo.allocationSize = MemoryRequirements.size;

unsigned long typeIndex;
_BitScanForward(&typeIndex, MemoryRequirements.memoryTypeBits);
MemoryAllocateInfo.memoryTypeIndex = typeIndex;

static auto _vkBindImageMemory2 = (PFN_vkBindImageMemory2)vkGetDeviceProcAddr(device, "vkBindImageMemory2");

VkDeviceMemory ImageMemory;
result = vkAllocateMemory(device, &MemoryAllocateInfo, nullptr, &ImageMemory);

if (result != VK_SUCCESS)
{
FatalError("Failed to allocate memory for Vulkan. VkResult: %s", ResultToString(result));
}

VkBindImageMemoryInfo BindImageMemoryInfo = { VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO };
BindImageMemoryInfo.image = Image;
BindImageMemoryInfo.memory = ImageMemory;

result = _vkBindImageMemory2(device, 1, &BindImageMemoryInfo);

if (result != VK_SUCCESS)
{
FatalError("Failed to bind Vulkan image memory. VkResult: %s", ResultToString(result));
}
VkDeviceMemory DeviceMemory;
CreateVKImageFromShareHandle(device, shareHandle, width, height, Image, DeviceMemory);

auto newImage = new rage::sga::TextureVK::ImageData;
//memcpy(newImage, texRef->image, sizeof(*newImage));
Expand All @@ -719,7 +660,9 @@ fwRefContainer<GITexture> GtaNuiInterface::CreateTextureFromShareHandle(HANDLE s
texRef->image = newImage;

texRef->image->image = Image;
texRef->image->memory = ImageMemory;
texRef->image->memory = DeviceMemory;
texRef->width = width;
texRef->height = height;

rage::sga::TextureViewDesc srvDesc;
srvDesc.mipLevels = 1;
Expand Down
14 changes: 13 additions & 1 deletion code/components/rage-graphics-rdr3/component.lua
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
includedirs { '../../../vendor/vulkan-headers/include/' }
includedirs {
'../../../vendor/vulkan-headers/include/',
'../rage-graphics-five/include'
}

return function()
filter {}

files {
'components/rage-graphics-five/include/dxerr.h',
'components/rage-graphics-five/src/dxerr.cpp'
}
end
3 changes: 3 additions & 0 deletions code/components/rage-graphics-rdr3/include/DrawCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ extern GFX_EXPORT GraphicsAPI GetCurrentGraphicsAPI();
// VK context or D3D12 device
extern GFX_EXPORT void* GetGraphicsDriverHandle();

// VK physicalDevice
extern GFX_EXPORT VkPhysicalDevice GetVulkanPhysicalHandle();

namespace rage::sga
{
class GFX_EXPORT GraphicsContext
Expand Down
75 changes: 75 additions & 0 deletions code/components/rage-graphics-rdr3/include/VulkanHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#if IS_RDR3
#include <string_view>
#include <vulkan/vulkan_core.h>
#include <vulkan/vulkan_win32.h>

#include <DrawCommands.h>

inline std::string_view ResultToString(VkResult result)
{
Expand Down Expand Up @@ -71,5 +74,77 @@ inline std::string_view ResultToString(VkResult result)
default:
return std::to_string(static_cast<uint32_t>(result));
}
}

static uint32_t FindMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter, VkMemoryPropertyFlags properties)
{
VkPhysicalDeviceMemoryProperties memProperties;
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);

for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++)
{
if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
{
return i;
}
}

return INT32_MAX;
}

static void CreateVKImageFromShareHandle(VkDevice& device, HANDLE handle, unsigned int width, unsigned int height, VkImage& outImage, VkDeviceMemory& outMemory)
{
VkExternalMemoryImageCreateInfo ExternalMemoryImageCreateInfo = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO };
ExternalMemoryImageCreateInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
VkImageCreateInfo ImageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
ImageCreateInfo.pNext = &ExternalMemoryImageCreateInfo;
ImageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
ImageCreateInfo.format = VK_FORMAT_B8G8R8A8_UNORM;
ImageCreateInfo.extent = { width, height, 1 };
ImageCreateInfo.mipLevels = 1;
ImageCreateInfo.arrayLayers = 1;
ImageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
ImageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
ImageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
ImageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
ImageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

VkResult result;
if (result = vkCreateImage(device, &ImageCreateInfo, nullptr, &outImage); result != VK_SUCCESS)
{
FatalError("Failed to create a Vulkan image. VkResult: %s", ResultToString(result));
}

VkMemoryRequirements MemoryRequirements;
vkGetImageMemoryRequirements(device, outImage, &MemoryRequirements);

VkMemoryDedicatedAllocateInfo MemoryDedicatedAllocateInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO };
MemoryDedicatedAllocateInfo.image = outImage;
VkImportMemoryWin32HandleInfoKHR ImportMemoryWin32HandleInfo = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR };
ImportMemoryWin32HandleInfo.pNext = &MemoryDedicatedAllocateInfo;
ImportMemoryWin32HandleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT;
ImportMemoryWin32HandleInfo.handle = handle;
VkMemoryAllocateInfo MemoryAllocateInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
MemoryAllocateInfo.pNext = &ImportMemoryWin32HandleInfo;
MemoryAllocateInfo.allocationSize = MemoryRequirements.size;

VkPhysicalDeviceMemoryProperties memProps;
vkGetPhysicalDeviceMemoryProperties(GetVulkanPhysicalHandle(), &memProps);

MemoryAllocateInfo.memoryTypeIndex = FindMemoryType(GetVulkanPhysicalHandle(), MemoryRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
if (MemoryAllocateInfo.memoryTypeIndex == INT32_MAX)
{
FatalError("Failed to compatible memory type for NUI. This system may not be equipped to run RedM under Vulkan.\n");
}

if (result = vkAllocateMemory(device, &MemoryAllocateInfo, nullptr, &outMemory); result != VK_SUCCESS)
{
FatalError("Failed to allocate memory for Vulkan. VkResult: %s", ResultToString(result));
}

if (result = vkBindImageMemory(device, outImage, outMemory, 0); result != VK_SUCCESS)
{
FatalError("Failed to bind Vulkan image memory. VkResult: %s", ResultToString(result));
}
}
#endif
5 changes: 4 additions & 1 deletion code/components/rage-graphics-rdr3/include/grcTexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,10 @@ namespace rage
uint32_t pad[24];
};

char pad[64];
char pad[0x10];
uint16_t width;
uint16_t height;
char pad2[44];
ImageData* image;
};

Expand Down
41 changes: 22 additions & 19 deletions code/components/rage-graphics-rdr3/src/GfxSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,19 +522,6 @@ static void WrapEndDraw(void* cxt)
origEndDraw(cxt);
}

static LPWSTR GetCommandLineWHook()
{
static wchar_t str[8192];
wcscpy(str, GetCommandLineW());

if (!wcsstr(str, L"sgadriver"))
{
wcscat(str, L" -sgadriver=d3d12");
}

return str;
}

static void* g_d3d12Driver;
static void* g_vkDriver;

Expand All @@ -555,6 +542,8 @@ GraphicsAPI GetCurrentGraphicsAPI()
void** g_d3d12Device;
VkDevice* g_vkHandle;

VkPhysicalDevice* g_vkPhysicalHandle;

void* GetGraphicsDriverHandle()
{
switch (GetCurrentGraphicsAPI())
Expand All @@ -568,6 +557,14 @@ void* GetGraphicsDriverHandle()
}
}

GFX_EXPORT VkPhysicalDevice GetVulkanPhysicalHandle()
{
if (GetCurrentGraphicsAPI() == GraphicsAPI::Vulkan)
{
return *g_vkPhysicalHandle;
}
}

namespace rage::sga
{
void Driver_Create_ShaderResourceView(rage::sga::Texture* texture, const rage::sga::TextureViewDesc& desc)
Expand Down Expand Up @@ -679,9 +676,17 @@ void DynamicTexture2::UnmapInternal(GraphicsContext* context, const MapData& map
}

static bool ShouldUsePipelineCache(const char* pipelineCachePrefix)
{
// #TODO: check for ERR_GFX_STATE or similar failures last launch?
return true;
{
// This file is created on any hooked graphics related crashes (currently ERR_GFX_STATE)
FILE* f = _wfopen(MakeRelativeCitPath("data/cache/clearPipelineCache").c_str(), L"r");
if (!f)
{
fclose(f);
return true;
}

_wunlink(MakeRelativeCitPath("data/cache/clearPipelineCache").c_str());
return false;
}

static HookFunction hookFunction([]()
Expand Down Expand Up @@ -722,15 +727,13 @@ static HookFunction hookFunction([]()

g_d3d12Device = hook::get_address<decltype(g_d3d12Device)>(hook::get_pattern("48 8B 01 FF 50 78 48 8B 0B 48 8D", -7));
g_vkHandle = hook::get_address<decltype(g_vkHandle)>(hook::get_pattern("8D 50 41 8B CA 44 8B C2 F3 48 AB 48 8B 0D", 14));
g_vkPhysicalHandle = hook::get_address<decltype(g_vkPhysicalHandle)>(hook::get_pattern("FF 15 ? ? ? ? 33 D2 48 8D 4C 24 ? 41 B8", 27));

{
auto location = hook::get_pattern<char>("83 25 ? ? ? ? 00 83 25 ? ? ? ? 00 D1 F8 89 05", -0x26);
rage::g_WindowWidth = hook::get_address<int*>(location + 6);
rage::g_WindowHeight = hook::get_address<int*>(location + 0x3E);
}

// #TODORDR: badly force d3d12 sga driver (vulkan crashes on older Windows 10?)
hook::iat("kernel32.dll", GetCommandLineWHook, "GetCommandLineW");

MH_EnableHook(MH_ALL_HOOKS);
});
Loading
Loading