lavapipe: create gallium descriptor image/sampler view types for views

this simplifies handling pipe_sampler_view and pipe_image_view by creating
them at the time the view is created, thus enabling the lifetime of samplerview
objects to be managed by the object that owns them instead of everywhere

Reviewed-by: Konstantin Seurer <konstantin.seurer@gmail.com>
Acked-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17740>
This commit is contained in:
Mike Blumenkrantz 2022-07-25 11:23:30 -04:00 committed by Marge Bot
parent be2185aa49
commit 6a01053bb2
4 changed files with 221 additions and 139 deletions

View file

@ -450,7 +450,7 @@ VKAPI_ATTR void VKAPI_CALL lvp_UpdateDescriptorSets(
LVP_FROM_HANDLE(lvp_image_view, iview,
write->pImageInfo[j].imageView);
desc[j].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
desc[j].info.iview = iview;
desc[j].info.sampler_view = iview ? iview->sv : NULL;
/*
* All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those
* with a descriptorCount of zero, must all either use immutable samplers or must all not
@ -468,6 +468,16 @@ VKAPI_ATTR void VKAPI_CALL lvp_UpdateDescriptorSets(
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
for (uint32_t j = 0; j < write->descriptorCount; j++) {
LVP_FROM_HANDLE(lvp_image_view, iview,
write->pImageInfo[j].imageView);
desc[j] = (struct lvp_descriptor) {
.type = write->descriptorType,
.info.sampler_view = iview ? iview->sv : NULL,
};
}
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
for (uint32_t j = 0; j < write->descriptorCount; j++) {
@ -476,12 +486,23 @@ VKAPI_ATTR void VKAPI_CALL lvp_UpdateDescriptorSets(
desc[j] = (struct lvp_descriptor) {
.type = write->descriptorType,
.info.iview = iview,
.info.image_view = iview ? iview->iv : ((struct pipe_image_view){0}),
};
}
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
for (uint32_t j = 0; j < write->descriptorCount; j++) {
LVP_FROM_HANDLE(lvp_buffer_view, bview,
write->pTexelBufferView[j]);
desc[j] = (struct lvp_descriptor) {
.type = write->descriptorType,
.info.sampler_view = bview ? bview->sv : NULL,
};
}
break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
for (uint32_t j = 0; j < write->descriptorCount; j++) {
LVP_FROM_HANDLE(lvp_buffer_view, bview,
@ -489,7 +510,7 @@ VKAPI_ATTR void VKAPI_CALL lvp_UpdateDescriptorSets(
desc[j] = (struct lvp_descriptor) {
.type = write->descriptorType,
.info.buffer_view = bview,
.info.image_view = bview ? bview->iv : ((struct pipe_image_view){0}),
};
}
break;
@ -720,31 +741,48 @@ VKAPI_ATTR void VKAPI_CALL lvp_UpdateDescriptorSetWithTemplate(VkDevice _device,
}
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
VkDescriptorImageInfo *info = (VkDescriptorImageInfo *)pSrc;
LVP_FROM_HANDLE(lvp_image_view, iview, info->imageView);
desc[idx] = (struct lvp_descriptor) {
.type = entry->descriptorType,
.info.iview = lvp_image_view_from_handle(info->imageView),
.info.sampler_view = iview ? iview->sv : NULL,
.info.sampler = info->sampler ? &lvp_sampler_from_handle(info->sampler)->state : NULL,
};
break;
}
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: {
VkDescriptorImageInfo *info = (VkDescriptorImageInfo *)pSrc;
LVP_FROM_HANDLE(lvp_image_view, iview, info->imageView);
desc[idx] = (struct lvp_descriptor) {
.type = entry->descriptorType,
.info.sampler_view = iview ? iview->sv : NULL,
};
break;
}
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
LVP_FROM_HANDLE(lvp_image_view, iview,
((VkDescriptorImageInfo *)pSrc)->imageView);
desc[idx] = (struct lvp_descriptor) {
.type = entry->descriptorType,
.info.iview = iview,
.info.image_view = iview ? iview->iv : ((struct pipe_image_view){0}),
};
break;
}
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: {
LVP_FROM_HANDLE(lvp_buffer_view, bview,
*(VkBufferView *)pSrc);
desc[idx] = (struct lvp_descriptor) {
.type = entry->descriptorType,
.info.sampler_view = bview ? bview->sv : NULL,
};
break;
}
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
LVP_FROM_HANDLE(lvp_buffer_view, bview,
*(VkBufferView *)pSrc);
desc[idx] = (struct lvp_descriptor) {
.type = entry->descriptorType,
.info.buffer_view = bview,
.info.image_view = bview ? bview->iv : ((struct pipe_image_view){0}),
};
break;
}

View file

@ -1061,15 +1061,6 @@ static void fill_sampler_stage(struct rendering_state *state,
state->ss_dirty[p_stage] = true;
}
#define fix_depth_swizzle(x) do { \
if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \
x = PIPE_SWIZZLE_0; \
} while (0)
#define fix_depth_swizzle_a(x) do { \
if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \
x = PIPE_SWIZZLE_1; \
} while (0)
static void fill_sampler_view_stage(struct rendering_state *state,
struct dyn_info *dyn_info,
gl_shader_stage stage,
@ -1083,58 +1074,10 @@ static void fill_sampler_view_stage(struct rendering_state *state,
return;
sv_idx += array_idx;
sv_idx += dyn_info->stage[stage].sampler_view_count;
struct lvp_image_view *iv = descriptor->iview;
if (iv) {
struct pipe_sampler_view templ;
enum pipe_format pformat;
if (iv->vk.aspects == VK_IMAGE_ASPECT_DEPTH_BIT)
pformat = lvp_vk_format_to_pipe_format(iv->vk.format);
else if (iv->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT)
pformat = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->vk.format));
else
pformat = lvp_vk_format_to_pipe_format(iv->vk.format);
u_sampler_view_default_template(&templ,
iv->image->bo,
pformat);
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_1D)
templ.target = PIPE_TEXTURE_1D;
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_2D)
templ.target = PIPE_TEXTURE_2D;
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE)
templ.target = PIPE_TEXTURE_CUBE;
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
templ.target = PIPE_TEXTURE_CUBE_ARRAY;
templ.u.tex.first_layer = iv->vk.base_array_layer;
templ.u.tex.last_layer = iv->vk.base_array_layer + iv->vk.layer_count - 1;
templ.u.tex.first_level = iv->vk.base_mip_level;
templ.u.tex.last_level = iv->vk.base_mip_level + iv->vk.level_count - 1;
templ.swizzle_r = vk_conv_swizzle(iv->vk.swizzle.r);
templ.swizzle_g = vk_conv_swizzle(iv->vk.swizzle.g);
templ.swizzle_b = vk_conv_swizzle(iv->vk.swizzle.b);
templ.swizzle_a = vk_conv_swizzle(iv->vk.swizzle.a);
assert(sv_idx < ARRAY_SIZE(state->sv[p_stage]));
state->sv[p_stage][sv_idx] = descriptor->sampler_view;
/* depth stencil swizzles need special handling to pass VK CTS
* but also for zink GL tests.
* piping A swizzle into R fixes GL_ALPHA depth texture mode
* only swizzling from R/0/1 (for alpha) fixes VK CTS tests
* and a bunch of zink tests.
*/
if (iv->vk.aspects == VK_IMAGE_ASPECT_DEPTH_BIT ||
iv->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT) {
fix_depth_swizzle(templ.swizzle_r);
fix_depth_swizzle(templ.swizzle_g);
fix_depth_swizzle(templ.swizzle_b);
fix_depth_swizzle_a(templ.swizzle_a);
}
assert(sv_idx < ARRAY_SIZE(state->sv[p_stage]));
if (state->sv[p_stage][sv_idx])
pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL);
state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, iv->image->bo, &templ);
} else {
state->sv[p_stage][sv_idx] = NULL;
}
if (state->num_sampler_views[p_stage] <= sv_idx)
state->num_sampler_views[p_stage] = sv_idx + 1;
state->sv_dirty[p_stage] = true;
@ -1153,27 +1096,9 @@ static void fill_sampler_buffer_view_stage(struct rendering_state *state,
return;
sv_idx += array_idx;
sv_idx += dyn_info->stage[stage].sampler_view_count;
struct lvp_buffer_view *bv = descriptor->buffer_view;
assert(sv_idx < ARRAY_SIZE(state->sv[p_stage]));
if (state->sv[p_stage][sv_idx])
pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL);
if (bv) {
struct pipe_sampler_view templ;
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_BUFFER;
templ.swizzle_r = PIPE_SWIZZLE_X;
templ.swizzle_g = PIPE_SWIZZLE_Y;
templ.swizzle_b = PIPE_SWIZZLE_Z;
templ.swizzle_a = PIPE_SWIZZLE_W;
templ.format = bv->pformat;
templ.u.buf.offset = bv->offset;
templ.u.buf.size = bv->range;
templ.texture = bv->buffer->bo;
templ.context = state->pctx;
state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, bv->buffer->bo, &templ);
}
state->sv[p_stage][sv_idx] = descriptor->sampler_view;
if (state->num_sampler_views[p_stage] <= sv_idx)
state->num_sampler_views[p_stage] = sv_idx + 1;
@ -1188,36 +1113,16 @@ static void fill_image_view_stage(struct rendering_state *state,
const union lvp_descriptor_info *descriptor,
const struct lvp_descriptor_set_binding_layout *binding)
{
struct lvp_image_view *iv = descriptor->iview;
int idx = binding->stage[stage].image_index;
if (idx == -1)
return;
idx += array_idx;
idx += dyn_info->stage[stage].image_count;
if (iv) {
state->iv[p_stage][idx].resource = iv->image->bo;
if (iv->vk.aspects == VK_IMAGE_ASPECT_DEPTH_BIT)
state->iv[p_stage][idx].format = lvp_vk_format_to_pipe_format(iv->vk.format);
else if (iv->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT)
state->iv[p_stage][idx].format = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->vk.format));
else
state->iv[p_stage][idx].format = lvp_vk_format_to_pipe_format(iv->vk.format);
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_3D) {
state->iv[p_stage][idx].u.tex.first_layer = 0;
state->iv[p_stage][idx].u.tex.last_layer = iv->vk.extent.depth - 1;
} else {
state->iv[p_stage][idx].u.tex.first_layer = iv->vk.base_array_layer,
state->iv[p_stage][idx].u.tex.last_layer = iv->vk.base_array_layer + iv->vk.layer_count - 1;
}
state->iv[p_stage][idx].u.tex.level = iv->vk.base_mip_level;
} else {
state->iv[p_stage][idx].resource = NULL;
state->iv[p_stage][idx].format = PIPE_FORMAT_NONE;
state->iv[p_stage][idx].u.tex.first_layer = 0;
state->iv[p_stage][idx].u.tex.last_layer = 0;
state->iv[p_stage][idx].u.tex.level = 0;
}
uint16_t access = state->iv[p_stage][idx].access;
uint16_t shader_access = state->iv[p_stage][idx].shader_access;
state->iv[p_stage][idx] = descriptor->image_view;
state->iv[p_stage][idx].access = access;
state->iv[p_stage][idx].shader_access = shader_access;
if (state->num_shader_images[p_stage] <= idx)
state->num_shader_images[p_stage] = idx + 1;
@ -1233,23 +1138,16 @@ static void fill_image_buffer_view_stage(struct rendering_state *state,
const union lvp_descriptor_info *descriptor,
const struct lvp_descriptor_set_binding_layout *binding)
{
struct lvp_buffer_view *bv = descriptor->buffer_view;
int idx = binding->stage[stage].image_index;
if (idx == -1)
return;
idx += array_idx;
idx += dyn_info->stage[stage].image_count;
if (bv) {
state->iv[p_stage][idx].resource = bv->buffer->bo;
state->iv[p_stage][idx].format = bv->pformat;
state->iv[p_stage][idx].u.buf.offset = bv->offset;
state->iv[p_stage][idx].u.buf.size = bv->range;
} else {
state->iv[p_stage][idx].resource = NULL;
state->iv[p_stage][idx].format = PIPE_FORMAT_NONE;
state->iv[p_stage][idx].u.buf.offset = 0;
state->iv[p_stage][idx].u.buf.size = 0;
}
uint16_t access = state->iv[p_stage][idx].access;
uint16_t shader_access = state->iv[p_stage][idx].shader_access;
state->iv[p_stage][idx] = descriptor->image_view;
state->iv[p_stage][idx].access = access;
state->iv[p_stage][idx].shader_access = shader_access;
if (state->num_shader_images[p_stage] <= idx)
state->num_shader_images[p_stage] = idx + 1;
state->iv_dirty[p_stage] = true;
@ -3227,7 +3125,8 @@ static void handle_compute_push_descriptor_set(struct lvp_cmd_push_descriptor_se
}
}
static struct lvp_cmd_push_descriptor_set *create_push_descriptor_set(struct vk_cmd_push_descriptor_set_khr *in_cmd)
static struct lvp_cmd_push_descriptor_set *
create_push_descriptor_set(struct rendering_state *state, struct vk_cmd_push_descriptor_set_khr *in_cmd)
{
LVP_FROM_HANDLE(lvp_pipeline_layout, layout, in_cmd->layout);
struct lvp_cmd_push_descriptor_set *out_cmd;
@ -3280,17 +3179,34 @@ static struct lvp_cmd_push_descriptor_set *create_push_descriptor_set(struct vk_
info->sampler = &lvp_sampler_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].sampler)->state;
else
info->sampler = NULL;
info->iview = lvp_image_view_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].imageView);
if (in_cmd->descriptor_writes[i].pImageInfo[j].imageView)
info->sampler_view = lvp_image_view_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].imageView)->sv;
else
info->sampler_view = NULL;
break;
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
if (in_cmd->descriptor_writes[i].pImageInfo[j].imageView)
info->sampler_view = lvp_image_view_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].imageView)->sv;
else
info->sampler_view = NULL;
break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
info->iview = lvp_image_view_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].imageView);
if (in_cmd->descriptor_writes[i].pImageInfo[j].imageView)
info->image_view = lvp_image_view_from_handle(in_cmd->descriptor_writes[i].pImageInfo[j].imageView)->iv;
else
info->image_view = ((struct pipe_image_view){0});
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
info->buffer_view = lvp_buffer_view_from_handle(in_cmd->descriptor_writes[i].pTexelBufferView[j]);
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: {
struct lvp_buffer_view *bview = lvp_buffer_view_from_handle(in_cmd->descriptor_writes[i].pTexelBufferView[j]);
info->sampler_view = bview ? bview->sv : NULL;
break;
}
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
struct lvp_buffer_view *bview = lvp_buffer_view_from_handle(in_cmd->descriptor_writes[i].pTexelBufferView[j]);
info->image_view = bview ? bview->iv : ((struct pipe_image_view){0});
break;
}
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
LVP_FROM_HANDLE(lvp_buffer, buffer, in_cmd->descriptor_writes[i].pBufferInfo[j].buffer);
@ -3324,7 +3240,7 @@ static struct lvp_cmd_push_descriptor_set *create_push_descriptor_set(struct vk_
static void handle_push_descriptor_set_generic(struct vk_cmd_push_descriptor_set_khr *_pds,
struct rendering_state *state)
{
struct lvp_cmd_push_descriptor_set *pds = create_push_descriptor_set(_pds);
struct lvp_cmd_push_descriptor_set *pds = create_push_descriptor_set(state, _pds);
const struct lvp_descriptor_set_layout *layout =
vk_to_lvp_descriptor_set_layout(pds->layout->vk.set_layouts[pds->set]);
@ -4159,13 +4075,6 @@ VkResult lvp_execute_cmds(struct lvp_device *device,
}
}
for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) {
for (unsigned i = 0; i < ARRAY_SIZE(state->sv[s]); i++) {
if (state->sv[s][i])
pipe_sampler_view_reference(&state->sv[s][i], NULL);
}
}
free(state->color_att);
return VK_SUCCESS;
}

View file

@ -168,6 +168,96 @@ lvp_DestroyImage(VkDevice _device, VkImage _image,
vk_image_destroy(&device->vk, pAllocator, &image->vk);
}
#include "lvp_conv.h"
#include "util/u_sampler.h"
#include "util/u_inlines.h"
#define fix_depth_swizzle(x) do { \
if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \
x = PIPE_SWIZZLE_0; \
} while (0)
#define fix_depth_swizzle_a(x) do { \
if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \
x = PIPE_SWIZZLE_1; \
} while (0)
static struct pipe_sampler_view *
lvp_create_samplerview(struct pipe_context *pctx, struct lvp_image_view *iv)
{
if (!iv)
return NULL;
struct pipe_sampler_view templ;
enum pipe_format pformat;
if (iv->vk.aspects == VK_IMAGE_ASPECT_DEPTH_BIT)
pformat = lvp_vk_format_to_pipe_format(iv->vk.format);
else if (iv->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT)
pformat = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->vk.format));
else
pformat = lvp_vk_format_to_pipe_format(iv->vk.format);
u_sampler_view_default_template(&templ,
iv->image->bo,
pformat);
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_1D)
templ.target = PIPE_TEXTURE_1D;
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_2D)
templ.target = PIPE_TEXTURE_2D;
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE)
templ.target = PIPE_TEXTURE_CUBE;
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
templ.target = PIPE_TEXTURE_CUBE_ARRAY;
templ.u.tex.first_layer = iv->vk.base_array_layer;
templ.u.tex.last_layer = iv->vk.base_array_layer + iv->vk.layer_count - 1;
templ.u.tex.first_level = iv->vk.base_mip_level;
templ.u.tex.last_level = iv->vk.base_mip_level + iv->vk.level_count - 1;
templ.swizzle_r = vk_conv_swizzle(iv->vk.swizzle.r);
templ.swizzle_g = vk_conv_swizzle(iv->vk.swizzle.g);
templ.swizzle_b = vk_conv_swizzle(iv->vk.swizzle.b);
templ.swizzle_a = vk_conv_swizzle(iv->vk.swizzle.a);
/* depth stencil swizzles need special handling to pass VK CTS
* but also for zink GL tests.
* piping A swizzle into R fixes GL_ALPHA depth texture mode
* only swizzling from R/0/1 (for alpha) fixes VK CTS tests
* and a bunch of zink tests.
*/
if (iv->vk.aspects == VK_IMAGE_ASPECT_DEPTH_BIT ||
iv->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT) {
fix_depth_swizzle(templ.swizzle_r);
fix_depth_swizzle(templ.swizzle_g);
fix_depth_swizzle(templ.swizzle_b);
fix_depth_swizzle_a(templ.swizzle_a);
}
return pctx->create_sampler_view(pctx, iv->image->bo, &templ);
}
static struct pipe_image_view
lvp_create_imageview(const struct lvp_image_view *iv)
{
struct pipe_image_view view = {0};
if (!iv)
return view;
view.resource = iv->image->bo;
if (iv->vk.aspects == VK_IMAGE_ASPECT_DEPTH_BIT)
view.format = lvp_vk_format_to_pipe_format(iv->vk.format);
else if (iv->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT)
view.format = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->vk.format));
else
view.format = lvp_vk_format_to_pipe_format(iv->vk.format);
if (iv->vk.view_type == VK_IMAGE_VIEW_TYPE_3D) {
view.u.tex.first_layer = 0;
view.u.tex.last_layer = iv->vk.extent.depth - 1;
} else {
view.u.tex.first_layer = iv->vk.base_array_layer,
view.u.tex.last_layer = iv->vk.base_array_layer + iv->vk.layer_count - 1;
}
view.u.tex.level = iv->vk.base_mip_level;
return view;
}
VKAPI_ATTR VkResult VKAPI_CALL
lvp_CreateImageView(VkDevice _device,
const VkImageViewCreateInfo *pCreateInfo,
@ -186,6 +276,8 @@ lvp_CreateImageView(VkDevice _device,
view->pformat = lvp_vk_format_to_pipe_format(view->vk.format);
view->image = image;
view->surface = NULL;
view->iv = lvp_create_imageview(view);
view->sv = lvp_create_samplerview(device->queue.ctx, view);
*pView = lvp_image_view_to_handle(view);
return VK_SUCCESS;
@ -201,6 +293,7 @@ lvp_DestroyImageView(VkDevice _device, VkImageView _iview,
if (!_iview)
return;
pipe_sampler_view_reference(&iview->sv, NULL);
pipe_surface_reference(&iview->surface, NULL);
vk_image_view_destroy(&device->vk, pAllocator, &iview->vk);
}
@ -364,6 +457,40 @@ VKAPI_ATTR uint64_t VKAPI_CALL lvp_GetDeviceMemoryOpaqueCaptureAddress(
return 0;
}
static struct pipe_sampler_view *
lvp_create_samplerview_buffer(struct pipe_context *pctx, struct lvp_buffer_view *bv)
{
if (!bv)
return NULL;
struct pipe_sampler_view templ;
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_BUFFER;
templ.swizzle_r = PIPE_SWIZZLE_X;
templ.swizzle_g = PIPE_SWIZZLE_Y;
templ.swizzle_b = PIPE_SWIZZLE_Z;
templ.swizzle_a = PIPE_SWIZZLE_W;
templ.format = bv->pformat;
templ.u.buf.offset = bv->offset;
templ.u.buf.size = bv->range;
templ.texture = bv->buffer->bo;
templ.context = pctx;
return pctx->create_sampler_view(pctx, bv->buffer->bo, &templ);
}
static struct pipe_image_view
lvp_create_imageview_buffer(const struct lvp_buffer_view *bv)
{
struct pipe_image_view view = {0};
if (!bv)
return view;
view.resource = bv->buffer->bo;
view.format = bv->pformat;
view.u.buf.offset = bv->offset;
view.u.buf.size = bv->range;
return view;
}
VKAPI_ATTR VkResult VKAPI_CALL
lvp_CreateBufferView(VkDevice _device,
const VkBufferViewCreateInfo *pCreateInfo,
@ -388,6 +515,8 @@ lvp_CreateBufferView(VkDevice _device,
view->range = view->buffer->size - view->offset;
else
view->range = pCreateInfo->range;
view->sv = lvp_create_samplerview_buffer(device->queue.ctx, view);
view->iv = lvp_create_imageview_buffer(view);
*pView = lvp_buffer_view_to_handle(view);
return VK_SUCCESS;
@ -402,6 +531,7 @@ lvp_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
if (!bufferView)
return;
pipe_sampler_view_reference(&view->sv, NULL);
vk_object_base_finish(&view->base);
vk_free2(&device->vk.alloc, pAllocator, view);
}

View file

@ -255,6 +255,9 @@ struct lvp_image_view {
enum pipe_format pformat;
struct pipe_sampler_view *sv;
struct pipe_image_view iv;
struct pipe_surface *surface; /* have we created a pipe surface for this? */
struct lvp_image_view *multisample; //VK_EXT_multisampled_render_to_single_sampled
};
@ -329,11 +332,11 @@ vk_to_lvp_descriptor_set_layout(const struct vk_descriptor_set_layout *layout)
union lvp_descriptor_info {
struct {
struct pipe_sampler_state *sampler;
struct lvp_image_view *iview;
struct pipe_sampler_view *sampler_view;
};
struct pipe_image_view image_view;
struct pipe_shader_buffer ssbo;
struct pipe_constant_buffer ubo;
struct lvp_buffer_view *buffer_view;
uint8_t *uniform;
};
@ -468,6 +471,8 @@ struct lvp_buffer_view {
struct vk_object_base base;
VkFormat format;
enum pipe_format pformat;
struct pipe_sampler_view *sv;
struct pipe_image_view iv;
struct lvp_buffer *buffer;
uint32_t offset;
uint64_t range;