mirror of
https://github.com/elwrcl/intel-hard-graphics.git
synced 2026-11-01 03:18:02 +03:00
init
This commit is contained in:
12511 files changed
+6156641
No files matched your search
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* The purpose of this file is to abstract the differences between the Windows
|
||||
* C ABI for D3D12 and the Linux ABI. Essentially, for class methods that return
|
||||
* structures, the MSVC C++ ABI specifies that they are always called with the return
|
||||
* structure allocated by the caller, and passed as a hidden second parameter,
|
||||
* after "this". But the C compiler doesn't apply that automatically to the C
|
||||
* equivalent definition of the method, and so that ABI needs to be explicitly
|
||||
* embedded in the C function signature. For Linux, no such ABI difference between
|
||||
* C and C++ exists, and so C callers should use the same signature as C++.
|
||||
*/
|
||||
|
||||
#ifndef DZN_ABI_HELPER_H
|
||||
#define DZN_ABI_HELPER_H
|
||||
|
||||
static inline D3D12_HEAP_PROPERTIES
|
||||
dzn_ID3D12Device4_GetCustomHeapProperties(ID3D12Device4 *dev, UINT node_mask, D3D12_HEAP_TYPE type)
|
||||
{
|
||||
D3D12_HEAP_PROPERTIES ret;
|
||||
#ifdef _WIN32
|
||||
ID3D12Device4_GetCustomHeapProperties(dev, &ret, node_mask, type);
|
||||
#else
|
||||
ret = ID3D12Device4_GetCustomHeapProperties(dev, node_mask, type);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline D3D12_RESOURCE_ALLOCATION_INFO
|
||||
dzn_ID3D12Device4_GetResourceAllocationInfo(ID3D12Device4 *dev, UINT visible_mask, UINT num_resource_descs, const D3D12_RESOURCE_DESC *resource_descs)
|
||||
{
|
||||
D3D12_RESOURCE_ALLOCATION_INFO ret;
|
||||
#ifdef _WIN32
|
||||
ID3D12Device4_GetResourceAllocationInfo(dev, &ret, visible_mask, num_resource_descs, resource_descs);
|
||||
#else
|
||||
ret = ID3D12Device4_GetResourceAllocationInfo(dev, visible_mask, num_resource_descs, resource_descs);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline D3D12_RESOURCE_ALLOCATION_INFO
|
||||
dzn_ID3D12Device12_GetResourceAllocationInfo3(ID3D12Device12 *dev, UINT visible_mask, UINT num_resource_descs, const D3D12_RESOURCE_DESC1 *resource_descs,
|
||||
const UINT *num_castable_formats, const DXGI_FORMAT *const *castable_formats,
|
||||
D3D12_RESOURCE_ALLOCATION_INFO1 *allocation_info1)
|
||||
{
|
||||
D3D12_RESOURCE_ALLOCATION_INFO ret;
|
||||
#ifdef _WIN32
|
||||
ID3D12Device12_GetResourceAllocationInfo3(dev, &ret, visible_mask, num_resource_descs, resource_descs, num_castable_formats, castable_formats, allocation_info1);
|
||||
#else
|
||||
ret = ID3D12Device12_GetResourceAllocationInfo3(dev, visible_mask, num_resource_descs, resource_descs, num_castable_formats, castable_formats, allocation_info1);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline D3D12_RESOURCE_DESC
|
||||
dzn_ID3D12Resource_GetDesc(ID3D12Resource *res)
|
||||
{
|
||||
D3D12_RESOURCE_DESC ret;
|
||||
#ifdef _WIN32
|
||||
ID3D12Resource_GetDesc(res, &ret);
|
||||
#else
|
||||
ret = ID3D12Resource_GetDesc(res);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline D3D12_HEAP_DESC
|
||||
dzn_ID3D12Heap_GetDesc(ID3D12Heap *heap)
|
||||
{
|
||||
D3D12_HEAP_DESC ret;
|
||||
#ifdef _WIN32
|
||||
ID3D12Heap_GetDesc(heap, &ret);
|
||||
#else
|
||||
ret = ID3D12Heap_GetDesc(heap);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline D3D12_CPU_DESCRIPTOR_HANDLE
|
||||
dzn_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(ID3D12DescriptorHeap *heap)
|
||||
{
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE ret;
|
||||
#ifdef _WIN32
|
||||
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap, &ret);
|
||||
#else
|
||||
ret = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline D3D12_GPU_DESCRIPTOR_HANDLE
|
||||
dzn_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(ID3D12DescriptorHeap *heap)
|
||||
{
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE ret;
|
||||
#ifdef _WIN32
|
||||
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap, &ret);
|
||||
#else
|
||||
ret = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /*DZN_ABI_HELPER_H*/
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "dzn_physical_device_enum.h"
|
||||
#include <directx/dxcore.h>
|
||||
#include <dxguids/dxguids.h>
|
||||
|
||||
#include "util/u_dl.h"
|
||||
#include "util/log.h"
|
||||
|
||||
VkResult
|
||||
dzn_enumerate_physical_devices_dxcore(struct vk_instance *instance)
|
||||
{
|
||||
util_dl_library *dxcore = util_dl_open(UTIL_DL_PREFIX "dxcore" UTIL_DL_EXT);
|
||||
if (!dxcore) {
|
||||
mesa_loge("Failed to load DXCore\n");
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
using PFNDXCoreCreateAdapterFactory = HRESULT (APIENTRY*)(REFIID, void **);
|
||||
PFNDXCoreCreateAdapterFactory create_func = (PFNDXCoreCreateAdapterFactory)util_dl_get_proc_address(dxcore, "DXCoreCreateAdapterFactory");
|
||||
if (!create_func) {
|
||||
mesa_loge("Failed to load DXCoreCreateAdapterFactory\n");
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
IDXCoreAdapterFactory *factory;
|
||||
if (FAILED(create_func(IID_PPV_ARGS(&factory)))) {
|
||||
mesa_loge("Failed to create DXCore adapter factory\n");
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
IDXCoreAdapterList *list;
|
||||
if (FAILED(factory->CreateAdapterList(1, &DXCORE_ADAPTER_ATTRIBUTE_D3D12_GRAPHICS, IID_PPV_ARGS(&list)))) {
|
||||
factory->Release();
|
||||
mesa_loge("Failed to create DXCore adapter list\n");
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
VkResult result = VK_SUCCESS;
|
||||
uint32_t adapter_count = list->GetAdapterCount();
|
||||
IDXCoreAdapter *adapter;
|
||||
for (uint32_t i = 0; i < adapter_count && result == VK_SUCCESS; ++i) {
|
||||
result = VK_ERROR_INITIALIZATION_FAILED;
|
||||
if (SUCCEEDED(list->GetAdapter(i, IID_PPV_ARGS(&adapter)))) {
|
||||
dzn_physical_device_desc desc = { 0 };
|
||||
DXCoreHardwareID hardware_id;
|
||||
bool is_hardware;
|
||||
if (FAILED(adapter->GetProperty(DXCoreAdapterProperty::HardwareID, &hardware_id)) ||
|
||||
FAILED(adapter->GetProperty(DXCoreAdapterProperty::DedicatedAdapterMemory, &desc.dedicated_video_memory)) ||
|
||||
FAILED(adapter->GetProperty(DXCoreAdapterProperty::SharedSystemMemory, &desc.shared_system_memory)) ||
|
||||
FAILED(adapter->GetProperty(DXCoreAdapterProperty::DedicatedSystemMemory, &desc.dedicated_system_memory)) ||
|
||||
FAILED(adapter->GetProperty(DXCoreAdapterProperty::InstanceLuid, &desc.adapter_luid)) ||
|
||||
FAILED(adapter->GetProperty(DXCoreAdapterProperty::IsHardware, &is_hardware)) ||
|
||||
FAILED(adapter->GetProperty(DXCoreAdapterProperty::DriverDescription, sizeof(desc.description), desc.description))) {
|
||||
mesa_loge("Failed to retrieve DXCore adapter properties\n");
|
||||
result = VK_ERROR_INITIALIZATION_FAILED;
|
||||
} else {
|
||||
desc.vendor_id = hardware_id.vendorID;
|
||||
desc.device_id = hardware_id.deviceID;
|
||||
desc.subsys_id = hardware_id.subSysID;
|
||||
desc.revision = hardware_id.revision;
|
||||
desc.is_warp = !is_hardware;
|
||||
result = dzn_instance_add_physical_device(instance, adapter, &desc);
|
||||
}
|
||||
|
||||
adapter->Release();
|
||||
}
|
||||
}
|
||||
|
||||
list->Release();
|
||||
factory->Release();
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
dzn_query_memory_info(IUnknown* unk, d3d12_memory_info* output){
|
||||
IDXCoreAdapter* adapter = NULL;
|
||||
HRESULT hr = unk->QueryInterface(
|
||||
__uuidof(IDXCoreAdapter),
|
||||
reinterpret_cast<void**>(&adapter));
|
||||
|
||||
if(SUCCEEDED(hr)){
|
||||
|
||||
DXCoreAdapterMemoryBudget local_info, nonlocal_info;
|
||||
DXCoreAdapterMemoryBudgetNodeSegmentGroup local_node_segment = { 0, DXCoreSegmentGroup::Local };
|
||||
DXCoreAdapterMemoryBudgetNodeSegmentGroup nonlocal_node_segment = { 0, DXCoreSegmentGroup::NonLocal };
|
||||
adapter->QueryState(DXCoreAdapterState::AdapterMemoryBudget, &local_node_segment, &local_info);
|
||||
adapter->QueryState(DXCoreAdapterState::AdapterMemoryBudget, &nonlocal_node_segment, &nonlocal_info);
|
||||
|
||||
output->budget_local = local_info.budget;
|
||||
output->budget_nonlocal = nonlocal_info.budget;
|
||||
output->budget = local_info.budget + nonlocal_info.budget;
|
||||
output->usage_local = local_info.currentUsage;
|
||||
output->usage_nonlocal = nonlocal_info.currentUsage;
|
||||
output->usage = local_info.currentUsage + nonlocal_info.currentUsage;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define COBJMACROS
|
||||
#include "dzn_physical_device_enum.h"
|
||||
#include "dzn_dxgi.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
VkResult
|
||||
dzn_enumerate_physical_devices_dxgi(struct vk_instance *instance)
|
||||
{
|
||||
IDXGIFactory4 *factory = dxgi_get_factory(false);
|
||||
IDXGIAdapter1 *adapter = NULL;
|
||||
VkResult result = VK_SUCCESS;
|
||||
for (UINT i = 0; SUCCEEDED(IDXGIFactory4_EnumAdapters1(factory, i, &adapter)); ++i) {
|
||||
DXGI_ADAPTER_DESC1 dxgi_desc;
|
||||
IDXGIAdapter1_GetDesc1(adapter, &dxgi_desc);
|
||||
|
||||
struct dzn_physical_device_desc desc = {
|
||||
.adapter_luid = dxgi_desc.AdapterLuid,
|
||||
.vendor_id = dxgi_desc.VendorId,
|
||||
.device_id = dxgi_desc.DeviceId,
|
||||
.subsys_id = dxgi_desc.SubSysId,
|
||||
.revision = dxgi_desc.Revision,
|
||||
.shared_system_memory = dxgi_desc.SharedSystemMemory,
|
||||
.dedicated_system_memory = dxgi_desc.DedicatedSystemMemory,
|
||||
.dedicated_video_memory = dxgi_desc.DedicatedVideoMemory,
|
||||
.is_warp = (dxgi_desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) != 0,
|
||||
};
|
||||
WideCharToMultiByte(CP_ACP, 0, dxgi_desc.Description, ARRAYSIZE(dxgi_desc.Description),
|
||||
desc.description, ARRAYSIZE(desc.description), NULL, NULL);
|
||||
result =
|
||||
dzn_instance_add_physical_device(instance, (IUnknown *)adapter, &desc);
|
||||
|
||||
IDXGIAdapter1_Release(adapter);
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
IDXGIFactory4_Release(factory);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
IDXGIFactory4 *
|
||||
dxgi_get_factory(bool debug)
|
||||
{
|
||||
static const GUID IID_IDXGIFactory4 = {
|
||||
0x1bc6ea02, 0xef36, 0x464f,
|
||||
{ 0xbf, 0x0c, 0x21, 0xca, 0x39, 0xe5, 0x16, 0x8a }
|
||||
};
|
||||
|
||||
HMODULE dxgi_mod = LoadLibraryA("DXGI.DLL");
|
||||
if (!dxgi_mod) {
|
||||
mesa_loge("failed to load DXGI.DLL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY2)(UINT flags, REFIID riid, void **ppFactory);
|
||||
PFN_CREATE_DXGI_FACTORY2 CreateDXGIFactory2;
|
||||
|
||||
CreateDXGIFactory2 = (PFN_CREATE_DXGI_FACTORY2)GetProcAddress(dxgi_mod, "CreateDXGIFactory2");
|
||||
if (!CreateDXGIFactory2) {
|
||||
mesa_loge("failed to load CreateDXGIFactory2 from DXGI.DLL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UINT flags = 0;
|
||||
if (debug)
|
||||
flags |= DXGI_CREATE_FACTORY_DEBUG;
|
||||
|
||||
IDXGIFactory4 *factory;
|
||||
HRESULT hr = CreateDXGIFactory2(flags, &IID_IDXGIFactory4, (void **)&factory);
|
||||
if (FAILED(hr)) {
|
||||
mesa_loge("CreateDXGIFactory2 failed: %08x\n", (int32_t)hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef DZN_DXGI_H
|
||||
#define DZN_DXGI_H
|
||||
|
||||
#include <dxgi1_4.h>
|
||||
|
||||
struct dzn_instance;
|
||||
|
||||
IDXGIFactory4 *
|
||||
dxgi_get_factory(bool debug);
|
||||
|
||||
#endif /* DZN_DXGI_H */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,850 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "dzn_private.h"
|
||||
|
||||
#include "spirv_to_dxil.h"
|
||||
#include "nir_to_dxil.h"
|
||||
|
||||
#include "dxil_nir.h"
|
||||
#include "dxil_nir_lower_int_samplers.h"
|
||||
#include "dxil_validator.h"
|
||||
|
||||
static void
|
||||
dzn_meta_compile_shader(struct dzn_device *device, nir_shader *nir,
|
||||
D3D12_SHADER_BYTECODE *slot)
|
||||
{
|
||||
struct dzn_instance *instance =
|
||||
container_of(device->vk.physical->instance, struct dzn_instance, vk);
|
||||
struct dzn_physical_device *pdev =
|
||||
container_of(device->vk.physical, struct dzn_physical_device, vk);
|
||||
|
||||
nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
|
||||
|
||||
if ((instance->debug_flags & DZN_DEBUG_NIR) &&
|
||||
(instance->debug_flags & DZN_DEBUG_INTERNAL))
|
||||
nir_print_shader(nir, stderr);
|
||||
|
||||
struct nir_to_dxil_options opts = {
|
||||
.environment = DXIL_ENVIRONMENT_VULKAN,
|
||||
.shader_model_max = dzn_get_shader_model(pdev),
|
||||
#ifdef _WIN32
|
||||
.validator_version_max = dxil_get_validator_version(instance->dxil_validator),
|
||||
#endif
|
||||
};
|
||||
struct blob dxil_blob;
|
||||
ASSERTED bool ret = nir_to_dxil(nir, &opts, NULL, &dxil_blob);
|
||||
assert(ret);
|
||||
|
||||
#ifdef _WIN32
|
||||
char *err = NULL;
|
||||
bool res = dxil_validate_module(instance->dxil_validator,
|
||||
dxil_blob.data,
|
||||
dxil_blob.size, &err);
|
||||
|
||||
if ((instance->debug_flags & DZN_DEBUG_DXIL) &&
|
||||
(instance->debug_flags & DZN_DEBUG_INTERNAL)) {
|
||||
char *disasm = dxil_disasm_module(instance->dxil_validator,
|
||||
dxil_blob.data,
|
||||
dxil_blob.size);
|
||||
if (disasm) {
|
||||
fprintf(stderr,
|
||||
"== BEGIN SHADER ============================================\n"
|
||||
"%s\n"
|
||||
"== END SHADER ==============================================\n",
|
||||
disasm);
|
||||
ralloc_free(disasm);
|
||||
}
|
||||
}
|
||||
|
||||
if ((instance->debug_flags & DZN_DEBUG_DXIL) &&
|
||||
(instance->debug_flags & DZN_DEBUG_INTERNAL) &&
|
||||
!res && !(instance->debug_flags & DZN_DEBUG_EXPERIMENTAL)) {
|
||||
fprintf(stderr,
|
||||
"== VALIDATION ERROR =============================================\n"
|
||||
"%s\n"
|
||||
"== END ==========================================================\n",
|
||||
err ? err : "unknown");
|
||||
ralloc_free(err);
|
||||
}
|
||||
assert(res || (instance->debug_flags & DZN_DEBUG_EXPERIMENTAL));
|
||||
#endif
|
||||
|
||||
void *data;
|
||||
size_t size;
|
||||
blob_finish_get_buffer(&dxil_blob, &data, &size);
|
||||
slot->pShaderBytecode = data;
|
||||
slot->BytecodeLength = size;
|
||||
}
|
||||
|
||||
#define DZN_META_INDIRECT_DRAW_MAX_PARAM_COUNT 5
|
||||
|
||||
static void
|
||||
dzn_meta_indirect_draw_finish(struct dzn_device *device, struct dzn_indirect_draw_type type)
|
||||
{
|
||||
struct dzn_meta_indirect_draw *meta = &device->indirect_draws[type.value];
|
||||
|
||||
if (meta->root_sig)
|
||||
ID3D12RootSignature_Release(meta->root_sig);
|
||||
|
||||
if (meta->pipeline_state)
|
||||
ID3D12PipelineState_Release(meta->pipeline_state);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_meta_indirect_draw_init(struct dzn_device *device,
|
||||
struct dzn_indirect_draw_type type)
|
||||
{
|
||||
struct dzn_meta_indirect_draw *meta = &device->indirect_draws[type.value];
|
||||
struct dzn_instance *instance =
|
||||
container_of(device->vk.physical->instance, struct dzn_instance, vk);
|
||||
VkResult ret = VK_SUCCESS;
|
||||
|
||||
glsl_type_singleton_init_or_ref();
|
||||
|
||||
nir_shader *nir = dzn_nir_indirect_draw_shader(type);
|
||||
uint32_t shader_params_size =
|
||||
type.triangle_fan_primitive_restart ?
|
||||
sizeof(struct dzn_indirect_draw_triangle_fan_prim_restart_rewrite_params) :
|
||||
type.triangle_fan ?
|
||||
sizeof(struct dzn_indirect_draw_triangle_fan_rewrite_params) :
|
||||
sizeof(struct dzn_indirect_draw_rewrite_params);
|
||||
|
||||
uint32_t root_param_count = 0;
|
||||
D3D12_ROOT_PARAMETER1 root_params[DZN_META_INDIRECT_DRAW_MAX_PARAM_COUNT];
|
||||
|
||||
root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
|
||||
.Constants = {
|
||||
.ShaderRegister = 0,
|
||||
.RegisterSpace = 0,
|
||||
.Num32BitValues = shader_params_size / 4,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
|
||||
};
|
||||
|
||||
root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV,
|
||||
.Descriptor = {
|
||||
.ShaderRegister = 1,
|
||||
.RegisterSpace = 0,
|
||||
.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
|
||||
};
|
||||
|
||||
root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV,
|
||||
.Descriptor = {
|
||||
.ShaderRegister = 2,
|
||||
.RegisterSpace = 0,
|
||||
.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
|
||||
};
|
||||
|
||||
if (type.indirect_count) {
|
||||
root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV,
|
||||
.Descriptor = {
|
||||
.ShaderRegister = 3,
|
||||
.RegisterSpace = 0,
|
||||
.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
if (type.triangle_fan) {
|
||||
root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV,
|
||||
.Descriptor = {
|
||||
.ShaderRegister = 4,
|
||||
.RegisterSpace = 0,
|
||||
.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
|
||||
};
|
||||
}
|
||||
|
||||
assert(root_param_count <= ARRAY_SIZE(root_params));
|
||||
|
||||
D3D12_VERSIONED_ROOT_SIGNATURE_DESC root_sig_desc = {
|
||||
.Version = D3D_ROOT_SIGNATURE_VERSION_1_1,
|
||||
.Desc_1_1 = {
|
||||
.NumParameters = root_param_count,
|
||||
.pParameters = root_params,
|
||||
.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE,
|
||||
},
|
||||
};
|
||||
|
||||
D3D12_COMPUTE_PIPELINE_STATE_DESC desc = {
|
||||
.Flags = D3D12_PIPELINE_STATE_FLAG_NONE,
|
||||
};
|
||||
|
||||
meta->root_sig =
|
||||
dzn_device_create_root_sig(device, &root_sig_desc);
|
||||
if (!meta->root_sig) {
|
||||
ret = vk_error(instance, VK_ERROR_INITIALIZATION_FAILED);
|
||||
goto out;
|
||||
}
|
||||
|
||||
desc.pRootSignature = meta->root_sig;
|
||||
dzn_meta_compile_shader(device, nir, &desc.CS);
|
||||
assert(desc.CS.pShaderBytecode);
|
||||
|
||||
if (FAILED(ID3D12Device1_CreateComputePipelineState(device->dev, &desc,
|
||||
&IID_ID3D12PipelineState,
|
||||
(void **)&meta->pipeline_state)))
|
||||
ret = vk_error(instance, VK_ERROR_INITIALIZATION_FAILED);
|
||||
|
||||
out:
|
||||
if (ret != VK_SUCCESS)
|
||||
dzn_meta_indirect_draw_finish(device, type);
|
||||
|
||||
free((void *)desc.CS.pShaderBytecode);
|
||||
ralloc_free(nir);
|
||||
glsl_type_singleton_decref();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define DZN_META_TRIANGLE_FAN_REWRITE_IDX_MAX_PARAM_COUNT 4
|
||||
|
||||
static void
|
||||
dzn_meta_triangle_fan_rewrite_index_finish(struct dzn_device *device,
|
||||
enum dzn_index_type old_index_type)
|
||||
{
|
||||
struct dzn_meta_triangle_fan_rewrite_index *meta =
|
||||
&device->triangle_fan[old_index_type];
|
||||
|
||||
if (meta->root_sig)
|
||||
ID3D12RootSignature_Release(meta->root_sig);
|
||||
if (meta->pipeline_state)
|
||||
ID3D12PipelineState_Release(meta->pipeline_state);
|
||||
if (meta->cmd_sig)
|
||||
ID3D12CommandSignature_Release(meta->cmd_sig);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_meta_triangle_fan_rewrite_index_init(struct dzn_device *device,
|
||||
enum dzn_index_type old_index_type)
|
||||
{
|
||||
struct dzn_meta_triangle_fan_rewrite_index *meta =
|
||||
&device->triangle_fan[old_index_type];
|
||||
struct dzn_instance *instance =
|
||||
container_of(device->vk.physical->instance, struct dzn_instance, vk);
|
||||
VkResult ret = VK_SUCCESS;
|
||||
|
||||
glsl_type_singleton_init_or_ref();
|
||||
|
||||
uint8_t old_index_size = dzn_index_size(old_index_type);
|
||||
bool prim_restart =
|
||||
old_index_type == DZN_INDEX_2B_WITH_PRIM_RESTART ||
|
||||
old_index_type == DZN_INDEX_4B_WITH_PRIM_RESTART;
|
||||
|
||||
nir_shader *nir =
|
||||
prim_restart ?
|
||||
dzn_nir_triangle_fan_prim_restart_rewrite_index_shader(old_index_size) :
|
||||
dzn_nir_triangle_fan_rewrite_index_shader(old_index_size);
|
||||
|
||||
uint32_t root_param_count = 0;
|
||||
D3D12_ROOT_PARAMETER1 root_params[DZN_META_TRIANGLE_FAN_REWRITE_IDX_MAX_PARAM_COUNT];
|
||||
|
||||
root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV,
|
||||
.Descriptor = {
|
||||
.ShaderRegister = 1,
|
||||
.RegisterSpace = 0,
|
||||
.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
|
||||
};
|
||||
|
||||
uint32_t params_size =
|
||||
prim_restart ?
|
||||
sizeof(struct dzn_triangle_fan_prim_restart_rewrite_index_params) :
|
||||
sizeof(struct dzn_triangle_fan_rewrite_index_params);
|
||||
|
||||
root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
|
||||
.Constants = {
|
||||
.ShaderRegister = 0,
|
||||
.RegisterSpace = 0,
|
||||
.Num32BitValues = params_size / 4,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
|
||||
};
|
||||
|
||||
if (old_index_type != DZN_NO_INDEX) {
|
||||
root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV,
|
||||
.Descriptor = {
|
||||
.ShaderRegister = 2,
|
||||
.RegisterSpace = 0,
|
||||
.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
|
||||
};
|
||||
}
|
||||
|
||||
if (prim_restart) {
|
||||
root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV,
|
||||
.Descriptor = {
|
||||
.ShaderRegister = 3,
|
||||
.RegisterSpace = 0,
|
||||
.Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
|
||||
};
|
||||
}
|
||||
|
||||
assert(root_param_count <= ARRAY_SIZE(root_params));
|
||||
|
||||
D3D12_VERSIONED_ROOT_SIGNATURE_DESC root_sig_desc = {
|
||||
.Version = D3D_ROOT_SIGNATURE_VERSION_1_1,
|
||||
.Desc_1_1 = {
|
||||
.NumParameters = root_param_count,
|
||||
.pParameters = root_params,
|
||||
.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE,
|
||||
},
|
||||
};
|
||||
|
||||
D3D12_COMPUTE_PIPELINE_STATE_DESC desc = {
|
||||
.Flags = D3D12_PIPELINE_STATE_FLAG_NONE,
|
||||
};
|
||||
|
||||
uint32_t cmd_arg_count = 0;
|
||||
D3D12_INDIRECT_ARGUMENT_DESC cmd_args[4];
|
||||
|
||||
cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC) {
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW,
|
||||
.UnorderedAccessView = {
|
||||
.RootParameterIndex = 0,
|
||||
},
|
||||
};
|
||||
|
||||
cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC) {
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT,
|
||||
.Constant = {
|
||||
.RootParameterIndex = 1,
|
||||
.DestOffsetIn32BitValues = 0,
|
||||
.Num32BitValuesToSet = params_size / 4,
|
||||
},
|
||||
};
|
||||
|
||||
if (prim_restart) {
|
||||
cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC) {
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW,
|
||||
.UnorderedAccessView = {
|
||||
.RootParameterIndex = 3,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC) {
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH,
|
||||
};
|
||||
|
||||
assert(cmd_arg_count <= ARRAY_SIZE(cmd_args));
|
||||
|
||||
uint32_t exec_params_size =
|
||||
prim_restart ?
|
||||
sizeof(struct dzn_indirect_triangle_fan_prim_restart_rewrite_index_exec_params) :
|
||||
sizeof(struct dzn_indirect_triangle_fan_rewrite_index_exec_params);
|
||||
|
||||
D3D12_COMMAND_SIGNATURE_DESC cmd_sig_desc = {
|
||||
.ByteStride = exec_params_size,
|
||||
.NumArgumentDescs = cmd_arg_count,
|
||||
.pArgumentDescs = cmd_args,
|
||||
};
|
||||
|
||||
assert((cmd_sig_desc.ByteStride & 7) == 0);
|
||||
|
||||
meta->root_sig = dzn_device_create_root_sig(device, &root_sig_desc);
|
||||
if (!meta->root_sig) {
|
||||
ret = vk_error(instance, VK_ERROR_INITIALIZATION_FAILED);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
desc.pRootSignature = meta->root_sig;
|
||||
dzn_meta_compile_shader(device, nir, &desc.CS);
|
||||
|
||||
if (FAILED(ID3D12Device1_CreateComputePipelineState(device->dev, &desc,
|
||||
&IID_ID3D12PipelineState,
|
||||
(void **)&meta->pipeline_state))) {
|
||||
ret = vk_error(instance, VK_ERROR_INITIALIZATION_FAILED);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (FAILED(ID3D12Device1_CreateCommandSignature(device->dev, &cmd_sig_desc,
|
||||
meta->root_sig,
|
||||
&IID_ID3D12CommandSignature,
|
||||
(void **)&meta->cmd_sig)))
|
||||
ret = vk_error(instance, VK_ERROR_INITIALIZATION_FAILED);
|
||||
|
||||
out:
|
||||
if (ret != VK_SUCCESS)
|
||||
dzn_meta_triangle_fan_rewrite_index_finish(device, old_index_type);
|
||||
|
||||
free((void *)desc.CS.pShaderBytecode);
|
||||
ralloc_free(nir);
|
||||
glsl_type_singleton_decref();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const D3D12_SHADER_BYTECODE *
|
||||
dzn_meta_blits_get_vs(struct dzn_device *device)
|
||||
{
|
||||
struct dzn_meta_blits *meta = &device->blits;
|
||||
|
||||
mtx_lock(&meta->shaders_lock);
|
||||
|
||||
if (meta->vs.pShaderBytecode == NULL) {
|
||||
nir_shader *nir = dzn_nir_blit_vs();
|
||||
|
||||
NIR_PASS(_, nir, nir_lower_system_values);
|
||||
|
||||
gl_system_value system_values[] = {
|
||||
SYSTEM_VALUE_FIRST_VERTEX,
|
||||
SYSTEM_VALUE_BASE_VERTEX,
|
||||
};
|
||||
|
||||
NIR_PASS(_, nir, dxil_nir_lower_system_values_to_zero, system_values,
|
||||
ARRAY_SIZE(system_values));
|
||||
|
||||
D3D12_SHADER_BYTECODE bc;
|
||||
|
||||
dzn_meta_compile_shader(device, nir, &bc);
|
||||
meta->vs.pShaderBytecode =
|
||||
vk_alloc(&device->vk.alloc, bc.BytecodeLength, 8,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
|
||||
if (meta->vs.pShaderBytecode) {
|
||||
meta->vs.BytecodeLength = bc.BytecodeLength;
|
||||
memcpy((void *)meta->vs.pShaderBytecode, bc.pShaderBytecode, bc.BytecodeLength);
|
||||
}
|
||||
free((void *)bc.pShaderBytecode);
|
||||
ralloc_free(nir);
|
||||
}
|
||||
|
||||
mtx_unlock(&meta->shaders_lock);
|
||||
|
||||
return &meta->vs;
|
||||
}
|
||||
|
||||
static const D3D12_SHADER_BYTECODE *
|
||||
dzn_meta_blits_get_fs(struct dzn_device *device,
|
||||
const struct dzn_nir_blit_info *info)
|
||||
{
|
||||
struct dzn_meta_blits *meta = &device->blits;
|
||||
D3D12_SHADER_BYTECODE *out = NULL;
|
||||
|
||||
mtx_lock(&meta->shaders_lock);
|
||||
|
||||
STATIC_ASSERT(sizeof(struct dzn_nir_blit_info) == sizeof(uint32_t));
|
||||
|
||||
struct hash_entry *he =
|
||||
_mesa_hash_table_search(meta->fs, (void *)(uintptr_t)info->hash_key);
|
||||
|
||||
if (!he) {
|
||||
nir_shader *nir = dzn_nir_blit_fs(info);
|
||||
|
||||
if (info->out_type != GLSL_TYPE_FLOAT) {
|
||||
dxil_wrap_sampler_state wrap_state = {
|
||||
.is_int_sampler = 1,
|
||||
.is_linear_filtering = 0,
|
||||
.skip_boundary_conditions = 1,
|
||||
};
|
||||
dxil_lower_sample_to_txf_for_integer_tex(nir, 1, &wrap_state, NULL, 0);
|
||||
}
|
||||
|
||||
D3D12_SHADER_BYTECODE bc;
|
||||
|
||||
dzn_meta_compile_shader(device, nir, &bc);
|
||||
|
||||
out = vk_alloc(&device->vk.alloc,
|
||||
sizeof(D3D12_SHADER_BYTECODE) + bc.BytecodeLength, 8,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
|
||||
if (out) {
|
||||
out->pShaderBytecode = out + 1;
|
||||
memcpy((void *)out->pShaderBytecode, bc.pShaderBytecode, bc.BytecodeLength);
|
||||
out->BytecodeLength = bc.BytecodeLength;
|
||||
_mesa_hash_table_insert(meta->fs, &info->hash_key, out);
|
||||
}
|
||||
free((void *)bc.pShaderBytecode);
|
||||
ralloc_free(nir);
|
||||
} else {
|
||||
out = he->data;
|
||||
}
|
||||
|
||||
mtx_unlock(&meta->shaders_lock);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static void
|
||||
dzn_meta_blit_destroy(struct dzn_device *device, struct dzn_meta_blit *blit)
|
||||
{
|
||||
if (!blit)
|
||||
return;
|
||||
|
||||
if (blit->root_sig)
|
||||
ID3D12RootSignature_Release(blit->root_sig);
|
||||
if (blit->pipeline_state)
|
||||
ID3D12PipelineState_Release(blit->pipeline_state);
|
||||
|
||||
vk_free(&device->vk.alloc, blit);
|
||||
}
|
||||
|
||||
static struct dzn_meta_blit *
|
||||
dzn_meta_blit_create(struct dzn_device *device, const struct dzn_meta_blit_key *key)
|
||||
{
|
||||
struct dzn_meta_blit *blit =
|
||||
vk_zalloc(&device->vk.alloc, sizeof(*blit), 8,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
|
||||
|
||||
if (!blit)
|
||||
return NULL;
|
||||
|
||||
D3D12_DESCRIPTOR_RANGE1 ranges[] = {
|
||||
{
|
||||
.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV,
|
||||
.NumDescriptors = 1,
|
||||
.BaseShaderRegister = 0,
|
||||
.RegisterSpace = 0,
|
||||
.Flags = D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS,
|
||||
.OffsetInDescriptorsFromTableStart = 0,
|
||||
},
|
||||
};
|
||||
D3D12_DESCRIPTOR_RANGE1 sampler_ranges[] = {
|
||||
{
|
||||
.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER,
|
||||
.NumDescriptors = 1,
|
||||
.BaseShaderRegister = 0,
|
||||
.RegisterSpace = 0,
|
||||
.Flags = 0,
|
||||
.OffsetInDescriptorsFromTableStart = 0,
|
||||
},
|
||||
};
|
||||
|
||||
D3D12_STATIC_SAMPLER_DESC samplers[] = {
|
||||
{
|
||||
.Filter = key->linear_filter ?
|
||||
D3D12_FILTER_MIN_MAG_MIP_LINEAR :
|
||||
D3D12_FILTER_MIN_MAG_MIP_POINT,
|
||||
.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
|
||||
.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
|
||||
.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
|
||||
.MipLODBias = 0,
|
||||
.MaxAnisotropy = 0,
|
||||
.MinLOD = 0,
|
||||
.MaxLOD = D3D12_FLOAT32_MAX,
|
||||
.ShaderRegister = 0,
|
||||
.RegisterSpace = 0,
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
|
||||
},
|
||||
};
|
||||
|
||||
D3D12_ROOT_PARAMETER1 root_params[4] = {
|
||||
{
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
|
||||
.DescriptorTable = {
|
||||
.NumDescriptorRanges = ARRAY_SIZE(ranges),
|
||||
.pDescriptorRanges = ranges,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
|
||||
},
|
||||
{
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
|
||||
.Constants = {
|
||||
.ShaderRegister = 0,
|
||||
.RegisterSpace = 0,
|
||||
.Num32BitValues = 17,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX,
|
||||
},
|
||||
{
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
|
||||
.DescriptorTable = {
|
||||
.NumDescriptorRanges = ARRAY_SIZE(sampler_ranges),
|
||||
.pDescriptorRanges = sampler_ranges,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
|
||||
},
|
||||
{
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
|
||||
.Constants = {
|
||||
.ShaderRegister = 0,
|
||||
.RegisterSpace = 0,
|
||||
.Num32BitValues = 1,
|
||||
},
|
||||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL,
|
||||
},
|
||||
};
|
||||
uint32_t num_root_params = 2;
|
||||
|
||||
uint32_t samples = key->resolve_mode == dzn_blit_resolve_none ?
|
||||
key->samples : 1;
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = {
|
||||
.SampleMask = (1ULL << samples) - 1,
|
||||
.RasterizerState = {
|
||||
.FillMode = D3D12_FILL_MODE_SOLID,
|
||||
.CullMode = D3D12_CULL_MODE_NONE,
|
||||
.DepthClipEnable = true,
|
||||
},
|
||||
.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
|
||||
.SampleDesc = {
|
||||
.Count = samples,
|
||||
.Quality = 0,
|
||||
},
|
||||
.Flags = D3D12_PIPELINE_STATE_FLAG_NONE,
|
||||
};
|
||||
|
||||
struct dzn_nir_blit_info blit_fs_info = {
|
||||
.src_samples = key->samples,
|
||||
.loc = key->loc,
|
||||
.out_type = key->out_type,
|
||||
.sampler_dim = key->sampler_dim,
|
||||
.src_is_array = key->src_is_array,
|
||||
.resolve_mode = key->resolve_mode,
|
||||
.stencil_fallback = key->loc == FRAG_RESULT_STENCIL && key->stencil_bit != 0xf,
|
||||
.padding = 0,
|
||||
};
|
||||
|
||||
D3D12_VERSIONED_ROOT_SIGNATURE_DESC root_sig_desc = {
|
||||
.Version = D3D_ROOT_SIGNATURE_VERSION_1_1,
|
||||
.Desc_1_1 = {
|
||||
.NumParameters = num_root_params,
|
||||
.pParameters = root_params,
|
||||
.NumStaticSamplers = ARRAY_SIZE(samplers),
|
||||
.pStaticSamplers = samplers,
|
||||
.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE,
|
||||
},
|
||||
};
|
||||
|
||||
if (!device->support_static_samplers) {
|
||||
root_sig_desc.Desc_1_1.NumStaticSamplers = 0;
|
||||
root_sig_desc.Desc_1_1.NumParameters = 3;
|
||||
}
|
||||
|
||||
/* Don't need fs constants unless we're doing the stencil fallback */
|
||||
if (blit_fs_info.stencil_fallback) {
|
||||
if (device->support_static_samplers) {
|
||||
root_params[2] = root_params[3];
|
||||
root_sig_desc.Desc_1_1.NumParameters = 3;
|
||||
} else {
|
||||
root_sig_desc.Desc_1_1.NumParameters = 4;
|
||||
}
|
||||
}
|
||||
|
||||
blit->root_sig = dzn_device_create_root_sig(device, &root_sig_desc);
|
||||
if (!blit->root_sig) {
|
||||
dzn_meta_blit_destroy(device, blit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
desc.pRootSignature = blit->root_sig;
|
||||
|
||||
const D3D12_SHADER_BYTECODE *vs, *fs;
|
||||
|
||||
vs = dzn_meta_blits_get_vs(device);
|
||||
if (!vs) {
|
||||
dzn_meta_blit_destroy(device, blit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
desc.VS = *vs;
|
||||
assert(desc.VS.pShaderBytecode);
|
||||
|
||||
fs = dzn_meta_blits_get_fs(device, &blit_fs_info);
|
||||
if (!fs) {
|
||||
dzn_meta_blit_destroy(device, blit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
desc.PS = *fs;
|
||||
assert(desc.PS.pShaderBytecode);
|
||||
|
||||
assert(key->loc == FRAG_RESULT_DATA0 ||
|
||||
key->loc == FRAG_RESULT_DEPTH ||
|
||||
key->loc == FRAG_RESULT_STENCIL);
|
||||
|
||||
if (key->loc == FRAG_RESULT_DATA0) {
|
||||
desc.NumRenderTargets = 1;
|
||||
desc.RTVFormats[0] = key->out_format;
|
||||
desc.BlendState.RenderTarget[0].RenderTargetWriteMask = 0xf;
|
||||
} else {
|
||||
desc.DSVFormat = key->out_format;
|
||||
if (key->loc == FRAG_RESULT_DEPTH) {
|
||||
desc.DepthStencilState.DepthEnable = true;
|
||||
desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
|
||||
desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
||||
} else {
|
||||
assert(key->loc == FRAG_RESULT_STENCIL);
|
||||
desc.DepthStencilState.StencilEnable = true;
|
||||
desc.DepthStencilState.StencilWriteMask = key->stencil_bit == 0xf ? 0xff : (1 << key->stencil_bit);
|
||||
desc.DepthStencilState.FrontFace.StencilFailOp = D3D12_STENCIL_OP_REPLACE;
|
||||
desc.DepthStencilState.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP_REPLACE;
|
||||
desc.DepthStencilState.FrontFace.StencilPassOp = D3D12_STENCIL_OP_REPLACE;
|
||||
desc.DepthStencilState.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
||||
desc.DepthStencilState.BackFace = desc.DepthStencilState.FrontFace;
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(ID3D12Device1_CreateGraphicsPipelineState(device->dev, &desc,
|
||||
&IID_ID3D12PipelineState,
|
||||
(void **)&blit->pipeline_state))) {
|
||||
dzn_meta_blit_destroy(device, blit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return blit;
|
||||
}
|
||||
|
||||
const struct dzn_meta_blit *
|
||||
dzn_meta_blits_get_context(struct dzn_device *device,
|
||||
const struct dzn_meta_blit_key *key)
|
||||
{
|
||||
struct dzn_meta_blit *out = NULL;
|
||||
|
||||
STATIC_ASSERT(sizeof(*key) == sizeof(uint64_t));
|
||||
|
||||
mtx_lock(&device->blits.contexts_lock);
|
||||
|
||||
out =
|
||||
_mesa_hash_table_u64_search(device->blits.contexts, key->u64);
|
||||
if (!out) {
|
||||
out = dzn_meta_blit_create(device, key);
|
||||
|
||||
if (out)
|
||||
_mesa_hash_table_u64_insert(device->blits.contexts, key->u64, out);
|
||||
}
|
||||
|
||||
mtx_unlock(&device->blits.contexts_lock);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static void
|
||||
dzn_meta_blits_finish(struct dzn_device *device)
|
||||
{
|
||||
struct dzn_meta_blits *meta = &device->blits;
|
||||
|
||||
vk_free(&device->vk.alloc, (void *)meta->vs.pShaderBytecode);
|
||||
|
||||
if (meta->fs) {
|
||||
hash_table_foreach(meta->fs, he)
|
||||
vk_free(&device->vk.alloc, he->data);
|
||||
_mesa_hash_table_destroy(meta->fs, NULL);
|
||||
}
|
||||
|
||||
if (meta->contexts) {
|
||||
hash_table_foreach(&meta->contexts->table, he)
|
||||
dzn_meta_blit_destroy(device, he->data);
|
||||
_mesa_hash_table_u64_destroy(meta->contexts);
|
||||
}
|
||||
|
||||
mtx_destroy(&meta->shaders_lock);
|
||||
mtx_destroy(&meta->contexts_lock);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_meta_blits_init(struct dzn_device *device)
|
||||
{
|
||||
struct dzn_instance *instance =
|
||||
container_of(device->vk.physical->instance, struct dzn_instance, vk);
|
||||
struct dzn_meta_blits *meta = &device->blits;
|
||||
|
||||
mtx_init(&meta->shaders_lock, mtx_plain);
|
||||
mtx_init(&meta->contexts_lock, mtx_plain);
|
||||
|
||||
meta->fs = _mesa_hash_table_create_u32_keys(NULL);
|
||||
if (!meta->fs) {
|
||||
dzn_meta_blits_finish(device);
|
||||
return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
meta->contexts = _mesa_hash_table_u64_create(NULL);
|
||||
if (!meta->contexts) {
|
||||
dzn_meta_blits_finish(device);
|
||||
return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
dzn_meta_finish(struct dzn_device *device)
|
||||
{
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(device->triangle_fan); i++)
|
||||
dzn_meta_triangle_fan_rewrite_index_finish(device, i);
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(device->indirect_draws); i++)
|
||||
dzn_meta_indirect_draw_finish(device, (struct dzn_indirect_draw_type) { .value = i });
|
||||
|
||||
dzn_meta_blits_finish(device);
|
||||
}
|
||||
|
||||
VkResult
|
||||
dzn_meta_init(struct dzn_device *device)
|
||||
{
|
||||
struct dzn_physical_device *pdev = container_of(device->vk.physical, struct dzn_physical_device, vk);
|
||||
VkResult result = dzn_meta_blits_init(device);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out;
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(device->indirect_draws); i++) {
|
||||
struct dzn_indirect_draw_type type = { .value = i };
|
||||
if (type.triangle_fan_primitive_restart && !type.triangle_fan)
|
||||
continue;
|
||||
if (type.triangle_fan && pdev->options15.TriangleFanSupported)
|
||||
continue;
|
||||
if (type.draw_params && pdev->options21.ExtendedCommandInfoSupported)
|
||||
continue;
|
||||
if (type.draw_id && pdev->options21.ExecuteIndirectTier >= D3D12_EXECUTE_INDIRECT_TIER_1_1)
|
||||
continue;
|
||||
result = dzn_meta_indirect_draw_init(device, type);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!pdev->options15.TriangleFanSupported) {
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(device->triangle_fan); i++) {
|
||||
result = dzn_meta_triangle_fan_rewrite_index_init(device, i);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (result != VK_SUCCESS) {
|
||||
dzn_meta_finish(device);
|
||||
return result;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,986 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "dzn_nir.h"
|
||||
|
||||
#include "spirv_to_dxil.h"
|
||||
#include "nir_to_dxil.h"
|
||||
#include "nir_builder.h"
|
||||
#include "nir_builtin_builder.h"
|
||||
#include "dxil_nir.h"
|
||||
#include "vk_nir_convert_ycbcr.h"
|
||||
|
||||
static nir_def *
|
||||
dzn_nir_create_bo_desc(nir_builder *b,
|
||||
nir_variable_mode mode,
|
||||
uint32_t desc_set,
|
||||
uint32_t binding,
|
||||
const char *name,
|
||||
unsigned access)
|
||||
{
|
||||
struct glsl_struct_field field = {
|
||||
.type = mode == nir_var_mem_ubo ?
|
||||
glsl_array_type(glsl_uint_type(), 4096, 4) :
|
||||
glsl_uint_type(),
|
||||
.name = "dummy_int",
|
||||
};
|
||||
const struct glsl_type *dummy_type =
|
||||
glsl_struct_type(&field, 1, "dummy_type", false);
|
||||
|
||||
nir_variable *var =
|
||||
nir_variable_create(b->shader, mode, dummy_type, name);
|
||||
var->data.descriptor_set = desc_set;
|
||||
var->data.binding = binding;
|
||||
var->data.access = access;
|
||||
|
||||
assert(mode == nir_var_mem_ubo || mode == nir_var_mem_ssbo);
|
||||
if (mode == nir_var_mem_ubo)
|
||||
b->shader->info.num_ubos++;
|
||||
else
|
||||
b->shader->info.num_ssbos++;
|
||||
|
||||
nir_descriptor_type desc_type =
|
||||
var->data.mode == nir_var_mem_ubo ?
|
||||
nir_descriptor_type_uniform_buffer :
|
||||
nir_descriptor_type_storage_buffer;
|
||||
nir_address_format addr_format = nir_address_format_32bit_index_offset;
|
||||
nir_def *index =
|
||||
nir_vulkan_resource_index(b,
|
||||
nir_address_format_num_components(addr_format),
|
||||
nir_address_format_bit_size(addr_format),
|
||||
nir_imm_int(b, 0),
|
||||
.desc_set = desc_set,
|
||||
.binding = binding,
|
||||
.desc_type = desc_type);
|
||||
|
||||
nir_def *desc =
|
||||
nir_load_vulkan_descriptor(b,
|
||||
nir_address_format_num_components(addr_format),
|
||||
nir_address_format_bit_size(addr_format),
|
||||
index,
|
||||
.desc_type = desc_type);
|
||||
|
||||
return nir_channel(b, desc, 0);
|
||||
}
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_indirect_draw_shader(struct dzn_indirect_draw_type type)
|
||||
{
|
||||
nir_builder b =
|
||||
nir_builder_init_simple_shader(MESA_SHADER_COMPUTE,
|
||||
dxil_get_base_nir_compiler_options(),
|
||||
"dzn_meta_indirect_%sdraw%s%s%s()",
|
||||
type.indexed ? "indexed_" : "",
|
||||
type.indirect_count ? "_count" : "",
|
||||
type.triangle_fan ? "_triangle_fan" : "",
|
||||
type.triangle_fan_primitive_restart ? "_primitive_restart" : "");
|
||||
|
||||
nir_def *params_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ubo, 0, 0, "params", 0);
|
||||
nir_def *draw_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 1, "draw_buf", ACCESS_NON_WRITEABLE);
|
||||
nir_def *exec_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 2, "exec_buf", ACCESS_NON_READABLE);
|
||||
|
||||
unsigned params_size = 0;
|
||||
if (type.triangle_fan)
|
||||
params_size = sizeof(struct dzn_indirect_draw_triangle_fan_rewrite_params);
|
||||
else
|
||||
params_size = sizeof(struct dzn_indirect_draw_rewrite_params);
|
||||
|
||||
nir_def *params =
|
||||
nir_load_ubo(&b, params_size / 4, 32,
|
||||
params_desc, nir_imm_int(&b, 0),
|
||||
.align_mul = 4, .align_offset = 0, .range_base = 0, .range = ~0);
|
||||
|
||||
uint32_t exec_stride_imm = 0;
|
||||
uint32_t draw_args_offset = 0;
|
||||
if (type.triangle_fan)
|
||||
exec_stride_imm += sizeof(D3D12_INDEX_BUFFER_VIEW);
|
||||
if (type.draw_params)
|
||||
exec_stride_imm += sizeof(uint32_t) * 2;
|
||||
if (type.draw_id)
|
||||
exec_stride_imm += sizeof(uint32_t);
|
||||
draw_args_offset = exec_stride_imm;
|
||||
exec_stride_imm += (type.indexed || type.triangle_fan) ?
|
||||
sizeof(D3D12_DRAW_INDEXED_ARGUMENTS) : sizeof(D3D12_DRAW_ARGUMENTS);
|
||||
|
||||
nir_def *draw_stride = nir_channel(&b, params, 0);
|
||||
nir_def *exec_stride = nir_imm_int(&b, exec_stride_imm);
|
||||
nir_def *index =
|
||||
nir_channel(&b, nir_load_global_invocation_id(&b, 32), 0);
|
||||
|
||||
if (type.indirect_count) {
|
||||
nir_def *count_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 3, "count_buf", ACCESS_NON_WRITEABLE);
|
||||
|
||||
nir_def *draw_count =
|
||||
nir_load_ssbo(&b, 1, 32, count_buf_desc, nir_imm_int(&b, 0), .align_mul = 4);
|
||||
|
||||
nir_push_if(&b, nir_ieq_imm(&b, index, 0));
|
||||
nir_store_ssbo(&b, draw_count, exec_buf_desc, nir_imm_int(&b, 0),
|
||||
.write_mask = 0x1, .access = ACCESS_NON_READABLE,
|
||||
.align_mul = 16);
|
||||
nir_pop_if(&b, NULL);
|
||||
|
||||
nir_push_if(&b, nir_ult(&b, index, draw_count));
|
||||
}
|
||||
|
||||
nir_def *draw_offset = nir_imul(&b, draw_stride, index);
|
||||
|
||||
/* The first entry contains the indirect count */
|
||||
nir_def *exec_offset =
|
||||
type.indirect_count ?
|
||||
nir_imul(&b, exec_stride, nir_iadd_imm(&b, index, 1)) :
|
||||
nir_imul(&b, exec_stride, index);
|
||||
|
||||
nir_def *draw_info1 =
|
||||
nir_load_ssbo(&b, 4, 32, draw_buf_desc, draw_offset, .align_mul = 4);
|
||||
nir_def *draw_info2 =
|
||||
type.indexed ?
|
||||
nir_load_ssbo(&b, 1, 32, draw_buf_desc,
|
||||
nir_iadd_imm(&b, draw_offset, 16), .align_mul = 4) :
|
||||
nir_imm_int(&b, 0);
|
||||
|
||||
nir_def *first_vertex = nir_channel(&b, draw_info1, type.indexed ? 3 : 2);
|
||||
nir_def *base_instance =
|
||||
type.indexed ? draw_info2 : nir_channel(&b, draw_info1, 3);
|
||||
|
||||
uint32_t exec_val_idx = 0;
|
||||
nir_def *exec_vals[8] = { NULL };
|
||||
if (type.draw_params) {
|
||||
exec_vals[exec_val_idx++] = first_vertex;
|
||||
exec_vals[exec_val_idx++] = base_instance;
|
||||
}
|
||||
if (type.draw_id)
|
||||
exec_vals[exec_val_idx++] = index;
|
||||
|
||||
if (type.triangle_fan) {
|
||||
/* Patch {vertex,index}_count and first_index */
|
||||
nir_def *triangle_count =
|
||||
nir_usub_sat(&b, nir_channel(&b, draw_info1, 0), nir_imm_int(&b, 2));
|
||||
exec_vals[exec_val_idx++] = nir_imul_imm(&b, triangle_count, 3);
|
||||
exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 1);
|
||||
exec_vals[exec_val_idx++] = nir_imm_int(&b, 0);
|
||||
exec_vals[exec_val_idx++] = first_vertex;
|
||||
exec_vals[exec_val_idx++] = base_instance;
|
||||
|
||||
nir_def *triangle_fan_exec_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 4,
|
||||
"triangle_fan_exec_buf",
|
||||
ACCESS_NON_READABLE);
|
||||
nir_def *triangle_fan_index_buf_stride = nir_channel(&b, params, 1);
|
||||
nir_def *triangle_fan_index_buf_addr_lo =
|
||||
nir_iadd(&b, nir_channel(&b, params, 2),
|
||||
nir_imul(&b, triangle_fan_index_buf_stride, index));
|
||||
|
||||
nir_def *triangle_fan_exec_vals[9] = { 0 };
|
||||
uint32_t triangle_fan_exec_param_count = 0;
|
||||
nir_def *addr_lo_overflow =
|
||||
nir_ult(&b, triangle_fan_index_buf_addr_lo, nir_channel(&b, params, 2));
|
||||
nir_def *triangle_fan_index_buf_addr_hi =
|
||||
nir_iadd(&b, nir_channel(&b, params, 3),
|
||||
nir_bcsel(&b, addr_lo_overflow, nir_imm_int(&b, 1), nir_imm_int(&b, 0)));
|
||||
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = triangle_fan_index_buf_addr_lo;
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = triangle_fan_index_buf_addr_hi;
|
||||
|
||||
if (type.triangle_fan_primitive_restart) {
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_channel(&b, draw_info1, 2);
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_channel(&b, draw_info1, 0);
|
||||
uint32_t index_count_offset = draw_args_offset +
|
||||
offsetof(D3D12_DRAW_INDEXED_ARGUMENTS, IndexCountPerInstance);
|
||||
nir_def *exec_buf_start =
|
||||
nir_load_ubo(&b, 2, 32,
|
||||
params_desc, nir_imm_int(&b, 16),
|
||||
.align_mul = 4, .align_offset = 0, .range_base = 0, .range = ~0);
|
||||
nir_def *exec_buf_start_lo =
|
||||
nir_iadd(&b, nir_imm_int(&b, index_count_offset),
|
||||
nir_iadd(&b, nir_channel(&b, exec_buf_start, 0),
|
||||
nir_imul(&b, exec_stride, index)));
|
||||
addr_lo_overflow = nir_ult(&b, exec_buf_start_lo, nir_channel(&b, exec_buf_start, 0));
|
||||
nir_def *exec_buf_start_hi =
|
||||
nir_iadd(&b, nir_channel(&b, exec_buf_start, 0),
|
||||
nir_bcsel(&b, addr_lo_overflow, nir_imm_int(&b, 1), nir_imm_int(&b, 0)));
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = exec_buf_start_lo;
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = exec_buf_start_hi;
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_imm_int(&b, 1);
|
||||
} else {
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] =
|
||||
type.indexed ? nir_channel(&b, draw_info1, 2) : nir_imm_int(&b, 0);
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] =
|
||||
triangle_count;
|
||||
}
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_imm_int(&b, 1);
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_imm_int(&b, 1);
|
||||
|
||||
unsigned rewrite_index_exec_params =
|
||||
type.triangle_fan_primitive_restart ?
|
||||
sizeof(struct dzn_indirect_triangle_fan_prim_restart_rewrite_index_exec_params) :
|
||||
sizeof(struct dzn_indirect_triangle_fan_rewrite_index_exec_params);
|
||||
nir_def *triangle_fan_exec_stride =
|
||||
nir_imm_int(&b, rewrite_index_exec_params);
|
||||
nir_def *triangle_fan_exec_offset =
|
||||
nir_imul(&b, triangle_fan_exec_stride, index);
|
||||
|
||||
for (uint32_t i = 0; i < triangle_fan_exec_param_count; i += 4) {
|
||||
unsigned comps = MIN2(triangle_fan_exec_param_count - i, 4);
|
||||
uint32_t mask = (1 << comps) - 1;
|
||||
|
||||
nir_store_ssbo(&b, nir_vec(&b, &triangle_fan_exec_vals[i], comps),
|
||||
triangle_fan_exec_buf_desc,
|
||||
nir_iadd_imm(&b, triangle_fan_exec_offset, i * 4),
|
||||
.write_mask = mask, .access = ACCESS_NON_READABLE, .align_mul = 4);
|
||||
}
|
||||
|
||||
nir_def *ibview_vals[] = {
|
||||
triangle_fan_index_buf_addr_lo,
|
||||
triangle_fan_index_buf_addr_hi,
|
||||
triangle_fan_index_buf_stride,
|
||||
nir_imm_int(&b, DXGI_FORMAT_R32_UINT),
|
||||
};
|
||||
|
||||
nir_store_ssbo(&b, nir_vec(&b, ibview_vals, ARRAY_SIZE(ibview_vals)),
|
||||
exec_buf_desc, exec_offset,
|
||||
.write_mask = 0xf, .access = ACCESS_NON_READABLE, .align_mul = 16);
|
||||
exec_offset = nir_iadd_imm(&b, exec_offset, ARRAY_SIZE(ibview_vals) * 4);
|
||||
} else {
|
||||
exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 0);
|
||||
exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 1);
|
||||
exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 2);
|
||||
exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 3);
|
||||
if (type.indexed)
|
||||
exec_vals[exec_val_idx++] = draw_info2;
|
||||
}
|
||||
|
||||
nir_store_ssbo(&b, nir_vec(&b, exec_vals, MIN2(exec_val_idx, 4)),
|
||||
exec_buf_desc, exec_offset,
|
||||
.write_mask = ((1 << exec_val_idx) - 1) & 0xf, .access = ACCESS_NON_READABLE, .align_mul = 16);
|
||||
if (exec_val_idx > 4) {
|
||||
nir_store_ssbo(&b, nir_vec(&b, &exec_vals[4], exec_val_idx - 4),
|
||||
exec_buf_desc, nir_iadd_imm(&b, exec_offset, 16),
|
||||
.write_mask = ((1 << (exec_val_idx - 4)) - 1) & 0xf, .access = ACCESS_NON_READABLE, .align_mul = 16);
|
||||
}
|
||||
|
||||
if (type.indirect_count)
|
||||
nir_pop_if(&b, NULL);
|
||||
|
||||
return b.shader;
|
||||
}
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_triangle_fan_prim_restart_rewrite_index_shader(uint8_t old_index_size)
|
||||
{
|
||||
assert(old_index_size == 2 || old_index_size == 4);
|
||||
|
||||
nir_builder b =
|
||||
nir_builder_init_simple_shader(MESA_SHADER_COMPUTE,
|
||||
dxil_get_base_nir_compiler_options(),
|
||||
"dzn_meta_triangle_prim_rewrite_index(old_index_size=%d)",
|
||||
old_index_size);
|
||||
|
||||
nir_def *params_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ubo, 0, 0, "params", 0);
|
||||
nir_def *new_index_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 1,
|
||||
"new_index_buf", ACCESS_NON_READABLE);
|
||||
nir_def *old_index_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 2,
|
||||
"old_index_buf", ACCESS_NON_WRITEABLE);
|
||||
nir_def *new_index_count_ptr_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 3,
|
||||
"new_index_count_ptr", ACCESS_NON_READABLE);
|
||||
|
||||
nir_def *params =
|
||||
nir_load_ubo(&b, sizeof(struct dzn_triangle_fan_prim_restart_rewrite_index_params) / 4, 32,
|
||||
params_desc, nir_imm_int(&b, 0),
|
||||
.align_mul = 4, .align_offset = 0, .range_base = 0, .range = ~0);
|
||||
|
||||
nir_def *prim_restart_val =
|
||||
nir_imm_int(&b, old_index_size == 2 ? 0xffff : 0xffffffff);
|
||||
nir_variable *old_index_ptr_var =
|
||||
nir_local_variable_create(b.impl, glsl_uint_type(), "old_index_ptr_var");
|
||||
nir_def *old_index_ptr = nir_channel(&b, params, 0);
|
||||
nir_store_var(&b, old_index_ptr_var, old_index_ptr, 1);
|
||||
nir_variable *new_index_ptr_var =
|
||||
nir_local_variable_create(b.impl, glsl_uint_type(), "new_index_ptr_var");
|
||||
nir_store_var(&b, new_index_ptr_var, nir_imm_int(&b, 0), 1);
|
||||
nir_def *old_index_count = nir_channel(&b, params, 1);
|
||||
nir_variable *index0_var =
|
||||
nir_local_variable_create(b.impl, glsl_uint_type(), "index0_var");
|
||||
nir_store_var(&b, index0_var, prim_restart_val, 1);
|
||||
|
||||
/*
|
||||
* Filter out all primitive-restart magic values, and generate a triangle list
|
||||
* from the triangle fan definition.
|
||||
*
|
||||
* Basically:
|
||||
*
|
||||
* new_index_ptr = 0;
|
||||
* index0 = restart_prim_value; // 0xffff or 0xffffffff
|
||||
* for (old_index_ptr = firstIndex; old_index_ptr < indexCount;) {
|
||||
* // If we have no starting-point we need at least 3 vertices,
|
||||
* // otherwise we can do with two. If there's not enough vertices
|
||||
* // to form a primitive, we just bail out.
|
||||
* min_indices = index0 == restart_prim_value ? 3 : 2;
|
||||
* if (old_index_ptr + min_indices > firstIndex + indexCount)
|
||||
* break;
|
||||
*
|
||||
* if (index0 == restart_prim_value) {
|
||||
* // No starting point, skip all entries until we have a
|
||||
* // non-primitive-restart value
|
||||
* index0 = old_index_buf[old_index_ptr++];
|
||||
* continue;
|
||||
* }
|
||||
*
|
||||
* // If at least one index contains the primitive-restart pattern,
|
||||
// ignore this triangle, and skip the unused entries
|
||||
* if (old_index_buf[old_index_ptr + 1] == restart_prim_value) {
|
||||
* old_index_ptr += 2;
|
||||
* continue;
|
||||
* }
|
||||
* if (old_index_buf[old_index_ptr] == restart_prim_value) {
|
||||
* old_index_ptr++;
|
||||
* continue;
|
||||
* }
|
||||
*
|
||||
* // We have a valid primitive, queue it to the new index buffer
|
||||
* new_index_buf[new_index_ptr++] = old_index_buf[old_index_ptr];
|
||||
* new_index_buf[new_index_ptr++] = old_index_buf[old_index_ptr + 1];
|
||||
* new_index_buf[new_index_ptr++] = index0;
|
||||
* }
|
||||
*
|
||||
* expressed in NIR, which admitedly is not super easy to grasp with.
|
||||
* TODO: Might be a good thing to use use the CL compiler we have and turn
|
||||
* those shaders into CL kernels.
|
||||
*/
|
||||
nir_loop *loop = nir_push_loop(&b);
|
||||
nir_loop_add_continue_construct(loop);
|
||||
|
||||
old_index_ptr = nir_load_var(&b, old_index_ptr_var);
|
||||
nir_def *index0 = nir_load_var(&b, index0_var);
|
||||
|
||||
nir_def *read_index_count =
|
||||
nir_bcsel(&b, nir_ieq(&b, index0, prim_restart_val),
|
||||
nir_imm_int(&b, 3), nir_imm_int(&b, 2));
|
||||
nir_break_if(&b, nir_ult(&b, old_index_count, nir_iadd(&b, old_index_ptr, read_index_count)));
|
||||
|
||||
nir_def *old_index_offset =
|
||||
nir_imul_imm(&b, old_index_ptr, old_index_size);
|
||||
|
||||
nir_push_if(&b, nir_ieq(&b, index0, prim_restart_val));
|
||||
nir_def *index_val =
|
||||
nir_load_ssbo(&b, 1, 32, old_index_buf_desc,
|
||||
old_index_size == 2 ? nir_iand_imm(&b, old_index_offset, ~3ULL) : old_index_offset,
|
||||
.align_mul = 4);
|
||||
if (old_index_size == 2) {
|
||||
index_val = nir_bcsel(&b, nir_test_mask(&b, old_index_offset, 0x2),
|
||||
nir_ushr_imm(&b, index_val, 16),
|
||||
nir_iand_imm(&b, index_val, 0xffff));
|
||||
}
|
||||
|
||||
nir_store_var(&b, index0_var, index_val, 1);
|
||||
nir_store_var(&b, old_index_ptr_var, nir_iadd_imm(&b, old_index_ptr, 1), 1);
|
||||
nir_jump(&b, nir_jump_continue);
|
||||
nir_pop_if(&b, NULL);
|
||||
|
||||
nir_def *index12 =
|
||||
nir_load_ssbo(&b, 2, 32, old_index_buf_desc,
|
||||
old_index_size == 2 ? nir_iand_imm(&b, old_index_offset, ~3ULL) : old_index_offset,
|
||||
.align_mul = 4);
|
||||
if (old_index_size == 2) {
|
||||
nir_def *indices[] = {
|
||||
nir_iand_imm(&b, nir_channel(&b, index12, 0), 0xffff),
|
||||
nir_ushr_imm(&b, nir_channel(&b, index12, 0), 16),
|
||||
nir_iand_imm(&b, nir_channel(&b, index12, 1), 0xffff),
|
||||
};
|
||||
|
||||
index12 = nir_bcsel(&b, nir_test_mask(&b, old_index_offset, 0x2),
|
||||
nir_vec2(&b, indices[1], indices[2]),
|
||||
nir_vec2(&b, indices[0], indices[1]));
|
||||
}
|
||||
|
||||
nir_push_if(&b, nir_ieq(&b, nir_channel(&b, index12, 1), prim_restart_val));
|
||||
nir_store_var(&b, old_index_ptr_var, nir_iadd_imm(&b, old_index_ptr, 2), 1);
|
||||
nir_store_var(&b, index0_var, prim_restart_val, 1);
|
||||
nir_jump(&b, nir_jump_continue);
|
||||
nir_push_else(&b, NULL);
|
||||
nir_store_var(&b, old_index_ptr_var, nir_iadd_imm(&b, old_index_ptr, 1), 1);
|
||||
nir_push_if(&b, nir_ieq(&b, nir_channel(&b, index12, 0), prim_restart_val));
|
||||
nir_store_var(&b, index0_var, prim_restart_val, 1);
|
||||
nir_jump(&b, nir_jump_continue);
|
||||
nir_push_else(&b, NULL);
|
||||
nir_def *new_indices =
|
||||
nir_vec3(&b, nir_channel(&b, index12, 0), nir_channel(&b, index12, 1), index0);
|
||||
nir_def *new_index_ptr = nir_load_var(&b, new_index_ptr_var);
|
||||
nir_def *new_index_offset = nir_imul_imm(&b, new_index_ptr, sizeof(uint32_t));
|
||||
nir_store_ssbo(&b, new_indices, new_index_buf_desc,
|
||||
new_index_offset,
|
||||
.write_mask = 7, .access = ACCESS_NON_READABLE, .align_mul = 4);
|
||||
nir_store_var(&b, new_index_ptr_var, nir_iadd_imm(&b, new_index_ptr, 3), 1);
|
||||
nir_pop_if(&b, NULL);
|
||||
nir_pop_if(&b, NULL);
|
||||
nir_pop_loop(&b, NULL);
|
||||
|
||||
nir_store_ssbo(&b, nir_load_var(&b, new_index_ptr_var),
|
||||
new_index_count_ptr_desc, nir_imm_int(&b, 0),
|
||||
.write_mask = 1, .access = ACCESS_NON_READABLE, .align_mul = 4);
|
||||
|
||||
nir_lower_continue_constructs(b.shader);
|
||||
|
||||
return b.shader;
|
||||
}
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_triangle_fan_rewrite_index_shader(uint8_t old_index_size)
|
||||
{
|
||||
assert(old_index_size == 0 || old_index_size == 2 || old_index_size == 4);
|
||||
|
||||
nir_builder b =
|
||||
nir_builder_init_simple_shader(MESA_SHADER_COMPUTE,
|
||||
dxil_get_base_nir_compiler_options(),
|
||||
"dzn_meta_triangle_rewrite_index(old_index_size=%d)",
|
||||
old_index_size);
|
||||
|
||||
nir_def *params_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ubo, 0, 0, "params", 0);
|
||||
nir_def *new_index_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 1,
|
||||
"new_index_buf", ACCESS_NON_READABLE);
|
||||
|
||||
nir_def *old_index_buf_desc = NULL;
|
||||
if (old_index_size > 0) {
|
||||
old_index_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 2,
|
||||
"old_index_buf", ACCESS_NON_WRITEABLE);
|
||||
}
|
||||
|
||||
nir_def *params =
|
||||
nir_load_ubo(&b, sizeof(struct dzn_triangle_fan_rewrite_index_params) / 4, 32,
|
||||
params_desc, nir_imm_int(&b, 0),
|
||||
.align_mul = 4, .align_offset = 0, .range_base = 0, .range = ~0);
|
||||
|
||||
nir_def *triangle = nir_channel(&b, nir_load_global_invocation_id(&b, 32), 0);
|
||||
nir_def *new_indices;
|
||||
|
||||
if (old_index_size > 0) {
|
||||
nir_def *old_first_index = nir_channel(&b, params, 0);
|
||||
nir_def *old_index0_offset =
|
||||
nir_imul_imm(&b, old_first_index, old_index_size);
|
||||
nir_def *old_index1_offset =
|
||||
nir_imul_imm(&b, nir_iadd(&b, nir_iadd_imm(&b, triangle, 1), old_first_index),
|
||||
old_index_size);
|
||||
|
||||
nir_def *old_index0 =
|
||||
nir_load_ssbo(&b, 1, 32, old_index_buf_desc,
|
||||
old_index_size == 2 ? nir_iand_imm(&b, old_index0_offset, ~3ULL) : old_index0_offset,
|
||||
.align_mul = 4);
|
||||
|
||||
if (old_index_size == 2) {
|
||||
old_index0 = nir_bcsel(&b, nir_test_mask(&b, old_index0_offset, 0x2),
|
||||
nir_ushr_imm(&b, old_index0, 16),
|
||||
nir_iand_imm(&b, old_index0, 0xffff));
|
||||
}
|
||||
|
||||
nir_def *old_index12 =
|
||||
nir_load_ssbo(&b, 2, 32, old_index_buf_desc,
|
||||
old_index_size == 2 ? nir_iand_imm(&b, old_index1_offset, ~3ULL) : old_index1_offset,
|
||||
.align_mul = 4);
|
||||
if (old_index_size == 2) {
|
||||
nir_def *indices[] = {
|
||||
nir_iand_imm(&b, nir_channel(&b, old_index12, 0), 0xffff),
|
||||
nir_ushr_imm(&b, nir_channel(&b, old_index12, 0), 16),
|
||||
nir_iand_imm(&b, nir_channel(&b, old_index12, 1), 0xffff),
|
||||
};
|
||||
|
||||
old_index12 = nir_bcsel(&b, nir_test_mask(&b, old_index1_offset, 0x2),
|
||||
nir_vec2(&b, indices[1], indices[2]),
|
||||
nir_vec2(&b, indices[0], indices[1]));
|
||||
}
|
||||
|
||||
/* TODO: VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT */
|
||||
new_indices =
|
||||
nir_vec3(&b, nir_channel(&b, old_index12, 0),
|
||||
nir_channel(&b, old_index12, 1), old_index0);
|
||||
} else {
|
||||
new_indices =
|
||||
nir_vec3(&b,
|
||||
nir_iadd_imm(&b, triangle, 1),
|
||||
nir_iadd_imm(&b, triangle, 2),
|
||||
nir_imm_int(&b, 0));
|
||||
}
|
||||
|
||||
nir_def *new_index_offset =
|
||||
nir_imul_imm(&b, triangle, 4 * 3);
|
||||
|
||||
nir_store_ssbo(&b, new_indices, new_index_buf_desc,
|
||||
new_index_offset,
|
||||
.write_mask = 7, .access = ACCESS_NON_READABLE, .align_mul = 4);
|
||||
|
||||
return b.shader;
|
||||
}
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_blit_vs(void)
|
||||
{
|
||||
nir_builder b =
|
||||
nir_builder_init_simple_shader(MESA_SHADER_VERTEX,
|
||||
dxil_get_base_nir_compiler_options(),
|
||||
"dzn_meta_blit_vs()");
|
||||
|
||||
nir_def *params_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ubo, 0, 0, "params", 0);
|
||||
|
||||
nir_variable *out_pos =
|
||||
nir_variable_create(b.shader, nir_var_shader_out, glsl_vec4_type(),
|
||||
"gl_Position");
|
||||
out_pos->data.location = VARYING_SLOT_POS;
|
||||
out_pos->data.driver_location = 0;
|
||||
|
||||
nir_variable *out_coords =
|
||||
nir_variable_create(b.shader, nir_var_shader_out, glsl_vec_type(3),
|
||||
"coords");
|
||||
out_coords->data.location = VARYING_SLOT_TEX0;
|
||||
out_coords->data.driver_location = 1;
|
||||
|
||||
nir_def *vertex = nir_load_vertex_id(&b);
|
||||
nir_def *coords_arr[4] = {
|
||||
nir_load_ubo(&b, 4, 32, params_desc, nir_imm_int(&b, 0),
|
||||
.align_mul = 16, .align_offset = 0, .range_base = 0, .range = ~0),
|
||||
nir_load_ubo(&b, 4, 32, params_desc, nir_imm_int(&b, 16),
|
||||
.align_mul = 16, .align_offset = 0, .range_base = 0, .range = ~0),
|
||||
nir_load_ubo(&b, 4, 32, params_desc, nir_imm_int(&b, 32),
|
||||
.align_mul = 16, .align_offset = 0, .range_base = 0, .range = ~0),
|
||||
nir_load_ubo(&b, 4, 32, params_desc, nir_imm_int(&b, 48),
|
||||
.align_mul = 16, .align_offset = 0, .range_base = 0, .range = ~0),
|
||||
};
|
||||
nir_def *coords =
|
||||
nir_bcsel(&b, nir_ieq_imm(&b, vertex, 0), coords_arr[0],
|
||||
nir_bcsel(&b, nir_ieq_imm(&b, vertex, 1), coords_arr[1],
|
||||
nir_bcsel(&b, nir_ieq_imm(&b, vertex, 2), coords_arr[2], coords_arr[3])));
|
||||
nir_def *pos =
|
||||
nir_vec4(&b, nir_channel(&b, coords, 0), nir_channel(&b, coords, 1),
|
||||
nir_imm_float(&b, 0.0), nir_imm_float(&b, 1.0));
|
||||
nir_def *z_coord =
|
||||
nir_load_ubo(&b, 1, 32, params_desc, nir_imm_int(&b, 4 * 4 * sizeof(float)),
|
||||
.align_mul = 64, .align_offset = 0, .range_base = 0, .range = ~0);
|
||||
coords = nir_vec3(&b, nir_channel(&b, coords, 2), nir_channel(&b, coords, 3), z_coord);
|
||||
|
||||
nir_store_var(&b, out_pos, pos, 0xf);
|
||||
nir_store_var(&b, out_coords, coords, 0x7);
|
||||
return b.shader;
|
||||
}
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_blit_fs(const struct dzn_nir_blit_info *info)
|
||||
{
|
||||
bool ms = info->src_samples > 1;
|
||||
nir_alu_type nir_out_type =
|
||||
nir_get_nir_type_for_glsl_base_type(info->out_type);
|
||||
uint32_t coord_comps =
|
||||
glsl_get_sampler_dim_coordinate_components(info->sampler_dim) +
|
||||
info->src_is_array;
|
||||
|
||||
nir_builder b =
|
||||
nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT,
|
||||
dxil_get_base_nir_compiler_options(),
|
||||
"dzn_meta_blit_fs()");
|
||||
|
||||
const struct glsl_type *tex_type =
|
||||
glsl_texture_type(info->sampler_dim, info->src_is_array, info->out_type);
|
||||
nir_variable *tex_var =
|
||||
nir_variable_create(b.shader, nir_var_uniform, tex_type, "texture");
|
||||
nir_deref_instr *tex_deref = nir_build_deref_var(&b, tex_var);
|
||||
|
||||
nir_variable *pos_var =
|
||||
nir_variable_create(b.shader, nir_var_shader_in,
|
||||
glsl_vector_type(GLSL_TYPE_FLOAT, 4),
|
||||
"gl_FragCoord");
|
||||
pos_var->data.location = VARYING_SLOT_POS;
|
||||
pos_var->data.driver_location = 0;
|
||||
|
||||
nir_variable *coord_var =
|
||||
nir_variable_create(b.shader, nir_var_shader_in,
|
||||
glsl_vector_type(GLSL_TYPE_FLOAT, 3),
|
||||
"coord");
|
||||
coord_var->data.location = VARYING_SLOT_TEX0;
|
||||
coord_var->data.driver_location = 1;
|
||||
nir_def *coord =
|
||||
nir_trim_vector(&b, nir_load_var(&b, coord_var), coord_comps);
|
||||
|
||||
uint32_t out_comps =
|
||||
(info->loc == FRAG_RESULT_DEPTH || info->loc == FRAG_RESULT_STENCIL) ? 1 : 4;
|
||||
nir_variable *out = NULL;
|
||||
if (!info->stencil_fallback) {
|
||||
out = nir_variable_create(b.shader, nir_var_shader_out,
|
||||
glsl_vector_type(info->out_type, out_comps),
|
||||
"out");
|
||||
out->data.location = info->loc;
|
||||
}
|
||||
|
||||
nir_def *res = NULL;
|
||||
|
||||
if (info->resolve_mode != dzn_blit_resolve_none) {
|
||||
enum dzn_blit_resolve_mode resolve_mode = info->resolve_mode;
|
||||
|
||||
nir_op resolve_op = nir_op_mov;
|
||||
switch (resolve_mode) {
|
||||
case dzn_blit_resolve_average:
|
||||
/* When resolving a float type, we need to calculate the average of all
|
||||
* samples. For integer resolve, Vulkan says that one sample should be
|
||||
* chosen without telling which. Let's just pick the first one in that
|
||||
* case.
|
||||
*/
|
||||
if (info->out_type == GLSL_TYPE_FLOAT)
|
||||
resolve_op = nir_op_fadd;
|
||||
else
|
||||
resolve_mode = dzn_blit_resolve_sample_zero;
|
||||
break;
|
||||
case dzn_blit_resolve_min:
|
||||
switch (info->out_type) {
|
||||
case GLSL_TYPE_FLOAT: resolve_op = nir_op_fmin; break;
|
||||
case GLSL_TYPE_INT: resolve_op = nir_op_imin; break;
|
||||
case GLSL_TYPE_UINT: resolve_op = nir_op_umin; break;
|
||||
}
|
||||
break;
|
||||
case dzn_blit_resolve_max:
|
||||
switch (info->out_type) {
|
||||
case GLSL_TYPE_FLOAT: resolve_op = nir_op_fmax; break;
|
||||
case GLSL_TYPE_INT: resolve_op = nir_op_imax; break;
|
||||
case GLSL_TYPE_UINT: resolve_op = nir_op_umax; break;
|
||||
}
|
||||
break;
|
||||
case dzn_blit_resolve_none:
|
||||
case dzn_blit_resolve_sample_zero:
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned nsamples = resolve_mode == dzn_blit_resolve_sample_zero ?
|
||||
1 : info->src_samples;
|
||||
for (unsigned s = 0; s < nsamples; s++) {
|
||||
nir_tex_instr *tex = nir_tex_instr_create(b.shader, 4);
|
||||
|
||||
tex->op = nir_texop_txf_ms;
|
||||
tex->dest_type = nir_out_type;
|
||||
tex->texture_index = 0;
|
||||
tex->is_array = info->src_is_array;
|
||||
tex->sampler_dim = info->sampler_dim;
|
||||
|
||||
tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord,
|
||||
nir_f2i32(&b, coord));
|
||||
tex->coord_components = coord_comps;
|
||||
|
||||
tex->src[1] = nir_tex_src_for_ssa(nir_tex_src_ms_index,
|
||||
nir_imm_int(&b, s));
|
||||
|
||||
tex->src[2] = nir_tex_src_for_ssa(nir_tex_src_lod,
|
||||
nir_imm_int(&b, 0));
|
||||
|
||||
tex->src[3] = nir_tex_src_for_ssa(nir_tex_src_texture_deref,
|
||||
&tex_deref->def);
|
||||
|
||||
nir_def_init(&tex->instr, &tex->def, 4, 32);
|
||||
|
||||
nir_builder_instr_insert(&b, &tex->instr);
|
||||
res = res ? nir_build_alu2(&b, resolve_op, res, &tex->def) : &tex->def;
|
||||
}
|
||||
|
||||
if (resolve_mode == dzn_blit_resolve_average)
|
||||
res = nir_fmul_imm(&b, res, 1.0f / nsamples);
|
||||
} else {
|
||||
nir_tex_instr *tex =
|
||||
nir_tex_instr_create(b.shader, ms ? 4 : 3);
|
||||
|
||||
tex->dest_type = nir_out_type;
|
||||
tex->is_array = info->src_is_array;
|
||||
tex->sampler_dim = info->sampler_dim;
|
||||
|
||||
if (ms) {
|
||||
tex->op = nir_texop_txf_ms;
|
||||
|
||||
tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord,
|
||||
nir_f2i32(&b, coord));
|
||||
tex->coord_components = coord_comps;
|
||||
|
||||
tex->src[1] = nir_tex_src_for_ssa(nir_tex_src_ms_index,
|
||||
nir_load_sample_id(&b));
|
||||
|
||||
tex->src[2] = nir_tex_src_for_ssa(nir_tex_src_lod,
|
||||
nir_imm_int(&b, 0));
|
||||
|
||||
tex->src[3] = nir_tex_src_for_ssa(nir_tex_src_texture_deref,
|
||||
&tex_deref->def);
|
||||
} else {
|
||||
nir_variable *sampler_var =
|
||||
nir_variable_create(b.shader, nir_var_uniform, glsl_bare_sampler_type(), "sampler");
|
||||
nir_deref_instr *sampler_deref = nir_build_deref_var(&b, sampler_var);
|
||||
|
||||
tex->op = nir_texop_tex;
|
||||
tex->sampler_index = 0;
|
||||
|
||||
tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord, coord);
|
||||
tex->coord_components = coord_comps;
|
||||
|
||||
tex->src[1] = nir_tex_src_for_ssa(nir_tex_src_texture_deref,
|
||||
&tex_deref->def);
|
||||
|
||||
tex->src[2] = nir_tex_src_for_ssa(nir_tex_src_sampler_deref,
|
||||
&sampler_deref->def);
|
||||
}
|
||||
|
||||
nir_def_init(&tex->instr, &tex->def, 4, 32);
|
||||
nir_builder_instr_insert(&b, &tex->instr);
|
||||
res = &tex->def;
|
||||
}
|
||||
|
||||
if (info->stencil_fallback) {
|
||||
nir_def *mask_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ubo, 0, 0, "mask", 0);
|
||||
nir_def *mask = nir_load_ubo(&b, 1, 32, mask_desc, nir_imm_int(&b, 0),
|
||||
.align_mul = 16, .align_offset = 0, .range_base = 0, .range = ~0);
|
||||
nir_def *fail = nir_ieq_imm(&b, nir_iand(&b, nir_channel(&b, res, 0), mask), 0);
|
||||
nir_discard_if(&b, fail);
|
||||
} else {
|
||||
nir_store_var(&b, out, nir_trim_vector(&b, res, out_comps), 0xf);
|
||||
}
|
||||
|
||||
return b.shader;
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
cull_face(nir_builder *b, nir_variable *vertices, bool ccw)
|
||||
{
|
||||
nir_def *v0 =
|
||||
nir_load_deref(b, nir_build_deref_array(b, nir_build_deref_var(b, vertices), nir_imm_int(b, 0)));
|
||||
nir_def *v1 =
|
||||
nir_load_deref(b, nir_build_deref_array(b, nir_build_deref_var(b, vertices), nir_imm_int(b, 1)));
|
||||
nir_def *v2 =
|
||||
nir_load_deref(b, nir_build_deref_array(b, nir_build_deref_var(b, vertices), nir_imm_int(b, 2)));
|
||||
|
||||
nir_def *dir = nir_fdot(b, nir_cross4(b, nir_fsub(b, v1, v0),
|
||||
nir_fsub(b, v2, v0)),
|
||||
nir_imm_vec4(b, 0.0, 0.0, -1.0, 0.0));
|
||||
if (ccw)
|
||||
return nir_fle_imm(b, dir, 0.0f);
|
||||
else
|
||||
return nir_fgt_imm(b, dir, 0.0f);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_vars(nir_builder *b, nir_deref_instr *dst, nir_deref_instr *src)
|
||||
{
|
||||
assert(glsl_get_bare_type(dst->type) == glsl_get_bare_type(src->type));
|
||||
if (glsl_type_is_struct(dst->type)) {
|
||||
for (unsigned i = 0; i < glsl_get_length(dst->type); ++i) {
|
||||
copy_vars(b, nir_build_deref_struct(b, dst, i), nir_build_deref_struct(b, src, i));
|
||||
}
|
||||
} else if (glsl_type_is_array_or_matrix(dst->type)) {
|
||||
copy_vars(b, nir_build_deref_array_wildcard(b, dst), nir_build_deref_array_wildcard(b, src));
|
||||
} else {
|
||||
nir_copy_deref(b, dst, src);
|
||||
}
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
load_dynamic_depth_bias(nir_builder *b, struct dzn_nir_point_gs_info *info)
|
||||
{
|
||||
nir_address_format ubo_format = nir_address_format_32bit_index_offset;
|
||||
unsigned offset = offsetof(struct dxil_spirv_vertex_runtime_data, depth_bias);
|
||||
|
||||
nir_def *index = nir_vulkan_resource_index(
|
||||
b, nir_address_format_num_components(ubo_format),
|
||||
nir_address_format_bit_size(ubo_format),
|
||||
nir_imm_int(b, 0),
|
||||
.desc_set = info->runtime_data_cbv.register_space,
|
||||
.binding = info->runtime_data_cbv.base_shader_register,
|
||||
.desc_type = nir_descriptor_type_uniform_buffer);
|
||||
|
||||
nir_def *load_desc = nir_load_vulkan_descriptor(
|
||||
b, nir_address_format_num_components(ubo_format),
|
||||
nir_address_format_bit_size(ubo_format),
|
||||
index, .desc_type = nir_descriptor_type_uniform_buffer);
|
||||
|
||||
return nir_load_ubo(
|
||||
b, 1, 32,
|
||||
nir_channel(b, load_desc, 0),
|
||||
nir_imm_int(b, offset),
|
||||
.align_mul = 256,
|
||||
.align_offset = offset);
|
||||
}
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_polygon_point_mode_gs(const nir_shader *previous_shader, struct dzn_nir_point_gs_info *info)
|
||||
{
|
||||
nir_builder builder;
|
||||
nir_builder *b = &builder;
|
||||
nir_variable *pos_var = NULL;
|
||||
|
||||
unsigned num_vars = 0;
|
||||
nir_variable *in[VARYING_SLOT_MAX];
|
||||
nir_variable *out[VARYING_SLOT_MAX];
|
||||
|
||||
|
||||
builder = nir_builder_init_simple_shader(MESA_SHADER_GEOMETRY,
|
||||
dxil_get_base_nir_compiler_options(),
|
||||
"implicit_gs");
|
||||
|
||||
nir_shader *nir = b->shader;
|
||||
nir->info.inputs_read = nir->info.outputs_written = previous_shader->info.outputs_written;
|
||||
nir->info.outputs_written |= (1ull << VARYING_SLOT_VAR12);
|
||||
nir->info.gs.input_primitive = MESA_PRIM_TRIANGLES;
|
||||
nir->info.gs.output_primitive = MESA_PRIM_POINTS;
|
||||
nir->info.gs.vertices_in = 3;
|
||||
nir->info.gs.vertices_out = 3;
|
||||
nir->info.gs.invocations = 1;
|
||||
nir->info.gs.active_stream_mask = 1;
|
||||
|
||||
nir_foreach_shader_out_variable(var, previous_shader) {
|
||||
char tmp[100];
|
||||
snprintf(tmp, ARRAY_SIZE(tmp), "in_%d", num_vars);
|
||||
in[num_vars] = nir_variable_create(nir,
|
||||
nir_var_shader_in,
|
||||
glsl_array_type(var->type, 3, 0),
|
||||
tmp);
|
||||
in[num_vars]->data = var->data;
|
||||
in[num_vars]->data.mode = nir_var_shader_in;
|
||||
|
||||
if (var->data.location == VARYING_SLOT_POS)
|
||||
pos_var = in[num_vars];
|
||||
|
||||
snprintf(tmp, ARRAY_SIZE(tmp), "out_%d", num_vars);
|
||||
out[num_vars] = nir_variable_create(nir, nir_var_shader_out, var->type, tmp);
|
||||
out[num_vars]->data = var->data;
|
||||
|
||||
num_vars++;
|
||||
}
|
||||
|
||||
nir_variable *front_facing_var = nir_variable_create(nir,
|
||||
nir_var_shader_out,
|
||||
glsl_uint_type(),
|
||||
"gl_FrontFacing");
|
||||
front_facing_var->data.location = VARYING_SLOT_VAR12;
|
||||
front_facing_var->data.driver_location = num_vars;
|
||||
front_facing_var->data.interpolation = INTERP_MODE_FLAT;
|
||||
|
||||
nir_def *depth_bias_scale = NULL;
|
||||
if (info->depth_bias) {
|
||||
switch (info->ds_fmt) {
|
||||
case DXGI_FORMAT_D16_UNORM:
|
||||
depth_bias_scale = nir_imm_float(b, 1.0f / (1 << 16));
|
||||
break;
|
||||
case DXGI_FORMAT_D24_UNORM_S8_UINT:
|
||||
depth_bias_scale = nir_imm_float(b, 1.0f / (1 << 24));
|
||||
break;
|
||||
case DXGI_FORMAT_D32_FLOAT:
|
||||
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: {
|
||||
nir_deref_instr *deref_pos = nir_build_deref_var(b, pos_var);
|
||||
nir_def *max_z = NULL;
|
||||
for (uint32_t i = 0; i < 3; ++i) {
|
||||
nir_def *pos = nir_load_deref(b, nir_build_deref_array_imm(b, deref_pos, i));
|
||||
nir_def *z = nir_iand_imm(b, nir_channel(b, pos, 2), 0x7fffffff);
|
||||
max_z = i == 0 ? z : nir_imax(b, z, max_z);
|
||||
}
|
||||
nir_def *exponent = nir_ishr_imm(b, nir_iand_imm(b, max_z, 0x7f800000), 23);
|
||||
depth_bias_scale = nir_fexp2(b, nir_i2f32(b, nir_iadd_imm(b, exponent, -23)));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
depth_bias_scale = nir_imm_float(b, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/* Temporary variable "loop_index" to loop over input vertices */
|
||||
nir_function_impl *impl = nir_shader_get_entrypoint(nir);
|
||||
nir_variable *loop_index_var =
|
||||
nir_local_variable_create(impl, glsl_uint_type(), "loop_index");
|
||||
nir_deref_instr *loop_index_deref = nir_build_deref_var(b, loop_index_var);
|
||||
nir_store_deref(b, loop_index_deref, nir_imm_int(b, 0), 1);
|
||||
|
||||
nir_def *cull_pass = nir_imm_true(b);
|
||||
nir_def *front_facing;
|
||||
assert(info->cull_mode != VK_CULL_MODE_FRONT_AND_BACK);
|
||||
if (info->cull_mode == VK_CULL_MODE_FRONT_BIT) {
|
||||
cull_pass = cull_face(b, pos_var, info->front_ccw);
|
||||
front_facing = nir_b2i32(b, cull_pass);
|
||||
} else if (info->cull_mode == VK_CULL_MODE_BACK_BIT) {
|
||||
cull_pass = cull_face(b, pos_var, !info->front_ccw);
|
||||
front_facing = nir_inot(b, nir_b2i32(b, cull_pass));
|
||||
} else
|
||||
front_facing = nir_i2i32(b, cull_face(b, pos_var, info->front_ccw));
|
||||
|
||||
/**
|
||||
* if (cull_pass) {
|
||||
* while {
|
||||
* if (loop_index >= 3)
|
||||
* break;
|
||||
*/
|
||||
nir_if *cull_check = nir_push_if(b, cull_pass);
|
||||
nir_loop *loop = nir_push_loop(b);
|
||||
|
||||
nir_def *loop_index = nir_load_deref(b, loop_index_deref);
|
||||
nir_def *cmp = nir_ige(b, loop_index,
|
||||
nir_imm_int(b, 3));
|
||||
nir_break_if(b, cmp);
|
||||
|
||||
/**
|
||||
* [...] // Copy all variables
|
||||
* EmitVertex();
|
||||
*/
|
||||
for (unsigned i = 0; i < num_vars; ++i) {
|
||||
nir_def *index = loop_index;
|
||||
nir_deref_instr *in_value = nir_build_deref_array(b, nir_build_deref_var(b, in[i]), index);
|
||||
if (in[i] == pos_var && info->depth_bias) {
|
||||
nir_def *bias_val;
|
||||
if (info->depth_bias_dynamic) {
|
||||
bias_val = load_dynamic_depth_bias(b, info);
|
||||
} else {
|
||||
assert(info->slope_scaled_depth_bias == 0.0f);
|
||||
bias_val = nir_imm_float(b, info->constant_depth_bias);
|
||||
}
|
||||
bias_val = nir_fmul(b, bias_val, depth_bias_scale);
|
||||
nir_def *old_val = nir_load_deref(b, in_value);
|
||||
nir_def *new_val = nir_vector_insert_imm(b, old_val,
|
||||
nir_fadd(b, nir_channel(b, old_val, 2), bias_val),
|
||||
2);
|
||||
nir_store_var(b, out[i], new_val, 0xf);
|
||||
} else {
|
||||
copy_vars(b, nir_build_deref_var(b, out[i]), in_value);
|
||||
}
|
||||
}
|
||||
nir_store_var(b, front_facing_var, front_facing, 0x1);
|
||||
nir_emit_vertex(b, 0);
|
||||
|
||||
/**
|
||||
* loop_index++;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
nir_store_deref(b, loop_index_deref, nir_iadd_imm(b, loop_index, 1), 1);
|
||||
nir_pop_loop(b, loop);
|
||||
nir_pop_if(b, cull_check);
|
||||
|
||||
nir_validate_shader(nir, "in dzn_nir_polygon_point_mode_gs");
|
||||
|
||||
NIR_PASS(_, nir, nir_lower_var_copies);
|
||||
return b->shader;
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef DZN_NIR_H
|
||||
#define DZN_NIR_H
|
||||
|
||||
#define D3D12_IGNORE_SDK_LAYERS
|
||||
#define COBJMACROS
|
||||
#include <unknwn.h>
|
||||
#include <directx/d3d12.h>
|
||||
|
||||
#include "nir.h"
|
||||
|
||||
struct dzn_indirect_draw_rewrite_params {
|
||||
uint32_t draw_buf_stride;
|
||||
};
|
||||
|
||||
struct dzn_indirect_draw_triangle_fan_rewrite_params {
|
||||
uint32_t draw_buf_stride;
|
||||
uint32_t triangle_fan_index_buf_stride;
|
||||
uint64_t triangle_fan_index_buf_start;
|
||||
};
|
||||
|
||||
struct dzn_indirect_draw_triangle_fan_prim_restart_rewrite_params {
|
||||
uint32_t draw_buf_stride;
|
||||
uint32_t triangle_fan_index_buf_stride;
|
||||
uint64_t triangle_fan_index_buf_start;
|
||||
uint64_t exec_buf_start;
|
||||
};
|
||||
|
||||
struct dzn_triangle_fan_rewrite_index_params {
|
||||
uint32_t first_index;
|
||||
};
|
||||
|
||||
struct dzn_triangle_fan_prim_restart_rewrite_index_params {
|
||||
uint32_t first_index;
|
||||
uint32_t index_count;
|
||||
};
|
||||
|
||||
struct dzn_indirect_triangle_fan_rewrite_index_exec_params {
|
||||
uint64_t new_index_buf;
|
||||
struct dzn_triangle_fan_rewrite_index_params params;
|
||||
struct {
|
||||
uint32_t x, y, z;
|
||||
} group_count;
|
||||
};
|
||||
|
||||
struct dzn_indirect_triangle_fan_prim_restart_rewrite_index_exec_params {
|
||||
uint64_t new_index_buf;
|
||||
struct dzn_triangle_fan_prim_restart_rewrite_index_params params;
|
||||
uint64_t index_count_ptr;
|
||||
struct {
|
||||
uint32_t x, y, z;
|
||||
} group_count;
|
||||
};
|
||||
|
||||
struct dzn_indirect_draw_type {
|
||||
union {
|
||||
struct {
|
||||
uint8_t indexed : 1;
|
||||
uint8_t indirect_count : 1;
|
||||
uint8_t draw_params : 1;
|
||||
uint8_t draw_id : 1;
|
||||
uint8_t triangle_fan : 1;
|
||||
uint8_t triangle_fan_primitive_restart : 1;
|
||||
};
|
||||
uint8_t value;
|
||||
};
|
||||
};
|
||||
#define DZN_NUM_INDIRECT_DRAW_TYPES (1 << 6)
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_indirect_draw_shader(struct dzn_indirect_draw_type type);
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_triangle_fan_rewrite_index_shader(uint8_t old_index_size);
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_triangle_fan_prim_restart_rewrite_index_shader(uint8_t old_index_size);
|
||||
|
||||
enum dzn_blit_resolve_mode {
|
||||
dzn_blit_resolve_none,
|
||||
dzn_blit_resolve_average,
|
||||
dzn_blit_resolve_min,
|
||||
dzn_blit_resolve_max,
|
||||
dzn_blit_resolve_sample_zero,
|
||||
};
|
||||
struct dzn_nir_blit_info {
|
||||
union {
|
||||
struct {
|
||||
uint32_t src_samples : 6;
|
||||
uint32_t loc : 4;
|
||||
uint32_t out_type : 4;
|
||||
uint32_t sampler_dim : 4;
|
||||
uint32_t src_is_array : 1;
|
||||
uint32_t resolve_mode : 3;
|
||||
uint32_t stencil_fallback : 1;
|
||||
uint32_t padding : 9;
|
||||
};
|
||||
const uint32_t hash_key;
|
||||
};
|
||||
};
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_blit_vs(void);
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_blit_fs(const struct dzn_nir_blit_info *info);
|
||||
|
||||
struct dzn_nir_point_gs_info {
|
||||
unsigned cull_mode;
|
||||
bool front_ccw;
|
||||
bool depth_bias;
|
||||
bool depth_bias_dynamic;
|
||||
DXGI_FORMAT ds_fmt;
|
||||
/* Constant values */
|
||||
float constant_depth_bias;
|
||||
float slope_scaled_depth_bias;
|
||||
float depth_bias_clamp;
|
||||
/* Used for loading dynamic values */
|
||||
struct {
|
||||
uint32_t register_space;
|
||||
uint32_t base_shader_register;
|
||||
} runtime_data_cbv;
|
||||
};
|
||||
nir_shader *
|
||||
dzn_nir_polygon_point_mode_gs(const nir_shader *vs, struct dzn_nir_point_gs_info *info);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef DZN_PHYSICAL_DEVICE_ENUM_H
|
||||
#define DZN_PHYSICAL_DEVICE_ENUM_H
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <wsl/winadapter.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct vk_instance;
|
||||
|
||||
struct dzn_physical_device_desc {
|
||||
uint32_t vendor_id;
|
||||
uint32_t device_id;
|
||||
uint32_t subsys_id;
|
||||
uint32_t revision;
|
||||
uint64_t shared_system_memory;
|
||||
uint64_t dedicated_system_memory;
|
||||
uint64_t dedicated_video_memory;
|
||||
LUID adapter_luid;
|
||||
bool is_warp;
|
||||
char description[128];
|
||||
};
|
||||
|
||||
struct d3d12_memory_info {
|
||||
uint64_t usage_local;
|
||||
uint64_t budget_local;
|
||||
uint64_t usage_nonlocal;
|
||||
uint64_t budget_nonlocal;
|
||||
uint64_t usage; // local + nonlocal
|
||||
uint64_t budget; // local + nonlocal
|
||||
};
|
||||
|
||||
VkResult
|
||||
dzn_enumerate_physical_devices_dxgi(struct vk_instance *instance);
|
||||
|
||||
VkResult
|
||||
dzn_enumerate_physical_devices_dxcore(struct vk_instance *instance);
|
||||
|
||||
void
|
||||
dzn_query_memory_info(IUnknown* unk, struct d3d12_memory_info* memory_info);
|
||||
|
||||
VkResult
|
||||
dzn_instance_add_physical_device(struct vk_instance *instance,
|
||||
IUnknown *adapter,
|
||||
const struct dzn_physical_device_desc *desc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DZN_PHYSICAL_DEVICE_ENUM_H */
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "dzn_private.h"
|
||||
#include "dzn_abi_helper.h"
|
||||
|
||||
#include "vk_alloc.h"
|
||||
#include "vk_debug_report.h"
|
||||
#include "vk_util.h"
|
||||
|
||||
#include "util/os_time.h"
|
||||
|
||||
static D3D12_QUERY_HEAP_TYPE
|
||||
dzn_query_pool_get_heap_type(VkQueryType in)
|
||||
{
|
||||
switch (in) {
|
||||
case VK_QUERY_TYPE_OCCLUSION: return D3D12_QUERY_HEAP_TYPE_OCCLUSION;
|
||||
case VK_QUERY_TYPE_PIPELINE_STATISTICS: return D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS;
|
||||
case VK_QUERY_TYPE_TIMESTAMP: return D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
|
||||
default: UNREACHABLE("Unsupported query type");
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_QUERY_TYPE
|
||||
dzn_query_pool_get_query_type(const struct dzn_query_pool *qpool,
|
||||
VkQueryControlFlags flags)
|
||||
{
|
||||
switch (qpool->heap_type) {
|
||||
case D3D12_QUERY_HEAP_TYPE_OCCLUSION:
|
||||
return flags & VK_QUERY_CONTROL_PRECISE_BIT ?
|
||||
D3D12_QUERY_TYPE_OCCLUSION : D3D12_QUERY_TYPE_BINARY_OCCLUSION;
|
||||
case D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS: return D3D12_QUERY_TYPE_PIPELINE_STATISTICS;
|
||||
case D3D12_QUERY_HEAP_TYPE_TIMESTAMP: return D3D12_QUERY_TYPE_TIMESTAMP;
|
||||
default: UNREACHABLE("Unsupported query type");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dzn_query_pool_destroy(struct dzn_query_pool *qpool,
|
||||
const VkAllocationCallbacks *alloc)
|
||||
{
|
||||
if (!qpool)
|
||||
return;
|
||||
|
||||
struct dzn_device *device = container_of(qpool->base.device, struct dzn_device, vk);
|
||||
|
||||
if (qpool->collect_map)
|
||||
ID3D12Resource_Unmap(qpool->collect_buffer, 0, NULL);
|
||||
|
||||
if (qpool->collect_buffer)
|
||||
ID3D12Resource_Release(qpool->collect_buffer);
|
||||
|
||||
if (qpool->resolve_buffer)
|
||||
ID3D12Resource_Release(qpool->resolve_buffer);
|
||||
|
||||
if (qpool->heap)
|
||||
ID3D12QueryHeap_Release(qpool->heap);
|
||||
|
||||
for (uint32_t q = 0; q < qpool->query_count; q++) {
|
||||
if (qpool->queries[q].fence)
|
||||
ID3D12Fence_Release(qpool->queries[q].fence);
|
||||
}
|
||||
|
||||
mtx_destroy(&qpool->queries_lock);
|
||||
vk_object_base_finish(&qpool->base);
|
||||
vk_free2(&device->vk.alloc, alloc, qpool);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_query_pool_create(struct dzn_device *device,
|
||||
const VkQueryPoolCreateInfo *info,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
VkQueryPool *out)
|
||||
{
|
||||
VK_MULTIALLOC(ma);
|
||||
VK_MULTIALLOC_DECL(&ma, struct dzn_query_pool, qpool, 1);
|
||||
VK_MULTIALLOC_DECL(&ma, struct dzn_query, queries, info->queryCount);
|
||||
|
||||
if (!vk_multialloc_zalloc2(&ma, &device->vk.alloc, alloc,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
vk_object_base_init(&device->vk, &qpool->base, VK_OBJECT_TYPE_QUERY_POOL);
|
||||
|
||||
mtx_init(&qpool->queries_lock, mtx_plain);
|
||||
qpool->query_count = info->queryCount;
|
||||
qpool->queries = queries;
|
||||
|
||||
D3D12_QUERY_HEAP_DESC desc = { 0 };
|
||||
qpool->heap_type = desc.Type = dzn_query_pool_get_heap_type(info->queryType);
|
||||
desc.Count = info->queryCount;
|
||||
desc.NodeMask = 0;
|
||||
|
||||
HRESULT hres =
|
||||
ID3D12Device1_CreateQueryHeap(device->dev, &desc,
|
||||
&IID_ID3D12QueryHeap,
|
||||
(void **)&qpool->heap);
|
||||
if (FAILED(hres)) {
|
||||
dzn_query_pool_destroy(qpool, alloc);
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
}
|
||||
|
||||
switch (info->queryType) {
|
||||
case VK_QUERY_TYPE_OCCLUSION:
|
||||
case VK_QUERY_TYPE_TIMESTAMP:
|
||||
qpool->query_size = sizeof(uint64_t);
|
||||
break;
|
||||
case VK_QUERY_TYPE_PIPELINE_STATISTICS:
|
||||
qpool->pipeline_statistics = info->pipelineStatistics;
|
||||
qpool->query_size = sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS);
|
||||
break;
|
||||
default: UNREACHABLE("Unsupported query type");
|
||||
}
|
||||
|
||||
D3D12_HEAP_PROPERTIES hprops =
|
||||
dzn_ID3D12Device4_GetCustomHeapProperties(device->dev, 0, D3D12_HEAP_TYPE_DEFAULT);
|
||||
D3D12_RESOURCE_DESC rdesc = {
|
||||
.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER,
|
||||
.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT,
|
||||
.Width = info->queryCount * qpool->query_size,
|
||||
.Height = 1,
|
||||
.DepthOrArraySize = 1,
|
||||
.MipLevels = 1,
|
||||
.Format = DXGI_FORMAT_UNKNOWN,
|
||||
.SampleDesc = { .Count = 1, .Quality = 0 },
|
||||
.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
|
||||
.Flags = D3D12_RESOURCE_FLAG_NONE,
|
||||
};
|
||||
|
||||
hres = ID3D12Device1_CreateCommittedResource(device->dev, &hprops,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&rdesc,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
NULL,
|
||||
&IID_ID3D12Resource,
|
||||
(void **)&qpool->resolve_buffer);
|
||||
if (FAILED(hres)) {
|
||||
dzn_query_pool_destroy(qpool, alloc);
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
}
|
||||
|
||||
hprops = dzn_ID3D12Device4_GetCustomHeapProperties(device->dev, 0,
|
||||
D3D12_HEAP_TYPE_READBACK);
|
||||
rdesc.Width = info->queryCount * (qpool->query_size + sizeof(uint64_t));
|
||||
hres = ID3D12Device1_CreateCommittedResource(device->dev, &hprops,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&rdesc,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
NULL,
|
||||
&IID_ID3D12Resource,
|
||||
(void **)&qpool->collect_buffer);
|
||||
if (FAILED(hres)) {
|
||||
dzn_query_pool_destroy(qpool, alloc);
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
}
|
||||
|
||||
hres = ID3D12Resource_Map(qpool->collect_buffer, 0, NULL, (void **)&qpool->collect_map);
|
||||
if (FAILED(hres)) {
|
||||
dzn_query_pool_destroy(qpool, alloc);
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
memset(qpool->collect_map, 0, rdesc.Width);
|
||||
|
||||
*out = dzn_query_pool_to_handle(qpool);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dzn_query_pool_get_result_offset(const struct dzn_query_pool *qpool, uint32_t query)
|
||||
{
|
||||
return query * qpool->query_size;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dzn_query_pool_get_result_size(const struct dzn_query_pool *qpool, uint32_t query_count)
|
||||
{
|
||||
return query_count * qpool->query_size;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dzn_query_pool_get_availability_offset(const struct dzn_query_pool *qpool, uint32_t query)
|
||||
{
|
||||
return (qpool->query_count * qpool->query_size) + (sizeof(uint64_t) * query);
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
dzn_CreateQueryPool(VkDevice device,
|
||||
const VkQueryPoolCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkQueryPool *pQueryPool)
|
||||
{
|
||||
return dzn_query_pool_create(dzn_device_from_handle(device),
|
||||
pCreateInfo, pAllocator, pQueryPool);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
dzn_DestroyQueryPool(VkDevice device,
|
||||
VkQueryPool queryPool,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
dzn_query_pool_destroy(dzn_query_pool_from_handle(queryPool), pAllocator);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
dzn_ResetQueryPool(VkDevice device,
|
||||
VkQueryPool queryPool,
|
||||
uint32_t firstQuery,
|
||||
uint32_t queryCount)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_query_pool, qpool, queryPool);
|
||||
|
||||
mtx_lock(&qpool->queries_lock);
|
||||
for (uint32_t q = 0; q < queryCount; q++) {
|
||||
struct dzn_query *query = &qpool->queries[firstQuery + q];
|
||||
|
||||
query->fence_value = 0;
|
||||
if (query->fence) {
|
||||
ID3D12Fence_Release(query->fence);
|
||||
query->fence = NULL;
|
||||
}
|
||||
}
|
||||
mtx_unlock(&qpool->queries_lock);
|
||||
|
||||
memset((uint8_t *)qpool->collect_map + dzn_query_pool_get_result_offset(qpool, firstQuery),
|
||||
0, queryCount * qpool->query_size);
|
||||
memset((uint8_t *)qpool->collect_map + dzn_query_pool_get_availability_offset(qpool, firstQuery),
|
||||
0, queryCount * sizeof(uint64_t));
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
dzn_GetQueryPoolResults(VkDevice device,
|
||||
VkQueryPool queryPool,
|
||||
uint32_t firstQuery,
|
||||
uint32_t queryCount,
|
||||
size_t dataSize,
|
||||
void *pData,
|
||||
VkDeviceSize stride,
|
||||
VkQueryResultFlags flags)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_query_pool, qpool, queryPool);
|
||||
|
||||
uint32_t step = (flags & VK_QUERY_RESULT_64_BIT) ?
|
||||
sizeof(uint64_t) : sizeof(uint32_t);
|
||||
VkResult result = VK_SUCCESS;
|
||||
|
||||
for (uint32_t q = 0; q < queryCount; q++) {
|
||||
struct dzn_query *query = &qpool->queries[q + firstQuery];
|
||||
|
||||
uint8_t *dst_ptr = (uint8_t *)pData + (stride * q);
|
||||
uint8_t *src_ptr =
|
||||
(uint8_t *)qpool->collect_map +
|
||||
dzn_query_pool_get_result_offset(qpool, firstQuery + q);
|
||||
uint64_t available = 0;
|
||||
|
||||
if (flags & VK_QUERY_RESULT_WAIT_BIT) {
|
||||
ID3D12Fence *query_fence = NULL;
|
||||
uint64_t query_fence_val = 0;
|
||||
|
||||
while (true) {
|
||||
mtx_lock(&qpool->queries_lock);
|
||||
if (query->fence) {
|
||||
query_fence = query->fence;
|
||||
ID3D12Fence_AddRef(query_fence);
|
||||
}
|
||||
query_fence_val = query->fence_value;
|
||||
mtx_unlock(&qpool->queries_lock);
|
||||
|
||||
if (query_fence)
|
||||
break;
|
||||
|
||||
/* Check again in 10ms.
|
||||
* FIXME: decrease the polling period if it happens to hurt latency.
|
||||
*/
|
||||
os_time_sleep(10 * 1000);
|
||||
}
|
||||
|
||||
ID3D12Fence_SetEventOnCompletion(query_fence, query_fence_val, NULL);
|
||||
ID3D12Fence_Release(query_fence);
|
||||
available = UINT64_MAX;
|
||||
} else {
|
||||
ID3D12Fence *query_fence = NULL;
|
||||
mtx_lock(&qpool->queries_lock);
|
||||
if (query->fence) {
|
||||
query_fence = query->fence;
|
||||
ID3D12Fence_AddRef(query_fence);
|
||||
}
|
||||
uint64_t query_fence_val = query->fence_value;
|
||||
mtx_unlock(&qpool->queries_lock);
|
||||
|
||||
if (query_fence) {
|
||||
if (ID3D12Fence_GetCompletedValue(query_fence) >= query_fence_val)
|
||||
available = UINT64_MAX;
|
||||
ID3D12Fence_Release(query_fence);
|
||||
}
|
||||
}
|
||||
|
||||
if (qpool->heap_type != D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS) {
|
||||
if (available)
|
||||
memcpy(dst_ptr, src_ptr, step);
|
||||
else if (flags & VK_QUERY_RESULT_PARTIAL_BIT)
|
||||
memset(dst_ptr, 0, step);
|
||||
|
||||
dst_ptr += step;
|
||||
} else {
|
||||
for (uint32_t c = 0; c < sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS) / sizeof(uint64_t); c++) {
|
||||
if (!(BITFIELD_BIT(c) & qpool->pipeline_statistics))
|
||||
continue;
|
||||
|
||||
if (available)
|
||||
memcpy(dst_ptr, src_ptr + (c * sizeof(uint64_t)), step);
|
||||
else if (flags & VK_QUERY_RESULT_PARTIAL_BIT)
|
||||
memset(dst_ptr, 0, step);
|
||||
|
||||
dst_ptr += step;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)
|
||||
memcpy(dst_ptr, &available, step);
|
||||
|
||||
if (!available && !(flags & VK_QUERY_RESULT_PARTIAL_BIT))
|
||||
result = VK_NOT_READY;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "dzn_private.h"
|
||||
|
||||
#include "vk_alloc.h"
|
||||
#include "vk_debug_report.h"
|
||||
#include "vk_util.h"
|
||||
|
||||
#include "util/macros.h"
|
||||
#include "util/os_time.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/eventfd.h>
|
||||
#include <libsync.h>
|
||||
#endif
|
||||
|
||||
static VkResult
|
||||
dzn_sync_init(struct vk_device *device,
|
||||
struct vk_sync *sync,
|
||||
uint64_t initial_value)
|
||||
{
|
||||
struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
|
||||
struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
|
||||
|
||||
D3D12_FENCE_FLAGS flags = (sync->flags & VK_SYNC_IS_SHAREABLE) ?
|
||||
D3D12_FENCE_FLAG_SHARED : D3D12_FENCE_FLAG_NONE;
|
||||
|
||||
if (FAILED(ID3D12Device1_CreateFence(ddev->dev, initial_value,
|
||||
flags,
|
||||
&IID_ID3D12Fence,
|
||||
(void **)&dsync->fence)))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
dzn_sync_finish(struct vk_device *device,
|
||||
struct vk_sync *sync)
|
||||
{
|
||||
struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
|
||||
|
||||
ID3D12Fence_Release(dsync->fence);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (dsync->export_handle)
|
||||
CloseHandle(dsync->export_handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_sync_signal(struct vk_device *device,
|
||||
struct vk_sync *sync,
|
||||
uint64_t value)
|
||||
{
|
||||
struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
|
||||
|
||||
if (!(sync->flags & VK_SYNC_IS_TIMELINE))
|
||||
value = 1;
|
||||
|
||||
if (FAILED(ID3D12Fence_Signal(dsync->fence, value)))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_sync_get_value(struct vk_device *device,
|
||||
struct vk_sync *sync,
|
||||
uint64_t *value)
|
||||
{
|
||||
struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
|
||||
|
||||
*value = ID3D12Fence_GetCompletedValue(dsync->fence);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_sync_reset(struct vk_device *device,
|
||||
struct vk_sync *sync)
|
||||
{
|
||||
struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
|
||||
|
||||
if (FAILED(ID3D12Fence_Signal(dsync->fence, 0)))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_sync_move(struct vk_device *device,
|
||||
struct vk_sync *dst,
|
||||
struct vk_sync *src)
|
||||
{
|
||||
struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
|
||||
struct dzn_sync *ddst = container_of(dst, struct dzn_sync, vk);
|
||||
struct dzn_sync *dsrc = container_of(src, struct dzn_sync, vk);
|
||||
ID3D12Fence *new_fence;
|
||||
|
||||
if (FAILED(ID3D12Device1_CreateFence(ddev->dev, 0,
|
||||
D3D12_FENCE_FLAG_NONE,
|
||||
&IID_ID3D12Fence,
|
||||
(void **)&new_fence)))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
|
||||
ID3D12Fence_Release(ddst->fence);
|
||||
ddst->fence = dsrc->fence;
|
||||
dsrc->fence = new_fence;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_sync_wait(struct vk_device *device,
|
||||
uint32_t wait_count,
|
||||
const struct vk_sync_wait *waits,
|
||||
enum vk_sync_wait_flags wait_flags,
|
||||
uint64_t abs_timeout_ns)
|
||||
{
|
||||
struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE event = CreateEventA(NULL, false, false, NULL);
|
||||
if (event == NULL)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
#else
|
||||
int event_fd = eventfd(0, EFD_CLOEXEC);
|
||||
if (event_fd == -1)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
/* The D3D12 event-based APIs in WSL expect an eventfd file descriptor cast to HANDLE */
|
||||
HANDLE event = (HANDLE)(intptr_t)event_fd;
|
||||
#endif
|
||||
|
||||
STACK_ARRAY(ID3D12Fence *, fences, wait_count);
|
||||
STACK_ARRAY(uint64_t, values, wait_count);
|
||||
|
||||
for (uint32_t i = 0; i < wait_count; i++) {
|
||||
struct dzn_sync *sync = container_of(waits[i].sync, struct dzn_sync, vk);
|
||||
|
||||
fences[i] = sync->fence;
|
||||
values[i] = (sync->vk.flags & VK_SYNC_IS_TIMELINE) ? waits[i].wait_value : 1;
|
||||
}
|
||||
|
||||
D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags =
|
||||
(wait_flags & VK_SYNC_WAIT_ANY) ?
|
||||
D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY :
|
||||
D3D12_MULTIPLE_FENCE_WAIT_FLAG_ALL;
|
||||
|
||||
if (FAILED(ID3D12Device1_SetEventOnMultipleFenceCompletion(ddev->dev,
|
||||
fences,
|
||||
values,
|
||||
wait_count,
|
||||
flags,
|
||||
event))) {
|
||||
STACK_ARRAY_FINISH(fences);
|
||||
STACK_ARRAY_FINISH(values);
|
||||
#ifdef _WIN32
|
||||
CloseHandle(event);
|
||||
#else
|
||||
close(event_fd);
|
||||
#endif
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD timeout_ms;
|
||||
static const DWORD timeout_infinite = INFINITE;
|
||||
#else
|
||||
int timeout_ms;
|
||||
static const int timeout_infinite = -1;
|
||||
#endif
|
||||
|
||||
if (abs_timeout_ns == OS_TIMEOUT_INFINITE) {
|
||||
timeout_ms = timeout_infinite;
|
||||
} else {
|
||||
uint64_t cur_time = os_time_get_nano();
|
||||
uint64_t rel_timeout_ns =
|
||||
abs_timeout_ns > cur_time ? abs_timeout_ns - cur_time : 0;
|
||||
|
||||
timeout_ms = (rel_timeout_ns / 1000000) + (rel_timeout_ns % 1000000 ? 1 : 0);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD res =
|
||||
WaitForSingleObject(event, timeout_ms);
|
||||
|
||||
CloseHandle(event);
|
||||
VkResult ret = VK_SUCCESS;
|
||||
if (res == WAIT_TIMEOUT)
|
||||
ret = VK_TIMEOUT;
|
||||
else if (res != WAIT_OBJECT_0)
|
||||
ret = vk_error(device, VK_ERROR_UNKNOWN);
|
||||
#else
|
||||
VkResult ret = sync_wait(event_fd, timeout_ms) != 0 ? VK_TIMEOUT : VK_SUCCESS;
|
||||
close(event_fd);
|
||||
#endif
|
||||
|
||||
STACK_ARRAY_FINISH(fences);
|
||||
STACK_ARRAY_FINISH(values);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static VkResult
|
||||
dzn_sync_import_win32_handle(struct vk_device *device, struct vk_sync *sync,
|
||||
HANDLE handle, LPCWSTR name)
|
||||
{
|
||||
struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
|
||||
struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
|
||||
|
||||
dzn_sync_finish(device, sync);
|
||||
|
||||
HANDLE handle_to_close = NULL;
|
||||
if (name) {
|
||||
if (FAILED(ID3D12Device_OpenSharedHandleByName(ddev->dev, name, GENERIC_ALL, &handle_to_close)))
|
||||
return vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
||||
handle = handle_to_close;
|
||||
}
|
||||
|
||||
HRESULT hr = ID3D12Device_OpenSharedHandle(ddev->dev, handle, &IID_ID3D12Fence, (void **)&dsync->fence);
|
||||
if (handle_to_close)
|
||||
CloseHandle(handle_to_close);
|
||||
if (FAILED(hr))
|
||||
return vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_sync_export_win32_handle(struct vk_device *device, struct vk_sync *sync, HANDLE *handle)
|
||||
{
|
||||
struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
|
||||
if (dsync->export_handle) {
|
||||
if (!DuplicateHandle(GetCurrentProcess(), dsync->export_handle,
|
||||
GetCurrentProcess(), handle,
|
||||
0, false, DUPLICATE_SAME_ACCESS))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
|
||||
if (FAILED(ID3D12Device_CreateSharedHandle(ddev->dev, (ID3D12DeviceChild *)dsync->fence,
|
||||
NULL, GENERIC_ALL, NULL, handle)))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_sync_prep_win32_export(struct vk_device *device, struct vk_sync *sync,
|
||||
const void *security_attributes, uint32_t access,
|
||||
const wchar_t *name)
|
||||
{
|
||||
struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
|
||||
struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
|
||||
if (FAILED(ID3D12Device_CreateSharedHandle(ddev->dev, (ID3D12DeviceChild *)dsync->fence,
|
||||
(const LPSECURITY_ATTRIBUTES)security_attributes,
|
||||
GENERIC_ALL, name, &dsync->export_handle)))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static VkResult
|
||||
dzn_sync_import_opaque_fd(struct vk_device *device, struct vk_sync *sync,
|
||||
int fd)
|
||||
{
|
||||
struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
|
||||
struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
|
||||
|
||||
dzn_sync_finish(device, sync);
|
||||
|
||||
HANDLE handle = (HANDLE)(intptr_t)fd;
|
||||
if (FAILED(ID3D12Device_OpenSharedHandle(ddev->dev, handle, &IID_ID3D12Fence, (void **)&dsync->fence)))
|
||||
return vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_sync_export_opaque_fd(struct vk_device *device, struct vk_sync *sync, int *fd)
|
||||
{
|
||||
struct dzn_sync *dsync = container_of(sync, struct dzn_sync, vk);
|
||||
struct dzn_device *ddev = container_of(device, struct dzn_device, vk);
|
||||
HANDLE handle;
|
||||
if (FAILED(ID3D12Device_CreateSharedHandle(ddev->dev, (ID3D12DeviceChild *)dsync->fence,
|
||||
NULL, GENERIC_ALL, NULL, &handle)))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
*fd = (int)(intptr_t)handle;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
const struct vk_sync_type dzn_sync_type = {
|
||||
.size = sizeof(struct dzn_sync),
|
||||
.features = (enum vk_sync_features)
|
||||
(VK_SYNC_FEATURE_TIMELINE |
|
||||
VK_SYNC_FEATURE_GPU_WAIT |
|
||||
VK_SYNC_FEATURE_CPU_WAIT |
|
||||
VK_SYNC_FEATURE_CPU_SIGNAL |
|
||||
VK_SYNC_FEATURE_WAIT_ANY |
|
||||
VK_SYNC_FEATURE_WAIT_BEFORE_SIGNAL),
|
||||
|
||||
.init = dzn_sync_init,
|
||||
.finish = dzn_sync_finish,
|
||||
.signal = dzn_sync_signal,
|
||||
.get_value = dzn_sync_get_value,
|
||||
.reset = dzn_sync_reset,
|
||||
.move = dzn_sync_move,
|
||||
.wait_many = dzn_sync_wait,
|
||||
#ifdef _WIN32
|
||||
.import_win32_handle = dzn_sync_import_win32_handle,
|
||||
.export_win32_handle = dzn_sync_export_win32_handle,
|
||||
.set_win32_export_params = dzn_sync_prep_win32_export,
|
||||
#else
|
||||
.import_opaque_fd = dzn_sync_import_opaque_fd,
|
||||
.export_opaque_fd = dzn_sync_export_opaque_fd,
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,407 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "dzn_private.h"
|
||||
|
||||
#define D3D12_IGNORE_SDK_LAYERS
|
||||
#define COBJMACROS
|
||||
#include <directx/d3d12.h>
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "util/format/u_format.h"
|
||||
#include "util/log.h"
|
||||
|
||||
#include <directx/d3d12sdklayers.h>
|
||||
#include <util/u_dl.h>
|
||||
|
||||
static const DXGI_FORMAT formats[PIPE_FORMAT_COUNT] = {
|
||||
#define MAP_FORMAT_NORM(FMT) \
|
||||
[PIPE_FORMAT_ ## FMT ## _UNORM] = DXGI_FORMAT_ ## FMT ## _UNORM, \
|
||||
[PIPE_FORMAT_ ## FMT ## _SNORM] = DXGI_FORMAT_ ## FMT ## _SNORM,
|
||||
|
||||
#define MAP_FORMAT_INT(FMT) \
|
||||
[PIPE_FORMAT_ ## FMT ## _UINT] = DXGI_FORMAT_ ## FMT ## _UINT, \
|
||||
[PIPE_FORMAT_ ## FMT ## _SINT] = DXGI_FORMAT_ ## FMT ## _SINT,
|
||||
|
||||
#define MAP_FORMAT_SRGB(FMT) \
|
||||
[PIPE_FORMAT_ ## FMT ## _SRGB] = DXGI_FORMAT_ ## FMT ## _UNORM_SRGB,
|
||||
|
||||
#define MAP_FORMAT_FLOAT(FMT) \
|
||||
[PIPE_FORMAT_ ## FMT ## _FLOAT] = DXGI_FORMAT_ ## FMT ## _FLOAT,
|
||||
|
||||
#define MAP_EMU_FORMAT_NO_ALPHA(BITS, TYPE) \
|
||||
[PIPE_FORMAT_L ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \
|
||||
[PIPE_FORMAT_I ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \
|
||||
[PIPE_FORMAT_L ## BITS ## A ## BITS ## _ ## TYPE] = \
|
||||
DXGI_FORMAT_R ## BITS ## G ## BITS ## _ ## TYPE,
|
||||
|
||||
#define MAP_EMU_FORMAT(BITS, TYPE) \
|
||||
[PIPE_FORMAT_A ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \
|
||||
MAP_EMU_FORMAT_NO_ALPHA(BITS, TYPE)
|
||||
|
||||
MAP_FORMAT_NORM(R8)
|
||||
MAP_FORMAT_INT(R8)
|
||||
|
||||
MAP_FORMAT_NORM(R8G8)
|
||||
MAP_FORMAT_INT(R8G8)
|
||||
|
||||
MAP_FORMAT_NORM(R8G8B8A8)
|
||||
MAP_FORMAT_INT(R8G8B8A8)
|
||||
MAP_FORMAT_SRGB(R8G8B8A8)
|
||||
|
||||
[PIPE_FORMAT_B8G8R8X8_UNORM] = DXGI_FORMAT_B8G8R8X8_UNORM,
|
||||
[PIPE_FORMAT_B8G8R8A8_UNORM] = DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
[PIPE_FORMAT_B4G4R4A4_UNORM] = DXGI_FORMAT_B4G4R4A4_UNORM,
|
||||
[PIPE_FORMAT_A4R4G4B4_UNORM] = DXGI_FORMAT_A4B4G4R4_UNORM,
|
||||
[PIPE_FORMAT_A4B4G4R4_UNORM] = DXGI_FORMAT_A4B4G4R4_UNORM,
|
||||
[PIPE_FORMAT_B5G6R5_UNORM] = DXGI_FORMAT_B5G6R5_UNORM,
|
||||
[PIPE_FORMAT_B5G5R5A1_UNORM] = DXGI_FORMAT_B5G5R5A1_UNORM,
|
||||
|
||||
MAP_FORMAT_SRGB(B8G8R8A8)
|
||||
|
||||
MAP_FORMAT_INT(R32)
|
||||
MAP_FORMAT_FLOAT(R32)
|
||||
MAP_FORMAT_INT(R32G32)
|
||||
MAP_FORMAT_FLOAT(R32G32)
|
||||
MAP_FORMAT_INT(R32G32B32)
|
||||
MAP_FORMAT_FLOAT(R32G32B32)
|
||||
MAP_FORMAT_INT(R32G32B32A32)
|
||||
MAP_FORMAT_FLOAT(R32G32B32A32)
|
||||
|
||||
MAP_FORMAT_NORM(R16)
|
||||
MAP_FORMAT_INT(R16)
|
||||
MAP_FORMAT_FLOAT(R16)
|
||||
|
||||
MAP_FORMAT_NORM(R16G16)
|
||||
MAP_FORMAT_INT(R16G16)
|
||||
MAP_FORMAT_FLOAT(R16G16)
|
||||
|
||||
MAP_FORMAT_NORM(R16G16B16A16)
|
||||
MAP_FORMAT_INT(R16G16B16A16)
|
||||
MAP_FORMAT_FLOAT(R16G16B16A16)
|
||||
|
||||
[PIPE_FORMAT_A8_UNORM] = DXGI_FORMAT_A8_UNORM,
|
||||
MAP_EMU_FORMAT_NO_ALPHA(8, UNORM)
|
||||
MAP_EMU_FORMAT(8, SNORM)
|
||||
MAP_EMU_FORMAT(8, SINT)
|
||||
MAP_EMU_FORMAT(8, UINT)
|
||||
MAP_EMU_FORMAT(16, UNORM)
|
||||
MAP_EMU_FORMAT(16, SNORM)
|
||||
MAP_EMU_FORMAT(16, SINT)
|
||||
MAP_EMU_FORMAT(16, UINT)
|
||||
MAP_EMU_FORMAT(16, FLOAT)
|
||||
MAP_EMU_FORMAT(32, SINT)
|
||||
MAP_EMU_FORMAT(32, UINT)
|
||||
MAP_EMU_FORMAT(32, FLOAT)
|
||||
|
||||
[PIPE_FORMAT_R9G9B9E5_FLOAT] = DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
|
||||
[PIPE_FORMAT_R11G11B10_FLOAT] = DXGI_FORMAT_R11G11B10_FLOAT,
|
||||
[PIPE_FORMAT_R10G10B10A2_UINT] = DXGI_FORMAT_R10G10B10A2_UINT,
|
||||
[PIPE_FORMAT_R10G10B10A2_UNORM] = DXGI_FORMAT_R10G10B10A2_UNORM,
|
||||
|
||||
[PIPE_FORMAT_DXT1_RGB] = DXGI_FORMAT_BC1_UNORM,
|
||||
[PIPE_FORMAT_DXT1_RGBA] = DXGI_FORMAT_BC1_UNORM,
|
||||
[PIPE_FORMAT_DXT3_RGBA] = DXGI_FORMAT_BC2_UNORM,
|
||||
[PIPE_FORMAT_DXT5_RGBA] = DXGI_FORMAT_BC3_UNORM,
|
||||
|
||||
[PIPE_FORMAT_DXT1_SRGB] = DXGI_FORMAT_BC1_UNORM_SRGB,
|
||||
[PIPE_FORMAT_DXT1_SRGBA] = DXGI_FORMAT_BC1_UNORM_SRGB,
|
||||
[PIPE_FORMAT_DXT3_SRGBA] = DXGI_FORMAT_BC2_UNORM_SRGB,
|
||||
[PIPE_FORMAT_DXT5_SRGBA] = DXGI_FORMAT_BC3_UNORM_SRGB,
|
||||
|
||||
[PIPE_FORMAT_RGTC1_UNORM] = DXGI_FORMAT_BC4_UNORM,
|
||||
[PIPE_FORMAT_RGTC1_SNORM] = DXGI_FORMAT_BC4_SNORM,
|
||||
[PIPE_FORMAT_RGTC2_UNORM] = DXGI_FORMAT_BC5_UNORM,
|
||||
[PIPE_FORMAT_RGTC2_SNORM] = DXGI_FORMAT_BC5_SNORM,
|
||||
|
||||
[PIPE_FORMAT_BPTC_RGB_UFLOAT] = DXGI_FORMAT_BC6H_UF16,
|
||||
[PIPE_FORMAT_BPTC_RGB_FLOAT] = DXGI_FORMAT_BC6H_SF16,
|
||||
[PIPE_FORMAT_BPTC_RGBA_UNORM] = DXGI_FORMAT_BC7_UNORM,
|
||||
[PIPE_FORMAT_BPTC_SRGBA] = DXGI_FORMAT_BC7_UNORM_SRGB,
|
||||
|
||||
[PIPE_FORMAT_Z32_FLOAT] = DXGI_FORMAT_R32_TYPELESS,
|
||||
[PIPE_FORMAT_Z16_UNORM] = DXGI_FORMAT_R16_TYPELESS,
|
||||
[PIPE_FORMAT_Z24X8_UNORM] = DXGI_FORMAT_R24G8_TYPELESS,
|
||||
[PIPE_FORMAT_X24S8_UINT] = DXGI_FORMAT_R24G8_TYPELESS,
|
||||
|
||||
[PIPE_FORMAT_Z24_UNORM_S8_UINT] = DXGI_FORMAT_R24G8_TYPELESS,
|
||||
[PIPE_FORMAT_Z32_FLOAT_S8X24_UINT] = DXGI_FORMAT_R32G8X24_TYPELESS,
|
||||
[PIPE_FORMAT_X32_S8X24_UINT] = DXGI_FORMAT_R32G8X24_TYPELESS,
|
||||
};
|
||||
|
||||
DXGI_FORMAT
|
||||
dzn_pipe_to_dxgi_format(enum pipe_format in)
|
||||
{
|
||||
return formats[in];
|
||||
}
|
||||
|
||||
DXGI_FORMAT
|
||||
dzn_get_typeless_dxgi_format(DXGI_FORMAT in)
|
||||
{
|
||||
if (in >= DXGI_FORMAT_R32G32B32A32_TYPELESS && in <= DXGI_FORMAT_R32G32B32A32_SINT)
|
||||
return DXGI_FORMAT_R32G32B32A32_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_R32G32B32_TYPELESS && in <= DXGI_FORMAT_R32G32B32_SINT)
|
||||
return DXGI_FORMAT_R32G32B32_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_R16G16B16A16_TYPELESS && in <= DXGI_FORMAT_R16G16B16A16_SINT)
|
||||
return DXGI_FORMAT_R16G16B16A16_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_R32G32_TYPELESS && in <= DXGI_FORMAT_R32G32_SINT)
|
||||
return DXGI_FORMAT_R32G32_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_R32G8X24_TYPELESS && in <= DXGI_FORMAT_X32_TYPELESS_G8X24_UINT)
|
||||
return DXGI_FORMAT_R32G8X24_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_R10G10B10A2_TYPELESS && in <= DXGI_FORMAT_R10G10B10A2_UINT)
|
||||
return DXGI_FORMAT_R10G10B10A2_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_R8G8B8A8_TYPELESS && in <= DXGI_FORMAT_R8G8B8A8_SINT)
|
||||
return DXGI_FORMAT_R8G8B8A8_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_R16G16_TYPELESS && in <= DXGI_FORMAT_R16G16_SINT)
|
||||
return DXGI_FORMAT_R16G16_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_R32_TYPELESS && in <= DXGI_FORMAT_R32_SINT)
|
||||
return DXGI_FORMAT_R32_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_R24G8_TYPELESS && in <= DXGI_FORMAT_X24_TYPELESS_G8_UINT)
|
||||
return DXGI_FORMAT_R24G8_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_R8G8_TYPELESS && in <= DXGI_FORMAT_R8G8_SINT)
|
||||
return DXGI_FORMAT_R8G8_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_R16_TYPELESS && in <= DXGI_FORMAT_R16_SINT)
|
||||
return DXGI_FORMAT_R16_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_R8_TYPELESS && in <= DXGI_FORMAT_R8_SINT)
|
||||
return DXGI_FORMAT_R8_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_BC1_TYPELESS && in <= DXGI_FORMAT_BC1_UNORM_SRGB)
|
||||
return DXGI_FORMAT_BC1_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_BC2_TYPELESS && in <= DXGI_FORMAT_BC2_UNORM_SRGB)
|
||||
return DXGI_FORMAT_BC2_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_BC3_TYPELESS && in <= DXGI_FORMAT_BC3_UNORM_SRGB)
|
||||
return DXGI_FORMAT_BC3_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_BC4_TYPELESS && in <= DXGI_FORMAT_BC4_SNORM)
|
||||
return DXGI_FORMAT_BC4_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_BC5_TYPELESS && in <= DXGI_FORMAT_BC5_SNORM)
|
||||
return DXGI_FORMAT_BC5_TYPELESS;
|
||||
if (in == DXGI_FORMAT_B8G8R8A8_UNORM ||
|
||||
(in >= DXGI_FORMAT_B8G8R8A8_TYPELESS && in <= DXGI_FORMAT_B8G8R8A8_UNORM_SRGB))
|
||||
return DXGI_FORMAT_B8G8R8A8_TYPELESS;
|
||||
if (in == DXGI_FORMAT_B8G8R8X8_UNORM ||
|
||||
(in >= DXGI_FORMAT_B8G8R8X8_TYPELESS && in <= DXGI_FORMAT_B8G8R8X8_UNORM_SRGB))
|
||||
return DXGI_FORMAT_B8G8R8X8_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_BC6H_TYPELESS && in <= DXGI_FORMAT_BC6H_SF16)
|
||||
return DXGI_FORMAT_BC6H_TYPELESS;
|
||||
if (in >= DXGI_FORMAT_BC7_TYPELESS && in <= DXGI_FORMAT_BC7_UNORM_SRGB)
|
||||
return DXGI_FORMAT_BC7_TYPELESS;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
static D3D12_FILTER_TYPE
|
||||
translate_filter_type(VkFilter type)
|
||||
{
|
||||
switch (type) {
|
||||
case VK_FILTER_NEAREST: return D3D12_FILTER_TYPE_POINT;
|
||||
case VK_FILTER_LINEAR: return D3D12_FILTER_TYPE_LINEAR;
|
||||
default:
|
||||
assert(!"Unsupported filter mode");
|
||||
return D3D12_FILTER_TYPE_POINT;
|
||||
}
|
||||
}
|
||||
|
||||
static D3D12_FILTER_TYPE
|
||||
translate_mip_filter_type(VkSamplerMipmapMode type)
|
||||
{
|
||||
switch (type) {
|
||||
case VK_SAMPLER_MIPMAP_MODE_NEAREST: return D3D12_FILTER_TYPE_POINT;
|
||||
case VK_SAMPLER_MIPMAP_MODE_LINEAR: return D3D12_FILTER_TYPE_LINEAR;
|
||||
default:
|
||||
assert(!"Unsupported filter mode");
|
||||
return D3D12_FILTER_TYPE_POINT;
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_FILTER
|
||||
dzn_translate_sampler_filter(const struct dzn_physical_device *pdev,
|
||||
const VkSamplerCreateInfo *create_info)
|
||||
{
|
||||
D3D12_FILTER_REDUCTION_TYPE reduction = create_info->compareEnable ?
|
||||
D3D12_FILTER_REDUCTION_TYPE_COMPARISON : D3D12_FILTER_REDUCTION_TYPE_STANDARD;
|
||||
|
||||
if (create_info->anisotropyEnable) {
|
||||
if (create_info->mipmapMode == VK_SAMPLER_MIPMAP_MODE_NEAREST &&
|
||||
pdev->options19.AnisoFilterWithPointMipSupported)
|
||||
return D3D12_ENCODE_MIN_MAG_ANISOTROPIC_MIP_POINT_FILTER(reduction);
|
||||
return D3D12_ENCODE_ANISOTROPIC_FILTER(reduction);
|
||||
}
|
||||
|
||||
return D3D12_ENCODE_BASIC_FILTER(
|
||||
translate_filter_type(create_info->minFilter),
|
||||
translate_filter_type(create_info->magFilter),
|
||||
translate_mip_filter_type(create_info->mipmapMode),
|
||||
reduction);
|
||||
}
|
||||
|
||||
D3D12_COMPARISON_FUNC
|
||||
dzn_translate_compare_op(VkCompareOp in)
|
||||
{
|
||||
switch (in) {
|
||||
case VK_COMPARE_OP_NEVER: return D3D12_COMPARISON_FUNC_NEVER;
|
||||
case VK_COMPARE_OP_LESS: return D3D12_COMPARISON_FUNC_LESS;
|
||||
case VK_COMPARE_OP_EQUAL: return D3D12_COMPARISON_FUNC_EQUAL;
|
||||
case VK_COMPARE_OP_LESS_OR_EQUAL: return D3D12_COMPARISON_FUNC_LESS_EQUAL;
|
||||
case VK_COMPARE_OP_GREATER: return D3D12_COMPARISON_FUNC_GREATER;
|
||||
case VK_COMPARE_OP_NOT_EQUAL: return D3D12_COMPARISON_FUNC_NOT_EQUAL;
|
||||
case VK_COMPARE_OP_GREATER_OR_EQUAL: return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
|
||||
case VK_COMPARE_OP_ALWAYS: return D3D12_COMPARISON_FUNC_ALWAYS;
|
||||
default: UNREACHABLE("Invalid compare op");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dzn_translate_viewport(D3D12_VIEWPORT *out,
|
||||
const VkViewport *in)
|
||||
{
|
||||
out->TopLeftX = in->x;
|
||||
out->TopLeftY = in->height < 0 ? in->height + in->y : in->y;
|
||||
out->Width = in->width;
|
||||
out->Height = fabs(in->height);
|
||||
out->MinDepth = MIN2(in->minDepth, in->maxDepth);
|
||||
out->MaxDepth = MAX2(in->maxDepth, in->minDepth);
|
||||
}
|
||||
|
||||
void
|
||||
dzn_translate_rect(D3D12_RECT *out,
|
||||
const VkRect2D *in)
|
||||
{
|
||||
out->left = in->offset.x;
|
||||
out->top = in->offset.y;
|
||||
out->right = in->offset.x + in->extent.width;
|
||||
out->bottom = in->offset.y + in->extent.height;
|
||||
}
|
||||
|
||||
static ID3D12Debug *
|
||||
get_debug_interface(struct util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory)
|
||||
{
|
||||
typedef HRESULT(WINAPI *PFN_D3D12_GET_DEBUG_INTERFACE)(REFIID riid, void **ppFactory);
|
||||
PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterface;
|
||||
|
||||
ID3D12Debug *debug;
|
||||
if (factory) {
|
||||
if (FAILED(ID3D12DeviceFactory_GetConfigurationInterface(factory, &CLSID_D3D12Debug, &IID_ID3D12Debug, (void **)&debug))) {
|
||||
mesa_loge("Failed to retrieve ID3D12Debug from device factory\n");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
D3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)util_dl_get_proc_address(d3d12_mod, "D3D12GetDebugInterface");
|
||||
if (!D3D12GetDebugInterface) {
|
||||
mesa_loge("failed to load D3D12GetDebugInterface from D3D12.DLL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (FAILED(D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug))) {
|
||||
mesa_loge("D3D12GetDebugInterface failed\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_enable_debug_layer(struct util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory)
|
||||
{
|
||||
ID3D12Debug *debug = get_debug_interface(d3d12_mod, factory);
|
||||
if (debug) {
|
||||
ID3D12Debug_EnableDebugLayer(debug);
|
||||
ID3D12Debug_Release(debug);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_enable_gpu_validation(struct util_dl_library *d3d12_mod, ID3D12DeviceFactory *factory)
|
||||
{
|
||||
ID3D12Debug *debug = get_debug_interface(d3d12_mod, factory);
|
||||
if (debug) {
|
||||
ID3D12Debug3 *debug3;
|
||||
if (SUCCEEDED(ID3D12Debug_QueryInterface(debug,
|
||||
&IID_ID3D12Debug3,
|
||||
(void **)&debug3))) {
|
||||
ID3D12Debug3_SetEnableGPUBasedValidation(debug3, true);
|
||||
ID3D12Debug3_Release(debug3);
|
||||
}
|
||||
ID3D12Debug_Release(debug);
|
||||
}
|
||||
}
|
||||
|
||||
ID3D12Device4 *
|
||||
d3d12_create_device(struct util_dl_library *d3d12_mod, IUnknown *adapter, ID3D12DeviceFactory *factory, bool experimental_features)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (experimental_features)
|
||||
#endif
|
||||
{
|
||||
if (factory) {
|
||||
if (FAILED(ID3D12DeviceFactory_EnableExperimentalFeatures(factory, 1, &D3D12ExperimentalShaderModels, NULL, NULL))) {
|
||||
mesa_loge("failed to enable experimental shader models\n");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
typedef HRESULT(WINAPI *PFN_D3D12ENABLEEXPERIMENTALFEATURES)(UINT, const IID *, void *, UINT *);
|
||||
PFN_D3D12ENABLEEXPERIMENTALFEATURES D3D12EnableExperimentalFeatures =
|
||||
(PFN_D3D12ENABLEEXPERIMENTALFEATURES)util_dl_get_proc_address(d3d12_mod, "D3D12EnableExperimentalFeatures");
|
||||
if (FAILED(D3D12EnableExperimentalFeatures(1, &D3D12ExperimentalShaderModels, NULL, NULL))) {
|
||||
mesa_loge("failed to enable experimental shader models\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ID3D12Device4 *dev;
|
||||
if (factory) {
|
||||
ID3D12DeviceFactory_SetFlags(factory, D3D12_DEVICE_FACTORY_FLAG_ALLOW_RETURNING_EXISTING_DEVICE |
|
||||
D3D12_DEVICE_FACTORY_FLAG_ALLOW_RETURNING_INCOMPATIBLE_EXISTING_DEVICE);
|
||||
if (FAILED(ID3D12DeviceFactory_CreateDevice(factory, adapter, D3D_FEATURE_LEVEL_11_0,
|
||||
&IID_ID3D12Device4,
|
||||
(void **)&dev))) {
|
||||
mesa_loge("ID3D12DeviceFactory::CreateDevice failed\n");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
typedef HRESULT(WINAPI *PFN_D3D12CREATEDEVICE)(IUnknown *, D3D_FEATURE_LEVEL, REFIID, void **);
|
||||
PFN_D3D12CREATEDEVICE D3D12CreateDevice;
|
||||
|
||||
D3D12CreateDevice = (PFN_D3D12CREATEDEVICE)util_dl_get_proc_address(d3d12_mod, "D3D12CreateDevice");
|
||||
if (!D3D12CreateDevice) {
|
||||
mesa_loge("failed to load D3D12CreateDevice from D3D12\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (FAILED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0,
|
||||
&IID_ID3D12Device4,
|
||||
(void **)&dev))) {
|
||||
mesa_loge("D3D12CreateDevice failed\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
|
||||
PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE
|
||||
d3d12_get_serialize_root_sig(struct util_dl_library *d3d12_mod)
|
||||
{
|
||||
return (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)
|
||||
util_dl_get_proc_address(d3d12_mod, "D3D12SerializeVersionedRootSignature");
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright © Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "dzn_private.h"
|
||||
#include "vk_util.h"
|
||||
|
||||
static PFN_vkVoidFunction VKAPI_PTR
|
||||
dzn_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_physical_device, pdevice, physicalDevice);
|
||||
return vk_instance_get_proc_addr_unchecked(pdevice->vk.instance, pName);
|
||||
}
|
||||
|
||||
static void *
|
||||
dzn_wsi_get_d3d12_command_queue(VkDevice dev)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_device, device, dev);
|
||||
|
||||
return device->swapchain_queue->cmdqueue;
|
||||
}
|
||||
|
||||
static struct vk_queue *
|
||||
dzn_wsi_get_blit_queue(VkDevice dev)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_device, device, dev);
|
||||
|
||||
return &device->swapchain_queue->vk;
|
||||
}
|
||||
|
||||
static bool
|
||||
dzn_wsi_needs_blits(VkDevice dev)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_device, device, dev);
|
||||
return device->need_swapchain_blits;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_wsi_create_image_memory(VkDevice dev, void *resource,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
VkDeviceMemory *out)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_device, device, dev);
|
||||
|
||||
struct dzn_device_memory *mem =
|
||||
vk_zalloc2(&device->vk.alloc, alloc, sizeof(*mem), 8,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!mem)
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
|
||||
vk_object_base_init(&device->vk, &mem->base, VK_OBJECT_TYPE_DEVICE_MEMORY);
|
||||
mem->dedicated_res = resource;
|
||||
ID3D12Resource_AddRef(mem->dedicated_res);
|
||||
|
||||
*out = dzn_device_memory_to_handle(mem);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
dzn_wsi_finish(struct dzn_physical_device *physical_device)
|
||||
{
|
||||
wsi_device_finish(&physical_device->wsi_device,
|
||||
&physical_device->vk.instance->alloc);
|
||||
}
|
||||
|
||||
VkResult
|
||||
dzn_wsi_init(struct dzn_physical_device *physical_device)
|
||||
{
|
||||
VkResult result;
|
||||
|
||||
#ifdef _WIN32
|
||||
bool sw = false;
|
||||
#else
|
||||
bool sw = true;
|
||||
#endif
|
||||
|
||||
result = wsi_device_init(&physical_device->wsi_device,
|
||||
dzn_physical_device_to_handle(physical_device),
|
||||
dzn_wsi_proc_addr,
|
||||
&physical_device->vk.instance->alloc,
|
||||
-1, NULL,
|
||||
&(struct wsi_device_options){.sw_device = sw});
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
physical_device->wsi_device.win32.get_d3d12_command_queue =
|
||||
dzn_wsi_get_d3d12_command_queue;
|
||||
physical_device->wsi_device.win32.requires_blits = dzn_wsi_needs_blits;
|
||||
physical_device->wsi_device.get_blit_queue = dzn_wsi_get_blit_queue;
|
||||
physical_device->wsi_device.win32.create_image_memory =
|
||||
dzn_wsi_create_image_memory;
|
||||
physical_device->wsi_device.supports_modifiers = false;
|
||||
physical_device->vk.wsi_device = &physical_device->wsi_device;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
# Copyright © Microsoft Corporation
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
dzn_entrypoints = custom_target(
|
||||
'dzn_entrypoints',
|
||||
input : [vk_entrypoints_gen, vk_api_xml],
|
||||
output : ['dzn_entrypoints.h', 'dzn_entrypoints.c'],
|
||||
command : [
|
||||
prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--proto', '--weak',
|
||||
'--out-h', '@OUTPUT0@', '--out-c', '@OUTPUT1@', '--prefix', 'dzn',
|
||||
'--beta', with_vulkan_beta.to_string()
|
||||
],
|
||||
depend_files : vk_entrypoints_gen_depend_files,
|
||||
)
|
||||
|
||||
libdzn_files = files(
|
||||
'dzn_cmd_buffer.c',
|
||||
'dzn_descriptor_set.c',
|
||||
'dzn_device.c',
|
||||
'dzn_dxcore.cpp',
|
||||
'dzn_image.c',
|
||||
'dzn_meta.c',
|
||||
'dzn_nir.c',
|
||||
'dzn_pipeline.c',
|
||||
'dzn_query.c',
|
||||
'dzn_sync.c',
|
||||
'dzn_util.c',
|
||||
'dzn_wsi.c',
|
||||
)
|
||||
|
||||
dzn_deps = [
|
||||
idep_libdxil_compiler,
|
||||
idep_libspirv_to_dxil,
|
||||
idep_nir,
|
||||
idep_nir_headers,
|
||||
idep_vulkan_util,
|
||||
idep_vulkan_runtime,
|
||||
idep_vulkan_wsi,
|
||||
idep_mesautil,
|
||||
dep_dxheaders,
|
||||
]
|
||||
|
||||
dzn_flags = [ ]
|
||||
dzn_cpp_flags = [ ]
|
||||
|
||||
if with_platform_windows
|
||||
libdzn_files += files('dzn_dxgi.c')
|
||||
endif
|
||||
|
||||
if cc.get_argument_syntax() != 'msvc'
|
||||
dzn_flags_to_try = [
|
||||
'-Werror=unused-variable',
|
||||
'-Werror=unused-but-set-variable',
|
||||
'-Werror=unused-value',
|
||||
'-Werror=format',
|
||||
'-Werror=switch',
|
||||
]
|
||||
dzn_flags += cc.get_supported_arguments(dzn_flags_to_try)
|
||||
dzn_cpp_flags = cpp.get_supported_arguments(['-Wno-error=unused-value'])
|
||||
endif
|
||||
|
||||
libvulkan_dzn = shared_library(
|
||||
'vulkan_dzn',
|
||||
[libdzn_files, dzn_entrypoints, sha1_h],
|
||||
vs_module_defs : vulkan_api_def,
|
||||
include_directories : [inc_include, inc_src, inc_util],
|
||||
dependencies : [dzn_deps, idep_vulkan_wsi, idep_xmlconfig],
|
||||
c_args : dzn_flags,
|
||||
cpp_args : dzn_cpp_flags,
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
link_args : [ld_args_bsymbolic, ld_args_gc_sections],
|
||||
name_prefix : host_machine.system() == 'windows' ? '' : [],
|
||||
install : true,
|
||||
)
|
||||
|
||||
icd_file_name = libname_prefix + 'vulkan_dzn.' + libname_suffix
|
||||
|
||||
|
||||
icd_command = [
|
||||
prog_python, '@INPUT0@',
|
||||
'--api-version', '1.1', '--xml', '@INPUT1@',
|
||||
'--sizeof-pointer', sizeof_pointer,
|
||||
'--icd-lib-path', vulkan_icd_lib_path,
|
||||
'--icd-filename', icd_file_name,
|
||||
'--out', '@OUTPUT@',
|
||||
]
|
||||
|
||||
icd_dev_command = [
|
||||
prog_python, '@INPUT0@',
|
||||
'--api-version', '1.1', '--xml', '@INPUT1@',
|
||||
'--sizeof-pointer', sizeof_pointer,
|
||||
'--icd-lib-path', meson.current_build_dir(),
|
||||
'--icd-filename', icd_file_name,
|
||||
'--out', '@OUTPUT@',
|
||||
]
|
||||
|
||||
if with_platform_windows
|
||||
icd_command += '--use-backslash'
|
||||
icd_dev_command += '--use-backslash'
|
||||
endif
|
||||
|
||||
dzn_icd = custom_target(
|
||||
'dzn_icd',
|
||||
input : [vk_icd_gen, vk_api_xml],
|
||||
output : 'dzn_icd.' + vulkan_manifest_suffix,
|
||||
command : icd_command,
|
||||
build_by_default : true,
|
||||
install_dir : with_vulkan_icd_dir,
|
||||
install_tag : 'runtime',
|
||||
install : true,
|
||||
)
|
||||
|
||||
_dev_icdname = 'dzn_devenv_icd.@[email protected]'.format(host_machine.cpu())
|
||||
_dev_icd = custom_target(
|
||||
'dzn_devenv_icd',
|
||||
input : [vk_icd_gen, vk_api_xml],
|
||||
output : _dev_icdname,
|
||||
command : icd_dev_command,
|
||||
build_by_default : true,
|
||||
)
|
||||
|
||||
devenv.append('VK_DRIVER_FILES', _dev_icd.full_path())
|
||||
Reference in new issue
Block a user