On Wed, Oct 19, 2016 at 8:50 AM, Lionel Landwerlin <llandwer...@gmail.com> wrote:
> Up to this point we were using the gen8+ structures to program border > colors. This commit sets up the correct border colors for HSW & IVB. > > On HSW: > This fixes 140 failures of : > dEQP-VK.pipeline.sampler.view_type.*.format.*.address_modes. > all_mode_clamp_to_border_* > (11 failures remain out of 840 tests) > > Failures : > - dEQP-VK.pipeline.sampler.view_type.*.format.b4g4r4a4_unorm_ > pack16.address_modes.all_mode_clamp_to_border_* > > There is no equivalent of b4g4r4a4_unorm on the GLES31 test suite > and > the documentation doesn't seem to list this format in any of the > 8/16/32bits supported ones. > > - dEQP-VK.pipeline.sampler.view_type.2d.format.r32g32b32_uint. > address_modes.all_mode_clamp_to_border_* > > Some GLES31 equivalent tests are failing too : > > dEQP-GLES31.functional.texture.border_clamp.formats. > rgba32ui.nearest_size_pot > dEQP-GLES31.functional.texture.border_clamp.formats. > rgba32ui.nearest_size_npot > > - dEQP-VK.pipeline.sampler.view_type.2d.format.r32_uint. > address_modes.all_mode_clamp_to_border_* > > Seems to exhibit the same issue as r32g32b32_uint (some of the > corners of the sampled texture are missing). > > On IVB: > This fixes 73 failures of : > dEQP-VK.pipeline.sampler.view_type.*.format.*.address_modes. > all_mode_clamp_to_border_* > (139 failures remain out of 795 tests) > > All tests using *_sfloat, *_unorm, *_snorm formats are passing. > > Failures : > - dEQP-VK.pipeline.sampler.view_type.*.format.r8g8b8_uint. > address_modes.all_mode_clamp_to_border_* > dEQP-VK.pipeline.sampler.view_type.*.format.r16g16b16_sint. > address_modes.all_mode_clamp_to_border_* > dEQP-VK.pipeline.sampler.view_type.*.format.r16g16b16_ > sfloat.address_modes.all_mode_clamp_to_border_* > > These tests were triggering an assert before and remain broken. This > seems to be a hardware limitation we can't express through the > Vulkan > API. > > - Most of uint formats produce invalid results (some with invalid > border color, some with invalid texture data) with exception of : > > dEQP-VK.pipeline.sampler.view_type.*.format.r32_sint. > address_modes.all_mode_clamp_to_border_* > > v2: Implement Jason's suggestion to have all sampler configuration ready at > sampler cration > Also fix remaining issues with 1 & 2 components texture > > Signed-off-by: Lionel Landwerlin <lionel.g.landwer...@intel.com> > --- > src/intel/vulkan/anv_device.c | 42 ------- > src/intel/vulkan/anv_genX.h | 3 +- > src/intel/vulkan/anv_private.h | 11 +- > src/intel/vulkan/genX_cmd_buffer.c | 5 +- > src/intel/vulkan/genX_state.c | 229 ++++++++++++++++++++++++++++++ > ++++--- > 5 files changed, 228 insertions(+), 62 deletions(-) > > diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c > index c995630..3ad01b9 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) > @@ -943,8 +903,6 @@ VkResult anv_CreateDevice( > > anv_device_init_blorp(device); > > - anv_device_init_border_colors(device); > - > *pDevice = anv_device_to_handle(device); > > return VK_SUCCESS; > diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h > index d4ed325..ebd0ee7 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); > +uint32_t genX(sampler_index)(VkFormat format); > > 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 0e25827..2cca5c3 100644 > --- a/src/intel/vulkan/anv_private.h > +++ b/src/intel/vulkan/anv_private.h > @@ -552,6 +552,7 @@ struct anv_device { > struct blorp_context blorp; > > struct anv_state border_colors; > + uint32_t border_color_align; > > struct anv_queue queue; > > @@ -1642,7 +1643,15 @@ void anv_buffer_view_fill_image_param(struct > anv_device *device, > struct brw_image_param *param); > > struct anv_sampler { > - uint32_t state[4]; > + /* On Haswell we need to have all samplers declined per number of > component > + * for each possible integer format (8, 16 and 32 bits) and we also > need > + * sampler configurations for normalized and floating point formats : > + * > + * 4 components * 3 integer formats + floats&normalized = 13 > configurations > + * > + * On all other platforms, only state[0] is used. > + */ > + uint32_t state[13][4]; > }; > > struct anv_framebuffer { > diff --git a/src/intel/vulkan/genX_cmd_buffer.c > b/src/intel/vulkan/genX_cmd_buffer.c > index 5ea7c5f..88ed284 100644 > --- a/src/intel/vulkan/genX_cmd_buffer.c > +++ b/src/intel/vulkan/genX_cmd_buffer.c > @@ -905,8 +905,9 @@ emit_samplers(struct anv_cmd_buffer *cmd_buffer, > if (sampler == NULL) > continue; > > - memcpy(state->map + (s * 16), > - sampler->state, sizeof(sampler->state)); > + uint32_t sampler_index = genX(sampler_index)(desc-> > image_view->vk_format); > + memcpy(state->map + (s * 16), sampler->state[sampler_index], > + GENX(SAMPLER_STATE_length) * 4); > Unfortunately, this only works for the case where we have a combined image and sampler. desc->image_view could be null (just a plain sampler) or the shader could end up combining this sampler with a different image (and different format). Sadly, I think this is probably yet another CTS coverage hole. > } > > if (!cmd_buffer->device->info.has_llc) > diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c > index be1bd78..61aeef3 100644 > --- a/src/intel/vulkan/genX_state.c > +++ b/src/intel/vulkan/genX_state.c > @@ -28,11 +28,172 @@ > #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" > > +uint32_t > +genX(sampler_index)(VkFormat format) > +{ > +#if ! GEN_IS_HASWELL > + return 0; > +#else > + if (!vk_format_is_integer(format)) > + return 0; > + > + uint32_t index = 3 * (vk_format_n_channels(format) - 1); > + > + switch(vk_format_max_bpc(format)) { > + case 8: > + index += 1; > + break; > + > + case 10: > + case 16: > + case 24: > + index += 2; > + break; > + > + case 32: > + index += 3; > + break; > + default: > + anv_finishme("unsupported sampling format with border color"); > + return 0; > + } > + > + return index; > +#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, \ > + } > + > +static void > +border_colors_setup(struct anv_device *device) > +{ > +#if GEN_IS_HASWELL > + /* We order things differently for Haswell and only ever care about the > + * color, not whether the color integer or float (see > genX(sampler_index)). > + * This consumes 13 * 3 * 512 ~= 20kb of memory. */ > + static const struct GENX(SAMPLER_BORDER_COLOR_STATE) border_colors[] > = { > + /* Transparent black: */ > + BORDER_COLOR(Float, 0.0, 0.0, 0.0, 0.0), > + /* - R textures */ > + BORDER_COLOR(8bit, 0, 0, 0, 1), > + BORDER_COLOR(16bit, 0, 0, 0, 1), > + BORDER_COLOR(32bit, 0, 0, 0, 1), > + /* - RG textures */ > + BORDER_COLOR(8bit, 0, 0, 0, 1), > + BORDER_COLOR(16bit, 0, 0, 0, 1), > + BORDER_COLOR(32bit, 0, 0, 0, 1), > + /* - RGB textures */ > + BORDER_COLOR(8bit, 0, 0, 0, 1), > + BORDER_COLOR(16bit, 0, 0, 0, 1), > + BORDER_COLOR(32bit, 0, 0, 0, 1), > + /* - RBGA textures */ > + BORDER_COLOR(8bit, 0, 0, 0, 0), > + BORDER_COLOR(16bit, 0, 0, 0, 0), > + BORDER_COLOR(32bit, 0, 0, 0, 0), > + > + /* Opaque black: */ > + BORDER_COLOR(Float, 0.0, 0.0, 0.0, 1.0), > + /* - R textures */ > + BORDER_COLOR(8bit, 0, 0, 0, 1), > + BORDER_COLOR(16bit, 0, 0, 0, 1), > + BORDER_COLOR(32bit, 0, 0, 0, 1), > + /* - RG textures */ > + BORDER_COLOR(8bit, 0, 0, 0, 1), > + BORDER_COLOR(16bit, 0, 0, 0, 1), > + BORDER_COLOR(32bit, 0, 0, 0, 1), > + /* - RGB textures */ > + BORDER_COLOR(8bit, 0, 0, 0, 1), > + BORDER_COLOR(16bit, 0, 0, 0, 1), > + BORDER_COLOR(32bit, 0, 0, 0, 1), > + /* - RGBA textures */ > + BORDER_COLOR(8bit, 0, 0, 0, 1), > + BORDER_COLOR(16bit, 0, 0, 0, 1), > + BORDER_COLOR(32bit, 0, 0, 0, 1), > + > + /* Opaque white: */ > + BORDER_COLOR(Float, 1.0, 1.0, 1.0, 1.0), > + /* - R textures */ > + BORDER_COLOR(8bit, 1, 0, 0, 1), > + BORDER_COLOR(16bit, 1, 0, 0, 1), > + BORDER_COLOR(32bit, 1, 0, 0, 1), > + /* - RG textures */ > + BORDER_COLOR(8bit, 1, 1, 0, 1), > + BORDER_COLOR(16bit, 1, 1, 0, 1), > + BORDER_COLOR(32bit, 1, 1, 0, 1), > + /* - RGB textures */ > + BORDER_COLOR(8bit, 1, 1, 1, 1), > + BORDER_COLOR(16bit, 1, 1, 1, 1), > + BORDER_COLOR(32bit, 1, 1, 1, 1), > + /* - RGBA textures */ > + BORDER_COLOR(8bit, 1, 1, 1, 1), > + BORDER_COLOR(16bit, 1, 1, 1, 1), > + BORDER_COLOR(32bit, 1, 1, 1, 1), > + }; > + static_assert(sizeof(struct anv_sampler) / (4 * > GENX(SAMPLER_STATE_length)) == > + ARRAY_SIZE(border_colors) / 3, > + "struct anv_sampler size doesn't match border_colors"); > + 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) > { > @@ -91,6 +252,8 @@ genX(init_device_state)(struct anv_device *device) > > assert(batch.next <= batch.end); > > + border_colors_setup(device); > + > return anv_device_submit_simple_batch(device, &batch); > } > > @@ -148,24 +311,34 @@ static const uint32_t vk_to_gen_shadow_compare_op[] > = { > [VK_COMPARE_OP_ALWAYS] = PREFILTEROPNEVER, > }; > > -VkResult genX(CreateSampler)( > - VkDevice _device, > +static void > +pack_sampler_state( > + struct anv_device * device, > + struct anv_sampler * sampler, > const VkSamplerCreateInfo* pCreateInfo, > - const VkAllocationCallbacks* pAllocator, > - VkSampler* pSampler) > + uint32_t offset, > + void * dest) > { > - ANV_FROM_HANDLE(anv_device, device, _device); > - struct anv_sampler *sampler; > - > - assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO); > +#if GEN_IS_HASWELL > + static const uint32_t haswell_border_color_offset[] = { > + [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] = 0, > + [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] = 0, > > - sampler = vk_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8, > - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); > - if (!sampler) > - return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); > + [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] = 1, > + [VK_BORDER_COLOR_INT_OPAQUE_BLACK] = 1, > > - uint32_t border_color_offset = device->border_colors.offset + > - pCreateInfo->borderColor * 64; > + [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] = 2, > + [VK_BORDER_COLOR_INT_OPAQUE_WHITE] = 2, > + }; > + uint32_t color_index = > + ARRAY_SIZE(sampler->state) * > + haswell_border_color_offset[pCreateInfo->borderColor] + offset; > +#else > + uint32_t color_index = pCreateInfo->borderColor; > +#endif > + uint32_t color_offset = > + device->border_colors.offset + > + color_index * device->border_color_align; > > struct GENX(SAMPLER_STATE) sampler_state = { > .SamplerDisable = false, > @@ -195,7 +368,7 @@ VkResult genX(CreateSampler)( > .ShadowFunction = vk_to_gen_shadow_compare_op[ > pCreateInfo->compareOp], > .CubeSurfaceControlMode = OVERRIDE, > > - .BorderColorPointer = border_color_offset, > + .BorderColorPointer = color_offset, > > #if GEN_GEN >= 8 > .LODClampMagnificationMode = MIPNONE, > @@ -215,7 +388,31 @@ VkResult genX(CreateSampler)( > .TCZAddressControlMode = vk_to_gen_tex_address[ > pCreateInfo->addressModeW], > }; > > - GENX(SAMPLER_STATE_pack)(NULL, sampler->state, &sampler_state); > + GENX(SAMPLER_STATE_pack)(NULL, dest, &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 = vk_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8, > + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); > + if (!sampler) > + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); > + > + pack_sampler_state(device, sampler, pCreateInfo, 0, sampler->state[0]); > +#if GEN_IS_HASWELL > + for (uint32_t i = 1; i < ARRAY_SIZE(sampler->state); i++) > + pack_sampler_state(device, sampler, pCreateInfo, i, > sampler->state[i]); > +#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 >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev