xref: /aosp_15_r20/external/mesa3d/src/freedreno/vulkan/tu_sampler.cc (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Red Hat.
3*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Bas Nieuwenhuizen
4*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
5*61046927SAndroid Build Coastguard Worker  *
6*61046927SAndroid Build Coastguard Worker  * based in part on anv driver which is:
7*61046927SAndroid Build Coastguard Worker  * Copyright © 2015 Intel Corporation
8*61046927SAndroid Build Coastguard Worker  */
9*61046927SAndroid Build Coastguard Worker 
10*61046927SAndroid Build Coastguard Worker #include "tu_sampler.h"
11*61046927SAndroid Build Coastguard Worker 
12*61046927SAndroid Build Coastguard Worker #include "tu_device.h"
13*61046927SAndroid Build Coastguard Worker #include "tu_util.h"
14*61046927SAndroid Build Coastguard Worker 
15*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
tu_CreateSampler(VkDevice _device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)16*61046927SAndroid Build Coastguard Worker tu_CreateSampler(VkDevice _device,
17*61046927SAndroid Build Coastguard Worker                  const VkSamplerCreateInfo *pCreateInfo,
18*61046927SAndroid Build Coastguard Worker                  const VkAllocationCallbacks *pAllocator,
19*61046927SAndroid Build Coastguard Worker                  VkSampler *pSampler)
20*61046927SAndroid Build Coastguard Worker {
21*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_device, device, _device);
22*61046927SAndroid Build Coastguard Worker    struct tu_sampler *sampler;
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker    sampler = (struct tu_sampler *) vk_sampler_create(
27*61046927SAndroid Build Coastguard Worker       &device->vk, pCreateInfo, pAllocator, sizeof(*sampler));
28*61046927SAndroid Build Coastguard Worker    if (!sampler)
29*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker    const struct VkSamplerYcbcrConversionInfo *ycbcr_conversion =
32*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pCreateInfo->pNext,  SAMPLER_YCBCR_CONVERSION_INFO);
33*61046927SAndroid Build Coastguard Worker    /* for non-custom border colors, the VK enum is translated directly to an offset in
34*61046927SAndroid Build Coastguard Worker     * the border color buffer. custom border colors are located immediately after the
35*61046927SAndroid Build Coastguard Worker     * builtin colors, and thus an offset of TU_BORDER_COLOR_BUILTIN is added.
36*61046927SAndroid Build Coastguard Worker     */
37*61046927SAndroid Build Coastguard Worker    uint32_t border_color = (unsigned) pCreateInfo->borderColor;
38*61046927SAndroid Build Coastguard Worker    if (vk_border_color_is_custom(pCreateInfo->borderColor)) {
39*61046927SAndroid Build Coastguard Worker       mtx_lock(&device->mutex);
40*61046927SAndroid Build Coastguard Worker       border_color = BITSET_FFS(device->custom_border_color) - 1;
41*61046927SAndroid Build Coastguard Worker       assert(border_color < TU_BORDER_COLOR_COUNT);
42*61046927SAndroid Build Coastguard Worker       BITSET_CLEAR(device->custom_border_color, border_color);
43*61046927SAndroid Build Coastguard Worker       mtx_unlock(&device->mutex);
44*61046927SAndroid Build Coastguard Worker 
45*61046927SAndroid Build Coastguard Worker       VkClearColorValue color = sampler->vk.border_color_value;
46*61046927SAndroid Build Coastguard Worker       if (sampler->vk.format == VK_FORMAT_D24_UNORM_S8_UINT &&
47*61046927SAndroid Build Coastguard Worker           pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT &&
48*61046927SAndroid Build Coastguard Worker           device->use_z24uint_s8uint) {
49*61046927SAndroid Build Coastguard Worker          /* When sampling stencil using the special Z24UINT_S8UINT format, the
50*61046927SAndroid Build Coastguard Worker           * border color is in the second component. Note: if
51*61046927SAndroid Build Coastguard Worker           * customBorderColorWithoutFormat is enabled, we may miss doing this
52*61046927SAndroid Build Coastguard Worker           * here if the format isn't specified, which is why we don't use that
53*61046927SAndroid Build Coastguard Worker           * format.
54*61046927SAndroid Build Coastguard Worker           */
55*61046927SAndroid Build Coastguard Worker          color.uint32[1] = color.uint32[0];
56*61046927SAndroid Build Coastguard Worker       }
57*61046927SAndroid Build Coastguard Worker 
58*61046927SAndroid Build Coastguard Worker       tu6_pack_border_color(
59*61046927SAndroid Build Coastguard Worker          &device->global_bo_map->bcolor[border_color], &color,
60*61046927SAndroid Build Coastguard Worker          pCreateInfo->borderColor == VK_BORDER_COLOR_INT_CUSTOM_EXT);
61*61046927SAndroid Build Coastguard Worker       border_color += TU_BORDER_COLOR_BUILTIN;
62*61046927SAndroid Build Coastguard Worker    }
63*61046927SAndroid Build Coastguard Worker 
64*61046927SAndroid Build Coastguard Worker    unsigned aniso = pCreateInfo->anisotropyEnable ?
65*61046927SAndroid Build Coastguard Worker       util_last_bit(MIN2((uint32_t)pCreateInfo->maxAnisotropy >> 1, 8)) : 0;
66*61046927SAndroid Build Coastguard Worker    bool miplinear = (pCreateInfo->mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR);
67*61046927SAndroid Build Coastguard Worker    float min_lod = CLAMP(pCreateInfo->minLod, 0.0f, 4095.0f / 256.0f);
68*61046927SAndroid Build Coastguard Worker    float max_lod = CLAMP(pCreateInfo->maxLod, 0.0f, 4095.0f / 256.0f);
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    sampler->descriptor[0] =
71*61046927SAndroid Build Coastguard Worker       COND(miplinear, A6XX_TEX_SAMP_0_MIPFILTER_LINEAR_NEAR) |
72*61046927SAndroid Build Coastguard Worker       A6XX_TEX_SAMP_0_XY_MAG(tu6_tex_filter(pCreateInfo->magFilter, aniso)) |
73*61046927SAndroid Build Coastguard Worker       A6XX_TEX_SAMP_0_XY_MIN(tu6_tex_filter(pCreateInfo->minFilter, aniso)) |
74*61046927SAndroid Build Coastguard Worker       A6XX_TEX_SAMP_0_ANISO((enum a6xx_tex_aniso) aniso) |
75*61046927SAndroid Build Coastguard Worker       A6XX_TEX_SAMP_0_WRAP_S(tu6_tex_wrap(pCreateInfo->addressModeU)) |
76*61046927SAndroid Build Coastguard Worker       A6XX_TEX_SAMP_0_WRAP_T(tu6_tex_wrap(pCreateInfo->addressModeV)) |
77*61046927SAndroid Build Coastguard Worker       A6XX_TEX_SAMP_0_WRAP_R(tu6_tex_wrap(pCreateInfo->addressModeW)) |
78*61046927SAndroid Build Coastguard Worker       A6XX_TEX_SAMP_0_LOD_BIAS(pCreateInfo->mipLodBias);
79*61046927SAndroid Build Coastguard Worker    sampler->descriptor[1] =
80*61046927SAndroid Build Coastguard Worker       COND(pCreateInfo->flags & VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT,
81*61046927SAndroid Build Coastguard Worker            A6XX_TEX_SAMP_1_CUBEMAPSEAMLESSFILTOFF) |
82*61046927SAndroid Build Coastguard Worker       COND(pCreateInfo->unnormalizedCoordinates, A6XX_TEX_SAMP_1_UNNORM_COORDS) |
83*61046927SAndroid Build Coastguard Worker       A6XX_TEX_SAMP_1_MIN_LOD(min_lod) |
84*61046927SAndroid Build Coastguard Worker       A6XX_TEX_SAMP_1_MAX_LOD(max_lod) |
85*61046927SAndroid Build Coastguard Worker       COND(pCreateInfo->compareEnable,
86*61046927SAndroid Build Coastguard Worker            A6XX_TEX_SAMP_1_COMPARE_FUNC(tu6_compare_func(pCreateInfo->compareOp)));
87*61046927SAndroid Build Coastguard Worker    sampler->descriptor[2] = A6XX_TEX_SAMP_2_BCOLOR(border_color);
88*61046927SAndroid Build Coastguard Worker    sampler->descriptor[3] = 0;
89*61046927SAndroid Build Coastguard Worker 
90*61046927SAndroid Build Coastguard Worker    if (sampler->vk.reduction_mode != VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE) {
91*61046927SAndroid Build Coastguard Worker       sampler->descriptor[2] |= A6XX_TEX_SAMP_2_REDUCTION_MODE(
92*61046927SAndroid Build Coastguard Worker          tu6_reduction_mode(sampler->vk.reduction_mode));
93*61046927SAndroid Build Coastguard Worker    }
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker    sampler->vk.ycbcr_conversion = ycbcr_conversion ?
96*61046927SAndroid Build Coastguard Worker       vk_ycbcr_conversion_from_handle(ycbcr_conversion->conversion) : NULL;
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker    if (sampler->vk.ycbcr_conversion &&
99*61046927SAndroid Build Coastguard Worker        sampler->vk.ycbcr_conversion->state.chroma_filter == VK_FILTER_LINEAR) {
100*61046927SAndroid Build Coastguard Worker       sampler->descriptor[2] |= A6XX_TEX_SAMP_2_CHROMA_LINEAR;
101*61046927SAndroid Build Coastguard Worker    }
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker    /* TODO:
104*61046927SAndroid Build Coastguard Worker     * A6XX_TEX_SAMP_1_MIPFILTER_LINEAR_FAR disables mipmapping, but vk has no NONE mipfilter?
105*61046927SAndroid Build Coastguard Worker     */
106*61046927SAndroid Build Coastguard Worker 
107*61046927SAndroid Build Coastguard Worker    *pSampler = tu_sampler_to_handle(sampler);
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
110*61046927SAndroid Build Coastguard Worker }
111*61046927SAndroid Build Coastguard Worker 
112*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
tu_DestroySampler(VkDevice _device,VkSampler _sampler,const VkAllocationCallbacks * pAllocator)113*61046927SAndroid Build Coastguard Worker tu_DestroySampler(VkDevice _device,
114*61046927SAndroid Build Coastguard Worker                   VkSampler _sampler,
115*61046927SAndroid Build Coastguard Worker                   const VkAllocationCallbacks *pAllocator)
116*61046927SAndroid Build Coastguard Worker {
117*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_device, device, _device);
118*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(tu_sampler, sampler, _sampler);
119*61046927SAndroid Build Coastguard Worker    uint32_t border_color;
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker    if (!sampler)
122*61046927SAndroid Build Coastguard Worker       return;
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker    border_color = (sampler->descriptor[2] & A6XX_TEX_SAMP_2_BCOLOR__MASK) >> A6XX_TEX_SAMP_2_BCOLOR__SHIFT;
125*61046927SAndroid Build Coastguard Worker    if (border_color >= TU_BORDER_COLOR_BUILTIN) {
126*61046927SAndroid Build Coastguard Worker       border_color -= TU_BORDER_COLOR_BUILTIN;
127*61046927SAndroid Build Coastguard Worker       /* if the sampler had a custom border color, free it. TODO: no lock */
128*61046927SAndroid Build Coastguard Worker       mtx_lock(&device->mutex);
129*61046927SAndroid Build Coastguard Worker       assert(!BITSET_TEST(device->custom_border_color, border_color));
130*61046927SAndroid Build Coastguard Worker       BITSET_SET(device->custom_border_color, border_color);
131*61046927SAndroid Build Coastguard Worker       mtx_unlock(&device->mutex);
132*61046927SAndroid Build Coastguard Worker    }
133*61046927SAndroid Build Coastguard Worker 
134*61046927SAndroid Build Coastguard Worker    vk_sampler_destroy(&device->vk, pAllocator, &sampler->vk);
135*61046927SAndroid Build Coastguard Worker }
136