turnip: implement sampler state
authorJonathan Marek <jonathan@marek.ca>
Wed, 25 Sep 2019 16:55:14 +0000 (12:55 -0400)
committerJonathan Marek <jonathan@marek.ca>
Thu, 26 Sep 2019 21:18:13 +0000 (17:18 -0400)
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
Acked-by: Eric Anholt <eric@anholt.net>
src/freedreno/vulkan/tu_device.c
src/freedreno/vulkan/tu_private.h

index 8799f4109fb92583be7921fe590a0296797d4d26..54988ac83cd75c3d8adbf6dcea59d8f9ce1474ce 100644 (file)
@@ -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
index c2440471f379365e35e3a03901d5685e4a3f25cf..201ac49eda092825f955c02475499eece4b1003a 100644 (file)
@@ -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