[Mesa-dev] [PATCH 5/5] anv: setup appropriate border color structures on gen7/gen75
Lionel Landwerlin
llandwerlin at gmail.com
Mon Oct 17 15:46:59 UTC 2016
Up to this point we were using the gen8+ structures. Altough this commit
doesn't fixes the border color CTS tests, this is a step in the right
direction to fix the following tests :
dEQP-VK.pipeline.sampler.view_type.2d.format.*.address_modes.all_mode_clamp_to_border_*
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
---
src/intel/vulkan/anv_cmd_buffer.c | 10 ++
src/intel/vulkan/anv_device.c | 42 +-------
src/intel/vulkan/anv_genX.h | 3 +-
src/intel/vulkan/anv_private.h | 7 ++
src/intel/vulkan/genX_state.c | 220 ++++++++++++++++++++++++++++++++------
5 files changed, 208 insertions(+), 74 deletions(-)
diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c
index b051489..a63f3d9 100644
--- a/src/intel/vulkan/anv_cmd_buffer.c
+++ b/src/intel/vulkan/anv_cmd_buffer.c
@@ -931,6 +931,16 @@ anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
if (sampler == NULL)
continue;
+ /* On Haswell, although the border color structures are 20 dwords long
+ * and must be aligned at 512 bytes, the position of the 8/16/32bits
+ * colors overlap, meaning we can't have a single color structure
+ * configured for all formats. We therefore need to reemit the sampler
+ * structure for the used format. */
+ if (cmd_buffer->device->info.is_haswell) {
+ gen75_pack_sampler_state(cmd_buffer->device, sampler,
+ desc->image_view->vk_format);
+ }
+
memcpy(state->map + (s * 16),
sampler->state, sizeof(sampler->state));
}
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index ce1b9c1..4e69307 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -724,46 +724,6 @@ anv_queue_finish(struct anv_queue *queue)
{
}
-static struct anv_state
-anv_state_pool_emit_data(struct anv_state_pool *pool, size_t size, size_t align, const void *p)
-{
- struct anv_state state;
-
- state = anv_state_pool_alloc(pool, size, align);
- memcpy(state.map, p, size);
-
- if (!pool->block_pool->device->info.has_llc)
- anv_state_clflush(state);
-
- return state;
-}
-
-struct gen8_border_color {
- union {
- float float32[4];
- uint32_t uint32[4];
- };
- /* Pad out to 64 bytes */
- uint32_t _pad[12];
-};
-
-static void
-anv_device_init_border_colors(struct anv_device *device)
-{
- static const struct gen8_border_color border_colors[] = {
- [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 0.0 } },
- [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 1.0 } },
- [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] = { .float32 = { 1.0, 1.0, 1.0, 1.0 } },
- [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] = { .uint32 = { 0, 0, 0, 0 } },
- [VK_BORDER_COLOR_INT_OPAQUE_BLACK] = { .uint32 = { 0, 0, 0, 1 } },
- [VK_BORDER_COLOR_INT_OPAQUE_WHITE] = { .uint32 = { 1, 1, 1, 1 } },
- };
-
- device->border_colors = anv_state_pool_emit_data(&device->dynamic_state_pool,
- sizeof(border_colors), 64,
- border_colors);
-}
-
VkResult
anv_device_submit_simple_batch(struct anv_device *device,
struct anv_batch *batch)
@@ -926,7 +886,7 @@ VkResult anv_CreateDevice(
anv_device_init_blorp(device);
- anv_device_init_border_colors(device);
+ ANV_GEN_DISPATCH(device, border_colors_setup, device);
*pDevice = anv_device_to_handle(device);
diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h
index 27c55b9..a4a39e1 100644
--- a/src/intel/vulkan/anv_genX.h
+++ b/src/intel/vulkan/anv_genX.h
@@ -28,7 +28,7 @@
/*
* Gen-specific function declarations. This header must *not* be included
* directly. Instead, it is included multiple times by anv_private.h.
- *
+ *
* In this header file, the usual genx() macro is available.
*/
@@ -37,6 +37,7 @@
#endif
VkResult genX(init_device_state)(struct anv_device *device);
+void genX(border_colors_setup)(struct anv_device *device);
void genX(cmd_buffer_emit_state_base_address)(struct anv_cmd_buffer *cmd_buffer);
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 69e6aac..faebbb2 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -643,6 +643,7 @@ struct anv_device {
struct blorp_context blorp;
struct anv_state border_colors;
+ uint32_t border_color_align;
struct anv_queue queue;
@@ -1732,6 +1733,8 @@ void anv_buffer_view_fill_image_param(struct anv_device *device,
struct anv_sampler {
uint32_t state[4];
+
+ VkSamplerCreateInfo info;
};
struct anv_framebuffer {
@@ -1783,6 +1786,10 @@ struct anv_query_pool {
struct anv_bo bo;
};
+void gen75_pack_sampler_state(struct anv_device *device,
+ struct anv_sampler *sampler,
+ VkFormat format);
+
void *anv_lookup_entrypoint(const struct gen_device_info *devinfo,
const char *name);
diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c
index a6d405d..cbf7df2 100644
--- a/src/intel/vulkan/genX_state.c
+++ b/src/intel/vulkan/genX_state.c
@@ -28,11 +28,144 @@
#include <fcntl.h>
#include "anv_private.h"
+#include "vk_format_info.h"
#include "common/gen_sample_positions.h"
#include "genxml/gen_macros.h"
#include "genxml/genX_pack.h"
+static uint32_t
+border_color_index(VkBorderColor border_color, VkFormat format)
+{
+#if GEN_IS_HASWELL
+ if (!vk_format_is_integer(format))
+ return border_color;
+
+ uint32_t max_bpc = vk_format_max_bpc(format);
+ uint32_t index = 0;
+
+ if (max_bpc <= 8)
+ return border_color;
+
+ if (max_bpc <= 16)
+ index = VK_BORDER_COLOR_END_RANGE + 1;
+ else
+ index = VK_BORDER_COLOR_END_RANGE + 4;
+
+ switch (border_color) {
+ case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
+ case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
+ index += 0;
+ break;
+
+ case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
+ case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
+ index += 1;
+ break;
+
+ case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
+ case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
+ index += 2;
+ break;
+
+ default:
+ unreachable("invalid border color");
+ }
+
+ return index;
+#else
+ return border_color;
+#endif
+}
+
+#define BORDER_COLOR(name, r, g, b, a) { \
+ .BorderColor##name##Red = r, \
+ .BorderColor##name##Green = g, \
+ .BorderColor##name##Blue = b, \
+ .BorderColor##name##Alpha = a, \
+ }
+
+void
+genX(border_colors_setup)(struct anv_device *device)
+{
+#if GEN_IS_HASWELL
+ static const struct GENX(SAMPLER_BORDER_COLOR_STATE) border_colors[] = {
+ [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =
+ BORDER_COLOR(Float, 0.0, 0.0, 0.0, 0.0),
+ [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] =
+ BORDER_COLOR(Float, 0.0, 0.0, 0.0, 1.0),
+ [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] =
+ BORDER_COLOR(Float, 1.0, 1.0, 1.0, 1.0),
+ [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] =
+ BORDER_COLOR(8bit, 0, 0, 0, 0),
+ [VK_BORDER_COLOR_INT_OPAQUE_BLACK] =
+ BORDER_COLOR(8bit, 0, 0, 0, 1),
+ [VK_BORDER_COLOR_INT_OPAQUE_WHITE] =
+ BORDER_COLOR(8bit, 1, 1, 1, 1),
+ [VK_BORDER_COLOR_END_RANGE + 1] =
+ BORDER_COLOR(16bit, 0, 0, 0, 0),
+ [VK_BORDER_COLOR_END_RANGE + 2] =
+ BORDER_COLOR(16bit, 0, 0, 0, 1),
+ [VK_BORDER_COLOR_END_RANGE + 3] =
+ BORDER_COLOR(16bit, 1, 1, 1, 1),
+ [VK_BORDER_COLOR_END_RANGE + 4] =
+ BORDER_COLOR(32bit, 0, 0, 0, 0),
+ [VK_BORDER_COLOR_END_RANGE + 5] =
+ BORDER_COLOR(32bit, 0, 0, 0, 1),
+ [VK_BORDER_COLOR_END_RANGE + 6] =
+ BORDER_COLOR(32bit, 1, 1, 1, 1)
+ };
+ device->border_color_align = 512;
+#elif GEN_GEN == 7
+ static const struct GENX(SAMPLER_BORDER_COLOR_STATE) border_colors[] = {
+ [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =
+ BORDER_COLOR(Float, 0.0, 0.0, 0.0, 0.0),
+ [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] =
+ BORDER_COLOR(Float, 0.0, 0.0, 0.0, 1.0),
+ [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] =
+ BORDER_COLOR(Float, 1.0, 1.0, 1.0, 1.0),
+ [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] =
+ BORDER_COLOR(Float, 0.0, 0.0, 0.0, 0.0),
+ [VK_BORDER_COLOR_INT_OPAQUE_BLACK] =
+ BORDER_COLOR(Float, 0.0, 0.0, 0.0, 1.0),
+ [VK_BORDER_COLOR_INT_OPAQUE_WHITE] =
+ BORDER_COLOR(Float, 1.0, 1.0, 1.0, 1.0)
+ };
+ device->border_color_align = 64;
+#else /* GEN_GEN >= 8 */
+ static const struct GENX(SAMPLER_BORDER_COLOR_STATE) border_colors[] = {
+ [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =
+ BORDER_COLOR(Float, 0.0, 0.0, 0.0, 0.0),
+ [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] =
+ BORDER_COLOR(Float, 0.0, 0.0, 0.0, 1.0),
+ [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] =
+ BORDER_COLOR(Float, 1.0, 1.0, 1.0, 1.0),
+ [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] =
+ BORDER_COLOR(32bit, 0, 0, 0, 0),
+ [VK_BORDER_COLOR_INT_OPAQUE_BLACK] =
+ BORDER_COLOR(32bit, 0, 0, 0, 1),
+ [VK_BORDER_COLOR_INT_OPAQUE_WHITE] =
+ BORDER_COLOR(32bit, 1, 1, 1, 1)
+ };
+ device->border_color_align = 64;
+#endif
+
+ device->border_colors =
+ anv_state_pool_alloc(&device->dynamic_state_pool,
+ ARRAY_SIZE(border_colors) * device->border_color_align,
+ device->border_color_align);
+
+ for (uint32_t i = 0; i < ARRAY_SIZE(border_colors); i++) {
+ GENX(SAMPLER_BORDER_COLOR_STATE_pack)(
+ NULL,
+ device->border_colors.map + i * device->border_color_align,
+ &border_colors[i]);
+ }
+
+ if (!device->info.has_llc)
+ anv_state_clflush(device->border_colors);
+}
+
VkResult
genX(init_device_state)(struct anv_device *device)
{
@@ -148,24 +281,21 @@ static const uint32_t vk_to_gen_shadow_compare_op[] = {
[VK_COMPARE_OP_ALWAYS] = PREFILTEROPNEVER,
};
-VkResult genX(CreateSampler)(
- VkDevice _device,
- const VkSamplerCreateInfo* pCreateInfo,
- const VkAllocationCallbacks* pAllocator,
- VkSampler* pSampler)
+#if GEN_IS_HASWELL
+void
+#else
+static void
+#endif
+genX(pack_sampler_state)(
+ struct anv_device * device,
+ struct anv_sampler * sampler,
+ VkFormat format)
{
- ANV_FROM_HANDLE(anv_device, device, _device);
- struct anv_sampler *sampler;
-
- assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
-
- sampler = anv_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8,
- VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
- if (!sampler)
- return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
- uint32_t border_color_offset = device->border_colors.offset +
- pCreateInfo->borderColor * 64;
+ uint32_t color_index =
+ border_color_index(sampler->info.borderColor, format);
+ uint32_t color_offset =
+ device->border_colors.offset +
+ color_index * device->border_color_align;
struct GENX(SAMPLER_STATE) sampler_state = {
.SamplerDisable = false,
@@ -180,28 +310,28 @@ VkResult genX(CreateSampler)(
#if GEN_GEN == 8
.BaseMipLevel = 0.0,
#endif
- .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipmapMode],
- .MagModeFilter = vk_to_gen_tex_filter(pCreateInfo->magFilter,
- pCreateInfo->anisotropyEnable),
- .MinModeFilter = vk_to_gen_tex_filter(pCreateInfo->minFilter,
- pCreateInfo->anisotropyEnable),
- .TextureLODBias = anv_clamp_f(pCreateInfo->mipLodBias, -16, 15.996),
+ .MipModeFilter = vk_to_gen_mipmap_mode[sampler->info.mipmapMode],
+ .MagModeFilter = vk_to_gen_tex_filter(sampler->info.magFilter,
+ sampler->info.anisotropyEnable),
+ .MinModeFilter = vk_to_gen_tex_filter(sampler->info.minFilter,
+ sampler->info.anisotropyEnable),
+ .TextureLODBias = anv_clamp_f(sampler->info.mipLodBias, -16, 15.996),
.AnisotropicAlgorithm = EWAApproximation,
- .MinLOD = anv_clamp_f(pCreateInfo->minLod, 0, 14),
- .MaxLOD = anv_clamp_f(pCreateInfo->maxLod, 0, 14),
+ .MinLOD = anv_clamp_f(sampler->info.minLod, 0, 14),
+ .MaxLOD = anv_clamp_f(sampler->info.maxLod, 0, 14),
.ChromaKeyEnable = 0,
.ChromaKeyIndex = 0,
.ChromaKeyMode = 0,
- .ShadowFunction = vk_to_gen_shadow_compare_op[pCreateInfo->compareOp],
+ .ShadowFunction = vk_to_gen_shadow_compare_op[sampler->info.compareOp],
.CubeSurfaceControlMode = OVERRIDE,
- .BorderColorPointer = border_color_offset,
+ .BorderColorPointer = color_offset,
#if GEN_GEN >= 8
.LODClampMagnificationMode = MIPNONE,
#endif
- .MaximumAnisotropy = vk_to_gen_max_anisotropy(pCreateInfo->maxAnisotropy),
+ .MaximumAnisotropy = vk_to_gen_max_anisotropy(sampler->info.maxAnisotropy),
.RAddressMinFilterRoundingEnable = 0,
.RAddressMagFilterRoundingEnable = 0,
.VAddressMinFilterRoundingEnable = 0,
@@ -209,13 +339,39 @@ VkResult genX(CreateSampler)(
.UAddressMinFilterRoundingEnable = 0,
.UAddressMagFilterRoundingEnable = 0,
.TrilinearFilterQuality = 0,
- .NonnormalizedCoordinateEnable = pCreateInfo->unnormalizedCoordinates,
- .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeU],
- .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeV],
- .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeW],
+ .NonnormalizedCoordinateEnable = sampler->info.unnormalizedCoordinates,
+ .TCXAddressControlMode = vk_to_gen_tex_address[sampler->info.addressModeU],
+ .TCYAddressControlMode = vk_to_gen_tex_address[sampler->info.addressModeV],
+ .TCZAddressControlMode = vk_to_gen_tex_address[sampler->info.addressModeW],
};
GENX(SAMPLER_STATE_pack)(NULL, sampler->state, &sampler_state);
+}
+
+
+VkResult genX(CreateSampler)(
+ VkDevice _device,
+ const VkSamplerCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSampler* pSampler)
+{
+ ANV_FROM_HANDLE(anv_device, device, _device);
+ struct anv_sampler *sampler;
+
+ assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
+
+ sampler = anv_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (!sampler)
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ sampler->info = *pCreateInfo;
+
+ /* No need to pack the sampler state on HSW, as the packing will depend on
+ * the format of the associated texture. */
+#if ! GEN_IS_HASWELL
+ genX(pack_sampler_state)(device, sampler, VK_FORMAT_UNDEFINED);
+#endif
*pSampler = anv_sampler_to_handle(sampler);
--
2.9.3
More information about the mesa-dev
mailing list