summaryrefslogtreecommitdiffstats
path: root/src/freedreno/vulkan
diff options
context:
space:
mode:
authorJonathan Marek <[email protected]>2019-09-25 12:55:14 -0400
committerJonathan Marek <[email protected]>2019-09-26 17:18:13 -0400
commit5f2fb904a194fd30c97b54b45d85a692de5403f8 (patch)
tree99e1a99437ccaf281622aad3fe7a6343bb062631 /src/freedreno/vulkan
parent53277757aa504438191cf8cdd216d7ac034adccf (diff)
turnip: implement sampler state
Signed-off-by: Jonathan Marek <[email protected]> Reviewed-by: Kristian H. Kristensen <[email protected]> Acked-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/freedreno/vulkan')
-rw-r--r--src/freedreno/vulkan/tu_device.c66
-rw-r--r--src/freedreno/vulkan/tu_private.h7
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