From 63b299d013465ebf5e9331a0fd35ada5e166ac0d Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 2 Jul 2020 11:54:53 -0400 Subject: [PATCH] zink: implement ARB_texture_buffer_object the pipe cap for this was enabled for some reason, but the actual functionality was never implemented Reviewed-by: Erik Faye-Lund Part-of: --- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 7 ++- .../drivers/zink/nir_to_spirv/nir_to_spirv.h | 13 ++++++ src/gallium/drivers/zink/zink_compiler.c | 10 +++-- src/gallium/drivers/zink/zink_context.c | 52 ++++++++++++++-------- src/gallium/drivers/zink/zink_context.h | 5 ++- src/gallium/drivers/zink/zink_draw.c | 26 ++++++----- src/gallium/drivers/zink/zink_resource.c | 6 ++- 7 files changed, 81 insertions(+), 38 deletions(-) diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c index 47971cf..f8c1f34 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c @@ -446,6 +446,7 @@ zink_binding(gl_shader_stage stage, VkDescriptorType type, int index) return stage_offset + index; case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: assert(index < PIPE_MAX_SHADER_SAMPLER_VIEWS); return stage_offset + PIPE_MAX_CONSTANT_BUFFERS + index; @@ -500,7 +501,7 @@ emit_sampler(struct ntv_context *ctx, struct nir_variable *var) spirv_builder_emit_descriptor_set(&ctx->builder, var_id, 0); int binding = zink_binding(ctx->stage, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + zink_sampler_type(glsl_without_array(var->type)), var->data.binding + i); spirv_builder_emit_binding(&ctx->builder, var_id, binding); } @@ -520,7 +521,7 @@ emit_sampler(struct ntv_context *ctx, struct nir_variable *var) spirv_builder_emit_descriptor_set(&ctx->builder, var_id, 0); int binding = zink_binding(ctx->stage, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + zink_sampler_type(var->type), var->data.binding); spirv_builder_emit_binding(&ctx->builder, var_id, binding); } @@ -2166,6 +2167,8 @@ nir_to_spirv(struct nir_shader *s, const struct zink_so_info *so_info, case MESA_SHADER_FRAGMENT: case MESA_SHADER_COMPUTE: spirv_builder_emit_cap(&ctx.builder, SpvCapabilityShader); + spirv_builder_emit_cap(&ctx.builder, SpvCapabilityImageBuffer); + spirv_builder_emit_cap(&ctx.builder, SpvCapabilitySampledBuffer); break; case MESA_SHADER_TESS_CTRL: diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.h b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.h index 04543c3..ec170a7 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.h +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.h @@ -28,6 +28,7 @@ #include #include +#include "compiler/nir/nir.h" #include "compiler/shader_enums.h" #include "pipe/p_state.h" @@ -51,6 +52,18 @@ spirv_shader_delete(struct spirv_shader *s); uint32_t zink_binding(gl_shader_stage stage, VkDescriptorType type, int index); +static inline VkDescriptorType +zink_sampler_type(const struct glsl_type *type) +{ + assert(glsl_type_is_sampler(type)); + if (glsl_get_sampler_dim(type) < GLSL_SAMPLER_DIM_BUF || glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_MS) + return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF) + return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + unreachable("unimplemented"); + return 0; +} + struct nir_shader; bool diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index ad2e6b0..77297d5 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -311,12 +311,13 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir, } else { assert(var->data.mode == nir_var_uniform); if (glsl_type_is_sampler(var->type)) { + VkDescriptorType vktype = zink_sampler_type(var->type); int binding = zink_binding(nir->info.stage, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + vktype, var->data.binding); ret->bindings[ret->num_bindings].index = var->data.binding; ret->bindings[ret->num_bindings].binding = binding; - ret->bindings[ret->num_bindings].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + ret->bindings[ret->num_bindings].type = vktype; ret->num_bindings++; } else if (glsl_type_is_array(var->type)) { /* need to unroll possible arrays of arrays before checking type @@ -325,15 +326,16 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir, const struct glsl_type *type = glsl_without_array(var->type); if (!glsl_type_is_sampler(type)) continue; + VkDescriptorType vktype = zink_sampler_type(type); unsigned size = glsl_get_aoa_size(var->type); for (int i = 0; i < size; ++i) { int binding = zink_binding(nir->info.stage, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + vktype, var->data.binding + i); ret->bindings[ret->num_bindings].index = var->data.binding + i; ret->bindings[ret->num_bindings].binding = binding; - ret->bindings[ret->num_bindings].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + ret->bindings[ret->num_bindings].type = vktype; ret->num_bindings++; } } diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 514f705..1b0aaf5 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -252,6 +252,7 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres, struct zink_screen *screen = zink_screen(pctx->screen); struct zink_resource *res = zink_resource(pres); struct zink_sampler_view *sampler_view = CALLOC_STRUCT(zink_sampler_view); + VkResult err; sampler_view->base = *state; sampler_view->base.texture = NULL; @@ -259,28 +260,38 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres, sampler_view->base.reference.count = 1; sampler_view->base.context = pctx; - VkImageViewCreateInfo ivci = {}; - ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - ivci.image = res->image; - ivci.viewType = image_view_type(state->target); - ivci.format = zink_get_format(screen, state->format); - ivci.components.r = component_mapping(state->swizzle_r); - ivci.components.g = component_mapping(state->swizzle_g); - ivci.components.b = component_mapping(state->swizzle_b); - ivci.components.a = component_mapping(state->swizzle_a); - - ivci.subresourceRange.aspectMask = sampler_aspect_from_format(state->format); - ivci.subresourceRange.baseMipLevel = state->u.tex.first_level; - ivci.subresourceRange.baseArrayLayer = state->u.tex.first_layer; - ivci.subresourceRange.levelCount = state->u.tex.last_level - state->u.tex.first_level + 1; - ivci.subresourceRange.layerCount = state->u.tex.last_layer - state->u.tex.first_layer + 1; - - VkResult err = vkCreateImageView(screen->dev, &ivci, NULL, &sampler_view->image_view); + if (state->target != PIPE_BUFFER) { + VkImageViewCreateInfo ivci = {}; + ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + ivci.image = res->image; + ivci.viewType = image_view_type(state->target); + ivci.format = zink_get_format(screen, state->format); + ivci.components.r = component_mapping(state->swizzle_r); + ivci.components.g = component_mapping(state->swizzle_g); + ivci.components.b = component_mapping(state->swizzle_b); + ivci.components.a = component_mapping(state->swizzle_a); + + ivci.subresourceRange.aspectMask = sampler_aspect_from_format(state->format); + ivci.subresourceRange.baseMipLevel = state->u.tex.first_level; + ivci.subresourceRange.baseArrayLayer = state->u.tex.first_layer; + ivci.subresourceRange.levelCount = state->u.tex.last_level - state->u.tex.first_level + 1; + ivci.subresourceRange.layerCount = state->u.tex.last_layer - state->u.tex.first_layer + 1; + + err = vkCreateImageView(screen->dev, &ivci, NULL, &sampler_view->image_view); + } else { + VkBufferViewCreateInfo bvci = {}; + bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; + bvci.buffer = res->buffer; + bvci.format = zink_get_format(screen, state->format); + bvci.offset = state->u.buf.offset; + bvci.range = state->u.buf.size; + + err = vkCreateBufferView(screen->dev, &bvci, NULL, &sampler_view->buffer_view); + } if (err != VK_SUCCESS) { FREE(sampler_view); return NULL; } - return &sampler_view->base; } @@ -289,7 +300,10 @@ zink_sampler_view_destroy(struct pipe_context *pctx, struct pipe_sampler_view *pview) { struct zink_sampler_view *view = zink_sampler_view(pview); - vkDestroyImageView(zink_screen(pctx->screen)->dev, view->image_view, NULL); + if (pview->texture->target == PIPE_BUFFER) + vkDestroyBufferView(zink_screen(pctx->screen)->dev, view->buffer_view, NULL); + else + vkDestroyImageView(zink_screen(pctx->screen)->dev, view->image_view, NULL); pipe_resource_reference(&pview->texture, NULL); FREE(view); } diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index e76e256..52c5459 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -48,7 +48,10 @@ struct zink_vertex_elements_state; struct zink_sampler_view { struct pipe_sampler_view base; - VkImageView image_view; + union { + VkImageView image_view; + VkBufferView buffer_view; + }; }; static inline struct zink_sampler_view * diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index 6302436..ad5d6fa 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -320,18 +320,22 @@ zink_draw_vbo(struct pipe_context *pctx, struct zink_sampler_view *sampler_view = zink_sampler_view(psampler_view); struct zink_resource *res = zink_resource(psampler_view->texture); - VkImageLayout layout = res->layout; - if (layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL && - layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && - layout != VK_IMAGE_LAYOUT_GENERAL) { - transitions[num_transitions++] = res; - layout = VK_IMAGE_LAYOUT_GENERAL; + if (res->base.target == PIPE_BUFFER) + wds[num_wds].pTexelBufferView = &sampler_view->buffer_view; + else { + VkImageLayout layout = res->layout; + if (layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL && + layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && + layout != VK_IMAGE_LAYOUT_GENERAL) { + transitions[num_transitions++] = res; + layout = VK_IMAGE_LAYOUT_GENERAL; + } + image_infos[num_image_info].imageLayout = layout; + image_infos[num_image_info].imageView = sampler_view->image_view; + image_infos[num_image_info].sampler = ctx->samplers[i][index]; + wds[num_wds].pImageInfo = image_infos + num_image_info; + ++num_image_info; } - image_infos[num_image_info].imageLayout = layout; - image_infos[num_image_info].imageView = sampler_view->image_view; - image_infos[num_image_info].sampler = ctx->samplers[i][index]; - wds[num_wds].pImageInfo = image_infos + num_image_info; - ++num_image_info; } wds[num_wds].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index eab65c6..06041e7 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -110,8 +110,12 @@ resource_create(struct pipe_screen *pscreen, bci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + if (templ->bind & PIPE_BIND_SAMPLER_VIEW) + bci.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; + if (templ->bind & PIPE_BIND_VERTEX_BUFFER) - bci.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + bci.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; if (templ->bind & PIPE_BIND_INDEX_BUFFER) bci.usage |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT; -- 2.7.4