summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gallium/drivers
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2020-08-26 05:29:31 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2020-08-26 05:29:31 +0000
commitb588b4f3eff82e42345c0b15670ab089b53f9cd6 (patch)
tree49350a8ad21d0a8b6f6b5313a33a3080ae81d821 /lib/mesa/src/gallium/drivers
parent2ebab484cac65c01dd19e8c1b62eb58c83074390 (diff)
Import Mesa 20.1.6
Diffstat (limited to 'lib/mesa/src/gallium/drivers')
-rw-r--r--lib/mesa/src/gallium/drivers/panfrost/Android.mk3
-rw-r--r--lib/mesa/src/gallium/drivers/panfrost/Makefile.sources18
-rw-r--r--lib/mesa/src/gallium/drivers/zink/zink_draw.c678
3 files changed, 185 insertions, 514 deletions
diff --git a/lib/mesa/src/gallium/drivers/panfrost/Android.mk b/lib/mesa/src/gallium/drivers/panfrost/Android.mk
index 48c4d52c7..c7ad6e175 100644
--- a/lib/mesa/src/gallium/drivers/panfrost/Android.mk
+++ b/lib/mesa/src/gallium/drivers/panfrost/Android.mk
@@ -42,7 +42,8 @@ LOCAL_STATIC_LIBRARIES := \
libmesa_nir \
libmesa_winsys_panfrost \
libpanfrost_bifrost \
- libpanfrost_lib \
+ libpanfrost_decode \
+ libpanfrost_encoder \
libpanfrost_midgard \
libpanfrost_shared \
libpanfrost_util \
diff --git a/lib/mesa/src/gallium/drivers/panfrost/Makefile.sources b/lib/mesa/src/gallium/drivers/panfrost/Makefile.sources
index 470dfb31e..c734cd080 100644
--- a/lib/mesa/src/gallium/drivers/panfrost/Makefile.sources
+++ b/lib/mesa/src/gallium/drivers/panfrost/Makefile.sources
@@ -1,17 +1,31 @@
C_SOURCES := \
+ nir/nir_lower_blend.c \
+ nir/nir_lower_blend.h \
+ nir/nir_lower_framebuffer.c \
+ \
+ pan_allocate.c \
+ pan_allocate.h \
pan_assemble.c \
pan_blend_cso.c \
- pan_blend_cso.h \
+ pan_blend.h \
+ pan_blending.c \
+ pan_blending.h \
+ pan_blend_shaders.c \
+ pan_blend_shaders.h \
pan_blit.c \
pan_cmdstream.c \
pan_cmdstream.h \
pan_compute.c \
pan_context.c \
pan_context.h \
+ pan_fragment.c \
pan_job.c \
pan_job.h \
+ pan_mfbd.c \
pan_public.h \
pan_resource.c \
pan_resource.h \
+ pan_scoreboard.c \
pan_screen.c \
- pan_screen.h
+ pan_screen.h \
+ pan_sfbd.c \
diff --git a/lib/mesa/src/gallium/drivers/zink/zink_draw.c b/lib/mesa/src/gallium/drivers/zink/zink_draw.c
index 8fc31b13d..553579acf 100644
--- a/lib/mesa/src/gallium/drivers/zink/zink_draw.c
+++ b/lib/mesa/src/gallium/drivers/zink/zink_draw.c
@@ -1,141 +1,39 @@
#include "zink_compiler.h"
#include "zink_context.h"
#include "zink_program.h"
-#include "zink_query.h"
#include "zink_resource.h"
#include "zink_screen.h"
#include "zink_state.h"
-#include "zink_surface.h"
#include "indices/u_primconvert.h"
-#include "tgsi/tgsi_from_mesa.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"
-#include "util/u_prim_restart.h"
-
-static void
-zink_emit_xfb_counter_barrier(struct zink_context *ctx)
-{
- /* Between the pause and resume there needs to be a memory barrier for the counter buffers
- * with a source access of VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT
- * at pipeline stage VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT
- * to a destination access of VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT
- * at pipeline stage VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT.
- *
- * - from VK_EXT_transform_feedback spec
- */
- for (unsigned i = 0; i < ctx->num_so_targets; i++) {
- struct zink_so_target *t = zink_so_target(ctx->so_targets[i]);
- if (!t)
- continue;
- struct zink_resource *res = zink_resource(t->counter_buffer);
- if (t->counter_buffer_valid)
- zink_resource_buffer_barrier(ctx, NULL, res, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT,
- VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT);
- else
- zink_resource_buffer_barrier(ctx, NULL, res, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT,
- VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT);
- }
- ctx->xfb_barrier = false;
-}
-
-static void
-zink_emit_xfb_vertex_input_barrier(struct zink_context *ctx, struct zink_resource *res)
+static VkDescriptorSet
+allocate_descriptor_set(struct zink_screen *screen,
+ struct zink_batch *batch,
+ struct zink_gfx_program *prog)
{
- /* A pipeline barrier is required between using the buffers as
- * transform feedback buffers and vertex buffers to
- * ensure all writes to the transform feedback buffers are visible
- * when the data is read as vertex attributes.
- * The source access is VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT
- * and the destination access is VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
- * for the pipeline stages VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT
- * and VK_PIPELINE_STAGE_VERTEX_INPUT_BIT respectively.
- *
- * - 20.3.1. Drawing Transform Feedback
- */
- zink_resource_buffer_barrier(ctx, NULL, res, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
- VK_PIPELINE_STAGE_VERTEX_INPUT_BIT);
-}
-
-static void
-zink_emit_stream_output_targets(struct pipe_context *pctx)
-{
- struct zink_context *ctx = zink_context(pctx);
- struct zink_screen *screen = zink_screen(pctx->screen);
- struct zink_batch *batch = &ctx->batch;
- VkBuffer buffers[PIPE_MAX_SO_OUTPUTS] = {};
- VkDeviceSize buffer_offsets[PIPE_MAX_SO_OUTPUTS] = {};
- VkDeviceSize buffer_sizes[PIPE_MAX_SO_OUTPUTS] = {};
-
- for (unsigned i = 0; i < ctx->num_so_targets; i++) {
- struct zink_so_target *t = (struct zink_so_target *)ctx->so_targets[i];
- if (!t) {
- /* no need to reference this or anything */
- buffers[i] = zink_resource(ctx->dummy_xfb_buffer)->obj->buffer;
- buffer_offsets[i] = 0;
- buffer_sizes[i] = sizeof(uint8_t);
- continue;
- }
- struct zink_resource *res = zink_resource(t->base.buffer);
- if (!(res->bind_history & ZINK_RESOURCE_USAGE_STREAMOUT))
- /* resource has been rebound */
- t->counter_buffer_valid = false;
- buffers[i] = res->obj->buffer;
- zink_resource_buffer_barrier(ctx, NULL, zink_resource(t->base.buffer),
- VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT);
- zink_batch_reference_resource_rw(batch, res, true);
- buffer_offsets[i] = t->base.buffer_offset;
- buffer_sizes[i] = t->base.buffer_size;
- res->bind_history |= ZINK_RESOURCE_USAGE_STREAMOUT;
- util_range_add(t->base.buffer, &res->valid_buffer_range, t->base.buffer_offset,
- t->base.buffer_offset + t->base.buffer_size);
+ 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;
}
- screen->vk_CmdBindTransformFeedbackBuffersEXT(batch->state->cmdbuf, 0, ctx->num_so_targets,
- buffers, buffer_offsets,
- buffer_sizes);
- ctx->dirty_so_targets = false;
-}
-
-static void
-barrier_vertex_buffers(struct zink_context *ctx)
-{
- 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->vertex_buffers + ctx->element_state->binding_map[i];
- assert(vb);
- if (vb->buffer.resource) {
- struct zink_resource *res = zink_resource(vb->buffer.resource);
- zink_resource_buffer_barrier(ctx, NULL, res, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
- VK_PIPELINE_STAGE_VERTEX_INPUT_BIT);
- }
- }
-}
-
-static void
-check_buffer_barrier(struct zink_context *ctx, struct pipe_resource *pres, VkAccessFlags flags, VkPipelineStageFlags pipeline)
-{
- struct zink_resource *res = zink_resource(pres);
- zink_resource_buffer_barrier(ctx, NULL, res, flags, pipeline);
-}
-
-static void
-barrier_draw_buffers(struct zink_context *ctx, const struct pipe_draw_info *dinfo,
- const struct pipe_draw_indirect_info *dindirect, struct pipe_resource *index_buffer)
-{
- if (index_buffer)
- check_buffer_barrier(ctx, index_buffer, VK_ACCESS_INDEX_READ_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT);
- if (dindirect && dindirect->buffer) {
- check_buffer_barrier(ctx, dindirect->buffer,
- VK_ACCESS_INDIRECT_COMMAND_READ_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT);
- if (dindirect->indirect_draw_count)
- check_buffer_barrier(ctx, dindirect->indirect_draw_count,
- VK_ACCESS_INDIRECT_COMMAND_READ_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT);
- }
+ batch->descs_left -= prog->num_descriptors;
+ return desc_set;
}
static void
@@ -143,100 +41,43 @@ zink_bind_vertex_buffers(struct zink_batch *batch, struct zink_context *ctx)
{
VkBuffer buffers[PIPE_MAX_ATTRIBS];
VkDeviceSize buffer_offsets[PIPE_MAX_ATTRIBS];
- VkDeviceSize buffer_strides[PIPE_MAX_ATTRIBS];
const struct zink_vertex_elements_state *elems = ctx->element_state;
- struct zink_screen *screen = zink_screen(ctx->base.screen);
-
- if (!elems->hw_state.num_bindings)
- return;
-
for (unsigned i = 0; i < elems->hw_state.num_bindings; i++) {
- struct pipe_vertex_buffer *vb = ctx->vertex_buffers + ctx->element_state->binding_map[i];
+ struct pipe_vertex_buffer *vb = ctx->buffers + ctx->element_state->binding_map[i];
assert(vb);
if (vb->buffer.resource) {
struct zink_resource *res = zink_resource(vb->buffer.resource);
- buffers[i] = res->obj->buffer;
+ buffers[i] = res->buffer;
buffer_offsets[i] = vb->buffer_offset;
- buffer_strides[i] = vb->stride;
- zink_batch_reference_resource_rw(batch, res, false);
+ zink_batch_reference_resoure(batch, res);
} else {
- buffers[i] = zink_resource(ctx->dummy_vertex_buffer)->obj->buffer;
+ buffers[i] = zink_resource(ctx->dummy_buffer)->buffer;
buffer_offsets[i] = 0;
- buffer_strides[i] = 0;
}
}
- if (screen->info.have_EXT_extended_dynamic_state)
- screen->vk_CmdBindVertexBuffers2EXT(batch->state->cmdbuf, 0,
- elems->hw_state.num_bindings,
- buffers, buffer_offsets, NULL, buffer_strides);
- else
- vkCmdBindVertexBuffers(batch->state->cmdbuf, 0,
+ if (elems->hw_state.num_bindings > 0)
+ vkCmdBindVertexBuffers(batch->cmdbuf, 0,
elems->hw_state.num_bindings,
buffers, buffer_offsets);
}
-static struct zink_compute_program *
-get_compute_program(struct zink_context *ctx)
-{
- unsigned bits = 1 << PIPE_SHADER_COMPUTE;
- ctx->dirty_shader_stages |= ctx->inlinable_uniforms_dirty_mask &
- ctx->inlinable_uniforms_valid_mask &
- ctx->shader_has_inlinable_uniforms_mask & bits;
- if (ctx->dirty_shader_stages & bits) {
- struct hash_entry *entry = _mesa_hash_table_search(ctx->compute_program_cache,
- &ctx->compute_stage->shader_id);
- if (!entry) {
- struct zink_compute_program *comp;
- comp = zink_create_compute_program(ctx, ctx->compute_stage);
- entry = _mesa_hash_table_insert(ctx->compute_program_cache, &comp->shader->shader_id, comp);
- if (!entry)
- return NULL;
- }
- if (entry->data != ctx->curr_compute)
- ctx->compute_pipeline_state.dirty = true;
- ctx->curr_compute = entry->data;
- ctx->dirty_shader_stages &= bits;
- ctx->inlinable_uniforms_dirty_mask &= bits;
- }
-
- assert(ctx->curr_compute);
- return ctx->curr_compute;
-}
-
static struct zink_gfx_program *
get_gfx_program(struct zink_context *ctx)
{
- if (ctx->last_vertex_stage_dirty) {
- if (ctx->gfx_stages[PIPE_SHADER_GEOMETRY])
- ctx->dirty_shader_stages |= BITFIELD_BIT(PIPE_SHADER_GEOMETRY);
- else if (ctx->gfx_stages[PIPE_SHADER_TESS_EVAL])
- ctx->dirty_shader_stages |= BITFIELD_BIT(PIPE_SHADER_TESS_EVAL);
- else
- ctx->dirty_shader_stages |= BITFIELD_BIT(PIPE_SHADER_VERTEX);
- ctx->last_vertex_stage_dirty = false;
- }
- unsigned bits = u_bit_consecutive(PIPE_SHADER_VERTEX, 5);
- ctx->dirty_shader_stages |= ctx->inlinable_uniforms_dirty_mask &
- ctx->inlinable_uniforms_valid_mask &
- ctx->shader_has_inlinable_uniforms_mask & bits;
- if (ctx->dirty_shader_stages & bits) {
+ if (ctx->dirty_program) {
struct hash_entry *entry = _mesa_hash_table_search(ctx->program_cache,
ctx->gfx_stages);
- if (entry)
- zink_update_gfx_program(ctx, entry->data);
- else {
+ if (!entry) {
struct zink_gfx_program *prog;
- prog = zink_create_gfx_program(ctx, ctx->gfx_stages);
- entry = _mesa_hash_table_insert(ctx->program_cache, prog->shaders, 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;
}
- if (ctx->curr_program != entry->data)
- ctx->gfx_pipeline_state.combined_dirty = true;
ctx->curr_program = entry->data;
- ctx->dirty_shader_stages &= ~bits;
- ctx->inlinable_uniforms_dirty_mask &= ~bits;
+ ctx->dirty_program = false;
}
assert(ctx->curr_program);
@@ -262,92 +103,32 @@ line_width_needed(enum pipe_prim_type reduced_prim,
}
}
-static inline bool
-restart_supported(enum pipe_prim_type mode)
-{
- return mode == PIPE_PRIM_LINE_STRIP || mode == PIPE_PRIM_TRIANGLE_STRIP || mode == PIPE_PRIM_TRIANGLE_FAN;
-}
-
-static void
-update_drawid(struct zink_context *ctx, unsigned draw_id)
-{
- struct zink_batch *batch = &ctx->batch;
- if (ctx->drawid_broken) {
- vkCmdPushConstants(batch->state->cmdbuf, ctx->curr_program->base.layout, VK_SHADER_STAGE_VERTEX_BIT,
- offsetof(struct zink_gfx_push_constant, draw_id), sizeof(unsigned),
- &draw_id);
- }
-}
-
void
zink_draw_vbo(struct pipe_context *pctx,
- const struct pipe_draw_info *dinfo,
- const struct pipe_draw_indirect_info *dindirect,
- const struct pipe_draw_start_count *draws,
- unsigned num_draws)
+ const struct pipe_draw_info *dinfo)
{
- if (!dindirect && (!draws[0].count || !dinfo->instance_count))
- return;
-
struct zink_context *ctx = zink_context(pctx);
struct zink_screen *screen = zink_screen(pctx->screen);
struct zink_rasterizer_state *rast_state = ctx->rast_state;
- struct zink_depth_stencil_alpha_state *dsa_state = ctx->dsa_state;
- struct zink_so_target *so_target =
- dindirect && dindirect->count_from_stream_output ?
- zink_so_target(dindirect->count_from_stream_output) : NULL;
- VkBuffer counter_buffers[PIPE_MAX_SO_OUTPUTS];
- VkDeviceSize counter_buffer_offsets[PIPE_MAX_SO_OUTPUTS];
- bool need_index_buffer_unref = false;
-
- /* check memory usage and flush/stall as needed to avoid oom */
- zink_maybe_flush_or_stall(ctx);
-
- if (dinfo->primitive_restart && !restart_supported(dinfo->mode)) {
- util_draw_vbo_without_prim_restart(pctx, dinfo, dindirect, &draws[0]);
- return;
- }
- if (dinfo->mode == PIPE_PRIM_QUADS ||
- dinfo->mode == PIPE_PRIM_QUAD_STRIP ||
- dinfo->mode == PIPE_PRIM_POLYGON ||
- (dinfo->mode == PIPE_PRIM_TRIANGLE_FAN && !screen->have_triangle_fans) ||
- dinfo->mode == PIPE_PRIM_LINE_LOOP) {
+
+ 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, dindirect, draws, num_draws);
+ util_primconvert_draw_vbo(ctx->primconvert, dinfo);
return;
}
- if (ctx->gfx_pipeline_state.vertices_per_patch != dinfo->vertices_per_patch)
- ctx->gfx_pipeline_state.dirty = true;
- bool drawid_broken = ctx->drawid_broken;
- ctx->drawid_broken = BITSET_TEST(ctx->gfx_stages[PIPE_SHADER_VERTEX]->nir->info.system_values_read, SYSTEM_VALUE_DRAW_ID) &&
- (!dindirect || !dindirect->buffer);
- if (drawid_broken != ctx->drawid_broken)
- ctx->dirty_shader_stages |= BITFIELD_BIT(PIPE_SHADER_VERTEX);
- ctx->gfx_pipeline_state.vertices_per_patch = dinfo->vertices_per_patch;
- if (ctx->rast_state->base.point_quad_rasterization &&
- ctx->gfx_prim_mode != dinfo->mode) {
- if (ctx->gfx_prim_mode == PIPE_PRIM_POINTS || dinfo->mode == PIPE_PRIM_POINTS)
- ctx->dirty_shader_stages |= BITFIELD_BIT(PIPE_SHADER_FRAGMENT);
- }
- ctx->gfx_prim_mode = dinfo->mode;
+
struct zink_gfx_program *gfx_program = get_gfx_program(ctx);
if (!gfx_program)
return;
- if (ctx->gfx_pipeline_state.primitive_restart != !!dinfo->primitive_restart)
- ctx->gfx_pipeline_state.dirty = true;
- ctx->gfx_pipeline_state.primitive_restart = !!dinfo->primitive_restart;
-
- if (!zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state) {
- for (unsigned i = 0; i < ctx->element_state->hw_state.num_bindings; i++) {
- unsigned binding = ctx->element_state->binding_map[i];
- const struct pipe_vertex_buffer *vb = ctx->vertex_buffers + binding;
- if (ctx->gfx_pipeline_state.bindings[i].stride != vb->stride) {
- ctx->gfx_pipeline_state.bindings[i].stride = vb->stride;
- ctx->gfx_pipeline_state.dirty = true;
- }
- }
- }
+ 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);
@@ -372,285 +153,160 @@ zink_draw_vbo(struct pipe_context *pctx,
unsigned index_offset = 0;
struct pipe_resource *index_buffer = NULL;
if (dinfo->index_size > 0) {
- uint32_t restart_index = util_prim_restart_index_from_size(dinfo->index_size);
- if ((dinfo->primitive_restart && (dinfo->restart_index != restart_index)) ||
- (!screen->info.have_EXT_index_type_uint8 && dinfo->index_size == 1)) {
- util_translate_prim_restart_ib(pctx, dinfo, dindirect, &draws[0], &index_buffer);
- need_index_buffer_unref = true;
- } else {
- if (dinfo->has_user_indices) {
- if (!util_upload_index_buffer(pctx, dinfo, &draws[0], &index_buffer, &index_offset, 4)) {
- debug_printf("util_upload_index_buffer() failed\n");
- return;
- }
- } else
- index_buffer = dinfo->index.resource;
- }
+ if (dinfo->has_user_indices) {
+ if (!util_upload_index_buffer(pctx, dinfo, &index_buffer, &index_offset, 4)) {
+ debug_printf("util_upload_index_buffer() failed\n");
+ return;
+ }
+ } else
+ index_buffer = dinfo->index.resource;
}
- if (ctx->xfb_barrier)
- zink_emit_xfb_counter_barrier(ctx);
-
- if (ctx->dirty_so_targets && ctx->num_so_targets)
- zink_emit_stream_output_targets(pctx);
- if (so_target)
- zink_emit_xfb_vertex_input_barrier(ctx, zink_resource(so_target->base.buffer));
+ 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;
- barrier_vertex_buffers(ctx);
- barrier_draw_buffers(ctx, dinfo, dindirect, index_buffer);
+ struct zink_resource *transitions[PIPE_SHADER_TYPES * PIPE_MAX_SHADER_SAMPLER_VIEWS];
+ int num_transitions = 0;
- for (int i = 0; i < ZINK_SHADER_COUNT; i++) {
+ for (int i = 0; i < ARRAY_SIZE(ctx->gfx_stages); i++) {
struct zink_shader *shader = ctx->gfx_stages[i];
if (!shader)
continue;
- enum pipe_shader_type stage = pipe_shader_type_from_mesa(shader->nir->info.stage);
- if (ctx->num_so_targets &&
- (stage == PIPE_SHADER_GEOMETRY ||
- (stage == PIPE_SHADER_TESS_EVAL && !ctx->gfx_stages[PIPE_SHADER_GEOMETRY]) ||
- (stage == PIPE_SHADER_VERTEX && !ctx->gfx_stages[PIPE_SHADER_GEOMETRY] && !ctx->gfx_stages[PIPE_SHADER_TESS_EVAL]))) {
- for (unsigned j = 0; j < ctx->num_so_targets; j++) {
- struct zink_so_target *t = zink_so_target(ctx->so_targets[j]);
- if (t)
- t->stride = shader->streamout.so_info.stride[j] * sizeof(uint32_t);
+
+ 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;
}
- }
- }
- if (zink_program_has_descriptors(&gfx_program->base))
- zink_descriptors_update(ctx, screen, false);
-
- struct zink_batch *batch = zink_batch_rp(ctx);
- VkViewport viewports[PIPE_MAX_VIEWPORTS];
- for (unsigned i = 0; i < ctx->vp_state.num_viewports; i++) {
- VkViewport viewport = {
- ctx->vp_state.viewport_states[i].translate[0] - ctx->vp_state.viewport_states[i].scale[0],
- ctx->vp_state.viewport_states[i].translate[1] - ctx->vp_state.viewport_states[i].scale[1],
- ctx->vp_state.viewport_states[i].scale[0] * 2,
- ctx->vp_state.viewport_states[i].scale[1] * 2,
- ctx->rast_state->base.clip_halfz ?
- ctx->vp_state.viewport_states[i].translate[2] :
- ctx->vp_state.viewport_states[i].translate[2] - ctx->vp_state.viewport_states[i].scale[2],
- ctx->vp_state.viewport_states[i].translate[2] + ctx->vp_state.viewport_states[i].scale[2]
- };
- viewports[i] = viewport;
- }
- if (screen->info.have_EXT_extended_dynamic_state)
- screen->vk_CmdSetViewportWithCountEXT(batch->state->cmdbuf, ctx->vp_state.num_viewports, viewports);
- else
- vkCmdSetViewport(batch->state->cmdbuf, 0, ctx->vp_state.num_viewports, viewports);
- VkRect2D scissors[PIPE_MAX_VIEWPORTS];
- if (ctx->rast_state->base.scissor) {
- for (unsigned i = 0; i < ctx->vp_state.num_viewports; i++) {
- scissors[i].offset.x = ctx->vp_state.scissor_states[i].minx;
- scissors[i].offset.y = ctx->vp_state.scissor_states[i].miny;
- scissors[i].extent.width = ctx->vp_state.scissor_states[i].maxx - ctx->vp_state.scissor_states[i].minx;
- scissors[i].extent.height = ctx->vp_state.scissor_states[i].maxy - ctx->vp_state.scissor_states[i].miny;
- }
- } else {
- for (unsigned i = 0; i < ctx->vp_state.num_viewports; i++) {
- scissors[i].offset.x = 0;
- scissors[i].offset.y = 0;
- scissors[i].extent.width = ctx->fb_state.width;
- scissors[i].extent.height = ctx->fb_state.height;
+ 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;
}
}
- if (screen->info.have_EXT_extended_dynamic_state)
- screen->vk_CmdSetScissorWithCountEXT(batch->state->cmdbuf, ctx->vp_state.num_viewports, scissors);
- else
- vkCmdSetScissor(batch->state->cmdbuf, 0, ctx->vp_state.num_viewports, scissors);
- if (line_width_needed(reduced_prim, rast_state->hw_state.polygon_mode)) {
- if (screen->info.feats.features.wideLines || ctx->line_width == 1.0f)
- vkCmdSetLineWidth(batch->state->cmdbuf, ctx->line_width);
- else
- debug_printf("BUG: wide lines not supported, needs fallback!");
- }
+ struct zink_batch *batch;
+ if (num_transitions > 0) {
+ batch = zink_batch_no_rp(ctx);
- if (dsa_state->base.stencil[0].enabled) {
- if (dsa_state->base.stencil[1].enabled) {
- vkCmdSetStencilReference(batch->state->cmdbuf, VK_STENCIL_FACE_FRONT_BIT,
- ctx->stencil_ref.ref_value[0]);
- vkCmdSetStencilReference(batch->state->cmdbuf, VK_STENCIL_FACE_BACK_BIT,
- ctx->stencil_ref.ref_value[1]);
- } else
- vkCmdSetStencilReference(batch->state->cmdbuf,
- VK_STENCIL_FACE_FRONT_AND_BACK,
- ctx->stencil_ref.ref_value[0]);
+ for (int i = 0; i < num_transitions; ++i)
+ zink_resource_barrier(batch->cmdbuf, transitions[i],
+ transitions[i]->aspect,
+ VK_IMAGE_LAYOUT_GENERAL);
}
- if (depth_bias)
- vkCmdSetDepthBias(batch->state->cmdbuf, rast_state->offset_units, rast_state->offset_clamp, rast_state->offset_scale);
- else
- vkCmdSetDepthBias(batch->state->cmdbuf, 0.0f, 0.0f, 0.0f);
+ batch = zink_batch_rp(ctx);
- if (ctx->gfx_pipeline_state.blend_state->need_blend_constants)
- vkCmdSetBlendConstants(batch->state->cmdbuf, ctx->blend_constants);
+ 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);
- VkPipeline pipeline = zink_get_gfx_pipeline(screen, gfx_program,
- &ctx->gfx_pipeline_state,
- dinfo->mode);
- vkCmdBindPipeline(batch->state->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
-
- zink_bind_vertex_buffers(batch, ctx);
+ for (int i = 0; i < ARRAY_SIZE(ctx->gfx_stages); i++) {
+ struct zink_shader *shader = ctx->gfx_stages[i];
+ if (!shader)
+ continue;
- if (BITSET_TEST(ctx->gfx_stages[PIPE_SHADER_VERTEX]->nir->info.system_values_read, SYSTEM_VALUE_BASE_VERTEX)) {
- unsigned draw_mode_is_indexed = dinfo->index_size > 0;
- vkCmdPushConstants(batch->state->cmdbuf, gfx_program->base.layout, VK_SHADER_STAGE_VERTEX_BIT,
- offsetof(struct zink_gfx_push_constant, draw_mode_is_indexed), sizeof(unsigned),
- &draw_mode_is_indexed);
- }
- if (gfx_program->shaders[PIPE_SHADER_TESS_CTRL] && gfx_program->shaders[PIPE_SHADER_TESS_CTRL]->is_generated)
- vkCmdPushConstants(batch->state->cmdbuf, gfx_program->base.layout, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
- offsetof(struct zink_gfx_push_constant, default_inner_level), sizeof(float) * 6,
- &ctx->tess_levels[0]);
-
- zink_query_update_gs_states(ctx);
-
- if (ctx->num_so_targets) {
- for (unsigned i = 0; i < ctx->num_so_targets; i++) {
- struct zink_so_target *t = zink_so_target(ctx->so_targets[i]);
- counter_buffers[i] = VK_NULL_HANDLE;
- if (t) {
- struct zink_resource *res = zink_resource(t->counter_buffer);
- zink_batch_reference_resource_rw(batch, res, true);
- if (t->counter_buffer_valid) {
- counter_buffers[i] = res->obj->buffer;
- counter_buffer_offsets[i] = t->counter_buffer_offset;
- }
+ 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);
}
}
- screen->vk_CmdBeginTransformFeedbackEXT(batch->state->cmdbuf, 0, ctx->num_so_targets, counter_buffers, counter_buffer_offsets);
}
- unsigned draw_id = dinfo->drawid;
- if (dinfo->index_size > 0) {
- VkIndexType index_type;
- unsigned index_size = dinfo->index_size;
- if (need_index_buffer_unref)
- /* index buffer will have been promoted from uint8 to uint16 in this case */
- index_size = MAX2(index_size, 2);
- switch (index_size) {
- case 1:
- assert(screen->info.have_EXT_index_type_uint8);
- index_type = VK_INDEX_TYPE_UINT8_EXT;
- break;
- case 2:
- index_type = VK_INDEX_TYPE_UINT16;
- break;
- case 4:
- index_type = VK_INDEX_TYPE_UINT32;
- break;
- default:
- unreachable("unknown index size!");
- }
- struct zink_resource *res = zink_resource(index_buffer);
- vkCmdBindIndexBuffer(batch->state->cmdbuf, res->obj->buffer, index_offset, index_type);
- zink_batch_reference_resource_rw(batch, res, false);
- if (dindirect && dindirect->buffer) {
- assert(num_draws == 1);
- update_drawid(ctx, draw_id);
- struct zink_resource *indirect = zink_resource(dindirect->buffer);
- zink_batch_reference_resource_rw(batch, indirect, false);
- if (dindirect->indirect_draw_count) {
- struct zink_resource *indirect_draw_count = zink_resource(dindirect->indirect_draw_count);
- zink_batch_reference_resource_rw(batch, indirect_draw_count, false);
- screen->vk_CmdDrawIndexedIndirectCount(batch->state->cmdbuf, indirect->obj->buffer, dindirect->offset,
- indirect_draw_count->obj->buffer, dindirect->indirect_draw_count_offset,
- dindirect->draw_count, dindirect->stride);
- } else
- vkCmdDrawIndexedIndirect(batch->state->cmdbuf, indirect->obj->buffer, dindirect->offset, dindirect->draw_count, dindirect->stride);
- } else {
- for (unsigned i = 0; i < num_draws; i++) {
- update_drawid(ctx, draw_id);
- vkCmdDrawIndexed(batch->state->cmdbuf,
- draws[i].count, dinfo->instance_count,
- need_index_buffer_unref ? 0 : draws[i].start, dinfo->index_bias, dinfo->start_instance);
- if (dinfo->increment_draw_id)
- draw_id++;
- }
- }
- } else {
- if (so_target && screen->info.tf_props.transformFeedbackDraw) {
- update_drawid(ctx, draw_id);
- zink_batch_reference_resource_rw(batch, zink_resource(so_target->base.buffer), false);
- zink_batch_reference_resource_rw(batch, zink_resource(so_target->counter_buffer), true);
- screen->vk_CmdDrawIndirectByteCountEXT(batch->state->cmdbuf, dinfo->instance_count, dinfo->start_instance,
- zink_resource(so_target->counter_buffer)->obj->buffer, so_target->counter_buffer_offset, 0,
- MIN2(so_target->stride, screen->info.tf_props.maxTransformFeedbackBufferDataStride));
- } else if (dindirect && dindirect->buffer) {
- assert(num_draws == 1);
- update_drawid(ctx, draw_id);
- struct zink_resource *indirect = zink_resource(dindirect->buffer);
- zink_batch_reference_resource_rw(batch, indirect, false);
- if (dindirect->indirect_draw_count) {
- struct zink_resource *indirect_draw_count = zink_resource(dindirect->indirect_draw_count);
- zink_batch_reference_resource_rw(batch, indirect_draw_count, false);
- screen->vk_CmdDrawIndirectCount(batch->state->cmdbuf, indirect->obj->buffer, dindirect->offset,
- indirect_draw_count->obj->buffer, dindirect->indirect_draw_count_offset,
- dindirect->draw_count, dindirect->stride);
- } else
- vkCmdDrawIndirect(batch->state->cmdbuf, indirect->obj->buffer, dindirect->offset, dindirect->draw_count, dindirect->stride);
- } else {
- for (unsigned i = 0; i < num_draws; i++) {
- update_drawid(ctx, draw_id);
- vkCmdDraw(batch->state->cmdbuf, draws[i].count, dinfo->instance_count, draws[i].start, dinfo->start_instance);
- if (dinfo->increment_draw_id)
- draw_id++;
- }
- }
+ 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 (dinfo->index_size > 0 && (dinfo->has_user_indices || need_index_buffer_unref))
- pipe_resource_reference(&index_buffer, NULL);
-
- if (ctx->num_so_targets) {
- for (unsigned i = 0; i < ctx->num_so_targets; i++) {
- struct zink_so_target *t = zink_so_target(ctx->so_targets[i]);
- if (t) {
- counter_buffers[i] = zink_resource(t->counter_buffer)->obj->buffer;
- counter_buffer_offsets[i] = t->counter_buffer_offset;
- t->counter_buffer_valid = true;
- }
- }
- screen->vk_CmdEndTransformFeedbackEXT(batch->state->cmdbuf, 0, ctx->num_so_targets, counter_buffers, counter_buffer_offsets);
+ 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!");
}
- batch->has_work = true;
-}
-void
-zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
-{
- struct zink_context *ctx = zink_context(pctx);
- struct zink_screen *screen = zink_screen(pctx->screen);
- struct zink_batch *batch = &ctx->batch;
-
- /* check memory usage and flush/stall as needed to avoid oom */
- zink_maybe_flush_or_stall(ctx);
+ 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]);
- struct zink_compute_program *comp_program = get_compute_program(ctx);
- if (!comp_program)
- return;
-
- zink_program_update_compute_pipeline_state(ctx, comp_program, info->block);
- VkPipeline pipeline = zink_get_compute_pipeline(screen, comp_program,
- &ctx->compute_pipeline_state);
-
- if (zink_program_has_descriptors(&comp_program->base))
- zink_descriptors_update(ctx, screen, true);
+ 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);
- vkCmdBindPipeline(batch->state->cmdbuf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
+ 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);
+ }
- if (BITSET_TEST(comp_program->shader->nir->info.system_values_read, SYSTEM_VALUE_WORK_DIM))
- vkCmdPushConstants(batch->state->cmdbuf, comp_program->base.layout, VK_SHADER_STAGE_COMPUTE_BIT,
- offsetof(struct zink_cs_push_constant, work_dim), sizeof(uint32_t),
- &info->work_dim);
+ 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 (info->indirect) {
- vkCmdDispatchIndirect(batch->state->cmdbuf, zink_resource(info->indirect)->obj->buffer, info->indirect_offset);
- zink_batch_reference_resource_rw(batch, zink_resource(info->indirect), false);
+ 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
- vkCmdDispatch(batch->state->cmdbuf, info->grid[0], info->grid[1], info->grid[2]);
- batch->has_work = true;
+ 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);
}