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.landwer...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev