mirror of
https://gitee.com/openharmony/third_party_mesa3d
synced 2024-11-27 01:20:36 +00:00
microsoft: Initial vulkan-on-12 driver
This is Dozen, the Vulkan on DirectX 12 driver. Not to be confused with DirectEggs. This is an early prototype, and not meant to be upstreamed as-is. Co-Authored-by: Boris Brezillon <boris.brezillon@collabora.com> Co-Authored-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Co-Authored-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com> Co-Authored-by: Jesse Natalie <jenatali@microsoft.com> Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Acked-by: Jason Ekstrand <jason.ekstrand@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14766>
This commit is contained in:
parent
6635d011cb
commit
a012b21964
@ -276,6 +276,7 @@ with_freedreno_virtio = get_option('freedreno-virtio')
|
||||
with_broadcom_vk = _vulkan_drivers.contains('broadcom')
|
||||
with_imagination_vk = _vulkan_drivers.contains('imagination-experimental')
|
||||
with_imagination_srv = get_option('imagination-srv')
|
||||
with_microsoft_vk = _vulkan_drivers.contains('microsoft-experimental')
|
||||
with_any_vk = _vulkan_drivers.length() != 0
|
||||
|
||||
with_any_broadcom = with_gallium_vc4 or with_gallium_v3d or with_broadcom_vk
|
||||
@ -667,11 +668,11 @@ if with_gallium_zink
|
||||
endif
|
||||
|
||||
dep_dxheaders = null_dep
|
||||
if with_gallium_d3d12 or with_microsoft_clc
|
||||
if with_gallium_d3d12 or with_microsoft_clc or with_microsoft_vk
|
||||
dep_dxheaders = dependency('directx-headers', required : false)
|
||||
if not dep_dxheaders.found()
|
||||
dep_dxheaders = dependency('DirectX-Headers', fallback : ['DirectX-Headers', 'dep_dxheaders'],
|
||||
required : with_gallium_d3d12
|
||||
required : with_gallium_d3d12 or with_microsoft_vk
|
||||
)
|
||||
endif
|
||||
endif
|
||||
|
@ -192,7 +192,7 @@ option(
|
||||
'vulkan-drivers',
|
||||
type : 'array',
|
||||
value : ['auto'],
|
||||
choices : ['auto', 'amd', 'broadcom', 'freedreno', 'imagination-experimental', 'intel', 'panfrost', 'swrast', 'virtio-experimental'],
|
||||
choices : ['auto', 'amd', 'broadcom', 'freedreno', 'imagination-experimental', 'intel', 'microsoft-experimental', 'panfrost', 'swrast', 'virtio-experimental'],
|
||||
description : 'List of vulkan drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built'
|
||||
)
|
||||
option(
|
||||
|
@ -104,7 +104,7 @@ endif
|
||||
if with_gallium_virgl or with_virtio_vk
|
||||
subdir('virtio')
|
||||
endif
|
||||
if with_microsoft_clc or with_gallium_d3d12 or with_spirv_to_dxil
|
||||
if with_microsoft_clc or with_gallium_d3d12 or with_spirv_to_dxil or with_microsoft_vk
|
||||
subdir('microsoft')
|
||||
endif
|
||||
if with_gallium_nouveau
|
||||
|
@ -26,6 +26,9 @@ endif
|
||||
if with_gallium_d3d12
|
||||
subdir('resource_state_manager')
|
||||
endif
|
||||
if with_spirv_to_dxil
|
||||
if with_spirv_to_dxil or with_microsoft_vk
|
||||
subdir('spirv_to_dxil')
|
||||
endif
|
||||
if with_microsoft_vk
|
||||
subdir('vulkan')
|
||||
endif
|
||||
|
4119
src/microsoft/vulkan/dzn_cmd_buffer.cpp
Normal file
4119
src/microsoft/vulkan/dzn_cmd_buffer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
41
src/microsoft/vulkan/dzn_cmd_exec_functions
Normal file
41
src/microsoft/vulkan/dzn_cmd_exec_functions
Normal file
@ -0,0 +1,41 @@
|
||||
CmdBeginQuery
|
||||
CmdBeginRenderPass2
|
||||
CmdBindDescriptorSets
|
||||
CmdBindIndexBuffer
|
||||
CmdBindPipeline
|
||||
CmdBindVertexBuffers
|
||||
CmdBlitImage2
|
||||
CmdClearAttachments
|
||||
CmdClearColorImage
|
||||
CmdClearDepthStencilImage
|
||||
CmdCopyBuffer2
|
||||
CmdCopyBufferToImage2
|
||||
CmdCopyImage2
|
||||
CmdCopyImageToBuffer2
|
||||
CmdCopyQueryPoolResults
|
||||
CmdDispatch
|
||||
CmdDispatchIndirect
|
||||
CmdDraw
|
||||
CmdDrawIndexed
|
||||
CmdDrawIndexedIndirect
|
||||
CmdDrawIndirect
|
||||
CmdEndQuery
|
||||
CmdEndRenderPass2
|
||||
CmdFillBuffer
|
||||
CmdNextSubpass2
|
||||
CmdPipelineBarrier2
|
||||
CmdPushConstants
|
||||
CmdResetEvent
|
||||
CmdResetQueryPool
|
||||
CmdResolveImage2
|
||||
CmdSetBlendConstants
|
||||
CmdSetDepthBias
|
||||
CmdSetDepthBounds
|
||||
CmdSetEvent
|
||||
CmdSetLineWidth
|
||||
CmdSetScissor
|
||||
CmdSetStencilCompareMask
|
||||
CmdSetStencilReference
|
||||
CmdSetStencilWriteMask
|
||||
CmdUpdateBuffer
|
||||
CmdWaitEvents
|
1802
src/microsoft/vulkan/dzn_descriptor_set.cpp
Normal file
1802
src/microsoft/vulkan/dzn_descriptor_set.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2632
src/microsoft/vulkan/dzn_device.cpp
Normal file
2632
src/microsoft/vulkan/dzn_device.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1220
src/microsoft/vulkan/dzn_image.cpp
Normal file
1220
src/microsoft/vulkan/dzn_image.cpp
Normal file
File diff suppressed because it is too large
Load Diff
744
src/microsoft/vulkan/dzn_meta.cpp
Normal file
744
src/microsoft/vulkan/dzn_meta.cpp
Normal file
@ -0,0 +1,744 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
static void
|
||||
dzn_meta_compile_shader(dzn_device *device, nir_shader *nir,
|
||||
D3D12_SHADER_BYTECODE *slot)
|
||||
{
|
||||
dzn_instance *instance =
|
||||
container_of(device->vk.physical->instance, dzn_instance, vk);
|
||||
IDxcValidator *validator = instance->dxc.validator;
|
||||
IDxcLibrary *library = instance->dxc.library;
|
||||
IDxcCompiler *compiler = instance->dxc.compiler;
|
||||
|
||||
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 };
|
||||
struct blob dxil_blob;
|
||||
bool ret = nir_to_dxil(nir, &opts, &dxil_blob);
|
||||
assert(ret);
|
||||
|
||||
dzn_shader_blob blob(dxil_blob.data, dxil_blob.size);
|
||||
ComPtr<IDxcOperationResult> result;
|
||||
validator->Validate(&blob, DxcValidatorFlags_InPlaceEdit, &result);
|
||||
if ((instance->debug_flags & DZN_DEBUG_DXIL) &&
|
||||
(instance->debug_flags & DZN_DEBUG_INTERNAL)) {
|
||||
IDxcBlobEncoding *disassembly;
|
||||
compiler->Disassemble(&blob, &disassembly);
|
||||
ComPtr<IDxcBlobEncoding> blobUtf8;
|
||||
library->GetBlobAsUtf8(disassembly, blobUtf8.GetAddressOf());
|
||||
char *disasm = reinterpret_cast<char*>(blobUtf8->GetBufferPointer());
|
||||
disasm[blobUtf8->GetBufferSize() - 1] = 0;
|
||||
fprintf(stderr,
|
||||
"== BEGIN SHADER ============================================\n"
|
||||
"%s\n"
|
||||
"== END SHADER ==============================================\n",
|
||||
disasm);
|
||||
disassembly->Release();
|
||||
}
|
||||
|
||||
HRESULT validationStatus;
|
||||
result->GetStatus(&validationStatus);
|
||||
if (FAILED(validationStatus)) {
|
||||
if ((instance->debug_flags & DZN_DEBUG_DXIL) &&
|
||||
(instance->debug_flags & DZN_DEBUG_INTERNAL)) {
|
||||
ComPtr<IDxcBlobEncoding> printBlob, printBlobUtf8;
|
||||
result->GetErrorBuffer(&printBlob);
|
||||
library->GetBlobAsUtf8(printBlob.Get(), printBlobUtf8.GetAddressOf());
|
||||
|
||||
char *errorString;
|
||||
if (printBlobUtf8) {
|
||||
errorString = reinterpret_cast<char*>(printBlobUtf8->GetBufferPointer());
|
||||
errorString[printBlobUtf8->GetBufferSize() - 1] = 0;
|
||||
fprintf(stderr,
|
||||
"== VALIDATION ERROR =============================================\n"
|
||||
"%s\n"
|
||||
"== END ==========================================================\n",
|
||||
errorString);
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(!FAILED(validationStatus));
|
||||
|
||||
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 4
|
||||
|
||||
static void
|
||||
dzn_meta_indirect_draw_finish(dzn_device *device, enum dzn_indirect_draw_type type)
|
||||
{
|
||||
dzn_meta_indirect_draw *meta = &device->indirect_draws[type];
|
||||
|
||||
if (meta->root_sig)
|
||||
meta->root_sig->Release();
|
||||
|
||||
if (meta->pipeline_state)
|
||||
meta->pipeline_state->Release();
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_meta_indirect_draw_init(dzn_device *device,
|
||||
enum dzn_indirect_draw_type type)
|
||||
{
|
||||
dzn_meta_indirect_draw *meta = &device->indirect_draws[type];
|
||||
dzn_instance *instance =
|
||||
container_of(device->vk.physical->instance, dzn_instance, vk);
|
||||
VkResult ret = VK_SUCCESS;
|
||||
|
||||
glsl_type_singleton_init_or_ref();
|
||||
|
||||
nir_shader *nir = dzn_nir_indirect_draw_shader(type);
|
||||
bool triangle_fan = type == DZN_INDIRECT_DRAW_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN;
|
||||
uint32_t shader_params_size =
|
||||
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 (triangle_fan) {
|
||||
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,
|
||||
};
|
||||
|
||||
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(device->dev->CreateComputePipelineState(&desc,
|
||||
IID_PPV_ARGS(&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 3
|
||||
|
||||
static void
|
||||
dzn_meta_triangle_fan_rewrite_index_finish(dzn_device *device,
|
||||
enum dzn_index_type old_index_type)
|
||||
{
|
||||
dzn_meta_triangle_fan_rewrite_index *meta =
|
||||
&device->triangle_fan[old_index_type];
|
||||
|
||||
if (meta->root_sig)
|
||||
meta->root_sig->Release();
|
||||
if (meta->pipeline_state)
|
||||
meta->pipeline_state->Release();
|
||||
if (meta->cmd_sig)
|
||||
meta->cmd_sig->Release();
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_meta_triangle_fan_rewrite_index_init(dzn_device *device,
|
||||
enum dzn_index_type old_index_type)
|
||||
{
|
||||
dzn_meta_triangle_fan_rewrite_index *meta =
|
||||
&device->triangle_fan[old_index_type];
|
||||
dzn_instance *instance =
|
||||
container_of(device->vk.physical->instance, dzn_instance, vk);
|
||||
VkResult ret = VK_SUCCESS;
|
||||
|
||||
glsl_type_singleton_init_or_ref();
|
||||
|
||||
uint8_t old_index_size = dzn_index_size(old_index_type);
|
||||
|
||||
nir_shader *nir = 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,
|
||||
};
|
||||
|
||||
root_params[root_param_count++] = D3D12_ROOT_PARAMETER1 {
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
|
||||
.Constants = {
|
||||
.ShaderRegister = 0,
|
||||
.RegisterSpace = 0,
|
||||
.Num32BitValues = sizeof(struct dzn_triangle_fan_rewrite_index_params) / 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,
|
||||
};
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
D3D12_INDIRECT_ARGUMENT_DESC cmd_args[] = {
|
||||
{
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW,
|
||||
.UnorderedAccessView = {
|
||||
.RootParameterIndex = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT,
|
||||
.Constant = {
|
||||
.RootParameterIndex = 1,
|
||||
.DestOffsetIn32BitValues = 0,
|
||||
.Num32BitValuesToSet = sizeof(struct dzn_triangle_fan_rewrite_index_params) / 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH,
|
||||
},
|
||||
};
|
||||
|
||||
D3D12_COMMAND_SIGNATURE_DESC cmd_sig_desc = {
|
||||
.ByteStride = sizeof(struct dzn_indirect_triangle_fan_rewrite_index_exec_params),
|
||||
.NumArgumentDescs = ARRAY_SIZE(cmd_args),
|
||||
.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(device->dev->CreateComputePipelineState(&desc,
|
||||
IID_PPV_ARGS(&meta->pipeline_state)))) {
|
||||
ret = vk_error(instance, VK_ERROR_INITIALIZATION_FAILED);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (FAILED(device->dev->CreateCommandSignature(&cmd_sig_desc,
|
||||
meta->root_sig,
|
||||
IID_PPV_ARGS(&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(dzn_device *device)
|
||||
{
|
||||
dzn_meta_blits *meta = &device->blits;
|
||||
D3D12_SHADER_BYTECODE *out;
|
||||
|
||||
mtx_lock(&meta->shaders_lock);
|
||||
|
||||
if (meta->vs.pShaderBytecode == NULL) {
|
||||
nir_shader *nir = dzn_nir_blit_vs();
|
||||
|
||||
NIR_PASS_V(nir, nir_lower_system_values);
|
||||
|
||||
gl_system_value system_values[] = {
|
||||
SYSTEM_VALUE_FIRST_VERTEX,
|
||||
SYSTEM_VALUE_BASE_VERTEX,
|
||||
};
|
||||
|
||||
NIR_PASS_V(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);
|
||||
out = &meta->vs;
|
||||
}
|
||||
free((void *)bc.pShaderBytecode);
|
||||
ralloc_free(nir);
|
||||
} else {
|
||||
out = &meta->vs;
|
||||
}
|
||||
|
||||
mtx_unlock(&meta->shaders_lock);
|
||||
|
||||
return &meta->vs;
|
||||
}
|
||||
|
||||
static const D3D12_SHADER_BYTECODE *
|
||||
dzn_meta_blits_get_fs(dzn_device *device,
|
||||
const struct dzn_nir_blit_info *info)
|
||||
{
|
||||
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, &wrap_state, NULL, 0);
|
||||
}
|
||||
|
||||
D3D12_SHADER_BYTECODE bc;
|
||||
|
||||
dzn_meta_compile_shader(device, nir, &bc);
|
||||
|
||||
out = (D3D12_SHADER_BYTECODE *)
|
||||
vk_alloc(&device->vk.alloc,
|
||||
sizeof(D3D12_SHADER_BYTECODE) + bc.BytecodeLength, 8,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
|
||||
if (out) {
|
||||
out->pShaderBytecode = (void *)(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 = (D3D12_SHADER_BYTECODE *)he->data;
|
||||
}
|
||||
|
||||
mtx_unlock(&meta->shaders_lock);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static void
|
||||
dzn_meta_blit_destroy(dzn_device *device, dzn_meta_blit *blit)
|
||||
{
|
||||
if (!blit)
|
||||
return;
|
||||
|
||||
if (blit->root_sig)
|
||||
blit->root_sig->Release();
|
||||
if (blit->pipeline_state)
|
||||
blit->pipeline_state->Release();
|
||||
|
||||
vk_free(&device->vk.alloc, blit);
|
||||
}
|
||||
|
||||
static dzn_meta_blit *
|
||||
dzn_meta_blit_create(dzn_device *device, const dzn_meta_blit_key *key)
|
||||
{
|
||||
dzn_meta_blits *blits = &device->blits;
|
||||
dzn_meta_blit *blit = (dzn_meta_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_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[] = {
|
||||
{
|
||||
.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,
|
||||
},
|
||||
};
|
||||
|
||||
D3D12_VERSIONED_ROOT_SIGNATURE_DESC root_sig_desc = {
|
||||
.Version = D3D_ROOT_SIGNATURE_VERSION_1_1,
|
||||
.Desc_1_1 = {
|
||||
.NumParameters = ARRAY_SIZE(root_params),
|
||||
.pParameters = root_params,
|
||||
.NumStaticSamplers = ARRAY_SIZE(samplers),
|
||||
.pStaticSamplers = samplers,
|
||||
.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE,
|
||||
},
|
||||
};
|
||||
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = {
|
||||
.SampleMask = key->resolve ? 1 : (1ULL << key->samples) - 1,
|
||||
.RasterizerState = {
|
||||
.FillMode = D3D12_FILL_MODE_SOLID,
|
||||
.CullMode = D3D12_CULL_MODE_NONE,
|
||||
.DepthClipEnable = TRUE,
|
||||
},
|
||||
.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
|
||||
.SampleDesc = {
|
||||
.Count = key->resolve ? 1 : key->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 = key->resolve,
|
||||
.padding = 0,
|
||||
};
|
||||
|
||||
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 = 0xff;
|
||||
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(device->dev->CreateGraphicsPipelineState(&desc,
|
||||
IID_PPV_ARGS(&blit->pipeline_state)))) {
|
||||
dzn_meta_blit_destroy(device, blit);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return blit;
|
||||
}
|
||||
|
||||
const dzn_meta_blit *
|
||||
dzn_meta_blits_get_context(dzn_device *device,
|
||||
const dzn_meta_blit_key *key)
|
||||
{
|
||||
dzn_meta_blit *out = NULL;
|
||||
|
||||
STATIC_ASSERT(sizeof(key) == sizeof(uint64_t));
|
||||
|
||||
mtx_lock(&device->blits.contexts_lock);
|
||||
|
||||
out = (dzn_meta_blit *)
|
||||
_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(dzn_device *device)
|
||||
{
|
||||
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, (dzn_meta_blit *)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(dzn_device *device)
|
||||
{
|
||||
dzn_instance *instance =
|
||||
container_of(device->vk.physical->instance, dzn_instance, vk);
|
||||
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(dzn_device *device)
|
||||
{
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(device->triangle_fan); i++)
|
||||
dzn_meta_triangle_fan_rewrite_index_finish(device, (enum dzn_index_type)i);
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(device->indirect_draws); i++)
|
||||
dzn_meta_indirect_draw_finish(device, (enum dzn_indirect_draw_type)i);
|
||||
|
||||
dzn_meta_blits_finish(device);
|
||||
}
|
||||
|
||||
VkResult
|
||||
dzn_meta_init(dzn_device *device)
|
||||
{
|
||||
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++) {
|
||||
VkResult result =
|
||||
dzn_meta_indirect_draw_init(device, (enum dzn_indirect_draw_type)i);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(device->triangle_fan); i++) {
|
||||
VkResult result =
|
||||
dzn_meta_triangle_fan_rewrite_index_init(device, (enum dzn_index_type)i);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (result != VK_SUCCESS) {
|
||||
dzn_meta_finish(device);
|
||||
return result;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
513
src/microsoft/vulkan/dzn_nir.c
Normal file
513
src/microsoft/vulkan/dzn_nir.c
Normal file
@ -0,0 +1,513 @@
|
||||
/*
|
||||
* 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 <directx/d3d12.h>
|
||||
|
||||
#include "spirv_to_dxil.h"
|
||||
#include "nir_to_dxil.h"
|
||||
#include "nir_builder.h"
|
||||
#include "nir_vulkan.h"
|
||||
|
||||
#include "dzn_nir.h"
|
||||
|
||||
static nir_ssa_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++;
|
||||
|
||||
VkDescriptorType desc_type =
|
||||
var->data.mode == nir_var_mem_ubo ?
|
||||
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER :
|
||||
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
nir_address_format addr_format = nir_address_format_32bit_index_offset;
|
||||
nir_ssa_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_ssa_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(enum dzn_indirect_draw_type type)
|
||||
{
|
||||
const char *type_str[] = {
|
||||
"draw",
|
||||
"indexed_draw",
|
||||
"draw_triangle_fan",
|
||||
"indexed_draw_triangle_fan",
|
||||
};
|
||||
|
||||
assert(type < ARRAY_SIZE(type_str));
|
||||
|
||||
bool indexed = type == DZN_INDIRECT_INDEXED_DRAW ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN;
|
||||
bool triangle_fan = type == DZN_INDIRECT_DRAW_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN;
|
||||
nir_builder b =
|
||||
nir_builder_init_simple_shader(MESA_SHADER_COMPUTE,
|
||||
dxil_get_nir_compiler_options(),
|
||||
"dzn_meta_indirect_%s()",
|
||||
type_str[type]);
|
||||
b.shader->info.internal = true;
|
||||
|
||||
struct glsl_struct_field field = {
|
||||
.type = glsl_uint_type(),
|
||||
.name = "dummy_int",
|
||||
};
|
||||
const struct glsl_type *dummy_type =
|
||||
glsl_struct_type(&field, 1, "dummy_type", false);
|
||||
|
||||
nir_ssa_def *params_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ubo, 0, 0, "params", 0);
|
||||
nir_ssa_def *draw_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 1, "draw_buf", ACCESS_NON_WRITEABLE);
|
||||
nir_ssa_def *exec_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 2, "exec_buf", ACCESS_NON_READABLE);
|
||||
|
||||
unsigned params_size =
|
||||
triangle_fan ?
|
||||
sizeof(struct dzn_indirect_draw_triangle_fan_rewrite_params) :
|
||||
sizeof(struct dzn_indirect_draw_rewrite_params);
|
||||
|
||||
nir_ssa_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);
|
||||
|
||||
nir_ssa_def *draw_stride = nir_channel(&b, params, 0);
|
||||
nir_ssa_def *exec_stride = nir_imm_int(&b, sizeof(struct dzn_indirect_draw_exec_params));
|
||||
nir_ssa_def *index =
|
||||
nir_channel(&b, nir_load_global_invocation_id(&b, 32), 0);
|
||||
|
||||
nir_ssa_def *draw_offset = nir_imul(&b, draw_stride, index);
|
||||
nir_ssa_def *exec_offset = nir_imul(&b, exec_stride, index);
|
||||
|
||||
nir_ssa_def *draw_info1 =
|
||||
nir_load_ssbo(&b, 4, 32, draw_buf_desc, draw_offset, .align_mul = 4);
|
||||
nir_ssa_def *draw_info2 =
|
||||
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_ssa_def *first_vertex = nir_channel(&b, draw_info1, indexed ? 3 : 2);
|
||||
nir_ssa_def *base_instance =
|
||||
indexed ? draw_info2 : nir_channel(&b, draw_info1, 3);
|
||||
|
||||
nir_ssa_def *exec_vals[7] = {
|
||||
first_vertex,
|
||||
base_instance,
|
||||
};
|
||||
|
||||
if (triangle_fan) {
|
||||
/* Patch {vertex,index}_count and first_index */
|
||||
nir_ssa_def *triangle_count =
|
||||
nir_usub_sat(&b, nir_channel(&b, draw_info1, 0), nir_imm_int(&b, 2));
|
||||
exec_vals[2] = nir_imul_imm(&b, triangle_count, 3);
|
||||
exec_vals[3] = nir_channel(&b, draw_info1, 1);
|
||||
exec_vals[4] = nir_imm_int(&b, 0);
|
||||
exec_vals[5] = indexed ? nir_channel(&b, draw_info1, 3) : nir_imm_int(&b, 0);
|
||||
exec_vals[6] = indexed ? draw_info2 : nir_channel(&b, draw_info1, 3);
|
||||
|
||||
nir_ssa_def *triangle_fan_exec_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 3,
|
||||
"triangle_fan_exec_buf",
|
||||
ACCESS_NON_READABLE);
|
||||
nir_ssa_def *triangle_fan_index_buf_stride = nir_channel(&b, params, 1);
|
||||
nir_ssa_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_ssa_def *addr_lo_overflow =
|
||||
nir_ult(&b, triangle_fan_index_buf_addr_lo, nir_channel(&b, params, 2));
|
||||
nir_ssa_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)));
|
||||
|
||||
nir_ssa_def *triangle_fan_exec_vals[] = {
|
||||
triangle_fan_index_buf_addr_lo,
|
||||
triangle_fan_index_buf_addr_hi,
|
||||
nir_channel(&b, draw_info1, 2),
|
||||
triangle_count,
|
||||
nir_imm_int(&b, 1),
|
||||
nir_imm_int(&b, 1),
|
||||
};
|
||||
|
||||
assert(sizeof(struct dzn_indirect_triangle_fan_rewrite_index_exec_params) == (ARRAY_SIZE(triangle_fan_exec_vals) * 4));
|
||||
|
||||
nir_ssa_def *triangle_fan_exec_stride =
|
||||
nir_imm_int(&b, sizeof(struct dzn_indirect_triangle_fan_rewrite_index_exec_params));
|
||||
nir_ssa_def *triangle_fan_exec_offset =
|
||||
nir_imul(&b, triangle_fan_exec_stride, index);
|
||||
|
||||
nir_store_ssbo(&b, nir_vec(&b, &triangle_fan_exec_vals[0], 4),
|
||||
triangle_fan_exec_buf_desc, triangle_fan_exec_offset,
|
||||
.write_mask = 0xf, .access = ACCESS_NON_READABLE, .align_mul = 4);
|
||||
nir_store_ssbo(&b, nir_vec(&b, &triangle_fan_exec_vals[4], 2),
|
||||
triangle_fan_exec_buf_desc,
|
||||
nir_iadd_imm(&b, triangle_fan_exec_offset, 16),
|
||||
.write_mask = 0x3, .access = ACCESS_NON_READABLE, .align_mul = 4);
|
||||
|
||||
nir_ssa_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 = 0x3, .access = ACCESS_NON_READABLE, .align_mul = 4);
|
||||
exec_offset = nir_iadd_imm(&b, exec_offset, ARRAY_SIZE(ibview_vals) * 4);
|
||||
} else {
|
||||
exec_vals[2] = nir_channel(&b, draw_info1, 0);
|
||||
exec_vals[3] = nir_channel(&b, draw_info1, 1);
|
||||
exec_vals[4] = nir_channel(&b, draw_info1, 2);
|
||||
exec_vals[5] = nir_channel(&b, draw_info1, 3);
|
||||
exec_vals[6] = draw_info2;
|
||||
}
|
||||
|
||||
nir_store_ssbo(&b, nir_vec(&b, exec_vals, 4),
|
||||
exec_buf_desc, exec_offset,
|
||||
.write_mask = 0xf, .access = ACCESS_NON_READABLE, .align_mul = 4);
|
||||
nir_store_ssbo(&b, nir_vec(&b, &exec_vals[4], 3),
|
||||
exec_buf_desc, nir_iadd_imm(&b, exec_offset, 16),
|
||||
.write_mask = 7, .access = ACCESS_NON_READABLE, .align_mul = 4);
|
||||
|
||||
|
||||
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_nir_compiler_options(),
|
||||
"dzn_meta_triangle_rewrite_index(old_index_size=%d)",
|
||||
old_index_size);
|
||||
b.shader->info.internal = true;
|
||||
|
||||
nir_ssa_def *params_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ubo, 0, 0, "params", 0);
|
||||
nir_ssa_def *new_index_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 1,
|
||||
"new_index_buf", ACCESS_NON_READABLE);
|
||||
|
||||
nir_ssa_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_ssa_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_ssa_def *triangle = nir_channel(&b, nir_load_global_invocation_id(&b, 32), 0);
|
||||
nir_ssa_def *new_indices;
|
||||
|
||||
if (old_index_size > 0) {
|
||||
nir_ssa_def *old_first_index = nir_channel(&b, params, 0);
|
||||
nir_ssa_def *old_index0_offset =
|
||||
nir_imul_imm(&b, old_first_index, old_index_size);
|
||||
nir_ssa_def *old_index1_offset =
|
||||
nir_imul_imm(&b, nir_iadd(&b, nir_iadd_imm(&b, triangle, 1), old_first_index),
|
||||
old_index_size);
|
||||
|
||||
nir_ssa_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_ieq_imm(&b, nir_iand_imm(&b, old_index0_offset, 0x2), 0),
|
||||
nir_iand_imm(&b, old_index0, 0xffff),
|
||||
nir_ushr_imm(&b, old_index0, 16));
|
||||
}
|
||||
|
||||
nir_ssa_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_ssa_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_ieq_imm(&b, nir_iand_imm(&b, old_index1_offset, 0x2), 0),
|
||||
nir_vec2(&b, indices[0], indices[1]),
|
||||
nir_vec2(&b, indices[1], indices[2]));
|
||||
}
|
||||
|
||||
/* 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 {
|
||||
nir_ssa_def *first_vertex = nir_channel(&b, params, 0);
|
||||
|
||||
new_indices =
|
||||
nir_vec3(&b,
|
||||
nir_iadd(&b, nir_iadd_imm(&b, triangle, 1), first_vertex),
|
||||
nir_iadd(&b, nir_iadd_imm(&b, triangle, 2), first_vertex),
|
||||
first_vertex);
|
||||
}
|
||||
|
||||
nir_ssa_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_nir_compiler_options(),
|
||||
"dzn_meta_blit_vs()");
|
||||
b.shader->info.internal = true;
|
||||
|
||||
nir_ssa_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_ssa_def *vertex = nir_load_vertex_id(&b);
|
||||
nir_ssa_def *base = nir_imul_imm(&b, vertex, 4 * sizeof(float));
|
||||
nir_ssa_def *coords =
|
||||
nir_load_ubo(&b, 4, 32, params_desc, base,
|
||||
.align_mul = 16, .align_offset = 0, .range_base = 0, .range = ~0);
|
||||
nir_ssa_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_ssa_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_nir_compiler_options(),
|
||||
"dzn_meta_blit_fs()");
|
||||
b.shader->info.internal = true;
|
||||
|
||||
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_ssa_def *coord =
|
||||
nir_channels(&b, nir_load_var(&b, coord_var), (1 << coord_comps) - 1);
|
||||
|
||||
uint32_t out_comps =
|
||||
(info->loc == FRAG_RESULT_DEPTH || info->loc == FRAG_RESULT_STENCIL) ? 1 : 4;
|
||||
nir_variable *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_ssa_def *res = NULL;
|
||||
|
||||
if (info->resolve) {
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
unsigned nsamples = info->out_type == GLSL_TYPE_FLOAT ?
|
||||
info->src_samples : 1;
|
||||
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].src_type = nir_tex_src_coord;
|
||||
tex->src[0].src = nir_src_for_ssa(nir_f2i32(&b, coord));
|
||||
tex->coord_components = coord_comps;
|
||||
|
||||
tex->src[1].src_type = nir_tex_src_ms_index;
|
||||
tex->src[1].src = nir_src_for_ssa(nir_imm_int(&b, s));
|
||||
|
||||
tex->src[2].src_type = nir_tex_src_lod;
|
||||
tex->src[2].src = nir_src_for_ssa(nir_imm_int(&b, 0));
|
||||
|
||||
tex->src[3].src_type = nir_tex_src_texture_deref;
|
||||
tex->src[3].src = nir_src_for_ssa(&tex_deref->dest.ssa);
|
||||
|
||||
nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL);
|
||||
|
||||
nir_builder_instr_insert(&b, &tex->instr);
|
||||
res = res ? nir_fadd(&b, res, &tex->dest.ssa) : &tex->dest.ssa;
|
||||
}
|
||||
|
||||
if (nsamples > 1) {
|
||||
unsigned type_sz = nir_alu_type_get_type_size(nir_out_type);
|
||||
res = nir_fmul(&b, res, nir_imm_floatN_t(&b, 1.0f / nsamples, type_sz));
|
||||
}
|
||||
} 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].src_type = nir_tex_src_coord;
|
||||
tex->src[0].src = nir_src_for_ssa(nir_f2i32(&b, coord));
|
||||
tex->coord_components = coord_comps;
|
||||
|
||||
tex->src[1].src_type = nir_tex_src_ms_index;
|
||||
tex->src[1].src = nir_src_for_ssa(nir_load_sample_id(&b));
|
||||
|
||||
tex->src[2].src_type = nir_tex_src_lod;
|
||||
tex->src[2].src = nir_src_for_ssa(nir_imm_int(&b, 0));
|
||||
|
||||
tex->src[3].src_type = nir_tex_src_texture_deref;
|
||||
tex->src[3].src = nir_src_for_ssa(&tex_deref->dest.ssa);
|
||||
} 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].src_type = nir_tex_src_coord;
|
||||
tex->src[0].src = nir_src_for_ssa(coord);
|
||||
tex->coord_components = coord_comps;
|
||||
|
||||
tex->src[1].src_type = nir_tex_src_texture_deref;
|
||||
tex->src[1].src = nir_src_for_ssa(&tex_deref->dest.ssa);
|
||||
|
||||
tex->src[2].src_type = nir_tex_src_sampler_deref;
|
||||
tex->src[2].src = nir_src_for_ssa(&sampler_deref->dest.ssa);
|
||||
}
|
||||
|
||||
nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL);
|
||||
nir_builder_instr_insert(&b, &tex->instr);
|
||||
res = &tex->dest.ssa;
|
||||
}
|
||||
|
||||
nir_store_var(&b, out, nir_channels(&b, res, (1 << out_comps) - 1), 0xf);
|
||||
|
||||
return b.shader;
|
||||
}
|
138
src/microsoft/vulkan/dzn_nir.h
Normal file
138
src/microsoft/vulkan/dzn_nir.h
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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
|
||||
#include <directx/d3d12.h>
|
||||
|
||||
#include "nir.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dzn_indirect_draw_params {
|
||||
uint32_t vertex_count;
|
||||
uint32_t instance_count;
|
||||
uint32_t first_vertex;
|
||||
uint32_t first_instance;
|
||||
};
|
||||
|
||||
struct dzn_indirect_indexed_draw_params {
|
||||
uint32_t index_count;
|
||||
uint32_t instance_count;
|
||||
uint32_t first_index;
|
||||
int32_t vertex_offset;
|
||||
uint32_t first_instance;
|
||||
};
|
||||
|
||||
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_exec_params {
|
||||
struct {
|
||||
uint32_t first_vertex;
|
||||
uint32_t base_instance;
|
||||
} sysvals;
|
||||
union {
|
||||
struct dzn_indirect_draw_params draw;
|
||||
struct dzn_indirect_indexed_draw_params indexed_draw;
|
||||
};
|
||||
};
|
||||
|
||||
struct dzn_indirect_triangle_fan_draw_exec_params {
|
||||
D3D12_INDEX_BUFFER_VIEW ibview;
|
||||
struct {
|
||||
uint32_t first_vertex;
|
||||
uint32_t base_instance;
|
||||
} sysvals;
|
||||
union {
|
||||
struct dzn_indirect_draw_params draw;
|
||||
struct dzn_indirect_indexed_draw_params indexed_draw;
|
||||
};
|
||||
};
|
||||
|
||||
struct dzn_triangle_fan_rewrite_index_params {
|
||||
union {
|
||||
uint32_t first_index;
|
||||
uint32_t first_vertex;
|
||||
};
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
enum dzn_indirect_draw_type {
|
||||
DZN_INDIRECT_DRAW,
|
||||
DZN_INDIRECT_INDEXED_DRAW,
|
||||
DZN_INDIRECT_DRAW_TRIANGLE_FAN,
|
||||
DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN,
|
||||
DZN_NUM_INDIRECT_DRAW_TYPES,
|
||||
};
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type);
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_triangle_fan_rewrite_index_shader(uint8_t old_index_size);
|
||||
|
||||
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 : 1;
|
||||
uint32_t padding : 12;
|
||||
};
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
159
src/microsoft/vulkan/dzn_pass.cpp
Normal file
159
src/microsoft/vulkan/dzn_pass.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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_format.h"
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
dzn_CreateRenderPass2(VkDevice dev,
|
||||
const VkRenderPassCreateInfo2KHR *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkRenderPass *pRenderPass)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_device, device, dev);
|
||||
|
||||
VK_MULTIALLOC(ma);
|
||||
VK_MULTIALLOC_DECL(&ma, dzn_render_pass, pass, 1);
|
||||
VK_MULTIALLOC_DECL(&ma, dzn_subpass, subpasses,
|
||||
pCreateInfo->subpassCount);
|
||||
VK_MULTIALLOC_DECL(&ma, dzn_attachment, attachments,
|
||||
pCreateInfo->attachmentCount);
|
||||
|
||||
if (!vk_multialloc_zalloc2(&ma, &device->vk.alloc, pAllocator,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
vk_object_base_init(&device->vk, &pass->base, VK_OBJECT_TYPE_RENDER_PASS);
|
||||
pass->subpasses = subpasses;
|
||||
pass->subpass_count = pCreateInfo->subpassCount;
|
||||
pass->attachments = attachments;
|
||||
pass->attachment_count = pCreateInfo->attachmentCount;
|
||||
|
||||
assert(!pass->attachment_count || pass->attachments);
|
||||
for (uint32_t i = 0; i < pass->attachment_count; i++) {
|
||||
const VkAttachmentDescription2 *attachment = &pCreateInfo->pAttachments[i];
|
||||
|
||||
attachments[i].idx = i;
|
||||
attachments[i].format = attachment->format;
|
||||
assert(attachments[i].format);
|
||||
if (vk_format_is_depth_or_stencil(attachment->format)) {
|
||||
attachments[i].clear.depth =
|
||||
attachment->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachments[i].clear.stencil =
|
||||
attachment->stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
} else {
|
||||
attachments[i].clear.color =
|
||||
attachment->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
}
|
||||
attachments[i].samples = attachment->samples;
|
||||
attachments[i].before = dzn_image_layout_to_state(attachment->initialLayout);
|
||||
attachments[i].after = dzn_image_layout_to_state(attachment->finalLayout);
|
||||
attachments[i].last = attachments[i].before;
|
||||
}
|
||||
|
||||
assert(subpasses);
|
||||
for (uint32_t i = 0; i < pass->subpass_count; i++) {
|
||||
const VkSubpassDescription2 *subpass = &pCreateInfo->pSubpasses[i];
|
||||
const VkSubpassDescription2 *subpass_after = NULL;
|
||||
|
||||
if (i + 1 < pass->subpass_count)
|
||||
subpass_after = &pCreateInfo->pSubpasses[i + 1];
|
||||
|
||||
for (uint32_t j = 0; j < subpass->colorAttachmentCount; j++) {
|
||||
uint32_t idx = subpass->pColorAttachments[j].attachment;
|
||||
subpasses[i].colors[j].idx = idx;
|
||||
if (idx != VK_ATTACHMENT_UNUSED) {
|
||||
subpasses[i].colors[j].before = attachments[idx].last;
|
||||
subpasses[i].colors[j].during =
|
||||
dzn_image_layout_to_state(subpass->pColorAttachments[j].layout);
|
||||
attachments[idx].last = subpasses[i].colors[j].during;
|
||||
subpasses[i].color_count = j + 1;
|
||||
}
|
||||
|
||||
idx = subpass->pResolveAttachments ?
|
||||
subpass->pResolveAttachments[j].attachment :
|
||||
VK_ATTACHMENT_UNUSED;
|
||||
subpasses[i].resolve[j].idx = idx;
|
||||
if (idx != VK_ATTACHMENT_UNUSED) {
|
||||
subpasses[i].resolve[j].before = attachments[idx].last;
|
||||
subpasses[i].resolve[j].during =
|
||||
dzn_image_layout_to_state(subpass->pResolveAttachments[j].layout);
|
||||
attachments[idx].last = subpasses[i].resolve[j].during;
|
||||
}
|
||||
}
|
||||
|
||||
subpasses[i].zs.idx = VK_ATTACHMENT_UNUSED;
|
||||
if (subpass->pDepthStencilAttachment) {
|
||||
uint32_t idx = subpass->pDepthStencilAttachment->attachment;
|
||||
subpasses[i].zs.idx = idx;
|
||||
if (idx != VK_ATTACHMENT_UNUSED) {
|
||||
subpasses[i].zs.before = attachments[idx].last;
|
||||
subpasses[i].zs.during =
|
||||
dzn_image_layout_to_state(subpass->pDepthStencilAttachment->layout);
|
||||
attachments[idx].last = subpasses[i].zs.during;
|
||||
}
|
||||
}
|
||||
|
||||
subpasses[i].input_count = subpass->inputAttachmentCount;
|
||||
for (uint32_t j = 0; j < subpasses[i].input_count; j++) {
|
||||
uint32_t idx = subpass->pInputAttachments[j].attachment;
|
||||
subpasses[i].inputs[j].idx = idx;
|
||||
if (idx != VK_ATTACHMENT_UNUSED) {
|
||||
subpasses[i].inputs[j].before = attachments[idx].last;
|
||||
subpasses[i].inputs[j].during =
|
||||
dzn_image_layout_to_state(subpass->pInputAttachments[j].layout);
|
||||
attachments[idx].last = subpasses[i].inputs[j].during;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*pRenderPass = dzn_render_pass_to_handle(pass);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
dzn_DestroyRenderPass(VkDevice dev,
|
||||
VkRenderPass p,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
VK_FROM_HANDLE(dzn_device, device, dev);
|
||||
VK_FROM_HANDLE(dzn_render_pass, pass, p);
|
||||
|
||||
if (!pass)
|
||||
return;
|
||||
|
||||
vk_object_base_finish(&pass->base);
|
||||
vk_free2(&device->vk.alloc, pAllocator, pass);
|
||||
}
|
||||
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
dzn_GetRenderAreaGranularity(VkDevice device,
|
||||
VkRenderPass pass,
|
||||
VkExtent2D *pGranularity)
|
||||
{
|
||||
// FIXME: query the actual optimal granularity
|
||||
pGranularity->width = pGranularity->height = 1;
|
||||
}
|
1184
src/microsoft/vulkan/dzn_pipeline.cpp
Normal file
1184
src/microsoft/vulkan/dzn_pipeline.cpp
Normal file
File diff suppressed because it is too large
Load Diff
99
src/microsoft/vulkan/dzn_pipeline_cache.cpp
Normal file
99
src/microsoft/vulkan/dzn_pipeline_cache.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
static void
|
||||
dzn_pipeline_cache_destroy(dzn_pipeline_cache *pcache,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
if (!pcache)
|
||||
return;
|
||||
|
||||
dzn_device *device = container_of(pcache->base.device, dzn_device, vk);
|
||||
|
||||
vk_object_base_finish(&pcache->base);
|
||||
vk_free2(&device->vk.alloc, pAllocator, pcache);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_pipeline_cache_create(dzn_device *device,
|
||||
const VkPipelineCacheCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkPipelineCache *out)
|
||||
{
|
||||
dzn_pipeline_cache *pcache = (dzn_pipeline_cache *)
|
||||
vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*pcache), 8,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!pcache)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
vk_object_base_init(&device->vk, &pcache->base, VK_OBJECT_TYPE_PIPELINE_CACHE);
|
||||
|
||||
/* TODO: cache-ism! */
|
||||
|
||||
*out = dzn_pipeline_cache_to_handle(pcache);
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
dzn_CreatePipelineCache(VkDevice device,
|
||||
const VkPipelineCacheCreateInfo *pCreateInfo,
|
||||
const VkAllocationCallbacks *pAllocator,
|
||||
VkPipelineCache *pPipelineCache)
|
||||
{
|
||||
return dzn_pipeline_cache_create(dzn_device_from_handle(device),
|
||||
pCreateInfo, pAllocator, pPipelineCache);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
dzn_DestroyPipelineCache(VkDevice device,
|
||||
VkPipelineCache pipelineCache,
|
||||
const VkAllocationCallbacks *pAllocator)
|
||||
{
|
||||
return dzn_pipeline_cache_destroy(dzn_pipeline_cache_from_handle(pipelineCache),
|
||||
pAllocator);
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
dzn_GetPipelineCacheData(VkDevice device,
|
||||
VkPipelineCache pipelineCache,
|
||||
size_t *pDataSize,
|
||||
void *pData)
|
||||
{
|
||||
// FIXME
|
||||
*pDataSize = 0;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL
|
||||
dzn_MergePipelineCaches(VkDevice device,
|
||||
VkPipelineCache dstCache,
|
||||
uint32_t srcCacheCount,
|
||||
const VkPipelineCache *pSrcCaches)
|
||||
{
|
||||
// FIXME
|
||||
return VK_SUCCESS;
|
||||
}
|
1060
src/microsoft/vulkan/dzn_private.h
Normal file
1060
src/microsoft/vulkan/dzn_private.h
Normal file
File diff suppressed because it is too large
Load Diff
327
src/microsoft/vulkan/dzn_query.cpp
Normal file
327
src/microsoft/vulkan/dzn_query.cpp
Normal file
@ -0,0 +1,327 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
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 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(dzn_query_pool *qpool,
|
||||
const VkAllocationCallbacks *alloc)
|
||||
{
|
||||
if (!qpool)
|
||||
return;
|
||||
|
||||
dzn_device *device = container_of(qpool->base.device, dzn_device, vk);
|
||||
|
||||
if (qpool->collect_map)
|
||||
qpool->collect_buffer->Unmap(0, NULL);
|
||||
|
||||
if (qpool->collect_buffer)
|
||||
qpool->collect_buffer->Release();
|
||||
|
||||
if (qpool->resolve_buffer)
|
||||
qpool->resolve_buffer->Release();
|
||||
|
||||
if (qpool->heap)
|
||||
qpool->heap->Release();
|
||||
|
||||
for (uint32_t q = 0; q < qpool->query_count; q++) {
|
||||
if (qpool->queries[q].fence)
|
||||
qpool->queries[q].fence->Release();
|
||||
}
|
||||
|
||||
mtx_destroy(&qpool->queries_lock);
|
||||
vk_object_base_finish(&qpool->base);
|
||||
vk_free2(&device->vk.alloc, alloc, qpool);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_query_pool_create(dzn_device *device,
|
||||
const VkQueryPoolCreateInfo *info,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
VkQueryPool *out)
|
||||
{
|
||||
VK_MULTIALLOC(ma);
|
||||
VK_MULTIALLOC_DECL(&ma, dzn_query_pool, qpool, 1);
|
||||
VK_MULTIALLOC_DECL(&ma, 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 =
|
||||
device->dev->CreateQueryHeap(&desc, IID_PPV_ARGS(&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 =
|
||||
device->dev->GetCustomHeapProperties(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 = device->dev->CreateCommittedResource(&hprops,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&rdesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
NULL, IID_PPV_ARGS(&qpool->resolve_buffer));
|
||||
if (FAILED(hres)) {
|
||||
dzn_query_pool_destroy(qpool, alloc);
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
}
|
||||
|
||||
hprops = device->dev->GetCustomHeapProperties(0, D3D12_HEAP_TYPE_READBACK);
|
||||
rdesc.Width = info->queryCount * (qpool->query_size + sizeof(uint64_t));
|
||||
hres = device->dev->CreateCommittedResource(&hprops,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&rdesc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
NULL, IID_PPV_ARGS(&qpool->collect_buffer));
|
||||
if (FAILED(hres)) {
|
||||
dzn_query_pool_destroy(qpool, alloc);
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
}
|
||||
|
||||
hres = qpool->collect_buffer->Map(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 dzn_query_pool *qpool, uint32_t query)
|
||||
{
|
||||
return query * qpool->query_size;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dzn_query_pool_get_result_size(const dzn_query_pool *qpool, uint32_t query_count)
|
||||
{
|
||||
return query_count * qpool->query_size;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
dzn_query_pool_get_availability_offset(const 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++) {
|
||||
dzn_query *query = &qpool->queries[firstQuery + q];
|
||||
|
||||
query->fence_value = 0;
|
||||
if (query->fence) {
|
||||
query->fence->Release();
|
||||
query->fence = NULL;
|
||||
}
|
||||
}
|
||||
mtx_lock(&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++) {
|
||||
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) {
|
||||
ComPtr<ID3D12Fence> query_fence(NULL);
|
||||
uint64_t query_fence_val = 0;
|
||||
|
||||
while (true) {
|
||||
mtx_lock(&qpool->queries_lock);
|
||||
query_fence = ComPtr<ID3D12Fence>(query->fence);
|
||||
query_fence_val = query->fence_value;
|
||||
mtx_unlock(&qpool->queries_lock);
|
||||
|
||||
if (query_fence.Get())
|
||||
break;
|
||||
|
||||
/* Check again in 10ms.
|
||||
* FIXME: decrease the polling period if it happens to hurt latency.
|
||||
*/
|
||||
Sleep(10);
|
||||
}
|
||||
|
||||
query_fence->SetEventOnCompletion(query_fence_val, NULL);
|
||||
available = UINT64_MAX;
|
||||
} else {
|
||||
mtx_lock(&qpool->queries_lock);
|
||||
ComPtr<ID3D12Fence> query_fence(query->fence);
|
||||
uint64_t query_fence_val = query->fence_value;
|
||||
mtx_unlock(&qpool->queries_lock);
|
||||
|
||||
if (query_fence.Get() &&
|
||||
query_fence->GetCompletedValue() >= query_fence_val)
|
||||
available = UINT64_MAX;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
203
src/microsoft/vulkan/dzn_sync.cpp
Normal file
203
src/microsoft/vulkan/dzn_sync.cpp
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
static VkResult
|
||||
dzn_sync_init(struct vk_device *device,
|
||||
struct vk_sync *sync,
|
||||
uint64_t initial_value)
|
||||
{
|
||||
dzn_sync *dsync = container_of(sync, dzn_sync, vk);
|
||||
dzn_device *ddev = container_of(device, dzn_device, vk);
|
||||
|
||||
assert(!(sync->flags & VK_SYNC_IS_SHAREABLE));
|
||||
|
||||
if (FAILED(ddev->dev->CreateFence(initial_value, D3D12_FENCE_FLAG_NONE,
|
||||
IID_PPV_ARGS(&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)
|
||||
{
|
||||
dzn_sync *dsync = container_of(sync, dzn_sync, vk);
|
||||
|
||||
dsync->fence->Release();
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_sync_signal(struct vk_device *device,
|
||||
struct vk_sync *sync,
|
||||
uint64_t value)
|
||||
{
|
||||
dzn_sync *dsync = container_of(sync, dzn_sync, vk);
|
||||
|
||||
if (!(sync->flags & VK_SYNC_IS_TIMELINE))
|
||||
value = 1;
|
||||
|
||||
if (FAILED(dsync->fence->Signal(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)
|
||||
{
|
||||
dzn_sync *dsync = container_of(sync, dzn_sync, vk);
|
||||
|
||||
*value = dsync->fence->GetCompletedValue();
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
dzn_sync_reset(struct vk_device *device,
|
||||
struct vk_sync *sync)
|
||||
{
|
||||
dzn_sync *dsync = container_of(sync, dzn_sync, vk);
|
||||
|
||||
if (FAILED(dsync->fence->Signal(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)
|
||||
{
|
||||
dzn_device *ddev = container_of(device, dzn_device, vk);
|
||||
dzn_sync *ddst = container_of(dst, dzn_sync, vk);
|
||||
dzn_sync *dsrc = container_of(src, dzn_sync, vk);
|
||||
ID3D12Fence *new_fence;
|
||||
|
||||
if (FAILED(ddev->dev->CreateFence(0, D3D12_FENCE_FLAG_NONE,
|
||||
IID_PPV_ARGS(&new_fence))))
|
||||
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
|
||||
ddst->fence->Release();
|
||||
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)
|
||||
{
|
||||
dzn_device *ddev = container_of(device, dzn_device, vk);
|
||||
|
||||
HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL);
|
||||
if (event == NULL)
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
|
||||
STACK_ARRAY(ID3D12Fence *, fences, wait_count);
|
||||
STACK_ARRAY(uint64_t, values, wait_count);
|
||||
|
||||
for (uint32_t i = 0; i < wait_count; i++) {
|
||||
dzn_sync *sync = container_of(waits[i].sync, 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(ddev->dev->SetEventOnMultipleFenceCompletion(fences, values,
|
||||
wait_count, flags,
|
||||
event))) {
|
||||
STACK_ARRAY_FINISH(fences);
|
||||
STACK_ARRAY_FINISH(values);
|
||||
CloseHandle(event);
|
||||
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
}
|
||||
|
||||
DWORD timeout_ms;
|
||||
|
||||
if (abs_timeout_ns == OS_TIMEOUT_INFINITE) {
|
||||
timeout_ms = 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);
|
||||
}
|
||||
|
||||
DWORD res =
|
||||
WaitForSingleObject(event, timeout_ms);
|
||||
|
||||
CloseHandle(event);
|
||||
|
||||
STACK_ARRAY_FINISH(fences);
|
||||
STACK_ARRAY_FINISH(values);
|
||||
|
||||
if (res == WAIT_TIMEOUT)
|
||||
return VK_TIMEOUT;
|
||||
else if (res != WAIT_OBJECT_0)
|
||||
return vk_error(device, VK_ERROR_UNKNOWN);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
const struct vk_sync_type dzn_sync_type = {
|
||||
.size = sizeof(dzn_sync),
|
||||
.features = (enum vk_sync_features)
|
||||
(VK_SYNC_FEATURE_BINARY |
|
||||
VK_SYNC_FEATURE_TIMELINE |
|
||||
VK_SYNC_FEATURE_GPU_WAIT |
|
||||
VK_SYNC_FEATURE_GPU_MULTI_WAIT |
|
||||
VK_SYNC_FEATURE_CPU_WAIT |
|
||||
VK_SYNC_FEATURE_CPU_RESET |
|
||||
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,
|
||||
};
|
234
src/microsoft/vulkan/dzn_util.c
Normal file
234
src/microsoft/vulkan/dzn_util.c
Normal file
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* 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 <directx/d3d12.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include "util/format/u_format.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_B4G4R4A4_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];
|
||||
}
|
||||
|
||||
struct dzn_sampler_filter_info {
|
||||
VkFilter min, mag;
|
||||
VkSamplerMipmapMode mipmap;
|
||||
};
|
||||
|
||||
#define FILTER(__min, __mag, __mipmap) \
|
||||
{ \
|
||||
.min = VK_FILTER_ ## __min, \
|
||||
.mag = VK_FILTER_ ## __mag, \
|
||||
.mipmap = VK_SAMPLER_MIPMAP_MODE_ ## __mipmap, \
|
||||
}
|
||||
|
||||
static const struct dzn_sampler_filter_info filter_table[] = {
|
||||
[D3D12_FILTER_MIN_MAG_MIP_POINT] = FILTER(NEAREST, NEAREST, NEAREST),
|
||||
[D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR] = FILTER(NEAREST, NEAREST, LINEAR),
|
||||
[D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT] = FILTER(NEAREST, LINEAR, NEAREST),
|
||||
[D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR] = FILTER(NEAREST, LINEAR, LINEAR),
|
||||
[D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT] = FILTER(LINEAR, NEAREST, NEAREST),
|
||||
[D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR] = FILTER(LINEAR, NEAREST, LINEAR),
|
||||
[D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT] = FILTER(LINEAR, LINEAR, NEAREST),
|
||||
[D3D12_FILTER_MIN_MAG_MIP_LINEAR] = FILTER(LINEAR, LINEAR, LINEAR),
|
||||
};
|
||||
|
||||
dzn_translate_sampler_filter(const VkSamplerCreateInfo *create_info)
|
||||
{
|
||||
D3D12_FILTER filter;
|
||||
|
||||
if (!create_info->anisotropyEnable) {
|
||||
unsigned i;
|
||||
for (i = 0; i < ARRAY_SIZE(filter_table); i++) {
|
||||
if (create_info->minFilter == filter_table[i].min &&
|
||||
create_info->magFilter == filter_table[i].mag &&
|
||||
create_info->mipmapMode == filter_table[i].mipmap) {
|
||||
filter = (D3D12_FILTER)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(i < ARRAY_SIZE(filter_table));
|
||||
} else {
|
||||
filter = D3D12_FILTER_ANISOTROPIC;
|
||||
}
|
||||
|
||||
if (create_info->compareEnable)
|
||||
filter = (D3D12_FILTER)(filter + D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT);
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
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->y;
|
||||
out->Width = in->width;
|
||||
out->Height = abs(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;
|
||||
}
|
226
src/microsoft/vulkan/dzn_util.cpp
Normal file
226
src/microsoft/vulkan/dzn_util.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* 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_enum_to_str.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <directx/d3d12sdklayers.h>
|
||||
|
||||
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", hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
static ComPtr<ID3D12Debug>
|
||||
get_debug_interface()
|
||||
{
|
||||
typedef HRESULT(WINAPI *PFN_D3D12_GET_DEBUG_INTERFACE)(REFIID riid, void **ppFactory);
|
||||
PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterface;
|
||||
|
||||
HMODULE d3d12_mod = LoadLibraryA("D3D12.DLL");
|
||||
if (!d3d12_mod) {
|
||||
mesa_loge("failed to load D3D12.DLL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
D3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)GetProcAddress(d3d12_mod, "D3D12GetDebugInterface");
|
||||
if (!D3D12GetDebugInterface) {
|
||||
mesa_loge("failed to load D3D12GetDebugInterface from D3D12.DLL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ComPtr<ID3D12Debug> debug;
|
||||
if (FAILED(D3D12GetDebugInterface(IID_PPV_ARGS(&debug)))) {
|
||||
mesa_loge("D3D12GetDebugInterface failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_enable_debug_layer()
|
||||
{
|
||||
ComPtr<ID3D12Debug> debug = get_debug_interface();
|
||||
if (debug)
|
||||
debug->EnableDebugLayer();
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_enable_gpu_validation()
|
||||
{
|
||||
ComPtr<ID3D12Debug> debug = get_debug_interface();
|
||||
ComPtr<ID3D12Debug3> debug3;
|
||||
if (debug &&
|
||||
SUCCEEDED(debug->QueryInterface(IID_PPV_ARGS(&debug3))))
|
||||
debug3->SetEnableGPUBasedValidation(true);
|
||||
}
|
||||
|
||||
ID3D12Device1 *
|
||||
d3d12_create_device(IUnknown *adapter, bool experimental_features)
|
||||
{
|
||||
typedef HRESULT(WINAPI *PFN_D3D12CREATEDEVICE)(IUnknown*, D3D_FEATURE_LEVEL, REFIID, void**);
|
||||
PFN_D3D12CREATEDEVICE D3D12CreateDevice;
|
||||
|
||||
HMODULE d3d12_mod = LoadLibraryA("D3D12.DLL");
|
||||
if (!d3d12_mod) {
|
||||
mesa_loge("failed to load D3D12.DLL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (experimental_features)
|
||||
#endif
|
||||
{
|
||||
typedef HRESULT(WINAPI *PFN_D3D12ENABLEEXPERIMENTALFEATURES)(UINT, const IID*, void*, UINT*);
|
||||
PFN_D3D12ENABLEEXPERIMENTALFEATURES D3D12EnableExperimentalFeatures =
|
||||
(PFN_D3D12ENABLEEXPERIMENTALFEATURES)GetProcAddress(d3d12_mod, "D3D12EnableExperimentalFeatures");
|
||||
if (FAILED(D3D12EnableExperimentalFeatures(1, &D3D12ExperimentalShaderModels, NULL, NULL))) {
|
||||
mesa_loge("failed to enable experimental shader models\n");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
D3D12CreateDevice = (PFN_D3D12CREATEDEVICE)GetProcAddress(d3d12_mod, "D3D12CreateDevice");
|
||||
if (!D3D12CreateDevice) {
|
||||
mesa_loge("failed to load D3D12CreateDevice from D3D12.DLL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ID3D12Device1 *dev;
|
||||
if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0,
|
||||
IID_PPV_ARGS(&dev))))
|
||||
return dev;
|
||||
|
||||
mesa_loge("D3D12CreateDevice failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IDxcValidator *
|
||||
dxil_get_validator(void)
|
||||
{
|
||||
IDxcValidator *ret = NULL;
|
||||
|
||||
HMODULE dxil_mod = LoadLibraryA("dxil.dll");
|
||||
if (!dxil_mod) {
|
||||
mesa_loge("failed to load dxil.dll\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
DxcCreateInstanceProc CreateInstance = (DxcCreateInstanceProc)
|
||||
GetProcAddress(dxil_mod, "DxcCreateInstance");
|
||||
HRESULT hr = CreateInstance(CLSID_DxcValidator, IID_PPV_ARGS(&ret));
|
||||
if (FAILED(hr))
|
||||
mesa_loge("DxcCreateInstance failed: %08x\n", hr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE
|
||||
d3d12_get_serialize_root_sig(void)
|
||||
{
|
||||
HMODULE d3d12_mod = LoadLibraryA("d3d12.dll");
|
||||
if (!d3d12_mod) {
|
||||
mesa_loge("failed to load d3d12.dll\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)
|
||||
GetProcAddress(d3d12_mod, "D3D12SerializeVersionedRootSignature");
|
||||
}
|
||||
|
||||
IDxcLibrary *
|
||||
dxc_get_library(void)
|
||||
{
|
||||
IDxcLibrary *ret = NULL;
|
||||
|
||||
HMODULE dxil_mod = LoadLibraryA("dxcompiler.dll");
|
||||
if (!dxil_mod) {
|
||||
mesa_loge("failed to load dxcompiler.dll\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
DxcCreateInstanceProc CreateInstance = (DxcCreateInstanceProc)
|
||||
GetProcAddress(dxil_mod, "DxcCreateInstance");
|
||||
HRESULT hr = CreateInstance(CLSID_DxcLibrary, IID_PPV_ARGS(&ret));
|
||||
if (FAILED(hr))
|
||||
mesa_loge("DxcCreateInstance failed: %08x\n", hr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
IDxcCompiler *
|
||||
dxc_get_compiler(void)
|
||||
{
|
||||
IDxcCompiler *ret = NULL;
|
||||
|
||||
HMODULE dxil_mod = LoadLibraryA("dxcompiler.dll");
|
||||
if (!dxil_mod) {
|
||||
mesa_loge("failed to load dxcompiler.dll\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
DxcCreateInstanceProc CreateInstance = (DxcCreateInstanceProc)
|
||||
GetProcAddress(dxil_mod, "DxcCreateInstance");
|
||||
HRESULT hr = CreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&ret));
|
||||
if (FAILED(hr))
|
||||
mesa_loge("DxcCreateInstance failed: %08x\n", hr);
|
||||
|
||||
return ret;
|
||||
}
|
64
src/microsoft/vulkan/dzn_wsi.cpp
Normal file
64
src/microsoft/vulkan/dzn_wsi.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* TODO: implement a proper, non-sw winsys for D3D12 */
|
||||
bool sw_device = true;
|
||||
|
||||
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, sw_device);
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
physical_device->wsi_device.supports_modifiers = false;
|
||||
physical_device->vk.wsi_device = &physical_device->wsi_device;
|
||||
physical_device->wsi_device.signal_semaphore_with_memory = true;
|
||||
physical_device->wsi_device.signal_fence_with_memory = true;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
123
src/microsoft/vulkan/meson.build
Normal file
123
src/microsoft/vulkan/meson.build
Normal file
@ -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.
|
||||
|
||||
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'
|
||||
],
|
||||
depend_files : vk_entrypoints_gen_depend_files,
|
||||
)
|
||||
|
||||
libdzn_files = files(
|
||||
'dzn_cmd_buffer.cpp',
|
||||
'dzn_descriptor_set.cpp',
|
||||
'dzn_device.cpp',
|
||||
'dzn_image.cpp',
|
||||
'dzn_meta.cpp',
|
||||
'dzn_nir.c',
|
||||
'dzn_pass.cpp',
|
||||
'dzn_pipeline_cache.cpp',
|
||||
'dzn_pipeline.cpp',
|
||||
'dzn_query.cpp',
|
||||
'dzn_sync.cpp',
|
||||
'dzn_util.cpp',
|
||||
'dzn_util.c',
|
||||
'dzn_wsi.cpp',
|
||||
)
|
||||
|
||||
dzn_deps = [
|
||||
idep_libdxil_compiler,
|
||||
idep_libspirv_to_dxil,
|
||||
idep_nir,
|
||||
idep_nir_headers,
|
||||
idep_vulkan_util,
|
||||
idep_vulkan_runtime,
|
||||
idep_vulkan_wsi,
|
||||
dep_dxheaders,
|
||||
]
|
||||
|
||||
dzn_flags = [ ]
|
||||
|
||||
if with_platform_windows
|
||||
dzn_flags += '-DVK_USE_PLATFORM_WIN32_KHR'
|
||||
endif
|
||||
|
||||
libvulkan_dzn = shared_library(
|
||||
'vulkan_dzn',
|
||||
[libdzn_files, dzn_entrypoints, sha1_h],
|
||||
vs_module_defs : 'vulkan_dzn.def',
|
||||
include_directories : [
|
||||
inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux,
|
||||
inc_compiler, inc_util
|
||||
],
|
||||
dependencies : [dzn_deps, idep_vulkan_wsi],
|
||||
c_args : dzn_flags,
|
||||
cpp_args : dzn_flags,
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
link_args : [ld_args_bsymbolic, ld_args_gc_sections],
|
||||
name_prefix : host_machine.system() == 'windows' ? '' : 'lib',
|
||||
install : true,
|
||||
override_options: ['cpp_std=c++latest']
|
||||
)
|
||||
|
||||
icd_file_name = 'libvulkan_dzn.so'
|
||||
module_dir = join_paths(get_option('prefix'), get_option('libdir'))
|
||||
if with_platform_windows
|
||||
module_dir = join_paths(get_option('prefix'), get_option('bindir'))
|
||||
icd_file_name = 'vulkan_dzn.dll'
|
||||
endif
|
||||
|
||||
dzn_icd = custom_target(
|
||||
'dzn_icd',
|
||||
input : [vk_icd_gen, vk_api_xml],
|
||||
output : 'dzn_icd.@0@.json'.format(host_machine.cpu()),
|
||||
command : [
|
||||
prog_python, '@INPUT0@',
|
||||
'--api-version', '1.2', '--xml', '@INPUT1@',
|
||||
'--lib-path', join_paths(module_dir, icd_file_name),
|
||||
'--out', '@OUTPUT@',
|
||||
],
|
||||
build_by_default : true,
|
||||
install_dir : with_vulkan_icd_dir,
|
||||
install : true,
|
||||
)
|
||||
|
||||
if meson.version().version_compare('>= 0.58')
|
||||
_dev_icdname = 'dzn_devenv_icd.@0@.json'.format(host_machine.cpu())
|
||||
custom_target(
|
||||
'dzn_devenv_icd',
|
||||
input : [vk_icd_gen, vk_api_xml],
|
||||
output : _dev_icdname,
|
||||
command : [
|
||||
prog_python, '@INPUT0@',
|
||||
'--api-version', '1.1', '--xml', '@INPUT1@',
|
||||
'--lib-path', meson.current_build_dir() / icd_file_name,
|
||||
'--out', '@OUTPUT@',
|
||||
],
|
||||
build_by_default : true,
|
||||
)
|
||||
|
||||
devenv.append('VK_ICD_FILENAMES', meson.current_build_dir() / _dev_icdname)
|
||||
endif
|
4
src/microsoft/vulkan/vulkan_dzn.def
Normal file
4
src/microsoft/vulkan/vulkan_dzn.def
Normal file
@ -0,0 +1,4 @@
|
||||
EXPORTS
|
||||
vk_icdNegotiateLoaderICDInterfaceVersion
|
||||
vk_icdGetInstanceProcAddr
|
||||
vk_icdGetPhysicalDeviceProcAddr
|
Loading…
Reference in New Issue
Block a user