diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index c3472257..8f027d46 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -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;