Path: blob/21.2-virgl/src/intel/vulkan/anv_cmd_buffer.c
4547 views
/*1* Copyright © 2015 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include <assert.h>24#include <stdbool.h>25#include <string.h>26#include <unistd.h>27#include <fcntl.h>2829#include "anv_private.h"30#include "anv_measure.h"3132#include "vk_util.h"3334/** \file anv_cmd_buffer.c35*36* This file contains all of the stuff for emitting commands into a command37* buffer. This includes implementations of most of the vkCmd*38* entrypoints. This file is concerned entirely with state emission and39* not with the command buffer data structure itself. As far as this file40* is concerned, most of anv_cmd_buffer is magic.41*/4243/* TODO: These are taken from GLES. We should check the Vulkan spec */44const struct anv_dynamic_state default_dynamic_state = {45.viewport = {46.count = 0,47},48.scissor = {49.count = 0,50},51.line_width = 1.0f,52.depth_bias = {53.bias = 0.0f,54.clamp = 0.0f,55.slope = 0.0f,56},57.blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },58.depth_bounds = {59.min = 0.0f,60.max = 1.0f,61},62.stencil_compare_mask = {63.front = ~0u,64.back = ~0u,65},66.stencil_write_mask = {67.front = ~0u,68.back = ~0u,69},70.stencil_reference = {71.front = 0u,72.back = 0u,73},74.stencil_op = {75.front = {76.fail_op = 0,77.pass_op = 0,78.depth_fail_op = 0,79.compare_op = 0,80},81.back = {82.fail_op = 0,83.pass_op = 0,84.depth_fail_op = 0,85.compare_op = 0,86},87},88.line_stipple = {89.factor = 0u,90.pattern = 0u,91},92.cull_mode = 0,93.front_face = 0,94.primitive_topology = 0,95.depth_test_enable = 0,96.depth_write_enable = 0,97.depth_compare_op = 0,98.depth_bounds_test_enable = 0,99.stencil_test_enable = 0,100.dyn_vbo_stride = 0,101.dyn_vbo_size = 0,102.color_writes = 0xff,103.raster_discard = 0,104.depth_bias_enable = 0,105.primitive_restart_enable = 0,106.logic_op = 0,107};108109/**110* Copy the dynamic state from src to dest based on the copy_mask.111*112* Avoid copying states that have not changed, except for VIEWPORT, SCISSOR and113* BLEND_CONSTANTS (always copy them if they are in the copy_mask).114*115* Returns a mask of the states which changed.116*/117anv_cmd_dirty_mask_t118anv_dynamic_state_copy(struct anv_dynamic_state *dest,119const struct anv_dynamic_state *src,120anv_cmd_dirty_mask_t copy_mask)121{122anv_cmd_dirty_mask_t changed = 0;123124if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) {125dest->viewport.count = src->viewport.count;126typed_memcpy(dest->viewport.viewports, src->viewport.viewports,127src->viewport.count);128changed |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;129}130131if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SCISSOR) {132dest->scissor.count = src->scissor.count;133typed_memcpy(dest->scissor.scissors, src->scissor.scissors,134src->scissor.count);135changed |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;136}137138if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) {139typed_memcpy(dest->blend_constants, src->blend_constants, 4);140changed |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;141}142143#define ANV_CMP_COPY(field, flag) \144if (copy_mask & flag) { \145if (dest->field != src->field) { \146dest->field = src->field; \147changed |= flag; \148} \149}150151ANV_CMP_COPY(line_width, ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH);152153ANV_CMP_COPY(depth_bias.bias, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);154ANV_CMP_COPY(depth_bias.clamp, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);155ANV_CMP_COPY(depth_bias.slope, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);156157ANV_CMP_COPY(depth_bounds.min, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS);158ANV_CMP_COPY(depth_bounds.max, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS);159160ANV_CMP_COPY(stencil_compare_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK);161ANV_CMP_COPY(stencil_compare_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK);162163ANV_CMP_COPY(stencil_write_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK);164ANV_CMP_COPY(stencil_write_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK);165166ANV_CMP_COPY(stencil_reference.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE);167ANV_CMP_COPY(stencil_reference.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE);168169ANV_CMP_COPY(line_stipple.factor, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);170ANV_CMP_COPY(line_stipple.pattern, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);171172ANV_CMP_COPY(cull_mode, ANV_CMD_DIRTY_DYNAMIC_CULL_MODE);173ANV_CMP_COPY(front_face, ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE);174ANV_CMP_COPY(primitive_topology, ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY);175ANV_CMP_COPY(depth_test_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE);176ANV_CMP_COPY(depth_write_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE);177ANV_CMP_COPY(depth_compare_op, ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP);178ANV_CMP_COPY(depth_bounds_test_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE);179ANV_CMP_COPY(stencil_test_enable, ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE);180181if (copy_mask & VK_DYNAMIC_STATE_STENCIL_OP_EXT) {182ANV_CMP_COPY(stencil_op.front.fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);183ANV_CMP_COPY(stencil_op.front.pass_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);184ANV_CMP_COPY(stencil_op.front.depth_fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);185ANV_CMP_COPY(stencil_op.front.compare_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);186ANV_CMP_COPY(stencil_op.back.fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);187ANV_CMP_COPY(stencil_op.back.pass_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);188ANV_CMP_COPY(stencil_op.back.depth_fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);189ANV_CMP_COPY(stencil_op.back.compare_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);190}191192ANV_CMP_COPY(dyn_vbo_stride, ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE);193ANV_CMP_COPY(dyn_vbo_size, ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE);194195ANV_CMP_COPY(raster_discard, ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE);196ANV_CMP_COPY(depth_bias_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE);197ANV_CMP_COPY(primitive_restart_enable, ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE);198ANV_CMP_COPY(logic_op, ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP);199200if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) {201dest->sample_locations.samples = src->sample_locations.samples;202typed_memcpy(dest->sample_locations.locations,203src->sample_locations.locations,204dest->sample_locations.samples);205changed |= ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;206}207208ANV_CMP_COPY(color_writes, ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE);209210ANV_CMP_COPY(fragment_shading_rate.width, ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE);211ANV_CMP_COPY(fragment_shading_rate.height, ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE);212213#undef ANV_CMP_COPY214215return changed;216}217218static void219anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer)220{221struct anv_cmd_state *state = &cmd_buffer->state;222223memset(state, 0, sizeof(*state));224225state->current_pipeline = UINT32_MAX;226state->restart_index = UINT32_MAX;227state->gfx.dynamic = default_dynamic_state;228}229230static void231anv_cmd_pipeline_state_finish(struct anv_cmd_buffer *cmd_buffer,232struct anv_cmd_pipeline_state *pipe_state)233{234for (uint32_t i = 0; i < ARRAY_SIZE(pipe_state->push_descriptors); i++) {235if (pipe_state->push_descriptors[i]) {236anv_descriptor_set_layout_unref(cmd_buffer->device,237pipe_state->push_descriptors[i]->set.layout);238vk_free(&cmd_buffer->pool->alloc, pipe_state->push_descriptors[i]);239}240}241}242243static void244anv_cmd_state_finish(struct anv_cmd_buffer *cmd_buffer)245{246struct anv_cmd_state *state = &cmd_buffer->state;247248anv_cmd_pipeline_state_finish(cmd_buffer, &state->gfx.base);249anv_cmd_pipeline_state_finish(cmd_buffer, &state->compute.base);250251vk_free(&cmd_buffer->pool->alloc, state->attachments);252}253254static void255anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)256{257anv_cmd_state_finish(cmd_buffer);258anv_cmd_state_init(cmd_buffer);259}260261static VkResult anv_create_cmd_buffer(262struct anv_device * device,263struct anv_cmd_pool * pool,264VkCommandBufferLevel level,265VkCommandBuffer* pCommandBuffer)266{267struct anv_cmd_buffer *cmd_buffer;268VkResult result;269270cmd_buffer = vk_object_alloc(&device->vk, &pool->alloc, sizeof(*cmd_buffer),271VK_OBJECT_TYPE_COMMAND_BUFFER);272if (cmd_buffer == NULL)273return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);274275cmd_buffer->batch.status = VK_SUCCESS;276277cmd_buffer->device = device;278cmd_buffer->pool = pool;279cmd_buffer->level = level;280281result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);282if (result != VK_SUCCESS)283goto fail;284285anv_state_stream_init(&cmd_buffer->surface_state_stream,286&device->surface_state_pool, 4096);287anv_state_stream_init(&cmd_buffer->dynamic_state_stream,288&device->dynamic_state_pool, 16384);289anv_state_stream_init(&cmd_buffer->general_state_stream,290&device->general_state_pool, 16384);291292cmd_buffer->self_mod_locations = NULL;293294anv_cmd_state_init(cmd_buffer);295296list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);297298anv_measure_init(cmd_buffer);299300*pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer);301302return VK_SUCCESS;303304fail:305vk_free(&cmd_buffer->pool->alloc, cmd_buffer);306307return result;308}309310VkResult anv_AllocateCommandBuffers(311VkDevice _device,312const VkCommandBufferAllocateInfo* pAllocateInfo,313VkCommandBuffer* pCommandBuffers)314{315ANV_FROM_HANDLE(anv_device, device, _device);316ANV_FROM_HANDLE(anv_cmd_pool, pool, pAllocateInfo->commandPool);317318VkResult result = VK_SUCCESS;319uint32_t i;320321for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {322result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level,323&pCommandBuffers[i]);324if (result != VK_SUCCESS)325break;326}327328if (result != VK_SUCCESS) {329anv_FreeCommandBuffers(_device, pAllocateInfo->commandPool,330i, pCommandBuffers);331for (i = 0; i < pAllocateInfo->commandBufferCount; i++)332pCommandBuffers[i] = VK_NULL_HANDLE;333}334335return result;336}337338static void339anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)340{341anv_measure_destroy(cmd_buffer);342343list_del(&cmd_buffer->pool_link);344345anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);346347anv_state_stream_finish(&cmd_buffer->surface_state_stream);348anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);349anv_state_stream_finish(&cmd_buffer->general_state_stream);350351anv_cmd_state_finish(cmd_buffer);352353vk_free(&cmd_buffer->pool->alloc, cmd_buffer->self_mod_locations);354355vk_object_free(&cmd_buffer->device->vk, &cmd_buffer->pool->alloc, cmd_buffer);356}357358void anv_FreeCommandBuffers(359VkDevice device,360VkCommandPool commandPool,361uint32_t commandBufferCount,362const VkCommandBuffer* pCommandBuffers)363{364for (uint32_t i = 0; i < commandBufferCount; i++) {365ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCommandBuffers[i]);366367if (!cmd_buffer)368continue;369370anv_cmd_buffer_destroy(cmd_buffer);371}372}373374VkResult375anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer)376{377cmd_buffer->usage_flags = 0;378cmd_buffer->perf_query_pool = NULL;379anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);380anv_cmd_state_reset(cmd_buffer);381382anv_state_stream_finish(&cmd_buffer->surface_state_stream);383anv_state_stream_init(&cmd_buffer->surface_state_stream,384&cmd_buffer->device->surface_state_pool, 4096);385386anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);387anv_state_stream_init(&cmd_buffer->dynamic_state_stream,388&cmd_buffer->device->dynamic_state_pool, 16384);389390anv_state_stream_finish(&cmd_buffer->general_state_stream);391anv_state_stream_init(&cmd_buffer->general_state_stream,392&cmd_buffer->device->general_state_pool, 16384);393394anv_measure_reset(cmd_buffer);395return VK_SUCCESS;396}397398VkResult anv_ResetCommandBuffer(399VkCommandBuffer commandBuffer,400VkCommandBufferResetFlags flags)401{402ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);403return anv_cmd_buffer_reset(cmd_buffer);404}405406void407anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)408{409const struct intel_device_info *devinfo = &cmd_buffer->device->info;410anv_genX(devinfo, cmd_buffer_emit_state_base_address)(cmd_buffer);411}412413void414anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer,415const struct anv_image *image,416VkImageAspectFlagBits aspect,417enum isl_aux_usage aux_usage,418uint32_t level,419uint32_t base_layer,420uint32_t layer_count)421{422const struct intel_device_info *devinfo = &cmd_buffer->device->info;423anv_genX(devinfo, cmd_buffer_mark_image_written)(cmd_buffer, image,424aspect, aux_usage,425level, base_layer,426layer_count);427}428429void430anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer *cmd_buffer)431{432const struct intel_device_info *devinfo = &cmd_buffer->device->info;433anv_genX(devinfo, cmd_emit_conditional_render_predicate)(cmd_buffer);434}435436static bool437mem_update(void *dst, const void *src, size_t size)438{439if (memcmp(dst, src, size) == 0)440return false;441442memcpy(dst, src, size);443return true;444}445446static void447set_dirty_for_bind_map(struct anv_cmd_buffer *cmd_buffer,448gl_shader_stage stage,449const struct anv_pipeline_bind_map *map)450{451assert(stage < ARRAY_SIZE(cmd_buffer->state.surface_sha1s));452if (mem_update(cmd_buffer->state.surface_sha1s[stage],453map->surface_sha1, sizeof(map->surface_sha1)))454cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);455456assert(stage < ARRAY_SIZE(cmd_buffer->state.sampler_sha1s));457if (mem_update(cmd_buffer->state.sampler_sha1s[stage],458map->sampler_sha1, sizeof(map->sampler_sha1)))459cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);460461assert(stage < ARRAY_SIZE(cmd_buffer->state.push_sha1s));462if (mem_update(cmd_buffer->state.push_sha1s[stage],463map->push_sha1, sizeof(map->push_sha1)))464cmd_buffer->state.push_constants_dirty |= mesa_to_vk_shader_stage(stage);465}466467void anv_CmdBindPipeline(468VkCommandBuffer commandBuffer,469VkPipelineBindPoint pipelineBindPoint,470VkPipeline _pipeline)471{472ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);473ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);474475switch (pipelineBindPoint) {476case VK_PIPELINE_BIND_POINT_COMPUTE: {477struct anv_compute_pipeline *compute_pipeline =478anv_pipeline_to_compute(pipeline);479if (cmd_buffer->state.compute.pipeline == compute_pipeline)480return;481482cmd_buffer->state.compute.pipeline = compute_pipeline;483cmd_buffer->state.compute.pipeline_dirty = true;484set_dirty_for_bind_map(cmd_buffer, MESA_SHADER_COMPUTE,485&compute_pipeline->cs->bind_map);486break;487}488489case VK_PIPELINE_BIND_POINT_GRAPHICS: {490struct anv_graphics_pipeline *gfx_pipeline =491anv_pipeline_to_graphics(pipeline);492if (cmd_buffer->state.gfx.pipeline == gfx_pipeline)493return;494495cmd_buffer->state.gfx.pipeline = gfx_pipeline;496cmd_buffer->state.gfx.vb_dirty |= gfx_pipeline->vb_used;497cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE;498499anv_foreach_stage(stage, gfx_pipeline->active_stages) {500set_dirty_for_bind_map(cmd_buffer, stage,501&gfx_pipeline->shaders[stage]->bind_map);502}503504/* Apply the dynamic state from the pipeline */505cmd_buffer->state.gfx.dirty |=506anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic,507&gfx_pipeline->dynamic_state,508gfx_pipeline->dynamic_state_mask);509break;510}511512case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR: {513struct anv_ray_tracing_pipeline *rt_pipeline =514anv_pipeline_to_ray_tracing(pipeline);515if (cmd_buffer->state.rt.pipeline == rt_pipeline)516return;517518cmd_buffer->state.rt.pipeline = rt_pipeline;519cmd_buffer->state.rt.pipeline_dirty = true;520521if (rt_pipeline->stack_size > 0) {522anv_CmdSetRayTracingPipelineStackSizeKHR(commandBuffer,523rt_pipeline->stack_size);524}525break;526}527528default:529assert(!"invalid bind point");530break;531}532}533534void anv_CmdSetRasterizerDiscardEnableEXT(535VkCommandBuffer commandBuffer,536VkBool32 rasterizerDiscardEnable)537{538ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);539540cmd_buffer->state.gfx.dynamic.raster_discard = rasterizerDiscardEnable;541542cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE;543}544545void anv_CmdSetDepthBiasEnableEXT(546VkCommandBuffer commandBuffer,547VkBool32 depthBiasEnable)548{549ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);550551cmd_buffer->state.gfx.dynamic.depth_bias_enable = depthBiasEnable;552553cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE;554}555556void anv_CmdSetPrimitiveRestartEnableEXT(557VkCommandBuffer commandBuffer,558VkBool32 primitiveRestartEnable)559{560ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);561562cmd_buffer->state.gfx.dynamic.primitive_restart_enable = primitiveRestartEnable;563564cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;565}566567void anv_CmdSetLogicOpEXT(568VkCommandBuffer commandBuffer,569VkLogicOp logicOp)570{571ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);572573cmd_buffer->state.gfx.dynamic.logic_op = logicOp;574575cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP;576}577578void anv_CmdSetPatchControlPointsEXT(579VkCommandBuffer commandBuffer,580uint32_t patchControlPoints)581{582ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);583anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_FEATURE_NOT_PRESENT);584}585586void anv_CmdSetViewport(587VkCommandBuffer commandBuffer,588uint32_t firstViewport,589uint32_t viewportCount,590const VkViewport* pViewports)591{592ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);593594const uint32_t total_count = firstViewport + viewportCount;595if (cmd_buffer->state.gfx.dynamic.viewport.count < total_count)596cmd_buffer->state.gfx.dynamic.viewport.count = total_count;597598memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports + firstViewport,599pViewports, viewportCount * sizeof(*pViewports));600601cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;602}603604void anv_CmdSetViewportWithCountEXT(605VkCommandBuffer commandBuffer,606uint32_t viewportCount,607const VkViewport* pViewports)608{609ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);610611cmd_buffer->state.gfx.dynamic.viewport.count = viewportCount;612613memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports,614pViewports, viewportCount * sizeof(*pViewports));615616cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;617}618619void anv_CmdSetScissor(620VkCommandBuffer commandBuffer,621uint32_t firstScissor,622uint32_t scissorCount,623const VkRect2D* pScissors)624{625ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);626627const uint32_t total_count = firstScissor + scissorCount;628if (cmd_buffer->state.gfx.dynamic.scissor.count < total_count)629cmd_buffer->state.gfx.dynamic.scissor.count = total_count;630631memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors + firstScissor,632pScissors, scissorCount * sizeof(*pScissors));633634cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;635}636637void anv_CmdSetScissorWithCountEXT(638VkCommandBuffer commandBuffer,639uint32_t scissorCount,640const VkRect2D* pScissors)641{642ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);643644cmd_buffer->state.gfx.dynamic.scissor.count = scissorCount;645646memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors,647pScissors, scissorCount * sizeof(*pScissors));648649cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;650}651652void anv_CmdSetPrimitiveTopologyEXT(653VkCommandBuffer commandBuffer,654VkPrimitiveTopology primitiveTopology)655{656ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);657658cmd_buffer->state.gfx.dynamic.primitive_topology = primitiveTopology;659660cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;661}662663void anv_CmdSetLineWidth(664VkCommandBuffer commandBuffer,665float lineWidth)666{667ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);668669cmd_buffer->state.gfx.dynamic.line_width = lineWidth;670cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;671}672673void anv_CmdSetDepthBias(674VkCommandBuffer commandBuffer,675float depthBiasConstantFactor,676float depthBiasClamp,677float depthBiasSlopeFactor)678{679ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);680681cmd_buffer->state.gfx.dynamic.depth_bias.bias = depthBiasConstantFactor;682cmd_buffer->state.gfx.dynamic.depth_bias.clamp = depthBiasClamp;683cmd_buffer->state.gfx.dynamic.depth_bias.slope = depthBiasSlopeFactor;684685cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;686}687688void anv_CmdSetBlendConstants(689VkCommandBuffer commandBuffer,690const float blendConstants[4])691{692ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);693694memcpy(cmd_buffer->state.gfx.dynamic.blend_constants,695blendConstants, sizeof(float) * 4);696697cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;698}699700void anv_CmdSetDepthBounds(701VkCommandBuffer commandBuffer,702float minDepthBounds,703float maxDepthBounds)704{705ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);706707cmd_buffer->state.gfx.dynamic.depth_bounds.min = minDepthBounds;708cmd_buffer->state.gfx.dynamic.depth_bounds.max = maxDepthBounds;709710cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;711}712713void anv_CmdSetStencilCompareMask(714VkCommandBuffer commandBuffer,715VkStencilFaceFlags faceMask,716uint32_t compareMask)717{718ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);719720if (faceMask & VK_STENCIL_FACE_FRONT_BIT)721cmd_buffer->state.gfx.dynamic.stencil_compare_mask.front = compareMask;722if (faceMask & VK_STENCIL_FACE_BACK_BIT)723cmd_buffer->state.gfx.dynamic.stencil_compare_mask.back = compareMask;724725cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;726}727728void anv_CmdSetStencilWriteMask(729VkCommandBuffer commandBuffer,730VkStencilFaceFlags faceMask,731uint32_t writeMask)732{733ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);734735if (faceMask & VK_STENCIL_FACE_FRONT_BIT)736cmd_buffer->state.gfx.dynamic.stencil_write_mask.front = writeMask;737if (faceMask & VK_STENCIL_FACE_BACK_BIT)738cmd_buffer->state.gfx.dynamic.stencil_write_mask.back = writeMask;739740cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;741}742743void anv_CmdSetStencilReference(744VkCommandBuffer commandBuffer,745VkStencilFaceFlags faceMask,746uint32_t reference)747{748ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);749750if (faceMask & VK_STENCIL_FACE_FRONT_BIT)751cmd_buffer->state.gfx.dynamic.stencil_reference.front = reference;752if (faceMask & VK_STENCIL_FACE_BACK_BIT)753cmd_buffer->state.gfx.dynamic.stencil_reference.back = reference;754755cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;756}757758void anv_CmdSetSampleLocationsEXT(759VkCommandBuffer commandBuffer,760const VkSampleLocationsInfoEXT* pSampleLocationsInfo)761{762ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);763764struct anv_dynamic_state *dyn_state = &cmd_buffer->state.gfx.dynamic;765uint32_t samples = pSampleLocationsInfo->sampleLocationsPerPixel;766767dyn_state->sample_locations.samples = samples;768typed_memcpy(dyn_state->sample_locations.locations,769pSampleLocationsInfo->pSampleLocations, samples);770771cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;772}773774void anv_CmdSetLineStippleEXT(775VkCommandBuffer commandBuffer,776uint32_t lineStippleFactor,777uint16_t lineStipplePattern)778{779ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);780781cmd_buffer->state.gfx.dynamic.line_stipple.factor = lineStippleFactor;782cmd_buffer->state.gfx.dynamic.line_stipple.pattern = lineStipplePattern;783784cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;785}786787void anv_CmdSetCullModeEXT(788VkCommandBuffer commandBuffer,789VkCullModeFlags cullMode)790{791ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);792793cmd_buffer->state.gfx.dynamic.cull_mode = cullMode;794795cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_CULL_MODE;796}797798void anv_CmdSetFrontFaceEXT(799VkCommandBuffer commandBuffer,800VkFrontFace frontFace)801{802ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);803804cmd_buffer->state.gfx.dynamic.front_face = frontFace;805806cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE;807}808809void anv_CmdSetDepthTestEnableEXT(810VkCommandBuffer commandBuffer,811VkBool32 depthTestEnable)812813{814ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);815816cmd_buffer->state.gfx.dynamic.depth_test_enable = depthTestEnable;817818cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE;819}820821void anv_CmdSetDepthWriteEnableEXT(822VkCommandBuffer commandBuffer,823VkBool32 depthWriteEnable)824{825ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);826827cmd_buffer->state.gfx.dynamic.depth_write_enable = depthWriteEnable;828829cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE;830}831832void anv_CmdSetDepthCompareOpEXT(833VkCommandBuffer commandBuffer,834VkCompareOp depthCompareOp)835{836ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);837838cmd_buffer->state.gfx.dynamic.depth_compare_op = depthCompareOp;839840cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP;841}842843void anv_CmdSetDepthBoundsTestEnableEXT(844VkCommandBuffer commandBuffer,845VkBool32 depthBoundsTestEnable)846{847ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);848849cmd_buffer->state.gfx.dynamic.depth_bounds_test_enable = depthBoundsTestEnable;850851cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE;852}853854void anv_CmdSetStencilTestEnableEXT(855VkCommandBuffer commandBuffer,856VkBool32 stencilTestEnable)857{858ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);859860cmd_buffer->state.gfx.dynamic.stencil_test_enable = stencilTestEnable;861862cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE;863}864865void anv_CmdSetStencilOpEXT(866VkCommandBuffer commandBuffer,867VkStencilFaceFlags faceMask,868VkStencilOp failOp,869VkStencilOp passOp,870VkStencilOp depthFailOp,871VkCompareOp compareOp)872{873ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);874875if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {876cmd_buffer->state.gfx.dynamic.stencil_op.front.fail_op = failOp;877cmd_buffer->state.gfx.dynamic.stencil_op.front.pass_op = passOp;878cmd_buffer->state.gfx.dynamic.stencil_op.front.depth_fail_op = depthFailOp;879cmd_buffer->state.gfx.dynamic.stencil_op.front.compare_op = compareOp;880}881882if (faceMask & VK_STENCIL_FACE_BACK_BIT) {883cmd_buffer->state.gfx.dynamic.stencil_op.back.fail_op = failOp;884cmd_buffer->state.gfx.dynamic.stencil_op.back.pass_op = passOp;885cmd_buffer->state.gfx.dynamic.stencil_op.back.depth_fail_op = depthFailOp;886cmd_buffer->state.gfx.dynamic.stencil_op.back.compare_op = compareOp;887}888889cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP;890}891892static void893anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,894VkPipelineBindPoint bind_point,895struct anv_pipeline_layout *layout,896uint32_t set_index,897struct anv_descriptor_set *set,898uint32_t *dynamic_offset_count,899const uint32_t **dynamic_offsets)900{901struct anv_descriptor_set_layout *set_layout =902layout->set[set_index].layout;903904VkShaderStageFlags stages = set_layout->shader_stages;905struct anv_cmd_pipeline_state *pipe_state;906907switch (bind_point) {908case VK_PIPELINE_BIND_POINT_GRAPHICS:909stages &= VK_SHADER_STAGE_ALL_GRAPHICS;910pipe_state = &cmd_buffer->state.gfx.base;911break;912913case VK_PIPELINE_BIND_POINT_COMPUTE:914stages &= VK_SHADER_STAGE_COMPUTE_BIT;915pipe_state = &cmd_buffer->state.compute.base;916break;917918case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR:919stages &= VK_SHADER_STAGE_RAYGEN_BIT_KHR |920VK_SHADER_STAGE_ANY_HIT_BIT_KHR |921VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |922VK_SHADER_STAGE_MISS_BIT_KHR |923VK_SHADER_STAGE_INTERSECTION_BIT_KHR |924VK_SHADER_STAGE_CALLABLE_BIT_KHR;925pipe_state = &cmd_buffer->state.rt.base;926break;927928default:929unreachable("invalid bind point");930}931932VkShaderStageFlags dirty_stages = 0;933/* If it's a push descriptor set, we have to flag things as dirty934* regardless of whether or not the CPU-side data structure changed as we935* may have edited in-place.936*/937if (pipe_state->descriptors[set_index] != set ||938anv_descriptor_set_is_push(set)) {939pipe_state->descriptors[set_index] = set;940941/* Ray-tracing shaders are entirely bindless and so they don't have942* access to HW binding tables. This means that we have to upload the943* descriptor set as an 64-bit address in the push constants.944*/945if (bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR) {946struct anv_push_constants *push = &pipe_state->push_constants;947948struct anv_address addr = anv_descriptor_set_address(set);949push->desc_sets[set_index] = anv_address_physical(addr);950951if (addr.bo) {952anv_reloc_list_add_bo(cmd_buffer->batch.relocs,953cmd_buffer->batch.alloc,954addr.bo);955}956}957958dirty_stages |= stages;959}960961if (dynamic_offsets) {962if (set_layout->dynamic_offset_count > 0) {963struct anv_push_constants *push = &pipe_state->push_constants;964uint32_t dynamic_offset_start =965layout->set[set_index].dynamic_offset_start;966uint32_t *push_offsets =967&push->dynamic_offsets[dynamic_offset_start];968969/* Assert that everything is in range */970assert(set_layout->dynamic_offset_count <= *dynamic_offset_count);971assert(dynamic_offset_start + set_layout->dynamic_offset_count <=972ARRAY_SIZE(push->dynamic_offsets));973974for (uint32_t i = 0; i < set_layout->dynamic_offset_count; i++) {975if (push_offsets[i] != (*dynamic_offsets)[i]) {976push_offsets[i] = (*dynamic_offsets)[i];977/* dynamic_offset_stages[] elements could contain blanket978* values like VK_SHADER_STAGE_ALL, so limit this to the979* binding point's bits.980*/981dirty_stages |= set_layout->dynamic_offset_stages[i] & stages;982}983}984985*dynamic_offsets += set_layout->dynamic_offset_count;986*dynamic_offset_count -= set_layout->dynamic_offset_count;987}988}989990cmd_buffer->state.descriptors_dirty |= dirty_stages;991cmd_buffer->state.push_constants_dirty |= dirty_stages;992}993994void anv_CmdBindDescriptorSets(995VkCommandBuffer commandBuffer,996VkPipelineBindPoint pipelineBindPoint,997VkPipelineLayout _layout,998uint32_t firstSet,999uint32_t descriptorSetCount,1000const VkDescriptorSet* pDescriptorSets,1001uint32_t dynamicOffsetCount,1002const uint32_t* pDynamicOffsets)1003{1004ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);1005ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);10061007assert(firstSet + descriptorSetCount <= MAX_SETS);10081009for (uint32_t i = 0; i < descriptorSetCount; i++) {1010ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);1011anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,1012layout, firstSet + i, set,1013&dynamicOffsetCount,1014&pDynamicOffsets);1015}1016}10171018void anv_CmdBindVertexBuffers2EXT(1019VkCommandBuffer commandBuffer,1020uint32_t firstBinding,1021uint32_t bindingCount,1022const VkBuffer* pBuffers,1023const VkDeviceSize* pOffsets,1024const VkDeviceSize* pSizes,1025const VkDeviceSize* pStrides)1026{1027ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);1028struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;10291030/* We have to defer setting up vertex buffer since we need the buffer1031* stride from the pipeline. */10321033if (pSizes)1034cmd_buffer->state.gfx.dynamic.dyn_vbo_size = true;1035if (pStrides)1036cmd_buffer->state.gfx.dynamic.dyn_vbo_stride = true;10371038assert(firstBinding + bindingCount <= MAX_VBS);1039for (uint32_t i = 0; i < bindingCount; i++) {1040vb[firstBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);1041vb[firstBinding + i].offset = pOffsets[i];1042vb[firstBinding + i].size = pSizes ? pSizes[i] : 0;1043vb[firstBinding + i].stride = pStrides ? pStrides[i] : 0;1044cmd_buffer->state.gfx.vb_dirty |= 1 << (firstBinding + i);1045}1046}10471048void anv_CmdBindVertexBuffers(1049VkCommandBuffer commandBuffer,1050uint32_t firstBinding,1051uint32_t bindingCount,1052const VkBuffer* pBuffers,1053const VkDeviceSize* pOffsets)1054{1055return anv_CmdBindVertexBuffers2EXT(commandBuffer, firstBinding,1056bindingCount, pBuffers, pOffsets,1057NULL, NULL);1058}10591060void anv_CmdBindTransformFeedbackBuffersEXT(1061VkCommandBuffer commandBuffer,1062uint32_t firstBinding,1063uint32_t bindingCount,1064const VkBuffer* pBuffers,1065const VkDeviceSize* pOffsets,1066const VkDeviceSize* pSizes)1067{1068ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);1069struct anv_xfb_binding *xfb = cmd_buffer->state.xfb_bindings;10701071/* We have to defer setting up vertex buffer since we need the buffer1072* stride from the pipeline. */10731074assert(firstBinding + bindingCount <= MAX_XFB_BUFFERS);1075for (uint32_t i = 0; i < bindingCount; i++) {1076if (pBuffers[i] == VK_NULL_HANDLE) {1077xfb[firstBinding + i].buffer = NULL;1078} else {1079ANV_FROM_HANDLE(anv_buffer, buffer, pBuffers[i]);1080xfb[firstBinding + i].buffer = buffer;1081xfb[firstBinding + i].offset = pOffsets[i];1082xfb[firstBinding + i].size =1083anv_buffer_get_range(buffer, pOffsets[i],1084pSizes ? pSizes[i] : VK_WHOLE_SIZE);1085}1086}1087}10881089enum isl_format1090anv_isl_format_for_descriptor_type(const struct anv_device *device,1091VkDescriptorType type)1092{1093switch (type) {1094case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:1095case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:1096return device->physical->compiler->indirect_ubos_use_sampler ?1097ISL_FORMAT_R32G32B32A32_FLOAT : ISL_FORMAT_RAW;10981099case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:1100case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:1101return ISL_FORMAT_RAW;11021103default:1104unreachable("Invalid descriptor type");1105}1106}11071108struct anv_state1109anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,1110const void *data, uint32_t size, uint32_t alignment)1111{1112struct anv_state state;11131114state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);1115memcpy(state.map, data, size);11161117VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size));11181119return state;1120}11211122struct anv_state1123anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,1124uint32_t *a, uint32_t *b,1125uint32_t dwords, uint32_t alignment)1126{1127struct anv_state state;1128uint32_t *p;11291130state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,1131dwords * 4, alignment);1132p = state.map;1133for (uint32_t i = 0; i < dwords; i++)1134p[i] = a[i] | b[i];11351136VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));11371138return state;1139}11401141struct anv_state1142anv_cmd_buffer_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer)1143{1144struct anv_push_constants *data =1145&cmd_buffer->state.gfx.base.push_constants;11461147struct anv_state state =1148anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,1149sizeof(struct anv_push_constants),115032 /* bottom 5 bits MBZ */);1151memcpy(state.map, data, sizeof(struct anv_push_constants));11521153return state;1154}11551156struct anv_state1157anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)1158{1159const struct intel_device_info *devinfo = &cmd_buffer->device->info;1160struct anv_push_constants *data =1161&cmd_buffer->state.compute.base.push_constants;1162struct anv_compute_pipeline *pipeline = cmd_buffer->state.compute.pipeline;1163const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);1164const struct anv_push_range *range = &pipeline->cs->bind_map.push_ranges[0];11651166const struct brw_cs_dispatch_info dispatch =1167brw_cs_get_dispatch_info(devinfo, cs_prog_data, NULL);1168const unsigned total_push_constants_size =1169brw_cs_push_const_total_size(cs_prog_data, dispatch.threads);1170if (total_push_constants_size == 0)1171return (struct anv_state) { .offset = 0 };11721173const unsigned push_constant_alignment =1174cmd_buffer->device->info.ver < 8 ? 32 : 64;1175const unsigned aligned_total_push_constants_size =1176ALIGN(total_push_constants_size, push_constant_alignment);1177struct anv_state state;1178if (devinfo->verx10 >= 125) {1179state = anv_state_stream_alloc(&cmd_buffer->general_state_stream,1180aligned_total_push_constants_size,1181push_constant_alignment);1182} else {1183state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,1184aligned_total_push_constants_size,1185push_constant_alignment);1186}11871188void *dst = state.map;1189const void *src = (char *)data + (range->start * 32);11901191if (cs_prog_data->push.cross_thread.size > 0) {1192memcpy(dst, src, cs_prog_data->push.cross_thread.size);1193dst += cs_prog_data->push.cross_thread.size;1194src += cs_prog_data->push.cross_thread.size;1195}11961197if (cs_prog_data->push.per_thread.size > 0) {1198for (unsigned t = 0; t < dispatch.threads; t++) {1199memcpy(dst, src, cs_prog_data->push.per_thread.size);12001201uint32_t *subgroup_id = dst +1202offsetof(struct anv_push_constants, cs.subgroup_id) -1203(range->start * 32 + cs_prog_data->push.cross_thread.size);1204*subgroup_id = t;12051206dst += cs_prog_data->push.per_thread.size;1207}1208}12091210return state;1211}12121213void anv_CmdPushConstants(1214VkCommandBuffer commandBuffer,1215VkPipelineLayout layout,1216VkShaderStageFlags stageFlags,1217uint32_t offset,1218uint32_t size,1219const void* pValues)1220{1221ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);12221223if (stageFlags & VK_SHADER_STAGE_ALL_GRAPHICS) {1224struct anv_cmd_pipeline_state *pipe_state =1225&cmd_buffer->state.gfx.base;12261227memcpy(pipe_state->push_constants.client_data + offset, pValues, size);1228}1229if (stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) {1230struct anv_cmd_pipeline_state *pipe_state =1231&cmd_buffer->state.compute.base;12321233memcpy(pipe_state->push_constants.client_data + offset, pValues, size);1234}1235if (stageFlags & (VK_SHADER_STAGE_RAYGEN_BIT_KHR |1236VK_SHADER_STAGE_ANY_HIT_BIT_KHR |1237VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |1238VK_SHADER_STAGE_MISS_BIT_KHR |1239VK_SHADER_STAGE_INTERSECTION_BIT_KHR |1240VK_SHADER_STAGE_CALLABLE_BIT_KHR)) {1241struct anv_cmd_pipeline_state *pipe_state =1242&cmd_buffer->state.rt.base;12431244memcpy(pipe_state->push_constants.client_data + offset, pValues, size);1245}12461247cmd_buffer->state.push_constants_dirty |= stageFlags;1248}12491250VkResult anv_CreateCommandPool(1251VkDevice _device,1252const VkCommandPoolCreateInfo* pCreateInfo,1253const VkAllocationCallbacks* pAllocator,1254VkCommandPool* pCmdPool)1255{1256ANV_FROM_HANDLE(anv_device, device, _device);1257struct anv_cmd_pool *pool;12581259pool = vk_object_alloc(&device->vk, pAllocator, sizeof(*pool),1260VK_OBJECT_TYPE_COMMAND_POOL);1261if (pool == NULL)1262return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);12631264if (pAllocator)1265pool->alloc = *pAllocator;1266else1267pool->alloc = device->vk.alloc;12681269list_inithead(&pool->cmd_buffers);12701271pool->flags = pCreateInfo->flags;12721273*pCmdPool = anv_cmd_pool_to_handle(pool);12741275return VK_SUCCESS;1276}12771278void anv_DestroyCommandPool(1279VkDevice _device,1280VkCommandPool commandPool,1281const VkAllocationCallbacks* pAllocator)1282{1283ANV_FROM_HANDLE(anv_device, device, _device);1284ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);12851286if (!pool)1287return;12881289list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer,1290&pool->cmd_buffers, pool_link) {1291anv_cmd_buffer_destroy(cmd_buffer);1292}12931294vk_object_free(&device->vk, pAllocator, pool);1295}12961297VkResult anv_ResetCommandPool(1298VkDevice device,1299VkCommandPool commandPool,1300VkCommandPoolResetFlags flags)1301{1302ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);13031304list_for_each_entry(struct anv_cmd_buffer, cmd_buffer,1305&pool->cmd_buffers, pool_link) {1306anv_cmd_buffer_reset(cmd_buffer);1307}13081309return VK_SUCCESS;1310}13111312void anv_TrimCommandPool(1313VkDevice device,1314VkCommandPool commandPool,1315VkCommandPoolTrimFlags flags)1316{1317/* Nothing for us to do here. Our pools stay pretty tidy. */1318}13191320/**1321* Return NULL if the current subpass has no depthstencil attachment.1322*/1323const struct anv_image_view *1324anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer)1325{1326const struct anv_subpass *subpass = cmd_buffer->state.subpass;13271328if (subpass->depth_stencil_attachment == NULL)1329return NULL;13301331const struct anv_image_view *iview =1332cmd_buffer->state.attachments[subpass->depth_stencil_attachment->attachment].image_view;13331334assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT |1335VK_IMAGE_ASPECT_STENCIL_BIT));13361337return iview;1338}13391340static struct anv_descriptor_set *1341anv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer,1342VkPipelineBindPoint bind_point,1343struct anv_descriptor_set_layout *layout,1344uint32_t _set)1345{1346struct anv_cmd_pipeline_state *pipe_state;13471348switch (bind_point) {1349case VK_PIPELINE_BIND_POINT_GRAPHICS:1350pipe_state = &cmd_buffer->state.gfx.base;1351break;13521353case VK_PIPELINE_BIND_POINT_COMPUTE:1354pipe_state = &cmd_buffer->state.compute.base;1355break;13561357case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR:1358pipe_state = &cmd_buffer->state.rt.base;1359break;13601361default:1362unreachable("invalid bind point");1363}13641365struct anv_push_descriptor_set **push_set =1366&pipe_state->push_descriptors[_set];13671368if (*push_set == NULL) {1369*push_set = vk_zalloc(&cmd_buffer->pool->alloc,1370sizeof(struct anv_push_descriptor_set), 8,1371VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);1372if (*push_set == NULL) {1373anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY);1374return NULL;1375}1376}13771378struct anv_descriptor_set *set = &(*push_set)->set;13791380if (set->layout != layout) {1381if (set->layout)1382anv_descriptor_set_layout_unref(cmd_buffer->device, set->layout);1383anv_descriptor_set_layout_ref(layout);1384set->layout = layout;1385}1386set->size = anv_descriptor_set_layout_size(layout, 0);1387set->buffer_view_count = layout->buffer_view_count;1388set->descriptor_count = layout->descriptor_count;1389set->buffer_views = (*push_set)->buffer_views;13901391if (layout->descriptor_buffer_size &&1392((*push_set)->set_used_on_gpu ||1393set->desc_mem.alloc_size < layout->descriptor_buffer_size)) {1394/* The previous buffer is either actively used by some GPU command (so1395* we can't modify it) or is too small. Allocate a new one.1396*/1397struct anv_state desc_mem =1398anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,1399anv_descriptor_set_layout_descriptor_buffer_size(layout, 0),1400ANV_UBO_ALIGNMENT);1401if (set->desc_mem.alloc_size) {1402/* TODO: Do we really need to copy all the time? */1403memcpy(desc_mem.map, set->desc_mem.map,1404MIN2(desc_mem.alloc_size, set->desc_mem.alloc_size));1405}1406set->desc_mem = desc_mem;14071408set->desc_addr = (struct anv_address) {1409.bo = cmd_buffer->dynamic_state_stream.state_pool->block_pool.bo,1410.offset = set->desc_mem.offset,1411};14121413enum isl_format format =1414anv_isl_format_for_descriptor_type(cmd_buffer->device,1415VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);14161417const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;1418set->desc_surface_state =1419anv_state_stream_alloc(&cmd_buffer->surface_state_stream,1420isl_dev->ss.size, isl_dev->ss.align);1421anv_fill_buffer_surface_state(cmd_buffer->device,1422set->desc_surface_state, format,1423ISL_SURF_USAGE_CONSTANT_BUFFER_BIT,1424set->desc_addr,1425layout->descriptor_buffer_size, 1);1426}14271428return set;1429}14301431void anv_CmdPushDescriptorSetKHR(1432VkCommandBuffer commandBuffer,1433VkPipelineBindPoint pipelineBindPoint,1434VkPipelineLayout _layout,1435uint32_t _set,1436uint32_t descriptorWriteCount,1437const VkWriteDescriptorSet* pDescriptorWrites)1438{1439ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);1440ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);14411442assert(_set < MAX_SETS);14431444struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;14451446struct anv_descriptor_set *set =1447anv_cmd_buffer_push_descriptor_set(cmd_buffer, pipelineBindPoint,1448set_layout, _set);1449if (!set)1450return;14511452/* Go through the user supplied descriptors. */1453for (uint32_t i = 0; i < descriptorWriteCount; i++) {1454const VkWriteDescriptorSet *write = &pDescriptorWrites[i];14551456switch (write->descriptorType) {1457case VK_DESCRIPTOR_TYPE_SAMPLER:1458case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:1459case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:1460case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:1461case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:1462for (uint32_t j = 0; j < write->descriptorCount; j++) {1463anv_descriptor_set_write_image_view(cmd_buffer->device, set,1464write->pImageInfo + j,1465write->descriptorType,1466write->dstBinding,1467write->dstArrayElement + j);1468}1469break;14701471case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:1472case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:1473for (uint32_t j = 0; j < write->descriptorCount; j++) {1474ANV_FROM_HANDLE(anv_buffer_view, bview,1475write->pTexelBufferView[j]);14761477anv_descriptor_set_write_buffer_view(cmd_buffer->device, set,1478write->descriptorType,1479bview,1480write->dstBinding,1481write->dstArrayElement + j);1482}1483break;14841485case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:1486case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:1487case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:1488case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:1489for (uint32_t j = 0; j < write->descriptorCount; j++) {1490ANV_FROM_HANDLE(anv_buffer, buffer, write->pBufferInfo[j].buffer);14911492anv_descriptor_set_write_buffer(cmd_buffer->device, set,1493&cmd_buffer->surface_state_stream,1494write->descriptorType,1495buffer,1496write->dstBinding,1497write->dstArrayElement + j,1498write->pBufferInfo[j].offset,1499write->pBufferInfo[j].range);1500}1501break;15021503case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {1504const VkWriteDescriptorSetAccelerationStructureKHR *accel_write =1505vk_find_struct_const(write, WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR);1506assert(accel_write->accelerationStructureCount ==1507write->descriptorCount);1508for (uint32_t j = 0; j < write->descriptorCount; j++) {1509ANV_FROM_HANDLE(anv_acceleration_structure, accel,1510accel_write->pAccelerationStructures[j]);1511anv_descriptor_set_write_acceleration_structure(cmd_buffer->device,1512set, accel,1513write->dstBinding,1514write->dstArrayElement + j);1515}1516break;1517}15181519default:1520break;1521}1522}15231524anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,1525layout, _set, set, NULL, NULL);1526}15271528void anv_CmdPushDescriptorSetWithTemplateKHR(1529VkCommandBuffer commandBuffer,1530VkDescriptorUpdateTemplate descriptorUpdateTemplate,1531VkPipelineLayout _layout,1532uint32_t _set,1533const void* pData)1534{1535ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);1536ANV_FROM_HANDLE(anv_descriptor_update_template, template,1537descriptorUpdateTemplate);1538ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);15391540assert(_set < MAX_PUSH_DESCRIPTORS);15411542struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;15431544struct anv_descriptor_set *set =1545anv_cmd_buffer_push_descriptor_set(cmd_buffer, template->bind_point,1546set_layout, _set);1547if (!set)1548return;15491550anv_descriptor_set_write_template(cmd_buffer->device, set,1551&cmd_buffer->surface_state_stream,1552template,1553pData);15541555anv_cmd_buffer_bind_descriptor_set(cmd_buffer, template->bind_point,1556layout, _set, set, NULL, NULL);1557}15581559void anv_CmdSetDeviceMask(1560VkCommandBuffer commandBuffer,1561uint32_t deviceMask)1562{1563/* No-op */1564}15651566void anv_CmdSetColorWriteEnableEXT(1567VkCommandBuffer commandBuffer,1568uint32_t attachmentCount,1569const VkBool32* pColorWriteEnables)1570{1571ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);15721573assert(attachmentCount < MAX_RTS);15741575uint8_t color_writes = 0;1576for (uint32_t i = 0; i < attachmentCount; i++)1577color_writes |= pColorWriteEnables[i] ? (1 << i) : 0;15781579if (cmd_buffer->state.gfx.dynamic.color_writes != color_writes) {1580cmd_buffer->state.gfx.dynamic.color_writes = color_writes;1581cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE;1582}1583}15841585void anv_CmdSetFragmentShadingRateKHR(1586VkCommandBuffer commandBuffer,1587const VkExtent2D* pFragmentSize,1588const VkFragmentShadingRateCombinerOpKHR combinerOps[2])1589{1590ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);15911592cmd_buffer->state.gfx.dynamic.fragment_shading_rate = *pFragmentSize;1593cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE;1594}15951596static inline uint32_t1597ilog2_round_up(uint32_t value)1598{1599assert(value != 0);1600return 32 - __builtin_clz(value - 1);1601}16021603void anv_CmdSetRayTracingPipelineStackSizeKHR(1604VkCommandBuffer commandBuffer,1605uint32_t pipelineStackSize)1606{1607ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);1608struct anv_cmd_ray_tracing_state *rt = &cmd_buffer->state.rt;1609struct anv_device *device = cmd_buffer->device;16101611if (anv_batch_has_error(&cmd_buffer->batch))1612return;16131614uint32_t stack_ids_per_dss = 2048; /* TODO */16151616unsigned stack_size_log2 = ilog2_round_up(pipelineStackSize);1617if (stack_size_log2 < 10)1618stack_size_log2 = 10;16191620if (rt->scratch.layout.total_size == 1 << stack_size_log2)1621return;16221623brw_rt_compute_scratch_layout(&rt->scratch.layout, &device->info,1624stack_ids_per_dss, 1 << stack_size_log2);16251626unsigned bucket = stack_size_log2 - 10;1627assert(bucket < ARRAY_SIZE(device->rt_scratch_bos));16281629struct anv_bo *bo = p_atomic_read(&device->rt_scratch_bos[bucket]);1630if (bo == NULL) {1631struct anv_bo *new_bo;1632VkResult result = anv_device_alloc_bo(device, "RT scratch",1633rt->scratch.layout.total_size,16340, /* alloc_flags */16350, /* explicit_address */1636&new_bo);1637if (result != VK_SUCCESS) {1638rt->scratch.layout.total_size = 0;1639anv_batch_set_error(&cmd_buffer->batch, result);1640return;1641}16421643bo = p_atomic_cmpxchg(&device->rt_scratch_bos[bucket], NULL, new_bo);1644if (bo != NULL) {1645anv_device_release_bo(device, bo);1646} else {1647bo = new_bo;1648}1649}16501651rt->scratch.bo = bo;1652}165316541655