From: Erik Faye-Lund Date: Wed, 6 Nov 2019 14:46:16 +0000 (+0100) Subject: zink: move drawing separate source X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4c1cef68cf767057211ef589278523caffeb3d5b;p=mesa.git zink: move drawing separate source This code is kinda stand-alone, and it makes it a bit easier to find the right source in the source-tree. --- diff --git a/src/gallium/drivers/zink/meson.build b/src/gallium/drivers/zink/meson.build index 634d01e27b2..ccef3ff3b21 100644 --- a/src/gallium/drivers/zink/meson.build +++ b/src/gallium/drivers/zink/meson.build @@ -25,6 +25,7 @@ files_libzink = files( 'zink_blit.c', 'zink_compiler.c', 'zink_context.c', + 'zink_draw.c', 'zink_fence.c', 'zink_format.c', 'zink_framebuffer.c', diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 0429c8553bc..14937e33480 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -29,7 +29,6 @@ #include "zink_framebuffer.h" #include "zink_helpers.h" #include "zink_pipeline.h" -#include "zink_program.h" #include "zink_render_pass.h" #include "zink_resource.h" #include "zink_screen.h" @@ -47,7 +46,6 @@ #include "nir.h" #include "util/u_memory.h" -#include "util/u_prim.h" #include "util/u_upload_mgr.h" static void @@ -887,51 +885,6 @@ zink_shader_stage(enum pipe_shader_type type) return stages[type]; } -static VkDescriptorSet -allocate_descriptor_set(struct zink_screen *screen, - struct zink_batch *batch, - struct zink_gfx_program *prog) -{ - assert(batch->descs_left >= prog->num_descriptors); - VkDescriptorSetAllocateInfo dsai; - memset((void *)&dsai, 0, sizeof(dsai)); - dsai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - dsai.pNext = NULL; - dsai.descriptorPool = batch->descpool; - dsai.descriptorSetCount = 1; - dsai.pSetLayouts = &prog->dsl; - - VkDescriptorSet desc_set; - if (vkAllocateDescriptorSets(screen->dev, &dsai, &desc_set) != VK_SUCCESS) { - debug_printf("ZINK: failed to allocate descriptor set :/"); - return VK_NULL_HANDLE; - } - - batch->descs_left -= prog->num_descriptors; - return desc_set; -} - -static void -zink_bind_vertex_buffers(struct zink_batch *batch, struct zink_context *ctx) -{ - VkBuffer buffers[PIPE_MAX_ATTRIBS]; - VkDeviceSize buffer_offsets[PIPE_MAX_ATTRIBS]; - const struct zink_vertex_elements_state *elems = ctx->element_state; - for (unsigned i = 0; i < elems->hw_state.num_bindings; i++) { - struct pipe_vertex_buffer *vb = ctx->buffers + ctx->element_state->binding_map[i]; - assert(vb && vb->buffer.resource); - struct zink_resource *res = zink_resource(vb->buffer.resource); - buffers[i] = res->buffer; - buffer_offsets[i] = vb->buffer_offset; - zink_batch_reference_resoure(batch, res); - } - - if (elems->hw_state.num_bindings > 0) - vkCmdBindVertexBuffers(batch->cmdbuf, 0, - elems->hw_state.num_bindings, - buffers, buffer_offsets); -} - static uint32_t hash_gfx_program(const void *key) { @@ -970,255 +923,6 @@ equals_framebuffer_state(const void *a, const void *b) return memcmp(a, b, sizeof(struct zink_framebuffer_state) + sizeof(s->attachments) * s->num_attachments) == 0; } -static struct zink_gfx_program * -get_gfx_program(struct zink_context *ctx) -{ - if (ctx->dirty_program) { - struct hash_entry *entry = _mesa_hash_table_search(ctx->program_cache, - ctx->gfx_stages); - if (!entry) { - struct zink_gfx_program *prog; - prog = zink_create_gfx_program(zink_screen(ctx->base.screen), - ctx->gfx_stages); - entry = _mesa_hash_table_insert(ctx->program_cache, prog->stages, prog); - if (!entry) - return NULL; - } - ctx->curr_program = entry->data; - ctx->dirty_program = false; - } - - assert(ctx->curr_program); - return ctx->curr_program; -} - -static bool -line_width_needed(enum pipe_prim_type reduced_prim, - VkPolygonMode polygon_mode) -{ - switch (reduced_prim) { - case PIPE_PRIM_POINTS: - return false; - - case PIPE_PRIM_LINES: - return true; - - case PIPE_PRIM_TRIANGLES: - return polygon_mode == VK_POLYGON_MODE_LINE; - - default: - unreachable("unexpected reduced prim"); - } -} - -static void -zink_draw_vbo(struct pipe_context *pctx, - const struct pipe_draw_info *dinfo) -{ - struct zink_context *ctx = zink_context(pctx); - struct zink_screen *screen = zink_screen(pctx->screen); - struct zink_rasterizer_state *rast_state = ctx->rast_state; - - if (dinfo->mode >= PIPE_PRIM_QUADS || - dinfo->mode == PIPE_PRIM_LINE_LOOP || - dinfo->index_size == 1) { - if (!u_trim_pipe_prim(dinfo->mode, (unsigned *)&dinfo->count)) - return; - - util_primconvert_save_rasterizer_state(ctx->primconvert, &rast_state->base); - util_primconvert_draw_vbo(ctx->primconvert, dinfo); - return; - } - - struct zink_gfx_program *gfx_program = get_gfx_program(ctx); - if (!gfx_program) - return; - - VkPipeline pipeline = zink_get_gfx_pipeline(screen, gfx_program, - &ctx->gfx_pipeline_state, - dinfo->mode); - - enum pipe_prim_type reduced_prim = u_reduced_prim(dinfo->mode); - - bool depth_bias = false; - switch (reduced_prim) { - case PIPE_PRIM_POINTS: - depth_bias = rast_state->offset_point; - break; - - case PIPE_PRIM_LINES: - depth_bias = rast_state->offset_line; - break; - - case PIPE_PRIM_TRIANGLES: - depth_bias = rast_state->offset_tri; - break; - - default: - unreachable("unexpected reduced prim"); - } - - unsigned index_offset = 0; - struct pipe_resource *index_buffer = NULL; - if (dinfo->index_size > 0) { - if (dinfo->has_user_indices) { - if (!util_upload_index_buffer(pctx, dinfo, &index_buffer, &index_offset)) { - debug_printf("util_upload_index_buffer() failed\n"); - return; - } - } else - index_buffer = dinfo->index.resource; - } - - VkWriteDescriptorSet wds[PIPE_SHADER_TYPES * PIPE_MAX_CONSTANT_BUFFERS + PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS]; - VkDescriptorBufferInfo buffer_infos[PIPE_SHADER_TYPES * PIPE_MAX_CONSTANT_BUFFERS]; - VkDescriptorImageInfo image_infos[PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS]; - int num_wds = 0, num_buffer_info = 0, num_image_info = 0; - - struct zink_resource *transitions[PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS]; - int num_transitions = 0; - - for (int i = 0; i < ARRAY_SIZE(ctx->gfx_stages); i++) { - struct zink_shader *shader = ctx->gfx_stages[i]; - if (!shader) - continue; - - for (int j = 0; j < shader->num_bindings; j++) { - int index = shader->bindings[j].index; - if (shader->bindings[j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) { - assert(ctx->ubos[i][index].buffer_size > 0); - assert(ctx->ubos[i][index].buffer_size <= screen->props.limits.maxUniformBufferRange); - assert(ctx->ubos[i][index].buffer); - struct zink_resource *res = zink_resource(ctx->ubos[i][index].buffer); - buffer_infos[num_buffer_info].buffer = res->buffer; - buffer_infos[num_buffer_info].offset = ctx->ubos[i][index].buffer_offset; - buffer_infos[num_buffer_info].range = ctx->ubos[i][index].buffer_size; - wds[num_wds].pBufferInfo = buffer_infos + num_buffer_info; - ++num_buffer_info; - } else { - struct pipe_sampler_view *psampler_view = ctx->image_views[i][index]; - assert(psampler_view); - 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; - } - 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; - wds[num_wds].pNext = NULL; - wds[num_wds].dstBinding = shader->bindings[j].binding; - wds[num_wds].dstArrayElement = 0; - wds[num_wds].descriptorCount = 1; - wds[num_wds].descriptorType = shader->bindings[j].type; - ++num_wds; - } - } - - struct zink_batch *batch; - if (num_transitions > 0) { - batch = zink_batch_no_rp(ctx); - - for (int i = 0; i < num_transitions; ++i) - zink_resource_barrier(batch->cmdbuf, transitions[i], - transitions[i]->aspect, - VK_IMAGE_LAYOUT_GENERAL); - } - - batch = zink_batch_rp(ctx); - - if (batch->descs_left < gfx_program->num_descriptors) { - flush_batch(ctx); - batch = zink_batch_rp(ctx); - assert(batch->descs_left >= gfx_program->num_descriptors); - } - - VkDescriptorSet desc_set = allocate_descriptor_set(screen, batch, - gfx_program); - assert(desc_set != VK_NULL_HANDLE); - - for (int i = 0; i < ARRAY_SIZE(ctx->gfx_stages); i++) { - struct zink_shader *shader = ctx->gfx_stages[i]; - if (!shader) - continue; - - for (int j = 0; j < shader->num_bindings; j++) { - int index = shader->bindings[j].index; - if (shader->bindings[j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) { - struct zink_resource *res = zink_resource(ctx->ubos[i][index].buffer); - zink_batch_reference_resoure(batch, res); - } else { - struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->image_views[i][index]); - zink_batch_reference_sampler_view(batch, sampler_view); - } - } - } - - vkCmdSetViewport(batch->cmdbuf, 0, ctx->num_viewports, ctx->viewports); - if (ctx->rast_state->base.scissor) - vkCmdSetScissor(batch->cmdbuf, 0, ctx->num_viewports, ctx->scissors); - else if (ctx->fb_state.width && ctx->fb_state.height) { - VkRect2D fb_scissor = {}; - fb_scissor.extent.width = ctx->fb_state.width; - fb_scissor.extent.height = ctx->fb_state.height; - vkCmdSetScissor(batch->cmdbuf, 0, 1, &fb_scissor); - } - - if (line_width_needed(reduced_prim, rast_state->hw_state.polygon_mode)) { - if (screen->feats.wideLines || ctx->line_width == 1.0f) - vkCmdSetLineWidth(batch->cmdbuf, ctx->line_width); - else - debug_printf("BUG: wide lines not supported, needs fallback!"); - } - - vkCmdSetStencilReference(batch->cmdbuf, VK_STENCIL_FACE_FRONT_BIT, ctx->stencil_ref.ref_value[0]); - vkCmdSetStencilReference(batch->cmdbuf, VK_STENCIL_FACE_BACK_BIT, ctx->stencil_ref.ref_value[1]); - - if (depth_bias) - vkCmdSetDepthBias(batch->cmdbuf, rast_state->offset_units, rast_state->offset_clamp, rast_state->offset_scale); - else - vkCmdSetDepthBias(batch->cmdbuf, 0.0f, 0.0f, 0.0f); - - if (ctx->gfx_pipeline_state.blend_state->need_blend_constants) - vkCmdSetBlendConstants(batch->cmdbuf, ctx->blend_constants); - - if (num_wds > 0) { - for (int i = 0; i < num_wds; ++i) - wds[i].dstSet = desc_set; - vkUpdateDescriptorSets(screen->dev, num_wds, wds, 0, NULL); - } - - vkCmdBindPipeline(batch->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); - vkCmdBindDescriptorSets(batch->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, - gfx_program->layout, 0, 1, &desc_set, 0, NULL); - zink_bind_vertex_buffers(batch, ctx); - - if (dinfo->index_size > 0) { - assert(dinfo->index_size != 1); - VkIndexType index_type = dinfo->index_size == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32; - struct zink_resource *res = zink_resource(index_buffer); - vkCmdBindIndexBuffer(batch->cmdbuf, res->buffer, index_offset, index_type); - zink_batch_reference_resoure(batch, res); - vkCmdDrawIndexed(batch->cmdbuf, - dinfo->count, dinfo->instance_count, - dinfo->start, dinfo->index_bias, dinfo->start_instance); - } else - vkCmdDraw(batch->cmdbuf, dinfo->count, dinfo->instance_count, dinfo->start, dinfo->start_instance); - - if (dinfo->index_size > 0 && dinfo->has_user_indices) - pipe_resource_reference(&index_buffer, NULL); -} - static void zink_flush(struct pipe_context *pctx, struct pipe_fence_handle **pfence, diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index c1e2843ce8c..026a2e9791c 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -152,4 +152,8 @@ void zink_blit(struct pipe_context *pctx, const struct pipe_blit_info *info); +void +zink_draw_vbo(struct pipe_context *pctx, + const struct pipe_draw_info *dinfo); + #endif diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c new file mode 100644 index 00000000000..1d276502ca9 --- /dev/null +++ b/src/gallium/drivers/zink/zink_draw.c @@ -0,0 +1,307 @@ +#include "zink_compiler.h" +#include "zink_context.h" +#include "zink_program.h" +#include "zink_resource.h" +#include "zink_screen.h" +#include "zink_state.h" + +#include "indices/u_primconvert.h" +#include "util/hash_table.h" +#include "util/u_debug.h" +#include "util/u_helpers.h" +#include "util/u_inlines.h" +#include "util/u_prim.h" + +static VkDescriptorSet +allocate_descriptor_set(struct zink_screen *screen, + struct zink_batch *batch, + struct zink_gfx_program *prog) +{ + assert(batch->descs_left >= prog->num_descriptors); + VkDescriptorSetAllocateInfo dsai; + memset((void *)&dsai, 0, sizeof(dsai)); + dsai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + dsai.pNext = NULL; + dsai.descriptorPool = batch->descpool; + dsai.descriptorSetCount = 1; + dsai.pSetLayouts = &prog->dsl; + + VkDescriptorSet desc_set; + if (vkAllocateDescriptorSets(screen->dev, &dsai, &desc_set) != VK_SUCCESS) { + debug_printf("ZINK: failed to allocate descriptor set :/"); + return VK_NULL_HANDLE; + } + + batch->descs_left -= prog->num_descriptors; + return desc_set; +} + +static void +zink_bind_vertex_buffers(struct zink_batch *batch, struct zink_context *ctx) +{ + VkBuffer buffers[PIPE_MAX_ATTRIBS]; + VkDeviceSize buffer_offsets[PIPE_MAX_ATTRIBS]; + const struct zink_vertex_elements_state *elems = ctx->element_state; + for (unsigned i = 0; i < elems->hw_state.num_bindings; i++) { + struct pipe_vertex_buffer *vb = ctx->buffers + ctx->element_state->binding_map[i]; + assert(vb && vb->buffer.resource); + struct zink_resource *res = zink_resource(vb->buffer.resource); + buffers[i] = res->buffer; + buffer_offsets[i] = vb->buffer_offset; + zink_batch_reference_resoure(batch, res); + } + + if (elems->hw_state.num_bindings > 0) + vkCmdBindVertexBuffers(batch->cmdbuf, 0, + elems->hw_state.num_bindings, + buffers, buffer_offsets); +} + +static struct zink_gfx_program * +get_gfx_program(struct zink_context *ctx) +{ + if (ctx->dirty_program) { + struct hash_entry *entry = _mesa_hash_table_search(ctx->program_cache, + ctx->gfx_stages); + if (!entry) { + struct zink_gfx_program *prog; + prog = zink_create_gfx_program(zink_screen(ctx->base.screen), + ctx->gfx_stages); + entry = _mesa_hash_table_insert(ctx->program_cache, prog->stages, prog); + if (!entry) + return NULL; + } + ctx->curr_program = entry->data; + ctx->dirty_program = false; + } + + assert(ctx->curr_program); + return ctx->curr_program; +} + +static bool +line_width_needed(enum pipe_prim_type reduced_prim, + VkPolygonMode polygon_mode) +{ + switch (reduced_prim) { + case PIPE_PRIM_POINTS: + return false; + + case PIPE_PRIM_LINES: + return true; + + case PIPE_PRIM_TRIANGLES: + return polygon_mode == VK_POLYGON_MODE_LINE; + + default: + unreachable("unexpected reduced prim"); + } +} + +void +zink_draw_vbo(struct pipe_context *pctx, + const struct pipe_draw_info *dinfo) +{ + struct zink_context *ctx = zink_context(pctx); + struct zink_screen *screen = zink_screen(pctx->screen); + struct zink_rasterizer_state *rast_state = ctx->rast_state; + + if (dinfo->mode >= PIPE_PRIM_QUADS || + dinfo->mode == PIPE_PRIM_LINE_LOOP || + dinfo->index_size == 1) { + if (!u_trim_pipe_prim(dinfo->mode, (unsigned *)&dinfo->count)) + return; + + util_primconvert_save_rasterizer_state(ctx->primconvert, &rast_state->base); + util_primconvert_draw_vbo(ctx->primconvert, dinfo); + return; + } + + struct zink_gfx_program *gfx_program = get_gfx_program(ctx); + if (!gfx_program) + return; + + VkPipeline pipeline = zink_get_gfx_pipeline(screen, gfx_program, + &ctx->gfx_pipeline_state, + dinfo->mode); + + enum pipe_prim_type reduced_prim = u_reduced_prim(dinfo->mode); + + bool depth_bias = false; + switch (reduced_prim) { + case PIPE_PRIM_POINTS: + depth_bias = rast_state->offset_point; + break; + + case PIPE_PRIM_LINES: + depth_bias = rast_state->offset_line; + break; + + case PIPE_PRIM_TRIANGLES: + depth_bias = rast_state->offset_tri; + break; + + default: + unreachable("unexpected reduced prim"); + } + + unsigned index_offset = 0; + struct pipe_resource *index_buffer = NULL; + if (dinfo->index_size > 0) { + if (dinfo->has_user_indices) { + if (!util_upload_index_buffer(pctx, dinfo, &index_buffer, &index_offset)) { + debug_printf("util_upload_index_buffer() failed\n"); + return; + } + } else + index_buffer = dinfo->index.resource; + } + + VkWriteDescriptorSet wds[PIPE_SHADER_TYPES * PIPE_MAX_CONSTANT_BUFFERS + PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS]; + VkDescriptorBufferInfo buffer_infos[PIPE_SHADER_TYPES * PIPE_MAX_CONSTANT_BUFFERS]; + VkDescriptorImageInfo image_infos[PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS]; + int num_wds = 0, num_buffer_info = 0, num_image_info = 0; + + struct zink_resource *transitions[PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS]; + int num_transitions = 0; + + for (int i = 0; i < ARRAY_SIZE(ctx->gfx_stages); i++) { + struct zink_shader *shader = ctx->gfx_stages[i]; + if (!shader) + continue; + + for (int j = 0; j < shader->num_bindings; j++) { + int index = shader->bindings[j].index; + if (shader->bindings[j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) { + assert(ctx->ubos[i][index].buffer_size > 0); + assert(ctx->ubos[i][index].buffer_size <= screen->props.limits.maxUniformBufferRange); + assert(ctx->ubos[i][index].buffer); + struct zink_resource *res = zink_resource(ctx->ubos[i][index].buffer); + buffer_infos[num_buffer_info].buffer = res->buffer; + buffer_infos[num_buffer_info].offset = ctx->ubos[i][index].buffer_offset; + buffer_infos[num_buffer_info].range = ctx->ubos[i][index].buffer_size; + wds[num_wds].pBufferInfo = buffer_infos + num_buffer_info; + ++num_buffer_info; + } else { + struct pipe_sampler_view *psampler_view = ctx->image_views[i][index]; + assert(psampler_view); + 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; + } + 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; + wds[num_wds].pNext = NULL; + wds[num_wds].dstBinding = shader->bindings[j].binding; + wds[num_wds].dstArrayElement = 0; + wds[num_wds].descriptorCount = 1; + wds[num_wds].descriptorType = shader->bindings[j].type; + ++num_wds; + } + } + + struct zink_batch *batch; + if (num_transitions > 0) { + batch = zink_batch_no_rp(ctx); + + for (int i = 0; i < num_transitions; ++i) + zink_resource_barrier(batch->cmdbuf, transitions[i], + transitions[i]->aspect, + VK_IMAGE_LAYOUT_GENERAL); + } + + batch = zink_batch_rp(ctx); + + if (batch->descs_left < gfx_program->num_descriptors) { + ctx->base.flush(&ctx->base, NULL, 0); + batch = zink_batch_rp(ctx); + assert(batch->descs_left >= gfx_program->num_descriptors); + } + + VkDescriptorSet desc_set = allocate_descriptor_set(screen, batch, + gfx_program); + assert(desc_set != VK_NULL_HANDLE); + + for (int i = 0; i < ARRAY_SIZE(ctx->gfx_stages); i++) { + struct zink_shader *shader = ctx->gfx_stages[i]; + if (!shader) + continue; + + for (int j = 0; j < shader->num_bindings; j++) { + int index = shader->bindings[j].index; + if (shader->bindings[j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) { + struct zink_resource *res = zink_resource(ctx->ubos[i][index].buffer); + zink_batch_reference_resoure(batch, res); + } else { + struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->image_views[i][index]); + zink_batch_reference_sampler_view(batch, sampler_view); + } + } + } + + vkCmdSetViewport(batch->cmdbuf, 0, ctx->num_viewports, ctx->viewports); + if (ctx->rast_state->base.scissor) + vkCmdSetScissor(batch->cmdbuf, 0, ctx->num_viewports, ctx->scissors); + else if (ctx->fb_state.width && ctx->fb_state.height) { + VkRect2D fb_scissor = {}; + fb_scissor.extent.width = ctx->fb_state.width; + fb_scissor.extent.height = ctx->fb_state.height; + vkCmdSetScissor(batch->cmdbuf, 0, 1, &fb_scissor); + } + + if (line_width_needed(reduced_prim, rast_state->hw_state.polygon_mode)) { + if (screen->feats.wideLines || ctx->line_width == 1.0f) + vkCmdSetLineWidth(batch->cmdbuf, ctx->line_width); + else + debug_printf("BUG: wide lines not supported, needs fallback!"); + } + + vkCmdSetStencilReference(batch->cmdbuf, VK_STENCIL_FACE_FRONT_BIT, ctx->stencil_ref.ref_value[0]); + vkCmdSetStencilReference(batch->cmdbuf, VK_STENCIL_FACE_BACK_BIT, ctx->stencil_ref.ref_value[1]); + + if (depth_bias) + vkCmdSetDepthBias(batch->cmdbuf, rast_state->offset_units, rast_state->offset_clamp, rast_state->offset_scale); + else + vkCmdSetDepthBias(batch->cmdbuf, 0.0f, 0.0f, 0.0f); + + if (ctx->gfx_pipeline_state.blend_state->need_blend_constants) + vkCmdSetBlendConstants(batch->cmdbuf, ctx->blend_constants); + + if (num_wds > 0) { + for (int i = 0; i < num_wds; ++i) + wds[i].dstSet = desc_set; + vkUpdateDescriptorSets(screen->dev, num_wds, wds, 0, NULL); + } + + vkCmdBindPipeline(batch->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + vkCmdBindDescriptorSets(batch->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, + gfx_program->layout, 0, 1, &desc_set, 0, NULL); + zink_bind_vertex_buffers(batch, ctx); + + if (dinfo->index_size > 0) { + assert(dinfo->index_size != 1); + VkIndexType index_type = dinfo->index_size == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32; + struct zink_resource *res = zink_resource(index_buffer); + vkCmdBindIndexBuffer(batch->cmdbuf, res->buffer, index_offset, index_type); + zink_batch_reference_resoure(batch, res); + vkCmdDrawIndexed(batch->cmdbuf, + dinfo->count, dinfo->instance_count, + dinfo->start, dinfo->index_bias, dinfo->start_instance); + } else + vkCmdDraw(batch->cmdbuf, dinfo->count, dinfo->instance_count, dinfo->start, dinfo->start_instance); + + if (dinfo->index_size > 0 && dinfo->has_user_indices) + pipe_resource_reference(&index_buffer, NULL); +}