2005
2002
bool update = false;
2006
2003
bool shadow_update = false;
2007
for (i = 0; i < num_views; ++i) {
2008
struct pipe_sampler_view *pview = views ? views[i] : NULL;
2009
struct zink_sampler_view *a = zink_sampler_view(ctx->sampler_views[shader_type][start_slot + i]);
2010
struct zink_sampler_view *b = zink_sampler_view(pview);
2011
struct zink_resource *res = b ? zink_resource(b->base.texture) : NULL;
2012
if (b && b->base.texture) {
2013
if (!a || zink_resource(a->base.texture) != res) {
2015
unbind_samplerview(ctx, shader_type, start_slot + i);
2016
update_res_bind_count(ctx, res, shader_type == MESA_SHADER_COMPUTE, false);
2017
res->sampler_bind_count[shader_type == MESA_SHADER_COMPUTE]++;
2018
res->gfx_barrier |= zink_pipeline_flags_from_pipe_stage(shader_type);
2019
res->barrier_access[shader_type == MESA_SHADER_COMPUTE] |= VK_ACCESS_SHADER_READ_BIT;
2005
for (unsigned i = 0; i < num_views; ++i) {
2006
struct pipe_sampler_view *pview = views[i];
2007
struct zink_sampler_view *a = zink_sampler_view(ctx->sampler_views[shader_type][start_slot + i]);
2008
struct zink_sampler_view *b = zink_sampler_view(pview);
2011
if (take_ownership) {
2012
struct pipe_sampler_view *view = views[i];
2013
pipe_sampler_view_reference(&view, NULL);
2021
if (res->base.b.target == PIPE_BUFFER) {
2022
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
2023
if (!a || a->base.texture != b->base.texture || zink_resource(a->base.texture)->obj != res->obj ||
2024
memcmp(&a->base.u.buf, &b->base.u.buf, sizeof(b->base.u.buf)))
2026
} else if (b->buffer_view->bvci.buffer != res->obj->buffer) {
2027
/* if this resource has been rebound while it wasn't set here,
2028
* its backing resource will have changed and thus we need to update
2031
VkBufferViewCreateInfo bvci = b->buffer_view->bvci;
2032
bvci.buffer = res->obj->buffer;
2033
struct zink_buffer_view *buffer_view = get_buffer_view(ctx, res, &bvci);
2034
assert(buffer_view != b->buffer_view);
2035
zink_buffer_view_reference(zink_screen(ctx->base.screen), &b->buffer_view, NULL);
2036
b->buffer_view = buffer_view;
2038
} else if (!a || a->buffer_view->buffer_view != b->buffer_view->buffer_view)
2040
zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, VK_ACCESS_SHADER_READ_BIT,
2042
zink_batch_resource_usage_set(&ctx->batch, res, false, true);
2043
if (!ctx->unordered_blitting)
2044
res->obj->unordered_read = false;
2045
} else if (!res->obj->is_buffer) {
2046
if (!res->obj->dt && res->base.b.format != b->image_view->base.format)
2047
/* mutable not set by default */
2048
zink_resource_object_init_mutable(ctx, res);
2049
if (res->obj != b->image_view->obj) {
2050
struct pipe_surface *psurf = &b->image_view->base;
2051
VkImageView iv = b->image_view->image_view;
2052
zink_rebind_surface(ctx, &psurf);
2053
b->image_view = zink_surface(psurf);
2054
update |= iv != b->image_view->image_view;
2057
if (shader_type == MESA_SHADER_COMPUTE)
2058
flush_pending_clears(ctx, res);
2059
if (b->cube_array) {
2060
ctx->di.cubes[shader_type] |= BITFIELD_BIT(start_slot + i);
2062
if (!check_for_layout_update(ctx, res, shader_type == MESA_SHADER_COMPUTE) && !ctx->unordered_blitting) {
2063
/* no deferred barrier: unset unordered usage immediately */
2064
res->obj->unordered_read = false;
2065
// TODO: figure out a way to link up layouts between unordered and main cmdbuf
2066
res->obj->unordered_write = false;
2070
zink_batch_resource_usage_set(&ctx->batch, res, false, false);
2072
assert(start_slot + i < 32); //bitfield size
2073
ctx->di.zs_swizzle[shader_type].mask |= BITFIELD_BIT(start_slot + i);
2074
/* this is already gonna be slow, so don't bother trying to micro-optimize */
2075
shadow_update |= memcmp(&ctx->di.zs_swizzle[shader_type].swizzle[start_slot + i],
2076
&b->swizzle, sizeof(struct zink_zs_swizzle));
2077
memcpy(&ctx->di.zs_swizzle[shader_type].swizzle[start_slot + i], &b->swizzle, sizeof(struct zink_zs_swizzle));
2018
struct zink_resource *res = b ? zink_resource(b->base.texture) : NULL;
2019
if (b && b->base.texture) {
2020
if (!a || zink_resource(a->base.texture) != res) {
2022
unbind_samplerview(ctx, shader_type, start_slot + i);
2023
update_res_bind_count(ctx, res, shader_type == MESA_SHADER_COMPUTE, false);
2024
res->sampler_bind_count[shader_type == MESA_SHADER_COMPUTE]++;
2025
res->gfx_barrier |= zink_pipeline_flags_from_pipe_stage(shader_type);
2026
res->barrier_access[shader_type == MESA_SHADER_COMPUTE] |= VK_ACCESS_SHADER_READ_BIT;
2028
if (res->base.b.target == PIPE_BUFFER) {
2029
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
2030
if (!a || a->base.texture != b->base.texture || zink_resource(a->base.texture)->obj != res->obj ||
2031
memcmp(&a->base.u.buf, &b->base.u.buf, sizeof(b->base.u.buf)))
2033
} else if (b->buffer_view->bvci.buffer != res->obj->buffer) {
2034
/* if this resource has been rebound while it wasn't set here,
2035
* its backing resource will have changed and thus we need to update
2038
VkBufferViewCreateInfo bvci = b->buffer_view->bvci;
2039
bvci.buffer = res->obj->buffer;
2040
struct zink_buffer_view *buffer_view = get_buffer_view(ctx, res, &bvci);
2041
assert(buffer_view != b->buffer_view);
2042
zink_buffer_view_reference(zink_screen(ctx->base.screen), &b->buffer_view, NULL);
2043
b->buffer_view = buffer_view;
2045
} else if (!a || a->buffer_view->buffer_view != b->buffer_view->buffer_view)
2047
zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, VK_ACCESS_SHADER_READ_BIT,
2049
zink_batch_resource_usage_set(&ctx->batch, res, false, true);
2050
if (!ctx->unordered_blitting)
2051
res->obj->unordered_read = false;
2079
assert(start_slot + i < 32); //bitfield size
2080
ctx->di.zs_swizzle[shader_type].mask &= ~BITFIELD_BIT(start_slot + i);
2053
if (zink_format_needs_mutable(res->base.b.format, b->image_view->base.format))
2054
/* mutable not set by default */
2055
zink_resource_object_init_mutable(ctx, res);
2056
if (res->obj != b->image_view->obj) {
2057
struct pipe_surface *psurf = &b->image_view->base;
2058
VkImageView iv = b->image_view->image_view;
2059
zink_rebind_surface(ctx, &psurf);
2060
b->image_view = zink_surface(psurf);
2061
update |= iv != b->image_view->image_view;
2064
if (shader_type == MESA_SHADER_COMPUTE)
2065
flush_pending_clears(ctx, res);
2066
if (b->cube_array) {
2067
ctx->di.cubes[shader_type] |= BITFIELD_BIT(start_slot + i);
2069
if (!check_for_layout_update(ctx, res, shader_type == MESA_SHADER_COMPUTE) && !ctx->unordered_blitting) {
2070
/* no deferred barrier: unset unordered usage immediately */
2071
res->obj->unordered_read = false;
2072
// TODO: figure out a way to link up layouts between unordered and main cmdbuf
2073
res->obj->unordered_write = false;
2077
zink_batch_resource_usage_set(&ctx->batch, res, false, false);
2079
assert(start_slot + i < 32); //bitfield size
2080
ctx->di.zs_swizzle[shader_type].mask |= BITFIELD_BIT(start_slot + i);
2081
/* this is already gonna be slow, so don't bother trying to micro-optimize */
2082
shadow_update |= memcmp(&ctx->di.zs_swizzle[shader_type].swizzle[start_slot + i],
2083
&b->swizzle, sizeof(struct zink_zs_swizzle));
2084
memcpy(&ctx->di.zs_swizzle[shader_type].swizzle[start_slot + i], &b->swizzle, sizeof(struct zink_zs_swizzle));
2086
assert(start_slot + i < 32); //bitfield size
2087
ctx->di.zs_swizzle[shader_type].mask &= ~BITFIELD_BIT(start_slot + i);
2083
res->sampler_binds[shader_type] |= BITFIELD_BIT(start_slot + i);
2085
unbind_samplerview(ctx, shader_type, start_slot + i);
2088
if (take_ownership) {
2089
pipe_sampler_view_reference(&ctx->sampler_views[shader_type][start_slot + i], NULL);
2090
ctx->sampler_views[shader_type][start_slot + i] = pview;
2092
pipe_sampler_view_reference(&ctx->sampler_views[shader_type][start_slot + i], pview);
2094
update_descriptor_state_sampler(ctx, shader_type, start_slot + i, res);
2090
res->sampler_binds[shader_type] |= BITFIELD_BIT(start_slot + i);
2092
unbind_samplerview(ctx, shader_type, start_slot + i);
2095
if (take_ownership) {
2096
pipe_sampler_view_reference(&ctx->sampler_views[shader_type][start_slot + i], NULL);
2097
ctx->sampler_views[shader_type][start_slot + i] = pview;
2099
pipe_sampler_view_reference(&ctx->sampler_views[shader_type][start_slot + i], pview);
2101
update_descriptor_state_sampler(ctx, shader_type, start_slot + i, res);
2104
unbind_num_trailing_slots += num_views;
2096
for (; i < num_views + unbind_num_trailing_slots; ++i) {
2097
update |= !!ctx->sampler_views[shader_type][start_slot + i];
2098
unbind_samplerview(ctx, shader_type, start_slot + i);
2107
for (unsigned i = 0; i < unbind_num_trailing_slots; ++i) {
2108
unsigned slot = start_slot + num_views + i;
2109
update |= !!ctx->sampler_views[shader_type][slot];
2110
unbind_samplerview(ctx, shader_type, slot);
2099
2111
pipe_sampler_view_reference(
2100
&ctx->sampler_views[shader_type][start_slot + i],
2112
&ctx->sampler_views[shader_type][slot],
2102
update_descriptor_state_sampler(ctx, shader_type, start_slot + i, NULL);
2114
update_descriptor_state_sampler(ctx, shader_type, slot, NULL);
2104
2116
ctx->di.num_sampler_views[shader_type] = start_slot + num_views;
2106
2118
struct zink_screen *screen = zink_screen(pctx->screen);
2107
zink_context_invalidate_descriptor_state(ctx, shader_type, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot, num_views);
2119
ctx->invalidate_descriptor_state(ctx, shader_type, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot, num_views);
2108
2120
if (!screen->info.have_EXT_non_seamless_cube_map)
2109
2121
update_nonseamless_shader_key(ctx, shader_type);
2110
2122
shadow_update |= shadow_mask != ctx->di.zs_swizzle[shader_type].mask;
4826
VkIndirectCommandsLayoutTokenNV *
4827
zink_dgc_add_token(struct zink_context *ctx, VkIndirectCommandsTokenTypeNV type, void **mem)
4830
struct zink_screen *screen = zink_screen(ctx->base.screen);
4831
VkIndirectCommandsLayoutTokenNV *ret = util_dynarray_grow(&ctx->dgc.tokens, VkIndirectCommandsLayoutTokenNV, 1);
4832
ret->sType = VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_TOKEN_NV;
4834
ret->tokenType = type;
4835
ret->vertexDynamicStride = ctx->gfx_pipeline_state.uses_dynamic_stride;
4836
ret->indirectStateFlags = 0;
4837
ret->indexTypeCount = 0;
4839
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV:
4840
ret->stream = ZINK_DGC_VBO;
4841
size = sizeof(VkBindVertexBufferIndirectCommandNV);
4843
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV:
4844
ret->stream = ZINK_DGC_IB;
4845
size = sizeof(VkBindIndexBufferIndirectCommandNV);
4847
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV:
4848
ret->stream = ZINK_DGC_PSO;
4849
size = sizeof(VkBindShaderGroupIndirectCommandNV);
4851
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV:
4852
ret->stream = ZINK_DGC_PUSH;
4853
ret->pushconstantPipelineLayout = ctx->dgc.last_prog->base.layout;
4854
ret->pushconstantShaderStageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
4855
size = sizeof(float) * 6; //size for full tess level upload every time
4857
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV:
4858
ret->stream = ZINK_DGC_DRAW;
4859
size = sizeof(VkDrawIndirectCommand);
4861
case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV:
4862
ret->stream = ZINK_DGC_DRAW;
4863
size = sizeof(VkDrawIndexedIndirectCommand);
4868
struct zink_resource *old = NULL;
4869
unsigned stream_count = screen->info.nv_dgc_props.maxIndirectCommandsStreamCount >= ZINK_DGC_MAX ? ZINK_DGC_MAX : 1;
4870
if (stream_count == 1)
4872
unsigned stream = ret->stream;
4873
bool max_exceeded = !ctx->dgc.max_size[stream];
4874
ret->offset = ctx->dgc.cur_offsets[stream];
4875
if (ctx->dgc.buffers[stream]) {
4876
/* detect end of buffer */
4877
if (ctx->dgc.bind_offsets[stream] + ctx->dgc.cur_offsets[stream] + size > ctx->dgc.buffers[stream]->base.b.width0) {
4878
old = ctx->dgc.buffers[stream];
4879
ctx->dgc.buffers[stream] = NULL;
4880
max_exceeded = true;
4883
if (!ctx->dgc.buffers[stream]) {
4885
ctx->dgc.max_size[stream] += size * 5;
4888
u_upload_alloc(ctx->dgc.upload[stream], 0, ctx->dgc.max_size[stream],
4889
screen->info.props.limits.minMemoryMapAlignment, &offset,
4890
(struct pipe_resource **)&ctx->dgc.buffers[stream], (void **)&ptr);
4891
size_t cur_size = old ? (ctx->dgc.cur_offsets[stream] - ctx->dgc.bind_offsets[stream]) : 0;
4893
struct pipe_resource *pold = &old->base.b;
4894
/* copy and delete old buffer */
4895
zink_batch_reference_resource_rw(&ctx->batch, old, true);
4896
memcpy(ptr + offset, ctx->dgc.maps[stream] + ctx->dgc.bind_offsets[stream], cur_size);
4897
pipe_resource_reference(&pold, NULL);
4899
ctx->dgc.maps[stream] = ptr;
4900
ctx->dgc.bind_offsets[stream] = offset;
4901
ctx->dgc.cur_offsets[stream] = cur_size;
4903
*mem = ctx->dgc.maps[stream] + ctx->dgc.cur_offsets[stream];
4904
ctx->dgc.cur_offsets[stream] += size;
4909
zink_flush_dgc(struct zink_context *ctx)
4911
struct zink_screen *screen = zink_screen(ctx->base.screen);
4912
struct zink_batch_state *bs = ctx->batch.state;
4913
if (!ctx->dgc.valid)
4916
/* tokens should be created as they are used */
4917
unsigned num_cmds = util_dynarray_num_elements(&ctx->dgc.tokens, VkIndirectCommandsLayoutTokenNV);
4919
VkIndirectCommandsLayoutTokenNV *cmds = ctx->dgc.tokens.data;
4920
uint32_t strides[ZINK_DGC_MAX] = {0};
4922
unsigned stream_count = screen->info.nv_dgc_props.maxIndirectCommandsStreamCount >= ZINK_DGC_MAX ? ZINK_DGC_MAX : 1;
4923
VkIndirectCommandsStreamNV streams[ZINK_DGC_MAX];
4924
for (unsigned i = 0; i < stream_count; i++) {
4925
if (ctx->dgc.buffers[i]) {
4926
streams[i].buffer = ctx->dgc.buffers[i]->obj->buffer;
4927
streams[i].offset = ctx->dgc.bind_offsets[i];
4929
streams[i].buffer = zink_resource(ctx->dummy_vertex_buffer)->obj->buffer;
4930
streams[i].offset = 0;
4933
/* this is a stupid pipeline that will never actually be used as anything but a container */
4934
VkPipeline pipeline = VK_NULL_HANDLE;
4935
if (screen->info.nv_dgc_props.maxGraphicsShaderGroupCount == 1) {
4936
/* RADV doesn't support shader pipeline binds, so use this hacky path */
4937
pipeline = ctx->gfx_pipeline_state.pipeline;
4939
VkPrimitiveTopology vkmode = zink_primitive_topology(ctx->gfx_pipeline_state.gfx_prim_mode);
4940
pipeline = zink_create_gfx_pipeline(screen, ctx->dgc.last_prog, ctx->dgc.last_prog->objs, &ctx->gfx_pipeline_state, ctx->gfx_pipeline_state.element_state->binding_map, vkmode, false, &ctx->dgc.pipelines);
4942
util_dynarray_append(&bs->dgc.pipelines, VkPipeline, pipeline);
4943
VKCTX(CmdBindPipelineShaderGroupNV)(bs->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline, 0);
4945
unsigned remaining = num_cmds;
4946
for (unsigned i = 0; i < num_cmds; i += screen->info.nv_dgc_props.maxIndirectCommandsTokenCount, remaining -= screen->info.nv_dgc_props.maxIndirectCommandsTokenCount) {
4947
VkIndirectCommandsLayoutCreateInfoNV lci = {
4948
VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV,
4951
VK_PIPELINE_BIND_POINT_GRAPHICS,
4952
MIN2(remaining, screen->info.nv_dgc_props.maxIndirectCommandsTokenCount),
4957
VkIndirectCommandsLayoutNV iclayout;
4958
VkResult res = VKSCR(CreateIndirectCommandsLayoutNV)(screen->dev, &lci, NULL, &iclayout);
4959
assert(res == VK_SUCCESS);
4960
util_dynarray_append(&bs->dgc.layouts, VkIndirectCommandsLayoutNV, iclayout);
4962
/* a lot of hacks to set up a preprocess buffer */
4963
VkGeneratedCommandsMemoryRequirementsInfoNV info = {
4964
VK_STRUCTURE_TYPE_GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV,
4966
VK_PIPELINE_BIND_POINT_GRAPHICS,
4971
VkMemoryRequirements2 reqs = {
4972
VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2
4974
VKSCR(GetGeneratedCommandsMemoryRequirementsNV)(screen->dev, &info, &reqs);
4975
struct pipe_resource templ = {0};
4976
templ.target = PIPE_BUFFER;
4977
templ.format = PIPE_FORMAT_R8_UNORM;
4979
templ.usage = PIPE_USAGE_IMMUTABLE;
4981
templ.width0 = reqs.memoryRequirements.size;
4984
templ.array_size = 1;
4985
uint64_t params[] = {reqs.memoryRequirements.size, reqs.memoryRequirements.alignment, reqs.memoryRequirements.memoryTypeBits};
4986
struct pipe_resource *pres = screen->base.resource_create_with_modifiers(&screen->base, &templ, params, 3);
4988
zink_batch_reference_resource_rw(&ctx->batch, zink_resource(pres), true);
4990
VkGeneratedCommandsInfoNV gen = {
4991
VK_STRUCTURE_TYPE_GENERATED_COMMANDS_INFO_NV,
4993
VK_PIPELINE_BIND_POINT_GRAPHICS,
4999
zink_resource(pres)->obj->buffer,
5007
VKCTX(CmdExecuteGeneratedCommandsNV)(ctx->batch.state->cmdbuf, VK_FALSE, &gen);
5009
pipe_resource_reference(&pres, NULL);
5011
util_dynarray_clear(&ctx->dgc.pipelines);
5012
util_dynarray_clear(&ctx->dgc.tokens);
5013
ctx->dgc.valid = false;
5014
ctx->pipeline_changed[0] = true;
5015
zink_select_draw_vbo(ctx);
4760
5018
struct pipe_surface *
4761
5019
zink_get_dummy_pipe_surface(struct zink_context *ctx, int samples_index)