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 <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7132>
This commit is contained in:
Mike Blumenkrantz 2020-07-02 11:54:53 -04:00 committed by Marge Bot
parent 4c2b02f599
commit 63b299d013
7 changed files with 79 additions and 36 deletions

View file

@ -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:

View file

@ -28,6 +28,7 @@
#include <stdint.h>
#include <vulkan/vulkan.h>
#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

View file

@ -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++;
}
}

View file

@ -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);
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;
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);
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);
}

View file

@ -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 *

View file

@ -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;

View file

@ -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;