diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/freedreno/vulkan/tu_device.c | 66 | ||||
-rw-r--r-- | src/freedreno/vulkan/tu_private.h | 7 |
2 files changed, 73 insertions, 0 deletions
diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index 8799f4109fb..54988ac83cd 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -1875,11 +1875,77 @@ tu_DestroyFramebuffer(VkDevice _device, vk_free2(&device->alloc, pAllocator, fb); } +static enum a6xx_tex_clamp +tu_tex_wrap(VkSamplerAddressMode address_mode, bool *needs_border) +{ + switch (address_mode) { + case VK_SAMPLER_ADDRESS_MODE_REPEAT: + return A6XX_TEX_REPEAT; + case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: + return A6XX_TEX_MIRROR_REPEAT; + case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: + return A6XX_TEX_CLAMP_TO_EDGE; + case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: + *needs_border = true; + return A6XX_TEX_CLAMP_TO_BORDER; + case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: + /* only works for PoT.. need to emulate otherwise! */ + return A6XX_TEX_MIRROR_CLAMP; + default: + unreachable("illegal tex wrap mode"); + break; + } +} + +static enum a6xx_tex_filter +tex_filter(VkFilter filter, unsigned aniso) +{ + switch (filter) { + case VK_FILTER_NEAREST: + return A6XX_TEX_NEAREST; + case VK_FILTER_LINEAR: + return aniso > 1 ? A6XX_TEX_ANISO : A6XX_TEX_LINEAR; + case VK_FILTER_CUBIC_IMG: + default: + fprintf(stderr, "illegal texture filter"); + return 0; + } +} + static void tu_init_sampler(struct tu_device *device, struct tu_sampler *sampler, const VkSamplerCreateInfo *pCreateInfo) { + unsigned aniso = pCreateInfo->anisotropyEnable ? + util_last_bit(MIN2((uint32_t)pCreateInfo->maxAnisotropy >> 1, 8)) : 0; + bool miplinear = (pCreateInfo->mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR); + bool needs_border = false; + + sampler->state[0] = + COND(miplinear, A6XX_TEX_SAMP_0_MIPFILTER_LINEAR_NEAR) | + A6XX_TEX_SAMP_0_XY_MAG(tex_filter(pCreateInfo->magFilter, aniso)) | + A6XX_TEX_SAMP_0_XY_MIN(tex_filter(pCreateInfo->minFilter, aniso)) | + A6XX_TEX_SAMP_0_ANISO(aniso) | + A6XX_TEX_SAMP_0_WRAP_S(tu_tex_wrap(pCreateInfo->addressModeU, &needs_border)) | + A6XX_TEX_SAMP_0_WRAP_T(tu_tex_wrap(pCreateInfo->addressModeV, &needs_border)) | + A6XX_TEX_SAMP_0_WRAP_R(tu_tex_wrap(pCreateInfo->addressModeW, &needs_border)) | + A6XX_TEX_SAMP_0_LOD_BIAS(pCreateInfo->mipLodBias); + sampler->state[1] = + /* COND(!cso->seamless_cube_map, A6XX_TEX_SAMP_1_CUBEMAPSEAMLESSFILTOFF) | */ + COND(pCreateInfo->unnormalizedCoordinates, A6XX_TEX_SAMP_1_UNNORM_COORDS) | + A6XX_TEX_SAMP_1_MIN_LOD(pCreateInfo->minLod) | + A6XX_TEX_SAMP_1_MAX_LOD(pCreateInfo->maxLod) | + 0; /* A6XX_TEX_SAMP_1_COMPARE_FUNC(cso->compare_func); */ + sampler->state[2] = 0; + sampler->state[3] = 0; + + /* TODO: + * A6XX_TEX_SAMP_1_MIPFILTER_LINEAR_FAR disables mipmapping, but vk has no NONE mipfilter? + * border color + */ + + sampler->needs_border = needs_border; } VkResult diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index c2440471f37..201ac49eda0 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -103,6 +103,8 @@ typedef uint32_t xcb_window_t; */ #define TU_BUFFER_OPS_CS_THRESHOLD 4096 +#define A6XX_TEX_SAMP_DWORDS 4 + enum tu_mem_heap { TU_MEM_HEAP_VRAM, @@ -211,6 +213,8 @@ tu_clear_mask(uint32_t *inout_mask, uint32_t clear_mask) memcpy((dest), (src), (count) * sizeof(*(src))); \ }) +#define COND(bool, val) ((bool) ? (val) : 0) + /* Whenever we generate an error, pass it through this function. Useful for * debugging, where we can break on it. Only call at error site, not when * propagating errors. Might be useful to plug in a stack trace here. @@ -1274,6 +1278,9 @@ struct tu_image_view struct tu_sampler { + uint32_t state[A6XX_TEX_SAMP_DWORDS]; + + bool needs_border; }; struct tu_image_create_info |