vkd3d: Rework d3d12_create_sampler.

This now takes a sampler desc like d3d12_create_static_sampler,
and supports border colors if the provided border color matches
any of the supported Vulkan ones.

Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
This commit is contained in:
Philip Rebohle 2020-04-17 17:06:58 +02:00 committed by Hans-Kristian Arntzen
parent 532cb49abb
commit 9d361c56d6
1 changed files with 48 additions and 35 deletions

View File

@ -3314,6 +3314,32 @@ static VkBorderColor vk_static_border_color_from_d3d12(D3D12_STATIC_BORDER_COLOR
}
}
static VkBorderColor vk_border_color_from_d3d12(const float *border_color)
{
unsigned int i;
static const struct
{
float color[4];
VkBorderColor vk_border_color;
}
border_colors[] = {
{ {0.0f, 0.0f, 0.0f, 0.0f}, VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK },
{ {0.0f, 0.0f, 0.0f, 1.0f}, VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK },
{ {1.0f, 1.0f, 1.0f, 1.0f}, VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE },
};
for (i = 0; i < ARRAY_SIZE(border_colors); i++)
{
if (!memcmp(border_color, border_colors[i].color, sizeof(border_colors[i].color)))
return border_colors[i].vk_border_color;
}
FIXME("Unsupported border color (%f, %f, %f, %f).\n",
border_color[0], border_color[1], border_color[2], border_color[3]);
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
}
HRESULT d3d12_create_static_sampler(struct d3d12_device *device,
const D3D12_STATIC_SAMPLER_DESC *desc, VkSampler *vk_sampler)
{
@ -3349,44 +3375,39 @@ HRESULT d3d12_create_static_sampler(struct d3d12_device *device,
return hresult_from_vk_result(vr);
}
static VkResult d3d12_create_sampler(struct d3d12_device *device, D3D12_FILTER filter,
D3D12_TEXTURE_ADDRESS_MODE address_u, D3D12_TEXTURE_ADDRESS_MODE address_v,
D3D12_TEXTURE_ADDRESS_MODE address_w, float mip_lod_bias, unsigned int max_anisotropy,
D3D12_COMPARISON_FUNC comparison_func, float min_lod, float max_lod,
VkSampler *vk_sampler)
static HRESULT d3d12_create_sampler(struct d3d12_device *device,
const D3D12_SAMPLER_DESC *desc, VkSampler *vk_sampler)
{
const struct vkd3d_vk_device_procs *vk_procs;
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct VkSamplerCreateInfo sampler_desc;
VkResult vr;
vk_procs = &device->vk_procs;
if (D3D12_DECODE_FILTER_REDUCTION(filter) == D3D12_FILTER_REDUCTION_TYPE_MINIMUM
|| D3D12_DECODE_FILTER_REDUCTION(filter) == D3D12_FILTER_REDUCTION_TYPE_MAXIMUM)
FIXME("Min/max reduction mode not supported.\n");
sampler_desc.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
sampler_desc.pNext = NULL;
sampler_desc.flags = 0;
sampler_desc.magFilter = vk_filter_from_d3d12(D3D12_DECODE_MAG_FILTER(filter));
sampler_desc.minFilter = vk_filter_from_d3d12(D3D12_DECODE_MIN_FILTER(filter));
sampler_desc.mipmapMode = vk_mipmap_mode_from_d3d12(D3D12_DECODE_MIP_FILTER(filter));
sampler_desc.addressModeU = vk_address_mode_from_d3d12(address_u);
sampler_desc.addressModeV = vk_address_mode_from_d3d12(address_v);
sampler_desc.addressModeW = vk_address_mode_from_d3d12(address_w);
sampler_desc.mipLodBias = mip_lod_bias;
sampler_desc.anisotropyEnable = D3D12_DECODE_IS_ANISOTROPIC_FILTER(filter);
sampler_desc.maxAnisotropy = max_anisotropy;
sampler_desc.compareEnable = D3D12_DECODE_IS_COMPARISON_FILTER(filter);
sampler_desc.compareOp = sampler_desc.compareEnable ? vk_compare_op_from_d3d12(comparison_func) : 0;
sampler_desc.minLod = min_lod;
sampler_desc.maxLod = max_lod;
sampler_desc.magFilter = vk_filter_from_d3d12(D3D12_DECODE_MAG_FILTER(desc->Filter));
sampler_desc.minFilter = vk_filter_from_d3d12(D3D12_DECODE_MIN_FILTER(desc->Filter));
sampler_desc.mipmapMode = vk_mipmap_mode_from_d3d12(D3D12_DECODE_MIP_FILTER(desc->Filter));
sampler_desc.addressModeU = vk_address_mode_from_d3d12(desc->AddressU);
sampler_desc.addressModeV = vk_address_mode_from_d3d12(desc->AddressV);
sampler_desc.addressModeW = vk_address_mode_from_d3d12(desc->AddressW);
sampler_desc.mipLodBias = desc->MipLODBias;
sampler_desc.anisotropyEnable = D3D12_DECODE_IS_ANISOTROPIC_FILTER(desc->Filter);
sampler_desc.maxAnisotropy = desc->MaxAnisotropy;
sampler_desc.compareEnable = D3D12_DECODE_IS_COMPARISON_FILTER(desc->Filter);
sampler_desc.compareOp = sampler_desc.compareEnable ? vk_compare_op_from_d3d12(desc->ComparisonFunc) : 0;
sampler_desc.minLod = desc->MinLOD;
sampler_desc.maxLod = desc->MaxLOD;
sampler_desc.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
sampler_desc.unnormalizedCoordinates = VK_FALSE;
if (d3d12_sampler_needs_border_color(desc->AddressU, desc->AddressV, desc->AddressW))
sampler_desc.borderColor = vk_border_color_from_d3d12(desc->BorderColor);
if ((vr = VK_CALL(vkCreateSampler(device->vk_device, &sampler_desc, NULL, vk_sampler))) < 0)
WARN("Failed to create Vulkan sampler, vr %d.\n", vr);
return vr;
return hresult_from_vk_result(vr);
}
void d3d12_desc_create_sampler(struct d3d12_desc *sampler,
@ -3400,18 +3421,10 @@ void d3d12_desc_create_sampler(struct d3d12_desc *sampler,
return;
}
if (desc->AddressU == D3D12_TEXTURE_ADDRESS_MODE_BORDER
|| desc->AddressV == D3D12_TEXTURE_ADDRESS_MODE_BORDER
|| desc->AddressW == D3D12_TEXTURE_ADDRESS_MODE_BORDER)
FIXME("Ignoring border color {%.8e, %.8e, %.8e, %.8e}.\n",
desc->BorderColor[0], desc->BorderColor[1], desc->BorderColor[2], desc->BorderColor[3]);
if (!(view = vkd3d_view_create(VKD3D_VIEW_TYPE_SAMPLER)))
return;
if (d3d12_create_sampler(device, desc->Filter, desc->AddressU,
desc->AddressV, desc->AddressW, desc->MipLODBias, desc->MaxAnisotropy,
desc->ComparisonFunc, desc->MinLOD, desc->MaxLOD, &view->u.vk_sampler) < 0)
if (FAILED(d3d12_create_sampler(device, desc, &view->u.vk_sampler)))
{
vkd3d_free(view);
return;