mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2025-12-21 15:32:18 +00:00
Refactor g_vulkan + Upstream plume changes
Signed-off-by: Isaac Marovitz <isaacryu@icloud.com>
This commit is contained in:
parent
1db0a08a25
commit
2872dbb743
3 changed files with 151 additions and 101 deletions
|
|
@ -129,6 +129,9 @@ namespace plume
|
||||||
#ifdef UNLEASHED_RECOMP_D3D12
|
#ifdef UNLEASHED_RECOMP_D3D12
|
||||||
extern std::unique_ptr<RenderInterface> CreateD3D12Interface();
|
extern std::unique_ptr<RenderInterface> CreateD3D12Interface();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef UNLEASHED_RECOMP_METAL
|
||||||
|
extern std::unique_ptr<RenderInterface> CreateMetalInterface();
|
||||||
|
#endif
|
||||||
#ifdef SDL_VULKAN_ENABLED
|
#ifdef SDL_VULKAN_ENABLED
|
||||||
extern std::unique_ptr<RenderInterface> CreateVulkanInterface(RenderWindow sdlWindow);
|
extern std::unique_ptr<RenderInterface> CreateVulkanInterface(RenderWindow sdlWindow);
|
||||||
#else
|
#else
|
||||||
|
|
@ -309,17 +312,14 @@ static Profiler g_swapChainAcquireProfiler;
|
||||||
static bool g_profilerVisible;
|
static bool g_profilerVisible;
|
||||||
static bool g_profilerWasToggled;
|
static bool g_profilerWasToggled;
|
||||||
|
|
||||||
#ifdef UNLEASHED_RECOMP_D3D12
|
#if !defined(UNLEASHED_RECOMP_D3D12) && !defined(UNLEASHED_RECOMP_METAL)
|
||||||
static bool g_vulkan = false;
|
static constexpr Backend g_backend = Backend::VULKAN;
|
||||||
#else
|
#else
|
||||||
static constexpr bool g_vulkan = true;
|
static Backend g_backend;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool g_triangleStripWorkaround = false;
|
static bool g_triangleStripWorkaround = false;
|
||||||
|
|
||||||
static bool g_hardwareResolve = true;
|
|
||||||
static bool g_hardwareDepthResolve = true;
|
|
||||||
|
|
||||||
static std::unique_ptr<RenderInterface> g_interface;
|
static std::unique_ptr<RenderInterface> g_interface;
|
||||||
static std::unique_ptr<RenderDevice> g_device;
|
static std::unique_ptr<RenderDevice> g_device;
|
||||||
|
|
||||||
|
|
@ -806,25 +806,27 @@ static std::unique_ptr<uint8_t[]> g_buttonBcDiff;
|
||||||
|
|
||||||
static void LoadEmbeddedResources()
|
static void LoadEmbeddedResources()
|
||||||
{
|
{
|
||||||
if (g_vulkan)
|
switch (g_backend)
|
||||||
{
|
{
|
||||||
|
case Backend::VULKAN:
|
||||||
g_shaderCache = std::make_unique<uint8_t[]>(g_spirvCacheDecompressedSize);
|
g_shaderCache = std::make_unique<uint8_t[]>(g_spirvCacheDecompressedSize);
|
||||||
ZSTD_decompress(g_shaderCache.get(), g_spirvCacheDecompressedSize, g_compressedSpirvCache, g_spirvCacheCompressedSize);
|
ZSTD_decompress(g_shaderCache.get(), g_spirvCacheDecompressedSize, g_compressedSpirvCache, g_spirvCacheCompressedSize);
|
||||||
}
|
break;
|
||||||
#ifdef UNLEASHED_RECOMP_METAL
|
#ifdef UNLEASHED_RECOM_D3D12
|
||||||
else
|
case Backend::D3D12:
|
||||||
{
|
|
||||||
g_shaderCache = std::make_unique<uint8_t[]>(g_airCacheDecompressedSize);
|
|
||||||
ZSTD_decompress(g_shaderCache.get(), g_airCacheDecompressedSize, g_compressedAirCache, g_airCacheCompressedSize);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef UNLEASHED_RECOMP_D3D12
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_shaderCache = std::make_unique<uint8_t[]>(g_dxilCacheDecompressedSize);
|
g_shaderCache = std::make_unique<uint8_t[]>(g_dxilCacheDecompressedSize);
|
||||||
ZSTD_decompress(g_shaderCache.get(), g_dxilCacheDecompressedSize, g_compressedDxilCache, g_dxilCacheCompressedSize);
|
ZSTD_decompress(g_shaderCache.get(), g_dxilCacheDecompressedSize, g_compressedDxilCache, g_dxilCacheCompressedSize);
|
||||||
}
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef UNLEASHED_RECOMP_METAL
|
||||||
|
case Backend::METAL:
|
||||||
|
g_shaderCache = std::make_unique<uint8_t[]>(g_airCacheDecompressedSize);
|
||||||
|
ZSTD_decompress(g_shaderCache.get(), g_airCacheDecompressedSize, g_compressedAirCache, g_airCacheCompressedSize);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
g_buttonBcDiff = decompressZstd(g_button_bc_diff, g_button_bc_diff_uncompressed_size);
|
g_buttonBcDiff = decompressZstd(g_button_bc_diff, g_button_bc_diff_uncompressed_size);
|
||||||
}
|
}
|
||||||
|
|
@ -1331,10 +1333,19 @@ static std::unique_ptr<GuestShader> g_enhancedMotionBlurShader;
|
||||||
|
|
||||||
#define CREATE_SHADER(NAME) \
|
#define CREATE_SHADER(NAME) \
|
||||||
g_device->createShader( \
|
g_device->createShader( \
|
||||||
g_vulkan ? g_##NAME##_spirv : g_##NAME##_dxil, \
|
(g_backend == Backend::VULKAN) ? g_##NAME##_spirv : g_##NAME##_dxil, \
|
||||||
g_vulkan ? sizeof(g_##NAME##_spirv) : sizeof(g_##NAME##_dxil), \
|
(g_backend == Backend::VULKAN) ? sizeof(g_##NAME##_spirv) : sizeof(g_##NAME##_dxil), \
|
||||||
"main", \
|
"main", \
|
||||||
g_vulkan ? RenderShaderFormat::SPIRV : RenderShaderFormat::DXIL)
|
(g_backend == Backend::VULKAN) ? RenderShaderFormat::SPIRV : RenderShaderFormat::DXIL)
|
||||||
|
|
||||||
|
#elif UNLEASHED_RECOMP_METAL
|
||||||
|
|
||||||
|
#define CREATE_SHADER(NAME) \
|
||||||
|
g_device->createShader( \
|
||||||
|
(g_backend == Backend::VULKAN) ? g_##NAME##_spirv : g_##NAME##_air, \
|
||||||
|
(g_backend == Backend::VULKAN) ? sizeof(g_##NAME##_spirv) : sizeof(g_##NAME##_air), \
|
||||||
|
(g_backend == Backend::VULKAN) ? "main" : "shaderMain", \
|
||||||
|
(g_backend == Backend::VULKAN) ? RenderShaderFormat::SPIRV : RenderShaderFormat::METAL)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
@ -1705,7 +1716,12 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
|
||||||
GameWindow::Init(sdlVideoDriver);
|
GameWindow::Init(sdlVideoDriver);
|
||||||
|
|
||||||
#ifdef UNLEASHED_RECOMP_D3D12
|
#ifdef UNLEASHED_RECOMP_D3D12
|
||||||
g_vulkan = DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan;
|
g_backend = (DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan) ? Backend::VULKAN : Backend::D3D12;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef UNLEASHED_RECOMP_METAL
|
||||||
|
// TODO: Set this based on a config value and change default to Metal
|
||||||
|
g_backend = Backend::METAL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Attempt to create the possible backends using a vector of function pointers. Whichever succeeds first will be the chosen API.
|
// Attempt to create the possible backends using a vector of function pointers. Whichever succeeds first will be the chosen API.
|
||||||
|
|
@ -1716,11 +1732,21 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
|
||||||
if (graphicsApiRetry)
|
if (graphicsApiRetry)
|
||||||
{
|
{
|
||||||
// If we are attempting to create again after a reboot due to a crash, swap the order.
|
// If we are attempting to create again after a reboot due to a crash, swap the order.
|
||||||
g_vulkan = !g_vulkan;
|
if (g_backend == Backend::VULKAN)
|
||||||
|
{
|
||||||
|
g_backend = Backend::D3D12;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_backend = Backend::VULKAN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interfaceFunctions.push_back(g_vulkan ? CreateVulkanInterfaceWrapper : CreateD3D12Interface);
|
interfaceFunctions.push_back((g_backend == Backend::VULKAN) ? CreateVulkanInterfaceWrapper : CreateD3D12Interface);
|
||||||
interfaceFunctions.push_back(g_vulkan ? CreateD3D12Interface : CreateVulkanInterfaceWrapper);
|
interfaceFunctions.push_back((g_backend == Backend::VULKAN) ? CreateD3D12Interface : CreateVulkanInterfaceWrapper);
|
||||||
|
#elif UNLEASHED_RECOMP_METAL
|
||||||
|
interfaceFunctions.push_back((g_backend == Backend::VULKAN) ? CreateVulkanInterfaceWrapper : CreateMetalInterface);
|
||||||
|
interfaceFunctions.push_back((g_backend == Backend::VULKAN) ? CreateMetalInterface : CreateVulkanInterfaceWrapper);
|
||||||
#else
|
#else
|
||||||
interfaceFunctions.push_back(CreateVulkanInterfaceWrapper);
|
interfaceFunctions.push_back(CreateVulkanInterfaceWrapper);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1815,7 +1841,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
|
||||||
if (graphicsApiRetry)
|
if (graphicsApiRetry)
|
||||||
{
|
{
|
||||||
// If we managed to create a device after retrying it in a reboot, remember the one we picked.
|
// If we managed to create a device after retrying it in a reboot, remember the one we picked.
|
||||||
Config::GraphicsAPI = g_vulkan ? EGraphicsAPI::Vulkan : EGraphicsAPI::D3D12;
|
Config::GraphicsAPI = (g_backend == Backend::VULKAN) ? EGraphicsAPI::Vulkan : EGraphicsAPI::D3D12;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -1853,7 +1879,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
|
||||||
g_queue = g_device->createCommandQueue(RenderCommandListType::DIRECT);
|
g_queue = g_device->createCommandQueue(RenderCommandListType::DIRECT);
|
||||||
|
|
||||||
for (auto& commandList : g_commandLists)
|
for (auto& commandList : g_commandLists)
|
||||||
commandList = g_device->createCommandList(RenderCommandListType::DIRECT);
|
commandList = g_queue->createCommandList();
|
||||||
|
|
||||||
for (auto& commandFence : g_commandFences)
|
for (auto& commandFence : g_commandFences)
|
||||||
commandFence = g_device->createCommandFence();
|
commandFence = g_device->createCommandFence();
|
||||||
|
|
@ -1862,7 +1888,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
|
||||||
queryPool = g_device->createQueryPool(NUM_QUERIES);
|
queryPool = g_device->createQueryPool(NUM_QUERIES);
|
||||||
|
|
||||||
g_copyQueue = g_device->createCommandQueue(RenderCommandListType::COPY);
|
g_copyQueue = g_device->createCommandQueue(RenderCommandListType::COPY);
|
||||||
g_copyCommandList = g_device->createCommandList(RenderCommandListType::COPY);
|
g_copyCommandList = g_copyQueue->createCommandList();
|
||||||
g_copyCommandFence = g_device->createCommandFence();
|
g_copyCommandFence = g_device->createCommandFence();
|
||||||
|
|
||||||
uint32_t bufferCount = 2;
|
uint32_t bufferCount = 2;
|
||||||
|
|
@ -1870,17 +1896,19 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
|
||||||
switch (Config::TripleBuffering)
|
switch (Config::TripleBuffering)
|
||||||
{
|
{
|
||||||
case ETripleBuffering::Auto:
|
case ETripleBuffering::Auto:
|
||||||
if (g_vulkan)
|
switch (g_backend) {
|
||||||
{
|
case Backend::VULKAN:
|
||||||
// Defaulting to 3 is fine if presentWait as supported, as the maximum frame latency allowed is only 1.
|
// Defaulting to 3 is fine if presentWait as supported, as the maximum frame latency allowed is only 1.
|
||||||
bufferCount = g_device->getCapabilities().presentWait ? 3 : 2;
|
bufferCount = g_device->getCapabilities().presentWait ? 3 : 2;
|
||||||
}
|
break;
|
||||||
else
|
case Backend::D3D12:
|
||||||
{
|
|
||||||
// Defaulting to 3 is fine on D3D12 thanks to flip discard model.
|
// Defaulting to 3 is fine on D3D12 thanks to flip discard model.
|
||||||
bufferCount = 3;
|
bufferCount = 3;
|
||||||
|
break;
|
||||||
|
case Backend::METAL:
|
||||||
|
bufferCount = 2;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ETripleBuffering::On:
|
case ETripleBuffering::On:
|
||||||
bufferCount = 3;
|
bufferCount = 3;
|
||||||
|
|
@ -1975,7 +2003,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
|
||||||
|
|
||||||
pipelineLayoutBuilder.addDescriptorSet(descriptorSetBuilder);
|
pipelineLayoutBuilder.addDescriptorSet(descriptorSetBuilder);
|
||||||
|
|
||||||
if (g_vulkan)
|
if (g_backend != Backend::D3D12)
|
||||||
{
|
{
|
||||||
pipelineLayoutBuilder.addPushConstant(0, 4, 24, RenderShaderStageFlag::VERTEX | RenderShaderStageFlag::PIXEL);
|
pipelineLayoutBuilder.addPushConstant(0, 4, 24, RenderShaderStageFlag::VERTEX | RenderShaderStageFlag::PIXEL);
|
||||||
}
|
}
|
||||||
|
|
@ -2090,12 +2118,7 @@ void Video::WaitForGPU()
|
||||||
{
|
{
|
||||||
g_waitForGPUCount++;
|
g_waitForGPUCount++;
|
||||||
|
|
||||||
if (g_vulkan)
|
// Wait for all queued frames to finish.
|
||||||
{
|
|
||||||
g_device->waitIdle();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < NUM_FRAMES; i++)
|
for (size_t i = 0; i < NUM_FRAMES; i++)
|
||||||
{
|
{
|
||||||
if (g_commandListStates[i])
|
if (g_commandListStates[i])
|
||||||
|
|
@ -2104,9 +2127,11 @@ void Video::WaitForGPU()
|
||||||
g_commandListStates[i] = false;
|
g_commandListStates[i] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_queue->executeCommandLists(nullptr, g_commandFences[0].get());
|
// Execute an empty command list and wait for it to end to guarantee that any remaining presentation has finished.
|
||||||
|
g_commandLists[0]->begin();
|
||||||
|
g_commandLists[0]->end();
|
||||||
|
g_queue->executeCommandLists(g_commandLists[0].get(), g_commandFences[0].get());
|
||||||
g_queue->waitForCommandFence(g_commandFences[0].get());
|
g_queue->waitForCommandFence(g_commandFences[0].get());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t CreateDevice(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5, be<uint32_t>* a6)
|
static uint32_t CreateDevice(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5, be<uint32_t>* a6)
|
||||||
|
|
@ -2472,12 +2497,25 @@ static void DrawProfiler()
|
||||||
ImGui::Text("Present Wait: %s", g_capabilities.presentWait ? "Supported" : "Unsupported");
|
ImGui::Text("Present Wait: %s", g_capabilities.presentWait ? "Supported" : "Unsupported");
|
||||||
ImGui::Text("Triangle Fan: %s", g_capabilities.triangleFan ? "Supported" : "Unsupported");
|
ImGui::Text("Triangle Fan: %s", g_capabilities.triangleFan ? "Supported" : "Unsupported");
|
||||||
ImGui::Text("Dynamic Depth Bias: %s", g_capabilities.dynamicDepthBias ? "Supported" : "Unsupported");
|
ImGui::Text("Dynamic Depth Bias: %s", g_capabilities.dynamicDepthBias ? "Supported" : "Unsupported");
|
||||||
|
ImGui::Text("Hardware Resolve Modes: %s", g_capabilities.resolveModes ? "Supported" : "Unsupported");
|
||||||
ImGui::Text("Triangle Strip Workaround: %s", g_triangleStripWorkaround ? "Enabled" : "Disabled");
|
ImGui::Text("Triangle Strip Workaround: %s", g_triangleStripWorkaround ? "Enabled" : "Disabled");
|
||||||
ImGui::Text("Hardware Resolve: %s", g_hardwareResolve ? "Enabled" : "Disabled");
|
|
||||||
ImGui::Text("Hardware Depth Resolve: %s", g_hardwareDepthResolve ? "Enabled" : "Disabled");
|
|
||||||
ImGui::NewLine();
|
ImGui::NewLine();
|
||||||
|
|
||||||
ImGui::Text("API: %s", g_vulkan ? "Vulkan" : "D3D12");
|
std::string backend;
|
||||||
|
|
||||||
|
switch (g_backend) {
|
||||||
|
case Backend::VULKAN:
|
||||||
|
backend = "Vulkan";
|
||||||
|
break;
|
||||||
|
case Backend::D3D12:
|
||||||
|
backend = "D3D12";
|
||||||
|
break;
|
||||||
|
case Backend::METAL:
|
||||||
|
backend = "Metal";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("API: %s", backend.c_str());
|
||||||
ImGui::Text("Device: %s", g_device->getDescription().name.c_str());
|
ImGui::Text("Device: %s", g_device->getDescription().name.c_str());
|
||||||
ImGui::Text("Device Type: %s", DeviceTypeName(g_device->getDescription().type));
|
ImGui::Text("Device Type: %s", DeviceTypeName(g_device->getDescription().type));
|
||||||
ImGui::Text("VRAM: %.2f MiB", (double)(g_device->getDescription().dedicatedVideoMemory) / (1024.0 * 1024.0));
|
ImGui::Text("VRAM: %.2f MiB", (double)(g_device->getDescription().dedicatedVideoMemory) / (1024.0 * 1024.0));
|
||||||
|
|
@ -2901,7 +2939,7 @@ static void SetRootDescriptor(const UploadAllocation& allocation, size_t index)
|
||||||
{
|
{
|
||||||
auto& commandList = g_commandLists[g_frame];
|
auto& commandList = g_commandLists[g_frame];
|
||||||
|
|
||||||
if (g_vulkan)
|
if (g_backend != Backend::D3D12)
|
||||||
commandList->setGraphicsPushConstants(0, &allocation.deviceAddress, 8 * index, 8);
|
commandList->setGraphicsPushConstants(0, &allocation.deviceAddress, 8 * index, 8);
|
||||||
else
|
else
|
||||||
commandList->setGraphicsRootDescriptor(allocation.buffer->at(allocation.offset), index);
|
commandList->setGraphicsRootDescriptor(allocation.buffer->at(allocation.offset), index);
|
||||||
|
|
@ -3388,12 +3426,9 @@ static bool PopulateBarriersForStretchRect(GuestSurface* renderTarget, GuestSurf
|
||||||
RenderTextureLayout dstLayout;
|
RenderTextureLayout dstLayout;
|
||||||
bool shaderResolve = true;
|
bool shaderResolve = true;
|
||||||
|
|
||||||
if (multiSampling && g_hardwareResolve)
|
if (multiSampling)
|
||||||
{
|
{
|
||||||
// Hardware depth resolve is only supported on D3D12 when programmable sample positions are available.
|
if (surface->format != RenderFormat::D32_FLOAT || g_capabilities.resolveModes)
|
||||||
bool hardwareDepthResolveAvailable = g_hardwareDepthResolve && !g_vulkan && g_capabilities.sampleLocations;
|
|
||||||
|
|
||||||
if (surface->format != RenderFormat::D32_FLOAT || hardwareDepthResolveAvailable)
|
|
||||||
{
|
{
|
||||||
srcLayout = RenderTextureLayout::RESOLVE_SOURCE;
|
srcLayout = RenderTextureLayout::RESOLVE_SOURCE;
|
||||||
dstLayout = RenderTextureLayout::RESOLVE_DEST;
|
dstLayout = RenderTextureLayout::RESOLVE_DEST;
|
||||||
|
|
@ -3433,11 +3468,9 @@ static void ExecutePendingStretchRectCommands(GuestSurface* renderTarget, GuestS
|
||||||
{
|
{
|
||||||
bool shaderResolve = true;
|
bool shaderResolve = true;
|
||||||
|
|
||||||
if (multiSampling && g_hardwareResolve)
|
if (multiSampling)
|
||||||
{
|
{
|
||||||
bool hardwareDepthResolveAvailable = g_hardwareDepthResolve && !g_vulkan && g_capabilities.sampleLocations;
|
if (surface->format != RenderFormat::D32_FLOAT || g_capabilities.resolveModes)
|
||||||
|
|
||||||
if (surface->format != RenderFormat::D32_FLOAT || hardwareDepthResolveAvailable)
|
|
||||||
{
|
{
|
||||||
if (surface->format == RenderFormat::D32_FLOAT)
|
if (surface->format == RenderFormat::D32_FLOAT)
|
||||||
commandList->resolveTextureRegion(texture->texture, 0, 0, surface->texture, nullptr, RenderResolveMode::MIN);
|
commandList->resolveTextureRegion(texture->texture, 0, 0, surface->texture, nullptr, RenderResolveMode::MIN);
|
||||||
|
|
@ -3553,7 +3586,7 @@ static void ExecutePendingStretchRectCommands(GuestSurface* renderTarget, GuestS
|
||||||
g_dirtyStates.pipelineState = true;
|
g_dirtyStates.pipelineState = true;
|
||||||
g_dirtyStates.scissorRect = true;
|
g_dirtyStates.scissorRect = true;
|
||||||
|
|
||||||
if (g_vulkan)
|
if (g_backend != Backend::D3D12)
|
||||||
{
|
{
|
||||||
g_dirtyStates.vertexShaderConstants = true; // The push constant call invalidates vertex shader constants.
|
g_dirtyStates.vertexShaderConstants = true; // The push constant call invalidates vertex shader constants.
|
||||||
g_dirtyStates.depthBias = true; // Static depth bias in copy pipeline invalidates dynamic depth bias.
|
g_dirtyStates.depthBias = true; // Static depth bias in copy pipeline invalidates dynamic depth bias.
|
||||||
|
|
@ -3866,7 +3899,7 @@ static void ProcSetScissorRect(const RenderCommand& cmd)
|
||||||
|
|
||||||
static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specConstants)
|
static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specConstants)
|
||||||
{
|
{
|
||||||
if (g_vulkan ||
|
if (g_backend != Backend::D3D12 ||
|
||||||
guestShader->shaderCacheEntry == nullptr ||
|
guestShader->shaderCacheEntry == nullptr ||
|
||||||
guestShader->shaderCacheEntry->specConstantsMask == 0)
|
guestShader->shaderCacheEntry->specConstantsMask == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -3876,7 +3909,9 @@ static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specCons
|
||||||
{
|
{
|
||||||
assert(guestShader->shaderCacheEntry != nullptr);
|
assert(guestShader->shaderCacheEntry != nullptr);
|
||||||
|
|
||||||
if (g_vulkan)
|
switch (g_backend)
|
||||||
|
{
|
||||||
|
case Backend::VULKAN:
|
||||||
{
|
{
|
||||||
auto compressedSpirvData = g_shaderCache.get() + guestShader->shaderCacheEntry->spirvOffset;
|
auto compressedSpirvData = g_shaderCache.get() + guestShader->shaderCacheEntry->spirvOffset;
|
||||||
|
|
||||||
|
|
@ -3885,11 +3920,20 @@ static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specCons
|
||||||
assert(result);
|
assert(result);
|
||||||
|
|
||||||
guestShader->shader = g_device->createShader(decoded.data(), decoded.size(), "shaderMain", RenderShaderFormat::SPIRV);
|
guestShader->shader = g_device->createShader(decoded.data(), decoded.size(), "shaderMain", RenderShaderFormat::SPIRV);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case Backend::METAL:
|
||||||
|
{
|
||||||
|
guestShader->shader = g_device->createShader(g_shaderCache.get() + guestShader->shaderCacheEntry->airOffset,
|
||||||
|
guestShader->shaderCacheEntry->airSize, "shaderMain", RenderShaderFormat::METAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Backend::D3D12:
|
||||||
{
|
{
|
||||||
guestShader->shader = g_device->createShader(g_shaderCache.get() + guestShader->shaderCacheEntry->dxilOffset,
|
guestShader->shader = g_device->createShader(g_shaderCache.get() + guestShader->shaderCacheEntry->dxilOffset,
|
||||||
guestShader->shaderCacheEntry->dxilSize, "shaderMain", RenderShaderFormat::DXIL);
|
guestShader->shaderCacheEntry->dxilSize, "shaderMain", RenderShaderFormat::DXIL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4507,7 +4551,7 @@ static void FlushRenderStateForRenderThread()
|
||||||
|
|
||||||
// D3D12 resets depth bias values to the pipeline values, even if they are dynamic.
|
// D3D12 resets depth bias values to the pipeline values, even if they are dynamic.
|
||||||
// We can reduce unnecessary calls by making common depth bias values part of the pipeline.
|
// We can reduce unnecessary calls by making common depth bias values part of the pipeline.
|
||||||
if (g_capabilities.dynamicDepthBias && !g_vulkan)
|
if (g_capabilities.dynamicDepthBias && g_backend == Backend::D3D12)
|
||||||
{
|
{
|
||||||
bool useDepthBias = (g_depthBias != 0) || (g_slopeScaledDepthBias != 0.0f);
|
bool useDepthBias = (g_depthBias != 0) || (g_slopeScaledDepthBias != 0.0f);
|
||||||
|
|
||||||
|
|
@ -4523,7 +4567,7 @@ static void FlushRenderStateForRenderThread()
|
||||||
commandList->setPipeline(CreateGraphicsPipelineInRenderThread(g_pipelineState));
|
commandList->setPipeline(CreateGraphicsPipelineInRenderThread(g_pipelineState));
|
||||||
|
|
||||||
// D3D12 resets the depth bias values. Check if they need to be set again.
|
// D3D12 resets the depth bias values. Check if they need to be set again.
|
||||||
if (g_capabilities.dynamicDepthBias && !g_vulkan)
|
if (g_capabilities.dynamicDepthBias && g_backend == Backend::D3D12)
|
||||||
g_dirtyStates.depthBias = (g_depthBias != g_pipelineState.depthBias) || (g_slopeScaledDepthBias != g_pipelineState.slopeScaledDepthBias);
|
g_dirtyStates.depthBias = (g_depthBias != g_pipelineState.depthBias) || (g_slopeScaledDepthBias != g_pipelineState.slopeScaledDepthBias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4557,7 +4601,7 @@ static void FlushRenderStateForRenderThread()
|
||||||
g_inputSlots + g_dirtyStates.vertexStreamFirst);
|
g_inputSlots + g_dirtyStates.vertexStreamFirst);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_dirtyStates.indices && (!g_vulkan || g_indexBufferView.buffer.ref != nullptr))
|
if (g_dirtyStates.indices && (g_backend == Backend::D3D12 || g_indexBufferView.buffer.ref != nullptr))
|
||||||
commandList->setIndexBuffer(&g_indexBufferView);
|
commandList->setIndexBuffer(&g_indexBufferView);
|
||||||
|
|
||||||
g_dirtyStates = DirtyStates(false);
|
g_dirtyStates = DirtyStates(false);
|
||||||
|
|
@ -5748,7 +5792,7 @@ static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataS
|
||||||
auto copyTextureRegion = [&](Slice& slice, uint32_t subresourceIndex)
|
auto copyTextureRegion = [&](Slice& slice, uint32_t subresourceIndex)
|
||||||
{
|
{
|
||||||
g_copyCommandList->copyTextureRegion(
|
g_copyCommandList->copyTextureRegion(
|
||||||
RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex),
|
RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex % desc.mipLevels, subresourceIndex / desc.mipLevels),
|
||||||
RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), desc.format, slice.width, slice.height, slice.depth, (slice.dstRowPitch * 8) / ddsDesc.bitsPerPixelOrBlock * ddsDesc.blockWidth, slice.dstOffset));
|
RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), desc.format, slice.width, slice.height, slice.depth, (slice.dstRowPitch * 8) / ddsDesc.bitsPerPixelOrBlock * ddsDesc.blockWidth, slice.dstOffset));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -6492,7 +6536,7 @@ static void CompileMeshPipeline(const Mesh& mesh, CompilationArgs& args)
|
||||||
if (g_capabilities.dynamicDepthBias)
|
if (g_capabilities.dynamicDepthBias)
|
||||||
{
|
{
|
||||||
// Put common depth bias values for reducing unnecessary calls.
|
// Put common depth bias values for reducing unnecessary calls.
|
||||||
if (!g_vulkan)
|
if (g_backend == Backend::D3D12)
|
||||||
{
|
{
|
||||||
pipelineState.depthBias = COMMON_DEPTH_BIAS_VALUE;
|
pipelineState.depthBias = COMMON_DEPTH_BIAS_VALUE;
|
||||||
pipelineState.slopeScaledDepthBias = COMMON_SLOPE_SCALED_DEPTH_BIAS_VALUE;
|
pipelineState.slopeScaledDepthBias = COMMON_SLOPE_SCALED_DEPTH_BIAS_VALUE;
|
||||||
|
|
@ -7254,7 +7298,7 @@ static void PipelineTaskConsumerThread()
|
||||||
pipelineState.primitiveTopology = RenderPrimitiveTopology::TRIANGLE_LIST;
|
pipelineState.primitiveTopology = RenderPrimitiveTopology::TRIANGLE_LIST;
|
||||||
|
|
||||||
// Zero out depth bias for Vulkan, we only store common values for D3D12.
|
// Zero out depth bias for Vulkan, we only store common values for D3D12.
|
||||||
if (g_capabilities.dynamicDepthBias && g_vulkan)
|
if (g_capabilities.dynamicDepthBias && g_backend != Backend::D3D12)
|
||||||
{
|
{
|
||||||
pipelineState.depthBias = 0;
|
pipelineState.depthBias = 0;
|
||||||
pipelineState.slopeScaledDepthBias = 0.0f;
|
pipelineState.slopeScaledDepthBias = 0.0f;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,12 @@ struct Video
|
||||||
static void ComputeViewportDimensions();
|
static void ComputeViewportDimensions();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Backend {
|
||||||
|
VULKAN,
|
||||||
|
D3D12,
|
||||||
|
METAL
|
||||||
|
};
|
||||||
|
|
||||||
struct GuestSamplerState
|
struct GuestSamplerState
|
||||||
{
|
{
|
||||||
be<uint32_t> data[6];
|
be<uint32_t> data[6];
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,7 @@ void GameWindow::Init(const char* sdlVideoDriver)
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
s_renderWindow = { info.info.x11.display, info.info.x11.window };
|
s_renderWindow = { info.info.x11.display, info.info.x11.window };
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
s_renderWindow.window = s_pWindow;
|
s_renderWindow.window = info.info.cocoa.window;
|
||||||
s_renderWindow.view = SDL_Metal_GetLayer(SDL_Metal_CreateView(s_pWindow));
|
s_renderWindow.view = SDL_Metal_GetLayer(SDL_Metal_CreateView(s_pWindow));
|
||||||
#else
|
#else
|
||||||
static_assert(false, "Unknown platform.");
|
static_assert(false, "Unknown platform.");
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue