diff --git a/src/gallium/drivers/zink/ci/zink-radv-fails.txt b/src/gallium/drivers/zink/ci/zink-radv-fails.txt index 48945301922..cbb8293d2e1 100644 --- a/src/gallium/drivers/zink/ci/zink-radv-fails.txt +++ b/src/gallium/drivers/zink/ci/zink-radv-fails.txt @@ -32,12 +32,6 @@ dEQP-GLES31.functional.primitive_bounding_box.wide_points.tessellation_set_per_p dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_sample.non_multisample_buffer.sample_n_default_framebuffer,Fail dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_sample.non_multisample_buffer.sample_n_singlesample_rbo,Fail dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_sample.non_multisample_buffer.sample_n_singlesample_texture,Fail -dEQP-GLES31.functional.texture.border_clamp.formats.stencil_index8.nearest_size_npot,Fail -dEQP-GLES31.functional.texture.border_clamp.formats.stencil_index8.nearest_size_pot,Fail -dEQP-GLES31.functional.texture.border_clamp.range_clamp.nearest_unorm_depth,Fail -dEQP-GLES31.functional.texture.border_clamp.range_clamp.nearest_unorm_depth_uint_stencil_sample_depth,Fail -dEQP-GLES31.functional.texture.border_clamp.sampler.uint_stencil,Fail -dEQP-GLES31.functional.texture.border_clamp.unused_channels.stencil_index8,Fail dEQP-GLES3.functional.clipping.line.wide_line_clip_viewport_center,Fail dEQP-GLES3.functional.clipping.line.wide_line_clip_viewport_corner,Fail dEQP-GLES3.functional.clipping.point.wide_point_clip,Fail diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 3fb3664e04c..347bea9f158 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -305,9 +305,10 @@ zink_create_sampler_state(struct pipe_context *pctx, { struct zink_screen *screen = zink_screen(pctx->screen); bool need_custom = false; - + bool need_clamped_border_color = false; VkSamplerCreateInfo sci = {0}; VkSamplerCustomBorderColorCreateInfoEXT cbci = {0}; + VkSamplerCustomBorderColorCreateInfoEXT cbci_clamped = {0}; sci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; if (screen->info.have_EXT_non_seamless_cube_map && !state->seamless_cube_map) sci.flags |= VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT; @@ -381,6 +382,22 @@ zink_create_sampler_state(struct pipe_context *pctx, static bool warned = false; warn_missing_feature(warned, "VK_EXT_border_color_swizzle"); } + + if (!is_integer && !screen->have_D24_UNORM_S8_UINT) { + union pipe_color_union clamped_border_color; + for (unsigned i = 0; i < 4; ++i) { + /* Use channel 0 on purpose, so that we can use OPAQUE_WHITE + * when the border color is 1.0. */ + clamped_border_color.f[i] = CLAMP(state->border_color.f[0], 0, 1); + } + if (memcmp(&state->border_color, &clamped_border_color, sizeof(clamped_border_color)) != 0) { + need_clamped_border_color = true; + cbci_clamped.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT; + cbci_clamped.format = VK_FORMAT_UNDEFINED; + /* these are identical unions */ + memcpy(&cbci_clamped.customBorderColor, &clamped_border_color, sizeof(union pipe_color_union)); + } + } cbci.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT; cbci.format = VK_FORMAT_UNDEFINED; /* these are identical unions */ @@ -409,6 +426,15 @@ zink_create_sampler_state(struct pipe_context *pctx, FREE(sampler); return NULL; } + if (need_clamped_border_color) { + sci.pNext = &cbci_clamped; + if (VKSCR(CreateSampler)(screen->dev, &sci, NULL, &sampler->sampler_clamped) != VK_SUCCESS) { + mesa_loge("ZINK: vkCreateSampler failed"); + VKSCR(DestroySampler)(screen->dev, sampler->sampler, NULL); + FREE(sampler); + return NULL; + } + } util_dynarray_init(&sampler->desc_set_refs.refs, NULL); calc_descriptor_hash_sampler_state(sampler); sampler->custom_border_color = need_custom; @@ -539,6 +565,18 @@ update_descriptor_state_sampler(struct zink_context *ctx, enum pipe_shader_type struct zink_surface *surface = get_imageview_for_binding(ctx, shader, type, slot); ctx->di.textures[shader][slot].imageLayout = get_layout_for_binding(ctx, res, type, shader == PIPE_SHADER_COMPUTE); ctx->di.textures[shader][slot].imageView = surface->image_view; + if (!screen->have_D24_UNORM_S8_UINT && + ctx->sampler_states[shader][slot] && ctx->sampler_states[shader][slot]->sampler_clamped) { + struct zink_sampler_state *state = ctx->sampler_states[shader][slot]; + VkSampler sampler = (surface->base.format == PIPE_FORMAT_Z24X8_UNORM && surface->ivci.format == VK_FORMAT_D32_SFLOAT) || + (surface->base.format == PIPE_FORMAT_Z24_UNORM_S8_UINT && surface->ivci.format == VK_FORMAT_D32_SFLOAT_S8_UINT) ? + state->sampler_clamped : + state->sampler; + if (ctx->di.textures[shader][slot].sampler != sampler) { + screen->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1); + ctx->di.textures[shader][slot].sampler = sampler; + } + } ctx->di.sampler_surfaces[shader][slot].surface = surface; ctx->di.sampler_surfaces[shader][slot].is_buffer = false; } @@ -629,8 +667,15 @@ zink_bind_sampler_states(struct pipe_context *pctx, if (ctx->sampler_states[shader][start_slot + i]) was_nonseamless = ctx->sampler_states[shader][start_slot + i]->emulate_nonseamless; ctx->sampler_states[shader][start_slot + i] = state; - ctx->di.textures[shader][start_slot + i].sampler = state ? state->sampler : VK_NULL_HANDLE; if (state) { + ctx->di.textures[shader][start_slot + i].sampler = state->sampler; + if (state->sampler_clamped && !screen->have_D24_UNORM_S8_UINT) { + struct zink_surface *surface = get_imageview_for_binding(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot + i); + if (surface && + ((surface->base.format == PIPE_FORMAT_Z24X8_UNORM && surface->ivci.format == VK_FORMAT_D32_SFLOAT) || + (surface->base.format == PIPE_FORMAT_Z24_UNORM_S8_UINT && surface->ivci.format == VK_FORMAT_D32_SFLOAT_S8_UINT))) + ctx->di.textures[shader][start_slot + i].sampler = state->sampler_clamped; + } zink_batch_usage_set(&state->batch_uses, ctx->batch.state); if (screen->info.have_EXT_non_seamless_cube_map) continue; @@ -646,6 +691,8 @@ zink_bind_sampler_states(struct pipe_context *pctx, screen->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot + i, 1); } } + } else { + ctx->di.textures[shader][start_slot + i].sampler = VK_NULL_HANDLE; } } ctx->di.num_samplers[shader] = start_slot + num_samplers; @@ -661,9 +708,13 @@ zink_delete_sampler_state(struct pipe_context *pctx, struct zink_batch *batch = &zink_context(pctx)->batch; zink_descriptor_set_refs_clear(&sampler->desc_set_refs, sampler_state); /* may be called if context_create fails */ - if (batch->state) + if (batch->state) { util_dynarray_append(&batch->state->zombie_samplers, VkSampler, sampler->sampler); + if (sampler->sampler_clamped) + util_dynarray_append(&batch->state->zombie_samplers, VkSampler, + sampler->sampler_clamped); + } if (sampler->custom_border_color) p_atomic_dec(&zink_screen(pctx->screen)->cur_custom_border_color_samplers); FREE(sampler); diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 24e699302d3..539d6cdc657 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -82,6 +82,7 @@ enum zink_blit_flags { struct zink_sampler_state { VkSampler sampler; + VkSampler sampler_clamped; uint32_t hash; struct zink_descriptor_refs desc_set_refs; struct zink_batch_usage *batch_uses;