Path: blob/21.2-virgl/src/gallium/frontends/lavapipe/lvp_execute.c
4565 views
/*1* Copyright © 2019 Red Hat.2*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/* use a gallium context to execute a command buffer */2425#include "lvp_private.h"2627#include "pipe/p_context.h"28#include "pipe/p_state.h"29#include "lvp_conv.h"3031#include "pipe/p_shader_tokens.h"32#include "tgsi/tgsi_text.h"33#include "tgsi/tgsi_parse.h"3435#include "util/format/u_format.h"36#include "util/u_surface.h"37#include "util/u_sampler.h"38#include "util/u_box.h"39#include "util/u_inlines.h"40#include "util/u_prim.h"41#include "util/u_prim_restart.h"42#include "util/format/u_format_zs.h"4344#include "vk_util.h"4546#define DOUBLE_EQ(a, b) (fabs((a) - (b)) < DBL_EPSILON)4748enum gs_output {49GS_OUTPUT_NONE,50GS_OUTPUT_NOT_LINES,51GS_OUTPUT_LINES,52};5354struct rendering_state {55struct pipe_context *pctx;56struct cso_context *cso;5758bool blend_dirty;59bool rs_dirty;60bool dsa_dirty;61bool stencil_ref_dirty;62bool clip_state_dirty;63bool blend_color_dirty;64bool ve_dirty;65bool vb_dirty;66bool constbuf_dirty[PIPE_SHADER_TYPES];67bool pcbuf_dirty[PIPE_SHADER_TYPES];68bool vp_dirty;69bool scissor_dirty;70bool ib_dirty;71bool sample_mask_dirty;72bool min_samples_dirty;73struct pipe_draw_indirect_info indirect_info;74struct pipe_draw_info info;7576struct pipe_grid_info dispatch_info;77struct pipe_framebuffer_state framebuffer;7879struct pipe_blend_state blend_state;80struct {81float offset_units;82float offset_scale;83float offset_clamp;84bool enabled;85} depth_bias;86struct pipe_rasterizer_state rs_state;87struct pipe_depth_stencil_alpha_state dsa_state;8889struct pipe_blend_color blend_color;90struct pipe_stencil_ref stencil_ref;91struct pipe_clip_state clip_state;9293int num_scissors;94struct pipe_scissor_state scissors[16];9596int num_viewports;97struct pipe_viewport_state viewports[16];9899ubyte index_size;100unsigned index_offset;101struct pipe_resource *index_buffer;102struct pipe_constant_buffer pc_buffer[PIPE_SHADER_TYPES];103struct pipe_constant_buffer const_buffer[PIPE_SHADER_TYPES][16];104int num_const_bufs[PIPE_SHADER_TYPES];105int num_vb;106unsigned start_vb;107struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];108struct cso_velems_state velem;109110struct pipe_sampler_view *sv[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];111int num_sampler_views[PIPE_SHADER_TYPES];112struct pipe_sampler_state ss[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];113/* cso_context api is stupid */114const struct pipe_sampler_state *cso_ss_ptr[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];115int num_sampler_states[PIPE_SHADER_TYPES];116bool sv_dirty[PIPE_SHADER_TYPES];117bool ss_dirty[PIPE_SHADER_TYPES];118119struct pipe_image_view iv[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];120int num_shader_images[PIPE_SHADER_TYPES];121struct pipe_shader_buffer sb[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];122int num_shader_buffers[PIPE_SHADER_TYPES];123bool iv_dirty[PIPE_SHADER_TYPES];124bool sb_dirty[PIPE_SHADER_TYPES];125bool disable_multisample;126enum gs_output gs_output_lines : 2;127void *ss_cso[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];128void *velems_cso;129130uint8_t push_constants[128 * 4];131132const struct lvp_render_pass *pass;133uint32_t subpass;134const struct lvp_framebuffer *vk_framebuffer;135VkRect2D render_area;136137uint32_t sample_mask;138unsigned min_samples;139140struct lvp_image_view **imageless_views;141const struct lvp_attachment_state *attachments;142VkImageAspectFlags *pending_clear_aspects;143uint32_t *cleared_views;144int num_pending_aspects;145146uint32_t num_so_targets;147struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];148uint32_t so_offsets[PIPE_MAX_SO_BUFFERS];149};150151ALWAYS_INLINE static void152assert_subresource_layers(const struct pipe_resource *pres, const VkImageSubresourceLayers *layers, const VkOffset3D *offsets)153{154#ifndef NDEBUG155if (pres->target == PIPE_TEXTURE_3D) {156assert(layers->baseArrayLayer == 0);157assert(layers->layerCount == 1);158assert(offsets[0].z <= pres->depth0);159assert(offsets[1].z <= pres->depth0);160} else {161assert(layers->baseArrayLayer < pres->array_size);162assert(layers->baseArrayLayer + layers->layerCount <= pres->array_size);163assert(offsets[0].z == 0);164assert(offsets[1].z == 1);165}166#endif167}168169static void emit_compute_state(struct rendering_state *state)170{171if (state->iv_dirty[PIPE_SHADER_COMPUTE]) {172state->pctx->set_shader_images(state->pctx, PIPE_SHADER_COMPUTE,1730, state->num_shader_images[PIPE_SHADER_COMPUTE],1740, state->iv[PIPE_SHADER_COMPUTE]);175state->iv_dirty[PIPE_SHADER_COMPUTE] = false;176}177178if (state->pcbuf_dirty[PIPE_SHADER_COMPUTE]) {179state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE,1800, false, &state->pc_buffer[PIPE_SHADER_COMPUTE]);181state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = false;182}183184if (state->constbuf_dirty[PIPE_SHADER_COMPUTE]) {185for (unsigned i = 0; i < state->num_const_bufs[PIPE_SHADER_COMPUTE]; i++)186state->pctx->set_constant_buffer(state->pctx, PIPE_SHADER_COMPUTE,187i + 1, false, &state->const_buffer[PIPE_SHADER_COMPUTE][i]);188state->constbuf_dirty[PIPE_SHADER_COMPUTE] = false;189}190191if (state->sb_dirty[PIPE_SHADER_COMPUTE]) {192state->pctx->set_shader_buffers(state->pctx, PIPE_SHADER_COMPUTE,1930, state->num_shader_buffers[PIPE_SHADER_COMPUTE],194state->sb[PIPE_SHADER_COMPUTE], 0);195state->sb_dirty[PIPE_SHADER_COMPUTE] = false;196}197198if (state->sv_dirty[PIPE_SHADER_COMPUTE]) {199state->pctx->set_sampler_views(state->pctx, PIPE_SHADER_COMPUTE, 0, state->num_sampler_views[PIPE_SHADER_COMPUTE],2000, state->sv[PIPE_SHADER_COMPUTE]);201state->sv_dirty[PIPE_SHADER_COMPUTE] = false;202}203204if (state->ss_dirty[PIPE_SHADER_COMPUTE]) {205for (unsigned i = 0; i < state->num_sampler_states[PIPE_SHADER_COMPUTE]; i++) {206if (state->ss_cso[PIPE_SHADER_COMPUTE][i])207state->pctx->delete_sampler_state(state->pctx, state->ss_cso[PIPE_SHADER_COMPUTE][i]);208state->ss_cso[PIPE_SHADER_COMPUTE][i] = state->pctx->create_sampler_state(state->pctx, &state->ss[PIPE_SHADER_COMPUTE][i]);209}210state->pctx->bind_sampler_states(state->pctx, PIPE_SHADER_COMPUTE, 0, state->num_sampler_states[PIPE_SHADER_COMPUTE], state->ss_cso[PIPE_SHADER_COMPUTE]);211state->ss_dirty[PIPE_SHADER_COMPUTE] = false;212}213}214215static void emit_state(struct rendering_state *state)216{217int sh;218if (state->blend_dirty) {219cso_set_blend(state->cso, &state->blend_state);220state->blend_dirty = false;221}222223if (state->rs_dirty) {224bool ms = state->rs_state.multisample;225if (state->disable_multisample &&226(state->gs_output_lines == GS_OUTPUT_LINES ||227(state->gs_output_lines == GS_OUTPUT_NONE && u_reduced_prim(state->info.mode) == PIPE_PRIM_LINES)))228state->rs_state.multisample = false;229assert(offsetof(struct pipe_rasterizer_state, offset_clamp) - offsetof(struct pipe_rasterizer_state, offset_units) == sizeof(float) * 2);230if (state->depth_bias.enabled) {231memcpy(&state->rs_state.offset_units, &state->depth_bias, sizeof(float) * 3);232} else {233memset(&state->rs_state.offset_units, 0, sizeof(float) * 3);234}235cso_set_rasterizer(state->cso, &state->rs_state);236state->rs_dirty = false;237state->rs_state.multisample = ms;238}239240if (state->dsa_dirty) {241cso_set_depth_stencil_alpha(state->cso, &state->dsa_state);242state->dsa_dirty = false;243}244245if (state->sample_mask_dirty) {246cso_set_sample_mask(state->cso, state->sample_mask);247state->sample_mask_dirty = false;248}249250if (state->min_samples_dirty) {251cso_set_min_samples(state->cso, state->min_samples);252state->min_samples_dirty = false;253}254255if (state->blend_color_dirty) {256state->pctx->set_blend_color(state->pctx, &state->blend_color);257state->blend_color_dirty = false;258}259260if (state->stencil_ref_dirty) {261cso_set_stencil_ref(state->cso, state->stencil_ref);262state->stencil_ref_dirty = false;263}264265if (state->vb_dirty) {266cso_set_vertex_buffers(state->cso, state->start_vb, state->num_vb, state->vb);267state->vb_dirty = false;268}269270if (state->ve_dirty) {271cso_set_vertex_elements(state->cso, &state->velem);272state->ve_dirty = false;273}274275276for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {277if (state->constbuf_dirty[sh]) {278for (unsigned idx = 0; idx < state->num_const_bufs[sh]; idx++)279state->pctx->set_constant_buffer(state->pctx, sh,280idx + 1, false, &state->const_buffer[sh][idx]);281}282state->constbuf_dirty[sh] = false;283}284285for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {286if (state->pcbuf_dirty[sh]) {287state->pctx->set_constant_buffer(state->pctx, sh,2880, false, &state->pc_buffer[sh]);289}290}291292for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {293if (state->sb_dirty[sh]) {294state->pctx->set_shader_buffers(state->pctx, sh,2950, state->num_shader_buffers[sh],296state->sb[sh], 0);297}298}299300for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {301if (state->iv_dirty[sh]) {302state->pctx->set_shader_images(state->pctx, sh,3030, state->num_shader_images[sh], 0,304state->iv[sh]);305}306}307308for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {309310if (!state->sv_dirty[sh])311continue;312313state->pctx->set_sampler_views(state->pctx, sh, 0, state->num_sampler_views[sh],3140, state->sv[sh]);315state->sv_dirty[sh] = false;316}317318for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {319if (!state->ss_dirty[sh])320continue;321322cso_set_samplers(state->cso, sh, state->num_sampler_states[sh], state->cso_ss_ptr[sh]);323}324325if (state->vp_dirty) {326state->pctx->set_viewport_states(state->pctx, 0, state->num_viewports, state->viewports);327state->vp_dirty = false;328}329330if (state->scissor_dirty) {331state->pctx->set_scissor_states(state->pctx, 0, state->num_scissors, state->scissors);332state->scissor_dirty = false;333}334}335336static void handle_compute_pipeline(struct lvp_cmd_buffer_entry *cmd,337struct rendering_state *state)338{339struct lvp_pipeline *pipeline = cmd->u.pipeline.pipeline;340341state->dispatch_info.block[0] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[0];342state->dispatch_info.block[1] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[1];343state->dispatch_info.block[2] = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.workgroup_size[2];344state->pctx->bind_compute_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_COMPUTE]);345}346347static void348get_viewport_xform(const VkViewport *viewport,349float scale[3], float translate[3])350{351float x = viewport->x;352float y = viewport->y;353float half_width = 0.5f * viewport->width;354float half_height = 0.5f * viewport->height;355double n = viewport->minDepth;356double f = viewport->maxDepth;357358scale[0] = half_width;359translate[0] = half_width + x;360scale[1] = half_height;361translate[1] = half_height + y;362363scale[2] = (f - n);364translate[2] = n;365}366367/* enum re-indexing:368369VK_DYNAMIC_STATE_VIEWPORT370VK_DYNAMIC_STATE_SCISSOR371VK_DYNAMIC_STATE_LINE_WIDTH372VK_DYNAMIC_STATE_DEPTH_BIAS373VK_DYNAMIC_STATE_BLEND_CONSTANTS374VK_DYNAMIC_STATE_DEPTH_BOUNDS375VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK376VK_DYNAMIC_STATE_STENCIL_WRITE_MASK377VK_DYNAMIC_STATE_STENCIL_REFERENCE378379VK_DYNAMIC_STATE_LINE_STIPPLE_EXT380381VK_DYNAMIC_STATE_CULL_MODE_EXT382VK_DYNAMIC_STATE_FRONT_FACE_EXT383VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT384VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT385VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT386VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT387VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT388VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT389VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT390VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT391VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT392VK_DYNAMIC_STATE_STENCIL_OP_EXT393394VK_DYNAMIC_STATE_VERTEX_INPUT_EXT395396VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT397VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT398VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT399VK_DYNAMIC_STATE_LOGIC_OP_EXT400VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT401*/402static int conv_dynamic_state_idx(VkDynamicState dyn_state)403{404if (dyn_state <= VK_DYNAMIC_STATE_STENCIL_REFERENCE)405return dyn_state;406if (dyn_state == VK_DYNAMIC_STATE_LINE_STIPPLE_EXT)407/* this one has a weird id, map after the normal dynamic state ones */408return VK_DYNAMIC_STATE_STENCIL_REFERENCE + 1;409if (dyn_state >= VK_DYNAMIC_STATE_CULL_MODE_EXT &&410dyn_state <= VK_DYNAMIC_STATE_STENCIL_OP_EXT)411return dyn_state - VK_DYNAMIC_STATE_CULL_MODE_EXT + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2;412if (dyn_state == VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)413return (VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT) + VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1;414if (dyn_state >= VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT &&415dyn_state <= VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT)416return dyn_state - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT +417VK_DYNAMIC_STATE_STENCIL_OP_EXT - VK_DYNAMIC_STATE_CULL_MODE_EXT +418VK_DYNAMIC_STATE_STENCIL_REFERENCE + 2 + 1 + 1;419assert(0);420return -1;421}422423static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd,424struct rendering_state *state)425{426struct lvp_pipeline *pipeline = cmd->u.pipeline.pipeline;427bool dynamic_states[VK_DYNAMIC_STATE_STENCIL_REFERENCE+32];428unsigned fb_samples = 0;429430memset(dynamic_states, 0, sizeof(dynamic_states));431if (pipeline->graphics_create_info.pDynamicState)432{433const VkPipelineDynamicStateCreateInfo *dyn = pipeline->graphics_create_info.pDynamicState;434int i;435for (i = 0; i < dyn->dynamicStateCount; i++) {436int idx = conv_dynamic_state_idx(dyn->pDynamicStates[i]);437if (idx == -1)438continue;439dynamic_states[idx] = true;440}441}442443bool has_stage[PIPE_SHADER_TYPES] = { false };444445state->pctx->bind_gs_state(state->pctx, NULL);446if (state->pctx->bind_tcs_state)447state->pctx->bind_tcs_state(state->pctx, NULL);448if (state->pctx->bind_tes_state)449state->pctx->bind_tes_state(state->pctx, NULL);450state->gs_output_lines = GS_OUTPUT_NONE;451{452int i;453for (i = 0; i < pipeline->graphics_create_info.stageCount; i++) {454const VkPipelineShaderStageCreateInfo *sh = &pipeline->graphics_create_info.pStages[i];455switch (sh->stage) {456case VK_SHADER_STAGE_FRAGMENT_BIT:457state->pctx->bind_fs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);458has_stage[PIPE_SHADER_FRAGMENT] = true;459break;460case VK_SHADER_STAGE_VERTEX_BIT:461state->pctx->bind_vs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_VERTEX]);462has_stage[PIPE_SHADER_VERTEX] = true;463break;464case VK_SHADER_STAGE_GEOMETRY_BIT:465state->pctx->bind_gs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_GEOMETRY]);466state->gs_output_lines = pipeline->gs_output_lines ? GS_OUTPUT_LINES : GS_OUTPUT_NOT_LINES;467has_stage[PIPE_SHADER_GEOMETRY] = true;468break;469case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:470state->pctx->bind_tcs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_TESS_CTRL]);471has_stage[PIPE_SHADER_TESS_CTRL] = true;472break;473case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:474state->pctx->bind_tes_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_TESS_EVAL]);475has_stage[PIPE_SHADER_TESS_EVAL] = true;476break;477default:478assert(0);479break;480}481}482}483484/* there should always be a dummy fs. */485if (!has_stage[PIPE_SHADER_FRAGMENT])486state->pctx->bind_fs_state(state->pctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);487if (state->pctx->bind_gs_state && !has_stage[PIPE_SHADER_GEOMETRY])488state->pctx->bind_gs_state(state->pctx, NULL);489if (state->pctx->bind_tcs_state && !has_stage[PIPE_SHADER_TESS_CTRL])490state->pctx->bind_tcs_state(state->pctx, NULL);491if (state->pctx->bind_tes_state && !has_stage[PIPE_SHADER_TESS_EVAL])492state->pctx->bind_tes_state(state->pctx, NULL);493494/* rasterization state */495if (pipeline->graphics_create_info.pRasterizationState) {496const VkPipelineRasterizationStateCreateInfo *rsc = pipeline->graphics_create_info.pRasterizationState;497state->rs_state.depth_clip_near = state->rs_state.depth_clip_far = !rsc->depthClampEnable;498if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT)])499state->rs_state.rasterizer_discard = rsc->rasterizerDiscardEnable;500501state->rs_state.line_smooth = pipeline->line_smooth;502state->rs_state.line_stipple_enable = pipeline->line_stipple_enable;503state->rs_state.fill_front = vk_polygon_mode_to_pipe(rsc->polygonMode);504state->rs_state.fill_back = vk_polygon_mode_to_pipe(rsc->polygonMode);505state->rs_state.point_size_per_vertex = true;506state->rs_state.flatshade_first = !pipeline->provoking_vertex_last;507state->rs_state.point_quad_rasterization = true;508state->rs_state.clip_halfz = true;509state->rs_state.half_pixel_center = true;510state->rs_state.scissor = true;511state->rs_state.no_ms_sample_mask_out = true;512state->rs_state.line_rectangular = pipeline->line_rectangular;513514if (!dynamic_states[VK_DYNAMIC_STATE_LINE_WIDTH])515state->rs_state.line_width = rsc->lineWidth;516if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_LINE_STIPPLE_EXT)]) {517state->rs_state.line_stipple_factor = pipeline->line_stipple_factor;518state->rs_state.line_stipple_pattern = pipeline->line_stipple_pattern;519}520521if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT)])522state->depth_bias.enabled = pipeline->graphics_create_info.pRasterizationState->depthBiasEnable;523if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BIAS]) {524state->depth_bias.offset_units = rsc->depthBiasConstantFactor;525state->depth_bias.offset_scale = rsc->depthBiasSlopeFactor;526state->depth_bias.offset_clamp = rsc->depthBiasClamp;527}528529if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_CULL_MODE_EXT)])530state->rs_state.cull_face = vk_cull_to_pipe(rsc->cullMode);531532if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_FRONT_FACE_EXT)])533state->rs_state.front_ccw = (rsc->frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE);534state->rs_dirty = true;535}536537state->disable_multisample = pipeline->disable_multisample;538if (pipeline->graphics_create_info.pMultisampleState) {539const VkPipelineMultisampleStateCreateInfo *ms = pipeline->graphics_create_info.pMultisampleState;540state->rs_state.multisample = ms->rasterizationSamples > 1;541state->sample_mask = ms->pSampleMask ? ms->pSampleMask[0] : 0xffffffff;542state->blend_state.alpha_to_coverage = ms->alphaToCoverageEnable;543state->blend_state.alpha_to_one = ms->alphaToOneEnable;544state->blend_dirty = true;545state->rs_dirty = true;546state->min_samples = 1;547state->sample_mask_dirty = true;548fb_samples = ms->rasterizationSamples;549if (ms->sampleShadingEnable) {550state->min_samples = ceil(ms->rasterizationSamples * ms->minSampleShading);551if (state->min_samples > 1)552state->min_samples = ms->rasterizationSamples;553if (state->min_samples < 1)554state->min_samples = 1;555}556if (pipeline->force_min_sample)557state->min_samples = ms->rasterizationSamples;558state->min_samples_dirty = true;559} else {560state->rs_state.multisample = false;561state->sample_mask_dirty = state->sample_mask != 0xffffffff;562state->sample_mask = 0xffffffff;563state->min_samples_dirty = state->min_samples;564state->min_samples = 0;565state->blend_dirty |= state->blend_state.alpha_to_coverage || state->blend_state.alpha_to_one;566state->blend_state.alpha_to_coverage = false;567state->blend_state.alpha_to_one = false;568state->rs_dirty = true;569}570571if (pipeline->graphics_create_info.pDepthStencilState) {572const VkPipelineDepthStencilStateCreateInfo *dsa = pipeline->graphics_create_info.pDepthStencilState;573574if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT)])575state->dsa_state.depth_enabled = dsa->depthTestEnable;576if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT)])577state->dsa_state.depth_writemask = dsa->depthWriteEnable;578if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT)])579state->dsa_state.depth_func = dsa->depthCompareOp;580if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT)])581state->dsa_state.depth_bounds_test = dsa->depthBoundsTestEnable;582583if (!dynamic_states[VK_DYNAMIC_STATE_DEPTH_BOUNDS]) {584state->dsa_state.depth_bounds_min = dsa->minDepthBounds;585state->dsa_state.depth_bounds_max = dsa->maxDepthBounds;586}587588if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT)]) {589state->dsa_state.stencil[0].enabled = dsa->stencilTestEnable;590state->dsa_state.stencil[1].enabled = dsa->stencilTestEnable;591}592593if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_STENCIL_OP_EXT)]) {594state->dsa_state.stencil[0].func = dsa->front.compareOp;595state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(dsa->front.failOp);596state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(dsa->front.passOp);597state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(dsa->front.depthFailOp);598599state->dsa_state.stencil[1].func = dsa->back.compareOp;600state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(dsa->back.failOp);601state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(dsa->back.passOp);602state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(dsa->back.depthFailOp);603}604605if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK]) {606state->dsa_state.stencil[0].valuemask = dsa->front.compareMask;607state->dsa_state.stencil[1].valuemask = dsa->back.compareMask;608}609610if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_WRITE_MASK]) {611state->dsa_state.stencil[0].writemask = dsa->front.writeMask;612state->dsa_state.stencil[1].writemask = dsa->back.writeMask;613}614615if (dsa->stencilTestEnable) {616if (!dynamic_states[VK_DYNAMIC_STATE_STENCIL_REFERENCE]) {617state->stencil_ref.ref_value[0] = dsa->front.reference;618state->stencil_ref.ref_value[1] = dsa->back.reference;619state->stencil_ref_dirty = true;620}621}622} else623memset(&state->dsa_state, 0, sizeof(state->dsa_state));624state->dsa_dirty = true;625626if (pipeline->graphics_create_info.pColorBlendState) {627const VkPipelineColorBlendStateCreateInfo *cb = pipeline->graphics_create_info.pColorBlendState;628int i;629630if (cb->logicOpEnable) {631state->blend_state.logicop_enable = VK_TRUE;632if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_LOGIC_OP_EXT)])633state->blend_state.logicop_func = vk_conv_logic_op(cb->logicOp);634}635636if (cb->attachmentCount > 1)637state->blend_state.independent_blend_enable = true;638for (i = 0; i < cb->attachmentCount; i++) {639state->blend_state.rt[i].colormask = cb->pAttachments[i].colorWriteMask;640state->blend_state.rt[i].blend_enable = cb->pAttachments[i].blendEnable;641state->blend_state.rt[i].rgb_func = vk_conv_blend_func(cb->pAttachments[i].colorBlendOp);642state->blend_state.rt[i].rgb_src_factor = vk_conv_blend_factor(cb->pAttachments[i].srcColorBlendFactor);643state->blend_state.rt[i].rgb_dst_factor = vk_conv_blend_factor(cb->pAttachments[i].dstColorBlendFactor);644state->blend_state.rt[i].alpha_func = vk_conv_blend_func(cb->pAttachments[i].alphaBlendOp);645state->blend_state.rt[i].alpha_src_factor = vk_conv_blend_factor(cb->pAttachments[i].srcAlphaBlendFactor);646state->blend_state.rt[i].alpha_dst_factor = vk_conv_blend_factor(cb->pAttachments[i].dstAlphaBlendFactor);647648/* At least llvmpipe applies the blend factor prior to the blend function,649* regardless of what function is used. (like i965 hardware).650* It means for MIN/MAX the blend factor has to be stomped to ONE.651*/652if (cb->pAttachments[i].colorBlendOp == VK_BLEND_OP_MIN ||653cb->pAttachments[i].colorBlendOp == VK_BLEND_OP_MAX) {654state->blend_state.rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE;655state->blend_state.rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;656}657658if (cb->pAttachments[i].alphaBlendOp == VK_BLEND_OP_MIN ||659cb->pAttachments[i].alphaBlendOp == VK_BLEND_OP_MAX) {660state->blend_state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE;661state->blend_state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;662}663}664state->blend_dirty = true;665if (!dynamic_states[VK_DYNAMIC_STATE_BLEND_CONSTANTS]) {666memcpy(state->blend_color.color, cb->blendConstants, 4 * sizeof(float));667state->blend_color_dirty = true;668}669} else {670memset(&state->blend_state, 0, sizeof(state->blend_state));671state->blend_dirty = true;672}673674if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)]) {675const VkPipelineVertexInputStateCreateInfo *vi = pipeline->graphics_create_info.pVertexInputState;676int i;677const VkPipelineVertexInputDivisorStateCreateInfoEXT *div_state =678vk_find_struct_const(vi->pNext,679PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT);680681if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT)]) {682for (i = 0; i < vi->vertexBindingDescriptionCount; i++) {683state->vb[i].stride = vi->pVertexBindingDescriptions[i].stride;684}685}686687int max_location = -1;688for (i = 0; i < vi->vertexAttributeDescriptionCount; i++) {689unsigned location = vi->pVertexAttributeDescriptions[i].location;690state->velem.velems[location].src_offset = vi->pVertexAttributeDescriptions[i].offset;691state->velem.velems[location].vertex_buffer_index = vi->pVertexAttributeDescriptions[i].binding;692state->velem.velems[location].src_format = lvp_vk_format_to_pipe_format(vi->pVertexAttributeDescriptions[i].format);693694switch (vi->pVertexBindingDescriptions[vi->pVertexAttributeDescriptions[i].binding].inputRate) {695case VK_VERTEX_INPUT_RATE_VERTEX:696state->velem.velems[location].instance_divisor = 0;697break;698case VK_VERTEX_INPUT_RATE_INSTANCE:699if (div_state) {700for (unsigned j = 0; j < div_state->vertexBindingDivisorCount; j++) {701const VkVertexInputBindingDivisorDescriptionEXT *desc =702&div_state->pVertexBindingDivisors[j];703if (desc->binding == state->velem.velems[location].vertex_buffer_index) {704state->velem.velems[location].instance_divisor = desc->divisor;705break;706}707}708} else709state->velem.velems[location].instance_divisor = 1;710break;711default:712assert(0);713break;714}715716if ((int)location > max_location)717max_location = location;718}719state->velem.count = max_location + 1;720state->vb_dirty = true;721state->ve_dirty = true;722}723724{725const VkPipelineInputAssemblyStateCreateInfo *ia = pipeline->graphics_create_info.pInputAssemblyState;726727if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT)]) {728state->info.mode = vk_conv_topology(ia->topology);729state->rs_dirty = true;730}731if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT)])732state->info.primitive_restart = ia->primitiveRestartEnable;733}734735if (pipeline->graphics_create_info.pTessellationState) {736if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT)]) {737const VkPipelineTessellationStateCreateInfo *ts = pipeline->graphics_create_info.pTessellationState;738state->info.vertices_per_patch = ts->patchControlPoints;739}740} else741state->info.vertices_per_patch = 0;742743if (pipeline->graphics_create_info.pViewportState) {744const VkPipelineViewportStateCreateInfo *vpi= pipeline->graphics_create_info.pViewportState;745int i;746747if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)]) {748state->num_viewports = vpi->viewportCount;749state->vp_dirty = true;750}751if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)]) {752state->num_scissors = vpi->scissorCount;753state->scissor_dirty = true;754}755756if (!dynamic_states[VK_DYNAMIC_STATE_VIEWPORT] &&757!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)]) {758for (i = 0; i < vpi->viewportCount; i++)759get_viewport_xform(&vpi->pViewports[i], state->viewports[i].scale, state->viewports[i].translate);760state->vp_dirty = true;761}762if (!dynamic_states[VK_DYNAMIC_STATE_SCISSOR] &&763!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)]) {764for (i = 0; i < vpi->scissorCount; i++) {765const VkRect2D *ss = &vpi->pScissors[i];766state->scissors[i].minx = ss->offset.x;767state->scissors[i].miny = ss->offset.y;768state->scissors[i].maxx = ss->offset.x + ss->extent.width;769state->scissors[i].maxy = ss->offset.y + ss->extent.height;770state->scissor_dirty = true;771}772773}774}775776if (fb_samples != state->framebuffer.samples) {777state->framebuffer.samples = fb_samples;778state->pctx->set_framebuffer_state(state->pctx, &state->framebuffer);779}780}781782static void handle_pipeline(struct lvp_cmd_buffer_entry *cmd,783struct rendering_state *state)784{785struct lvp_pipeline *pipeline = cmd->u.pipeline.pipeline;786if (pipeline->is_compute_pipeline)787handle_compute_pipeline(cmd, state);788else789handle_graphics_pipeline(cmd, state);790}791792static void handle_vertex_buffers(struct lvp_cmd_buffer_entry *cmd,793struct rendering_state *state)794{795int i;796struct lvp_cmd_bind_vertex_buffers *vcb = &cmd->u.vertex_buffers;797for (i = 0; i < vcb->binding_count; i++) {798int idx = i + vcb->first;799800state->vb[idx].buffer_offset = vcb->offsets[i];801state->vb[idx].buffer.resource = vcb->buffers[i] ? vcb->buffers[i]->bo : NULL;802803if (vcb->strides) {804state->vb[idx].stride = vcb->strides[i];805}806}807if (vcb->first < state->start_vb)808state->start_vb = vcb->first;809if (vcb->first + vcb->binding_count >= state->num_vb)810state->num_vb = vcb->first + vcb->binding_count;811state->vb_dirty = true;812}813814struct dyn_info {815struct {816uint16_t const_buffer_count;817uint16_t shader_buffer_count;818uint16_t sampler_count;819uint16_t sampler_view_count;820uint16_t image_count;821} stage[MESA_SHADER_STAGES];822823uint32_t dyn_index;824const uint32_t *dynamic_offsets;825uint32_t dynamic_offset_count;826};827828static void fill_sampler(struct pipe_sampler_state *ss,829struct lvp_sampler *samp)830{831ss->wrap_s = vk_conv_wrap_mode(samp->create_info.addressModeU);832ss->wrap_t = vk_conv_wrap_mode(samp->create_info.addressModeV);833ss->wrap_r = vk_conv_wrap_mode(samp->create_info.addressModeW);834ss->min_img_filter = samp->create_info.minFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;835ss->min_mip_filter = samp->create_info.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR ? PIPE_TEX_MIPFILTER_LINEAR : PIPE_TEX_MIPFILTER_NEAREST;836ss->mag_img_filter = samp->create_info.magFilter == VK_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : PIPE_TEX_FILTER_NEAREST;837ss->min_lod = samp->create_info.minLod;838ss->max_lod = samp->create_info.maxLod;839ss->lod_bias = samp->create_info.mipLodBias;840ss->max_anisotropy = samp->create_info.maxAnisotropy;841ss->normalized_coords = !samp->create_info.unnormalizedCoordinates;842ss->compare_mode = samp->create_info.compareEnable ? PIPE_TEX_COMPARE_R_TO_TEXTURE : PIPE_TEX_COMPARE_NONE;843ss->compare_func = samp->create_info.compareOp;844ss->seamless_cube_map = true;845ss->reduction_mode = samp->reduction_mode;846memcpy(&ss->border_color, &samp->border_color,847sizeof(union pipe_color_union));848}849850static void fill_sampler_stage(struct rendering_state *state,851struct dyn_info *dyn_info,852gl_shader_stage stage,853enum pipe_shader_type p_stage,854int array_idx,855const union lvp_descriptor_info *descriptor,856const struct lvp_descriptor_set_binding_layout *binding)857{858int ss_idx = binding->stage[stage].sampler_index;859if (ss_idx == -1)860return;861ss_idx += array_idx;862ss_idx += dyn_info->stage[stage].sampler_count;863fill_sampler(&state->ss[p_stage][ss_idx], binding->immutable_samplers ? binding->immutable_samplers[array_idx] : descriptor->sampler);864if (state->num_sampler_states[p_stage] <= ss_idx)865state->num_sampler_states[p_stage] = ss_idx + 1;866state->ss_dirty[p_stage] = true;867}868869#define fix_depth_swizzle(x) do { \870if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \871x = PIPE_SWIZZLE_0; \872} while (0)873#define fix_depth_swizzle_a(x) do { \874if (x > PIPE_SWIZZLE_X && x < PIPE_SWIZZLE_0) \875x = PIPE_SWIZZLE_1; \876} while (0)877878static void fill_sampler_view_stage(struct rendering_state *state,879struct dyn_info *dyn_info,880gl_shader_stage stage,881enum pipe_shader_type p_stage,882int array_idx,883const union lvp_descriptor_info *descriptor,884const struct lvp_descriptor_set_binding_layout *binding)885{886int sv_idx = binding->stage[stage].sampler_view_index;887if (sv_idx == -1)888return;889sv_idx += array_idx;890sv_idx += dyn_info->stage[stage].sampler_view_count;891struct lvp_image_view *iv = descriptor->iview;892struct pipe_sampler_view templ;893894enum pipe_format pformat;895if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)896pformat = lvp_vk_format_to_pipe_format(iv->format);897else if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)898pformat = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->format));899else900pformat = lvp_vk_format_to_pipe_format(iv->format);901u_sampler_view_default_template(&templ,902iv->image->bo,903pformat);904if (iv->view_type == VK_IMAGE_VIEW_TYPE_1D)905templ.target = PIPE_TEXTURE_1D;906if (iv->view_type == VK_IMAGE_VIEW_TYPE_2D)907templ.target = PIPE_TEXTURE_2D;908if (iv->view_type == VK_IMAGE_VIEW_TYPE_CUBE)909templ.target = PIPE_TEXTURE_CUBE;910if (iv->view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)911templ.target = PIPE_TEXTURE_CUBE_ARRAY;912templ.u.tex.first_layer = iv->subresourceRange.baseArrayLayer;913templ.u.tex.last_layer = iv->subresourceRange.baseArrayLayer + lvp_get_layerCount(iv->image, &iv->subresourceRange) - 1;914templ.u.tex.first_level = iv->subresourceRange.baseMipLevel;915templ.u.tex.last_level = iv->subresourceRange.baseMipLevel + lvp_get_levelCount(iv->image, &iv->subresourceRange) - 1;916if (iv->components.r != VK_COMPONENT_SWIZZLE_IDENTITY)917templ.swizzle_r = vk_conv_swizzle(iv->components.r);918if (iv->components.g != VK_COMPONENT_SWIZZLE_IDENTITY)919templ.swizzle_g = vk_conv_swizzle(iv->components.g);920if (iv->components.b != VK_COMPONENT_SWIZZLE_IDENTITY)921templ.swizzle_b = vk_conv_swizzle(iv->components.b);922if (iv->components.a != VK_COMPONENT_SWIZZLE_IDENTITY)923templ.swizzle_a = vk_conv_swizzle(iv->components.a);924925/* depth stencil swizzles need special handling to pass VK CTS926* but also for zink GL tests.927* piping A swizzle into R fixes GL_ALPHA depth texture mode928* only swizzling from R/0/1 (for alpha) fixes VK CTS tests929* and a bunch of zink tests.930*/931if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT ||932iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {933if (templ.swizzle_a == PIPE_SWIZZLE_X)934templ.swizzle_r = PIPE_SWIZZLE_X;935fix_depth_swizzle(templ.swizzle_r);936fix_depth_swizzle(templ.swizzle_g);937fix_depth_swizzle(templ.swizzle_b);938fix_depth_swizzle_a(templ.swizzle_a);939}940941if (state->sv[p_stage][sv_idx])942pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL);943state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, iv->image->bo, &templ);944if (state->num_sampler_views[p_stage] <= sv_idx)945state->num_sampler_views[p_stage] = sv_idx + 1;946state->sv_dirty[p_stage] = true;947}948949static void fill_sampler_buffer_view_stage(struct rendering_state *state,950struct dyn_info *dyn_info,951gl_shader_stage stage,952enum pipe_shader_type p_stage,953int array_idx,954const union lvp_descriptor_info *descriptor,955const struct lvp_descriptor_set_binding_layout *binding)956{957int sv_idx = binding->stage[stage].sampler_view_index;958if (sv_idx == -1)959return;960sv_idx += array_idx;961sv_idx += dyn_info->stage[stage].sampler_view_count;962struct lvp_buffer_view *bv = descriptor->buffer_view;963struct pipe_sampler_view templ;964memset(&templ, 0, sizeof(templ));965templ.target = PIPE_BUFFER;966templ.swizzle_r = PIPE_SWIZZLE_X;967templ.swizzle_g = PIPE_SWIZZLE_Y;968templ.swizzle_b = PIPE_SWIZZLE_Z;969templ.swizzle_a = PIPE_SWIZZLE_W;970templ.format = bv->pformat;971templ.u.buf.offset = bv->offset + bv->buffer->offset;972templ.u.buf.size = bv->range == VK_WHOLE_SIZE ? (bv->buffer->size - bv->offset) : bv->range;973templ.texture = bv->buffer->bo;974templ.context = state->pctx;975976if (state->sv[p_stage][sv_idx])977pipe_sampler_view_reference(&state->sv[p_stage][sv_idx], NULL);978state->sv[p_stage][sv_idx] = state->pctx->create_sampler_view(state->pctx, bv->buffer->bo, &templ);979if (state->num_sampler_views[p_stage] <= sv_idx)980state->num_sampler_views[p_stage] = sv_idx + 1;981state->sv_dirty[p_stage] = true;982}983984static void fill_image_view_stage(struct rendering_state *state,985struct dyn_info *dyn_info,986gl_shader_stage stage,987enum pipe_shader_type p_stage,988int array_idx,989const union lvp_descriptor_info *descriptor,990const struct lvp_descriptor_set_binding_layout *binding)991{992struct lvp_image_view *iv = descriptor->iview;993int idx = binding->stage[stage].image_index;994if (idx == -1)995return;996idx += array_idx;997idx += dyn_info->stage[stage].image_count;998state->iv[p_stage][idx].resource = iv->image->bo;999if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)1000state->iv[p_stage][idx].format = lvp_vk_format_to_pipe_format(iv->format);1001else if (iv->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)1002state->iv[p_stage][idx].format = util_format_stencil_only(lvp_vk_format_to_pipe_format(iv->format));1003else1004state->iv[p_stage][idx].format = lvp_vk_format_to_pipe_format(iv->format);10051006if (iv->view_type == VK_IMAGE_VIEW_TYPE_3D) {1007state->iv[p_stage][idx].u.tex.first_layer = 0;1008state->iv[p_stage][idx].u.tex.last_layer = u_minify(iv->image->bo->depth0, iv->subresourceRange.baseMipLevel) - 1;1009} else {1010state->iv[p_stage][idx].u.tex.first_layer = iv->subresourceRange.baseArrayLayer;1011state->iv[p_stage][idx].u.tex.last_layer = iv->subresourceRange.baseArrayLayer + lvp_get_layerCount(iv->image, &iv->subresourceRange) - 1;1012}1013state->iv[p_stage][idx].u.tex.level = iv->subresourceRange.baseMipLevel;1014if (state->num_shader_images[p_stage] <= idx)1015state->num_shader_images[p_stage] = idx + 1;1016state->iv_dirty[p_stage] = true;1017}10181019static void fill_image_buffer_view_stage(struct rendering_state *state,1020struct dyn_info *dyn_info,1021gl_shader_stage stage,1022enum pipe_shader_type p_stage,1023int array_idx,1024const union lvp_descriptor_info *descriptor,1025const struct lvp_descriptor_set_binding_layout *binding)1026{1027struct lvp_buffer_view *bv = descriptor->buffer_view;1028int idx = binding->stage[stage].image_index;1029if (idx == -1)1030return;1031idx += array_idx;1032idx += dyn_info->stage[stage].image_count;1033state->iv[p_stage][idx].resource = bv->buffer->bo;1034state->iv[p_stage][idx].format = bv->pformat;1035state->iv[p_stage][idx].u.buf.offset = bv->offset + bv->buffer->offset;1036state->iv[p_stage][idx].u.buf.size = bv->range == VK_WHOLE_SIZE ? (bv->buffer->size - bv->offset): bv->range;1037if (state->num_shader_images[p_stage] <= idx)1038state->num_shader_images[p_stage] = idx + 1;1039state->iv_dirty[p_stage] = true;1040}10411042static void handle_descriptor(struct rendering_state *state,1043struct dyn_info *dyn_info,1044const struct lvp_descriptor_set_binding_layout *binding,1045gl_shader_stage stage,1046enum pipe_shader_type p_stage,1047int array_idx,1048VkDescriptorType type,1049const union lvp_descriptor_info *descriptor)1050{1051bool is_dynamic = type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||1052type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;10531054switch (type) {1055case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:1056case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {1057fill_image_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);1058break;1059}1060case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:1061case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {1062int idx = binding->stage[stage].const_buffer_index;1063if (idx == -1)1064return;1065idx += array_idx;1066idx += dyn_info->stage[stage].const_buffer_count;1067state->const_buffer[p_stage][idx].buffer = descriptor->buffer->bo;1068state->const_buffer[p_stage][idx].buffer_offset = descriptor->offset + descriptor->buffer->offset;1069if (is_dynamic) {1070uint32_t offset = dyn_info->dynamic_offsets[dyn_info->dyn_index + binding->dynamic_index + array_idx];1071state->const_buffer[p_stage][idx].buffer_offset += offset;1072}1073if (descriptor->range == VK_WHOLE_SIZE)1074state->const_buffer[p_stage][idx].buffer_size = descriptor->buffer->bo->width0 - state->const_buffer[p_stage][idx].buffer_offset;1075else1076state->const_buffer[p_stage][idx].buffer_size = descriptor->range;1077if (state->num_const_bufs[p_stage] <= idx)1078state->num_const_bufs[p_stage] = idx + 1;1079state->constbuf_dirty[p_stage] = true;1080break;1081}1082case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:1083case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {1084int idx = binding->stage[stage].shader_buffer_index;1085if (idx == -1)1086return;1087idx += array_idx;1088idx += dyn_info->stage[stage].shader_buffer_count;1089state->sb[p_stage][idx].buffer = descriptor->buffer->bo;1090state->sb[p_stage][idx].buffer_offset = descriptor->offset + descriptor->buffer->offset;1091if (is_dynamic) {1092uint32_t offset = dyn_info->dynamic_offsets[dyn_info->dyn_index + binding->dynamic_index + array_idx];1093state->sb[p_stage][idx].buffer_offset += offset;1094}1095if (descriptor->range == VK_WHOLE_SIZE)1096state->sb[p_stage][idx].buffer_size = descriptor->buffer->bo->width0 - state->sb[p_stage][idx].buffer_offset;1097else1098state->sb[p_stage][idx].buffer_size = descriptor->range;1099if (state->num_shader_buffers[p_stage] <= idx)1100state->num_shader_buffers[p_stage] = idx + 1;1101state->sb_dirty[p_stage] = true;1102break;1103}1104case VK_DESCRIPTOR_TYPE_SAMPLER:1105if (!descriptor->sampler)1106return;1107fill_sampler_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);1108break;1109case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:1110fill_sampler_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);1111break;1112case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:1113fill_sampler_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);1114fill_sampler_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);1115break;1116case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:1117fill_sampler_buffer_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);1118break;1119case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:1120fill_image_buffer_view_stage(state, dyn_info, stage, p_stage, array_idx, descriptor, binding);1121break;1122default:1123fprintf(stderr, "Unhandled descriptor set %d\n", type);1124break;1125}1126}11271128static void handle_set_stage(struct rendering_state *state,1129struct dyn_info *dyn_info,1130const struct lvp_descriptor_set *set,1131gl_shader_stage stage,1132enum pipe_shader_type p_stage)1133{1134int j;1135for (j = 0; j < set->layout->binding_count; j++) {1136const struct lvp_descriptor_set_binding_layout *binding;1137const struct lvp_descriptor *descriptor;1138binding = &set->layout->binding[j];11391140if (binding->valid) {1141for (int i = 0; i < binding->array_size; i++) {1142descriptor = &set->descriptors[binding->descriptor_index + i];1143handle_descriptor(state, dyn_info, binding, stage, p_stage, i, descriptor->type, &descriptor->info);1144}1145}1146}1147}11481149static void increment_dyn_info(struct dyn_info *dyn_info,1150struct lvp_descriptor_set_layout *layout, bool inc_dyn)1151{1152for (gl_shader_stage stage = MESA_SHADER_VERTEX; stage < MESA_SHADER_STAGES; stage++) {1153dyn_info->stage[stage].const_buffer_count += layout->stage[stage].const_buffer_count;1154dyn_info->stage[stage].shader_buffer_count += layout->stage[stage].shader_buffer_count;1155dyn_info->stage[stage].sampler_count += layout->stage[stage].sampler_count;1156dyn_info->stage[stage].sampler_view_count += layout->stage[stage].sampler_view_count;1157dyn_info->stage[stage].image_count += layout->stage[stage].image_count;1158}1159if (inc_dyn)1160dyn_info->dyn_index += layout->dynamic_offset_count;1161}11621163static void handle_compute_descriptor_sets(struct lvp_cmd_buffer_entry *cmd,1164struct dyn_info *dyn_info,1165struct rendering_state *state)1166{1167struct lvp_cmd_bind_descriptor_sets *bds = &cmd->u.descriptor_sets;1168int i;11691170for (i = 0; i < bds->first; i++) {1171increment_dyn_info(dyn_info, bds->set_layout[i], false);1172}1173for (i = 0; i < bds->count; i++) {1174const struct lvp_descriptor_set *set = bds->sets[i];11751176if (set->layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT)1177handle_set_stage(state, dyn_info, set, MESA_SHADER_COMPUTE, PIPE_SHADER_COMPUTE);1178increment_dyn_info(dyn_info, bds->set_layout[bds->first + i], true);1179}1180}11811182static void handle_descriptor_sets(struct lvp_cmd_buffer_entry *cmd,1183struct rendering_state *state)1184{1185struct lvp_cmd_bind_descriptor_sets *bds = &cmd->u.descriptor_sets;1186int i;1187struct dyn_info dyn_info;11881189dyn_info.dyn_index = 0;1190dyn_info.dynamic_offsets = bds->dynamic_offsets;1191dyn_info.dynamic_offset_count = bds->dynamic_offset_count;11921193memset(dyn_info.stage, 0, sizeof(dyn_info.stage));1194if (bds->bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {1195handle_compute_descriptor_sets(cmd, &dyn_info, state);1196return;1197}11981199for (i = 0; i < bds->first; i++) {1200increment_dyn_info(&dyn_info, bds->set_layout[i], false);1201}12021203for (i = 0; i < bds->count; i++) {1204const struct lvp_descriptor_set *set = bds->sets[i];12051206if (set->layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)1207handle_set_stage(state, &dyn_info, set, MESA_SHADER_VERTEX, PIPE_SHADER_VERTEX);12081209if (set->layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT)1210handle_set_stage(state, &dyn_info, set, MESA_SHADER_GEOMETRY, PIPE_SHADER_GEOMETRY);12111212if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)1213handle_set_stage(state, &dyn_info, set, MESA_SHADER_TESS_CTRL, PIPE_SHADER_TESS_CTRL);12141215if (set->layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)1216handle_set_stage(state, &dyn_info, set, MESA_SHADER_TESS_EVAL, PIPE_SHADER_TESS_EVAL);12171218if (set->layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT)1219handle_set_stage(state, &dyn_info, set, MESA_SHADER_FRAGMENT, PIPE_SHADER_FRAGMENT);1220increment_dyn_info(&dyn_info, bds->set_layout[bds->first + i], true);1221}1222}12231224static struct pipe_surface *create_img_surface_bo(struct rendering_state *state,1225VkImageSubresourceRange *range,1226struct pipe_resource *bo,1227enum pipe_format pformat,1228int width,1229int height,1230int base_layer, int layer_count,1231int level)1232{1233struct pipe_surface template;12341235memset(&template, 0, sizeof(struct pipe_surface));12361237template.format = pformat;1238template.width = width;1239template.height = height;1240template.u.tex.first_layer = range->baseArrayLayer + base_layer;1241template.u.tex.last_layer = range->baseArrayLayer + layer_count;1242template.u.tex.level = range->baseMipLevel + level;12431244if (template.format == PIPE_FORMAT_NONE)1245return NULL;1246return state->pctx->create_surface(state->pctx,1247bo, &template);12481249}1250static struct pipe_surface *create_img_surface(struct rendering_state *state,1251struct lvp_image_view *imgv,1252VkFormat format, int width,1253int height,1254int base_layer, int layer_count)1255{1256return create_img_surface_bo(state, &imgv->subresourceRange, imgv->image->bo,1257lvp_vk_format_to_pipe_format(format), width, height, base_layer, layer_count, 0);1258}12591260static void add_img_view_surface(struct rendering_state *state,1261struct lvp_image_view *imgv, VkFormat format, int width, int height)1262{1263if (!imgv->surface) {1264imgv->surface = create_img_surface(state, imgv, format,1265width, height,12660, lvp_get_layerCount(imgv->image, &imgv->subresourceRange) - 1);1267}1268}12691270static inline bool1271attachment_needs_clear(struct rendering_state *state,1272uint32_t a)1273{1274const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];1275uint32_t view_mask = subpass->view_mask;1276return (a != VK_ATTACHMENT_UNUSED &&1277state->pending_clear_aspects[a] &&1278(!view_mask || (view_mask & ~state->cleared_views[a])));1279}12801281static bool1282subpass_needs_clear(struct rendering_state *state)1283{1284uint32_t a;1285const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];1286for (uint32_t i = 0; i < subpass->color_count; i++) {1287a = subpass->color_attachments[i].attachment;1288if (attachment_needs_clear(state, a))1289return true;1290}1291if (subpass->depth_stencil_attachment) {1292a = subpass->depth_stencil_attachment->attachment;1293if (attachment_needs_clear(state, a))1294return true;1295}1296return false;1297}12981299static void clear_attachment_layers(struct rendering_state *state,1300struct lvp_image_view *imgv,1301VkRect2D *rect,1302unsigned base_layer, unsigned layer_count,1303unsigned ds_clear_flags, double dclear_val,1304uint32_t sclear_val,1305union pipe_color_union *col_val)1306{1307struct pipe_surface *clear_surf = create_img_surface(state,1308imgv,1309imgv->format,1310state->framebuffer.width,1311state->framebuffer.height,1312base_layer,1313base_layer + layer_count - 1);13141315if (ds_clear_flags) {1316state->pctx->clear_depth_stencil(state->pctx,1317clear_surf,1318ds_clear_flags,1319dclear_val, sclear_val,1320rect->offset.x, rect->offset.y,1321rect->extent.width, rect->extent.height,1322true);1323} else {1324state->pctx->clear_render_target(state->pctx, clear_surf,1325col_val,1326rect->offset.x, rect->offset.y,1327rect->extent.width, rect->extent.height,1328true);1329}1330state->pctx->surface_destroy(state->pctx, clear_surf);1331}13321333static struct lvp_image_view *1334get_attachment(struct rendering_state *state,1335unsigned idx)1336{1337if (state->imageless_views)1338return state->imageless_views[idx];1339else1340return state->vk_framebuffer->attachments[idx];1341}13421343static void render_subpass_clear(struct rendering_state *state)1344{1345const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];13461347for (unsigned i = 0; i < subpass->color_count; i++) {1348uint32_t a = subpass->color_attachments[i].attachment;13491350if (!attachment_needs_clear(state, a))1351continue;13521353union pipe_color_union color_clear_val = { 0 };1354const VkClearValue value = state->attachments[a].clear_value;1355color_clear_val.ui[0] = value.color.uint32[0];1356color_clear_val.ui[1] = value.color.uint32[1];1357color_clear_val.ui[2] = value.color.uint32[2];1358color_clear_val.ui[3] = value.color.uint32[3];13591360struct lvp_image_view *imgv = get_attachment(state, a);13611362assert(imgv->surface);13631364if (subpass->view_mask) {1365u_foreach_bit(i, subpass->view_mask)1366clear_attachment_layers(state, imgv, &state->render_area,1367i, 1, 0, 0, 0, &color_clear_val);1368state->cleared_views[a] |= subpass->view_mask;1369} else {1370state->pctx->clear_render_target(state->pctx,1371imgv->surface,1372&color_clear_val,1373state->render_area.offset.x, state->render_area.offset.y,1374state->render_area.extent.width, state->render_area.extent.height,1375false);1376state->pending_clear_aspects[a] = 0;1377}1378}13791380if (subpass->depth_stencil_attachment) {1381uint32_t ds = subpass->depth_stencil_attachment->attachment;13821383if (!attachment_needs_clear(state, ds))1384return;13851386struct lvp_render_pass_attachment *att = &state->pass->attachments[ds];1387struct lvp_image_view *imgv = get_attachment(state, ds);13881389assert (util_format_is_depth_or_stencil(imgv->surface->format));13901391const struct util_format_description *desc = util_format_description(imgv->surface->format);1392double dclear_val = 0;1393uint32_t sclear_val = 0;1394uint32_t ds_clear_flags = 0;13951396if ((util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||1397(util_format_is_depth_and_stencil(imgv->surface->format) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {1398ds_clear_flags |= PIPE_CLEAR_STENCIL;1399if (att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)1400sclear_val = state->attachments[ds].clear_value.depthStencil.stencil;1401}1402if ((util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||1403(util_format_is_depth_and_stencil(imgv->surface->format) && att->load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {1404ds_clear_flags |= PIPE_CLEAR_DEPTH;1405if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)1406dclear_val = state->attachments[ds].clear_value.depthStencil.depth;1407}14081409assert(imgv->surface);1410if (ds_clear_flags) {1411if (subpass->view_mask) {1412u_foreach_bit(i, subpass->view_mask)1413clear_attachment_layers(state, imgv, &state->render_area,1414i, 1, ds_clear_flags, dclear_val, sclear_val, NULL);1415state->cleared_views[ds] |= subpass->view_mask;1416} else {1417state->pctx->clear_depth_stencil(state->pctx,1418imgv->surface,1419ds_clear_flags,1420dclear_val, sclear_val,1421state->render_area.offset.x, state->render_area.offset.y,1422state->render_area.extent.width, state->render_area.extent.height,1423false);1424state->pending_clear_aspects[ds] = 0;1425}1426}14271428}14291430}14311432static void render_subpass_clear_fast(struct rendering_state *state)1433{1434/* attempt to use the clear interface first, then fallback to per-attchment clears */1435const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];1436bool has_color_value = false;1437uint32_t buffers = 0;1438VkClearValue color_value = {0};1439double dclear_val = 0;1440uint32_t sclear_val = 0;14411442/*1443* the state tracker clear interface only works if all the attachments have the same1444* clear color.1445*/1446/* llvmpipe doesn't support scissored clears yet */1447if (state->render_area.offset.x || state->render_area.offset.y)1448goto slow_clear;14491450if (state->render_area.extent.width != state->framebuffer.width ||1451state->render_area.extent.height != state->framebuffer.height)1452goto slow_clear;14531454if (subpass->view_mask)1455goto slow_clear;1456for (unsigned i = 0; i < subpass->color_count; i++) {1457uint32_t a = subpass->color_attachments[i].attachment;14581459if (!attachment_needs_clear(state, a))1460continue;14611462if (has_color_value) {1463if (memcmp(&color_value, &state->attachments[a].clear_value, sizeof(VkClearValue)))1464goto slow_clear;1465} else {1466memcpy(&color_value, &state->attachments[a].clear_value, sizeof(VkClearValue));1467has_color_value = true;1468}1469}14701471for (unsigned i = 0; i < subpass->color_count; i++) {1472uint32_t a = subpass->color_attachments[i].attachment;14731474if (!attachment_needs_clear(state, a))1475continue;1476buffers |= (PIPE_CLEAR_COLOR0 << i);1477state->pending_clear_aspects[a] = 0;1478}14791480if (subpass->depth_stencil_attachment &&1481attachment_needs_clear(state, subpass->depth_stencil_attachment->attachment)) {1482uint32_t ds = subpass->depth_stencil_attachment->attachment;14831484struct lvp_render_pass_attachment *att = &state->pass->attachments[ds];1485struct lvp_image_view *imgv = get_attachment(state, ds);1486const struct util_format_description *desc = util_format_description(imgv->surface->format);14871488/* also clear stencil for don't care to avoid RMW */1489if ((util_format_has_stencil(desc) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||1490(util_format_is_depth_and_stencil(imgv->surface->format) && att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE))1491buffers |= PIPE_CLEAR_STENCIL;1492if (util_format_has_depth(desc) && att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)1493buffers |= PIPE_CLEAR_DEPTH;14941495dclear_val = state->attachments[ds].clear_value.depthStencil.depth;1496sclear_val = state->attachments[ds].clear_value.depthStencil.stencil;1497state->pending_clear_aspects[ds] = 0;1498}14991500union pipe_color_union col_val;1501for (unsigned i = 0; i < 4; i++)1502col_val.ui[i] = color_value.color.uint32[i];15031504state->pctx->clear(state->pctx, buffers,1505NULL, &col_val,1506dclear_val, sclear_val);1507return;1508slow_clear:1509render_subpass_clear(state);1510}15111512static void render_pass_resolve(struct rendering_state *state)1513{1514const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];1515if (!subpass->has_color_resolve)1516return;1517for (uint32_t i = 0; i < subpass->color_count; i++) {1518struct lvp_subpass_attachment src_att = subpass->color_attachments[i];1519struct lvp_subpass_attachment dst_att = subpass->resolve_attachments[i];15201521if (dst_att.attachment == VK_ATTACHMENT_UNUSED)1522continue;15231524struct lvp_image_view *src_imgv = get_attachment(state, src_att.attachment);1525struct lvp_image_view *dst_imgv = get_attachment(state, dst_att.attachment);15261527struct pipe_blit_info info;1528memset(&info, 0, sizeof(info));15291530info.src.resource = src_imgv->image->bo;1531info.dst.resource = dst_imgv->image->bo;1532info.src.format = src_imgv->pformat;1533info.dst.format = dst_imgv->pformat;1534info.filter = PIPE_TEX_FILTER_NEAREST;1535info.mask = PIPE_MASK_RGBA;1536info.src.box.x = state->render_area.offset.x;1537info.src.box.y = state->render_area.offset.y;1538info.src.box.width = state->render_area.extent.width;1539info.src.box.height = state->render_area.extent.height;1540info.src.box.depth = state->vk_framebuffer->layers;15411542info.dst.box = info.src.box;15431544info.src.level = src_imgv->subresourceRange.baseMipLevel;1545info.dst.level = dst_imgv->subresourceRange.baseMipLevel;15461547state->pctx->blit(state->pctx, &info);1548}1549}15501551static void begin_render_subpass(struct rendering_state *state,1552int subpass_idx)1553{1554state->subpass = subpass_idx;15551556state->framebuffer.nr_cbufs = 0;15571558const struct lvp_subpass *subpass = &state->pass->subpasses[subpass_idx];1559for (unsigned i = 0; i < subpass->color_count; i++) {1560struct lvp_subpass_attachment *color_att = &subpass->color_attachments[i];1561if (color_att->attachment != VK_ATTACHMENT_UNUSED) {1562struct lvp_image_view *imgv = get_attachment(state, color_att->attachment);1563add_img_view_surface(state, imgv, state->pass->attachments[color_att->attachment].format, state->framebuffer.width, state->framebuffer.height);1564state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = imgv->surface;1565} else1566state->framebuffer.cbufs[state->framebuffer.nr_cbufs] = NULL;1567state->framebuffer.nr_cbufs++;1568}15691570if (subpass->depth_stencil_attachment) {1571struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment;15721573if (ds_att->attachment != VK_ATTACHMENT_UNUSED) {1574struct lvp_image_view *imgv = get_attachment(state, ds_att->attachment);1575add_img_view_surface(state, imgv, state->pass->attachments[ds_att->attachment].format, state->framebuffer.width, state->framebuffer.height);1576state->framebuffer.zsbuf = imgv->surface;1577}1578}15791580state->pctx->set_framebuffer_state(state->pctx,1581&state->framebuffer);15821583if (subpass_needs_clear(state))1584render_subpass_clear_fast(state);1585}15861587static void handle_begin_render_pass(struct lvp_cmd_buffer_entry *cmd,1588struct rendering_state *state)1589{1590state->pass = cmd->u.begin_render_pass.render_pass;1591state->vk_framebuffer = cmd->u.begin_render_pass.framebuffer;1592state->render_area = cmd->u.begin_render_pass.render_area;15931594state->attachments = cmd->u.begin_render_pass.attachments;15951596state->imageless_views = cmd->u.begin_render_pass.imageless_views;1597state->framebuffer.width = state->vk_framebuffer->width;1598state->framebuffer.height = state->vk_framebuffer->height;1599state->framebuffer.layers = state->vk_framebuffer->layers;16001601if (state->num_pending_aspects < state->pass->attachment_count) {1602state->pending_clear_aspects = realloc(state->pending_clear_aspects, sizeof(VkImageAspectFlags) * state->pass->attachment_count);1603state->cleared_views = realloc(state->cleared_views, sizeof(uint32_t) * state->pass->attachment_count);1604state->num_pending_aspects = state->pass->attachment_count;1605}16061607for (unsigned a = 0; a < state->pass->attachment_count; a++) {1608state->pending_clear_aspects[a] = state->attachments[a].pending_clear_aspects;1609state->cleared_views[a] = 0;1610}1611begin_render_subpass(state, 0);1612}16131614static void handle_end_render_pass(struct lvp_cmd_buffer_entry *cmd,1615struct rendering_state *state)1616{1617state->pctx->flush(state->pctx, NULL, 0);16181619render_pass_resolve(state);16201621state->attachments = NULL;1622state->pass = NULL;1623state->subpass = 0;1624}16251626static void handle_next_subpass(struct lvp_cmd_buffer_entry *cmd,1627struct rendering_state *state)1628{1629state->pctx->flush(state->pctx, NULL, 0);1630render_pass_resolve(state);1631state->subpass++;1632begin_render_subpass(state, state->subpass);1633}16341635static void handle_draw(struct lvp_cmd_buffer_entry *cmd,1636struct rendering_state *state)1637{1638const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];1639state->info.index_size = 0;1640state->info.index.resource = NULL;1641state->info.start_instance = cmd->u.draw.first_instance;1642state->info.instance_count = cmd->u.draw.instance_count;1643state->info.view_mask = subpass->view_mask;1644state->info.increment_draw_id = true;16451646state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, cmd->u.draw.draws, cmd->u.draw.draw_count);1647}16481649static void handle_set_viewport(struct lvp_cmd_buffer_entry *cmd,1650struct rendering_state *state)1651{1652int i;1653unsigned base = 0;1654if (cmd->u.set_viewport.first_viewport == UINT32_MAX)1655state->num_viewports = cmd->u.set_viewport.viewport_count;1656else1657base = cmd->u.set_viewport.first_viewport;16581659for (i = 0; i < cmd->u.set_viewport.viewport_count; i++) {1660int idx = i + base;1661const VkViewport *vp = &cmd->u.set_viewport.viewports[i];1662get_viewport_xform(vp, state->viewports[idx].scale, state->viewports[idx].translate);1663}1664state->vp_dirty = true;1665}16661667static void handle_set_scissor(struct lvp_cmd_buffer_entry *cmd,1668struct rendering_state *state)1669{1670int i;1671unsigned base = 0;1672if (cmd->u.set_scissor.first_scissor == UINT32_MAX)1673state->num_scissors = cmd->u.set_scissor.scissor_count;1674else1675base = cmd->u.set_scissor.first_scissor;16761677for (i = 0; i < cmd->u.set_scissor.scissor_count; i++) {1678int idx = i + base;1679const VkRect2D *ss = &cmd->u.set_scissor.scissors[i];1680state->scissors[idx].minx = ss->offset.x;1681state->scissors[idx].miny = ss->offset.y;1682state->scissors[idx].maxx = ss->offset.x + ss->extent.width;1683state->scissors[idx].maxy = ss->offset.y + ss->extent.height;1684}1685state->scissor_dirty = true;1686}16871688static void handle_set_line_width(struct lvp_cmd_buffer_entry *cmd,1689struct rendering_state *state)1690{1691state->rs_state.line_width = cmd->u.set_line_width.line_width;1692state->rs_dirty = true;1693}16941695static void handle_set_depth_bias(struct lvp_cmd_buffer_entry *cmd,1696struct rendering_state *state)1697{1698state->depth_bias.offset_units = cmd->u.set_depth_bias.constant_factor;1699state->depth_bias.offset_scale = cmd->u.set_depth_bias.slope_factor;1700state->depth_bias.offset_clamp = cmd->u.set_depth_bias.clamp;1701state->rs_dirty = true;1702}17031704static void handle_set_blend_constants(struct lvp_cmd_buffer_entry *cmd,1705struct rendering_state *state)1706{1707memcpy(state->blend_color.color, cmd->u.set_blend_constants.blend_constants, 4 * sizeof(float));1708state->blend_color_dirty = true;1709}17101711static void handle_set_depth_bounds(struct lvp_cmd_buffer_entry *cmd,1712struct rendering_state *state)1713{1714state->dsa_dirty |= !DOUBLE_EQ(state->dsa_state.depth_bounds_min, cmd->u.set_depth_bounds.min_depth);1715state->dsa_dirty |= !DOUBLE_EQ(state->dsa_state.depth_bounds_max, cmd->u.set_depth_bounds.max_depth);1716state->dsa_state.depth_bounds_min = cmd->u.set_depth_bounds.min_depth;1717state->dsa_state.depth_bounds_max = cmd->u.set_depth_bounds.max_depth;1718}17191720static void handle_set_stencil_compare_mask(struct lvp_cmd_buffer_entry *cmd,1721struct rendering_state *state)1722{1723if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_FRONT_BIT)1724state->dsa_state.stencil[0].valuemask = cmd->u.stencil_vals.value;1725if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_BACK_BIT)1726state->dsa_state.stencil[1].valuemask = cmd->u.stencil_vals.value;1727state->dsa_dirty = true;1728}17291730static void handle_set_stencil_write_mask(struct lvp_cmd_buffer_entry *cmd,1731struct rendering_state *state)1732{1733if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_FRONT_BIT)1734state->dsa_state.stencil[0].writemask = cmd->u.stencil_vals.value;1735if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_BACK_BIT)1736state->dsa_state.stencil[1].writemask = cmd->u.stencil_vals.value;1737state->dsa_dirty = true;1738}17391740static void handle_set_stencil_reference(struct lvp_cmd_buffer_entry *cmd,1741struct rendering_state *state)1742{1743if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_FRONT_BIT)1744state->stencil_ref.ref_value[0] = cmd->u.stencil_vals.value;1745if (cmd->u.stencil_vals.face_mask & VK_STENCIL_FACE_BACK_BIT)1746state->stencil_ref.ref_value[1] = cmd->u.stencil_vals.value;1747state->stencil_ref_dirty = true;1748}17491750static void1751copy_depth_rect(ubyte * dst,1752enum pipe_format dst_format,1753unsigned dst_stride,1754unsigned dst_x,1755unsigned dst_y,1756unsigned width,1757unsigned height,1758const ubyte * src,1759enum pipe_format src_format,1760int src_stride,1761unsigned src_x,1762unsigned src_y)1763{1764int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;1765int src_blocksize = util_format_get_blocksize(src_format);1766int src_blockwidth = util_format_get_blockwidth(src_format);1767int src_blockheight = util_format_get_blockheight(src_format);1768int dst_blocksize = util_format_get_blocksize(dst_format);1769int dst_blockwidth = util_format_get_blockwidth(dst_format);1770int dst_blockheight = util_format_get_blockheight(dst_format);17711772assert(src_blocksize > 0);1773assert(src_blockwidth > 0);1774assert(src_blockheight > 0);17751776dst_x /= dst_blockwidth;1777dst_y /= dst_blockheight;1778width = (width + src_blockwidth - 1)/src_blockwidth;1779height = (height + src_blockheight - 1)/src_blockheight;1780src_x /= src_blockwidth;1781src_y /= src_blockheight;17821783dst += dst_x * dst_blocksize;1784src += src_x * src_blocksize;1785dst += dst_y * dst_stride;1786src += src_y * src_stride_pos;17871788if (dst_format == PIPE_FORMAT_S8_UINT) {1789if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {1790util_format_z32_float_s8x24_uint_unpack_s_8uint(dst, dst_stride,1791src, src_stride,1792width, height);1793} else if (src_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {1794util_format_z24_unorm_s8_uint_unpack_s_8uint(dst, dst_stride,1795src, src_stride,1796width, height);1797} else {1798}1799} else if (dst_format == PIPE_FORMAT_Z24X8_UNORM) {1800util_format_z24_unorm_s8_uint_unpack_z24(dst, dst_stride,1801src, src_stride,1802width, height);1803} else if (dst_format == PIPE_FORMAT_Z32_FLOAT) {1804if (src_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {1805util_format_z32_float_s8x24_uint_unpack_z_float((float *)dst, dst_stride,1806src, src_stride,1807width, height);1808}1809} else if (dst_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) {1810if (src_format == PIPE_FORMAT_Z32_FLOAT)1811util_format_z32_float_s8x24_uint_pack_z_float(dst, dst_stride,1812(float *)src, src_stride,1813width, height);1814else if (src_format == PIPE_FORMAT_S8_UINT)1815util_format_z32_float_s8x24_uint_pack_s_8uint(dst, dst_stride,1816src, src_stride,1817width, height);1818} else if (dst_format == PIPE_FORMAT_Z24_UNORM_S8_UINT) {1819if (src_format == PIPE_FORMAT_S8_UINT)1820util_format_z24_unorm_s8_uint_pack_s_8uint(dst, dst_stride,1821src, src_stride,1822width, height);1823if (src_format == PIPE_FORMAT_Z24X8_UNORM)1824util_format_z24_unorm_s8_uint_pack_z24(dst, dst_stride,1825src, src_stride,1826width, height);1827}1828}18291830static void1831copy_depth_box(ubyte *dst,1832enum pipe_format dst_format,1833unsigned dst_stride, unsigned dst_slice_stride,1834unsigned dst_x, unsigned dst_y, unsigned dst_z,1835unsigned width, unsigned height, unsigned depth,1836const ubyte * src,1837enum pipe_format src_format,1838int src_stride, unsigned src_slice_stride,1839unsigned src_x, unsigned src_y, unsigned src_z)1840{1841unsigned z;1842dst += dst_z * dst_slice_stride;1843src += src_z * src_slice_stride;1844for (z = 0; z < depth; ++z) {1845copy_depth_rect(dst,1846dst_format,1847dst_stride,1848dst_x, dst_y,1849width, height,1850src,1851src_format,1852src_stride,1853src_x, src_y);18541855dst += dst_slice_stride;1856src += src_slice_stride;1857}1858}18591860static void handle_copy_image_to_buffer(struct lvp_cmd_buffer_entry *cmd,1861struct rendering_state *state)1862{1863int i;1864struct lvp_cmd_copy_image_to_buffer *copycmd = &cmd->u.img_to_buffer;1865struct pipe_box box, dbox;1866struct pipe_transfer *src_t, *dst_t;1867ubyte *src_data, *dst_data;18681869state->pctx->flush(state->pctx, NULL, 0);18701871for (i = 0; i < copycmd->region_count; i++) {18721873box.x = copycmd->regions[i].imageOffset.x;1874box.y = copycmd->regions[i].imageOffset.y;1875box.z = copycmd->src->type == VK_IMAGE_TYPE_3D ? copycmd->regions[i].imageOffset.z : copycmd->regions[i].imageSubresource.baseArrayLayer;1876box.width = copycmd->regions[i].imageExtent.width;1877box.height = copycmd->regions[i].imageExtent.height;1878box.depth = copycmd->src->type == VK_IMAGE_TYPE_3D ? copycmd->regions[i].imageExtent.depth : copycmd->regions[i].imageSubresource.layerCount;18791880src_data = state->pctx->texture_map(state->pctx,1881copycmd->src->bo,1882copycmd->regions[i].imageSubresource.mipLevel,1883PIPE_MAP_READ,1884&box,1885&src_t);18861887dbox.x = copycmd->regions[i].bufferOffset;1888dbox.y = 0;1889dbox.z = 0;1890dbox.width = copycmd->dst->bo->width0;1891dbox.height = 1;1892dbox.depth = 1;1893dst_data = state->pctx->buffer_map(state->pctx,1894copycmd->dst->bo,18950,1896PIPE_MAP_WRITE,1897&dbox,1898&dst_t);18991900enum pipe_format src_format = copycmd->src->bo->format;1901enum pipe_format dst_format = src_format;1902if (util_format_is_depth_or_stencil(src_format)) {1903if (copycmd->regions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {1904dst_format = util_format_get_depth_only(src_format);1905} else if (copycmd->regions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {1906dst_format = PIPE_FORMAT_S8_UINT;1907}1908}19091910unsigned buffer_row_len = util_format_get_stride(dst_format, copycmd->regions[i].bufferRowLength);1911if (buffer_row_len == 0)1912buffer_row_len = util_format_get_stride(dst_format, copycmd->regions[i].imageExtent.width);1913unsigned buffer_image_height = copycmd->regions[i].bufferImageHeight;1914if (buffer_image_height == 0)1915buffer_image_height = copycmd->regions[i].imageExtent.height;19161917unsigned img_stride = util_format_get_2d_size(dst_format, buffer_row_len, buffer_image_height);1918if (src_format != dst_format) {1919copy_depth_box(dst_data, dst_format,1920buffer_row_len, img_stride,19210, 0, 0,1922copycmd->regions[i].imageExtent.width,1923copycmd->regions[i].imageExtent.height,1924box.depth,1925src_data, src_format, src_t->stride, src_t->layer_stride, 0, 0, 0);1926} else {1927util_copy_box((ubyte *)dst_data, src_format,1928buffer_row_len, img_stride,19290, 0, 0,1930copycmd->regions[i].imageExtent.width,1931copycmd->regions[i].imageExtent.height,1932box.depth,1933src_data, src_t->stride, src_t->layer_stride, 0, 0, 0);1934}1935state->pctx->texture_unmap(state->pctx, src_t);1936state->pctx->buffer_unmap(state->pctx, dst_t);1937}1938}19391940static void handle_copy_buffer_to_image(struct lvp_cmd_buffer_entry *cmd,1941struct rendering_state *state)1942{1943int i;1944struct lvp_cmd_copy_buffer_to_image *copycmd = &cmd->u.buffer_to_img;1945struct pipe_box box, sbox;1946struct pipe_transfer *src_t, *dst_t;1947void *src_data, *dst_data;19481949state->pctx->flush(state->pctx, NULL, 0);19501951for (i = 0; i < copycmd->region_count; i++) {19521953sbox.x = copycmd->regions[i].bufferOffset;1954sbox.y = 0;1955sbox.z = 0;1956sbox.width = copycmd->src->bo->width0;1957sbox.height = 1;1958sbox.depth = 1;1959src_data = state->pctx->buffer_map(state->pctx,1960copycmd->src->bo,19610,1962PIPE_MAP_READ,1963&sbox,1964&src_t);196519661967box.x = copycmd->regions[i].imageOffset.x;1968box.y = copycmd->regions[i].imageOffset.y;1969box.z = copycmd->dst->type == VK_IMAGE_TYPE_3D ? copycmd->regions[i].imageOffset.z : copycmd->regions[i].imageSubresource.baseArrayLayer;1970box.width = copycmd->regions[i].imageExtent.width;1971box.height = copycmd->regions[i].imageExtent.height;1972box.depth = copycmd->dst->type == VK_IMAGE_TYPE_3D ? copycmd->regions[i].imageExtent.depth : copycmd->regions[i].imageSubresource.layerCount;19731974dst_data = state->pctx->texture_map(state->pctx,1975copycmd->dst->bo,1976copycmd->regions[i].imageSubresource.mipLevel,1977PIPE_MAP_WRITE,1978&box,1979&dst_t);19801981enum pipe_format dst_format = copycmd->dst->bo->format;1982enum pipe_format src_format = dst_format;1983if (util_format_is_depth_or_stencil(dst_format)) {1984if (copycmd->regions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {1985src_format = util_format_get_depth_only(copycmd->dst->bo->format);1986} else if (copycmd->regions[i].imageSubresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {1987src_format = PIPE_FORMAT_S8_UINT;1988}1989}19901991unsigned buffer_row_len = util_format_get_stride(src_format, copycmd->regions[i].bufferRowLength);1992if (buffer_row_len == 0)1993buffer_row_len = util_format_get_stride(src_format, copycmd->regions[i].imageExtent.width);1994unsigned buffer_image_height = copycmd->regions[i].bufferImageHeight;1995if (buffer_image_height == 0)1996buffer_image_height = copycmd->regions[i].imageExtent.height;19971998unsigned img_stride = util_format_get_2d_size(src_format, buffer_row_len, buffer_image_height);1999if (src_format != dst_format) {2000copy_depth_box(dst_data, dst_format,2001dst_t->stride, dst_t->layer_stride,20020, 0, 0,2003copycmd->regions[i].imageExtent.width,2004copycmd->regions[i].imageExtent.height,2005box.depth,2006src_data, src_format,2007buffer_row_len, img_stride, 0, 0, 0);2008} else {2009util_copy_box(dst_data, dst_format,2010dst_t->stride, dst_t->layer_stride,20110, 0, 0,2012copycmd->regions[i].imageExtent.width,2013copycmd->regions[i].imageExtent.height,2014box.depth,2015src_data,2016buffer_row_len, img_stride, 0, 0, 0);2017}2018state->pctx->buffer_unmap(state->pctx, src_t);2019state->pctx->texture_unmap(state->pctx, dst_t);2020}2021}20222023static void handle_copy_image(struct lvp_cmd_buffer_entry *cmd,2024struct rendering_state *state)2025{2026int i;2027struct lvp_cmd_copy_image *copycmd = &cmd->u.copy_image;20282029state->pctx->flush(state->pctx, NULL, 0);20302031for (i = 0; i < copycmd->region_count; i++) {2032struct pipe_box src_box;2033src_box.x = copycmd->regions[i].srcOffset.x;2034src_box.y = copycmd->regions[i].srcOffset.y;2035src_box.width = copycmd->regions[i].extent.width;2036src_box.height = copycmd->regions[i].extent.height;2037if (copycmd->src->bo->target == PIPE_TEXTURE_3D) {2038src_box.depth = copycmd->regions[i].extent.depth;2039src_box.z = copycmd->regions[i].srcOffset.z;2040} else {2041src_box.depth = copycmd->regions[i].srcSubresource.layerCount;2042src_box.z = copycmd->regions[i].srcSubresource.baseArrayLayer;2043}20442045unsigned dstz = copycmd->dst->bo->target == PIPE_TEXTURE_3D ?2046copycmd->regions[i].dstOffset.z :2047copycmd->regions[i].dstSubresource.baseArrayLayer;2048state->pctx->resource_copy_region(state->pctx, copycmd->dst->bo,2049copycmd->regions[i].dstSubresource.mipLevel,2050copycmd->regions[i].dstOffset.x,2051copycmd->regions[i].dstOffset.y,2052dstz,2053copycmd->src->bo,2054copycmd->regions[i].srcSubresource.mipLevel,2055&src_box);2056}2057}20582059static void handle_copy_buffer(struct lvp_cmd_buffer_entry *cmd,2060struct rendering_state *state)2061{2062int i;2063struct lvp_cmd_copy_buffer *copycmd = &cmd->u.copy_buffer;20642065for (i = 0; i < copycmd->region_count; i++) {2066struct pipe_box box = { 0 };2067u_box_1d(copycmd->regions[i].srcOffset, copycmd->regions[i].size, &box);2068state->pctx->resource_copy_region(state->pctx, copycmd->dst->bo, 0,2069copycmd->regions[i].dstOffset, 0, 0,2070copycmd->src->bo, 0, &box);2071}2072}20732074static void handle_blit_image(struct lvp_cmd_buffer_entry *cmd,2075struct rendering_state *state)2076{2077int i;2078struct lvp_cmd_blit_image *blitcmd = &cmd->u.blit_image;2079struct pipe_blit_info info;20802081memset(&info, 0, sizeof(info));20822083state->pctx->flush(state->pctx, NULL, 0);2084info.src.resource = blitcmd->src->bo;2085info.dst.resource = blitcmd->dst->bo;2086info.src.format = blitcmd->src->bo->format;2087info.dst.format = blitcmd->dst->bo->format;2088info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA;2089info.filter = blitcmd->filter == VK_FILTER_NEAREST ? PIPE_TEX_FILTER_NEAREST : PIPE_TEX_FILTER_LINEAR;2090for (i = 0; i < blitcmd->region_count; i++) {2091int srcX0, srcX1, srcY0, srcY1, srcZ0, srcZ1;2092unsigned dstX0, dstX1, dstY0, dstY1, dstZ0, dstZ1;20932094srcX0 = blitcmd->regions[i].srcOffsets[0].x;2095srcX1 = blitcmd->regions[i].srcOffsets[1].x;2096srcY0 = blitcmd->regions[i].srcOffsets[0].y;2097srcY1 = blitcmd->regions[i].srcOffsets[1].y;2098srcZ0 = blitcmd->regions[i].srcOffsets[0].z;2099srcZ1 = blitcmd->regions[i].srcOffsets[1].z;21002101dstX0 = blitcmd->regions[i].dstOffsets[0].x;2102dstX1 = blitcmd->regions[i].dstOffsets[1].x;2103dstY0 = blitcmd->regions[i].dstOffsets[0].y;2104dstY1 = blitcmd->regions[i].dstOffsets[1].y;2105dstZ0 = blitcmd->regions[i].dstOffsets[0].z;2106dstZ1 = blitcmd->regions[i].dstOffsets[1].z;21072108if (dstX0 < dstX1) {2109info.dst.box.x = dstX0;2110info.src.box.x = srcX0;2111info.dst.box.width = dstX1 - dstX0;2112info.src.box.width = srcX1 - srcX0;2113} else {2114info.dst.box.x = dstX1;2115info.src.box.x = srcX1;2116info.dst.box.width = dstX0 - dstX1;2117info.src.box.width = srcX0 - srcX1;2118}21192120if (dstY0 < dstY1) {2121info.dst.box.y = dstY0;2122info.src.box.y = srcY0;2123info.dst.box.height = dstY1 - dstY0;2124info.src.box.height = srcY1 - srcY0;2125} else {2126info.dst.box.y = dstY1;2127info.src.box.y = srcY1;2128info.dst.box.height = dstY0 - dstY1;2129info.src.box.height = srcY0 - srcY1;2130}21312132assert_subresource_layers(info.src.resource, &blitcmd->regions[i].srcSubresource, blitcmd->regions[i].srcOffsets);2133assert_subresource_layers(info.dst.resource, &blitcmd->regions[i].dstSubresource, blitcmd->regions[i].dstOffsets);2134if (blitcmd->src->bo->target == PIPE_TEXTURE_3D) {2135if (dstZ0 < dstZ1) {2136info.dst.box.z = dstZ0;2137info.src.box.z = srcZ0;2138info.dst.box.depth = dstZ1 - dstZ0;2139info.src.box.depth = srcZ1 - srcZ0;2140} else {2141info.dst.box.z = dstZ1;2142info.src.box.z = srcZ1;2143info.dst.box.depth = dstZ0 - dstZ1;2144info.src.box.depth = srcZ0 - srcZ1;2145}2146} else {2147info.src.box.z = blitcmd->regions[i].srcSubresource.baseArrayLayer;2148info.dst.box.z = blitcmd->regions[i].dstSubresource.baseArrayLayer;2149info.src.box.depth = blitcmd->regions[i].srcSubresource.layerCount;2150info.dst.box.depth = blitcmd->regions[i].dstSubresource.layerCount;2151}21522153info.src.level = blitcmd->regions[i].srcSubresource.mipLevel;2154info.dst.level = blitcmd->regions[i].dstSubresource.mipLevel;2155state->pctx->blit(state->pctx, &info);2156}2157}21582159static void handle_fill_buffer(struct lvp_cmd_buffer_entry *cmd,2160struct rendering_state *state)2161{2162struct lvp_cmd_fill_buffer *fillcmd = &cmd->u.fill_buffer;2163uint32_t size = fillcmd->fill_size;21642165if (fillcmd->fill_size == VK_WHOLE_SIZE) {2166size = fillcmd->buffer->bo->width0 - fillcmd->offset;2167size = ROUND_DOWN_TO(size, 4);2168}21692170state->pctx->clear_buffer(state->pctx,2171fillcmd->buffer->bo,2172fillcmd->offset,2173size,2174&fillcmd->data,21754);2176}21772178static void handle_update_buffer(struct lvp_cmd_buffer_entry *cmd,2179struct rendering_state *state)2180{2181struct lvp_cmd_update_buffer *updcmd = &cmd->u.update_buffer;2182uint32_t *dst;2183struct pipe_transfer *dst_t;2184struct pipe_box box;21852186u_box_1d(updcmd->offset, updcmd->data_size, &box);2187dst = state->pctx->buffer_map(state->pctx,2188updcmd->buffer->bo,21890,2190PIPE_MAP_WRITE,2191&box,2192&dst_t);21932194memcpy(dst, updcmd->data, updcmd->data_size);2195state->pctx->buffer_unmap(state->pctx, dst_t);2196}21972198static void handle_draw_indexed(struct lvp_cmd_buffer_entry *cmd,2199struct rendering_state *state)2200{2201const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];2202state->info.index_bounds_valid = false;2203state->info.min_index = 0;2204state->info.max_index = ~0;2205state->info.index_size = state->index_size;2206state->info.index.resource = state->index_buffer;2207state->info.start_instance = cmd->u.draw_indexed.first_instance;2208state->info.instance_count = cmd->u.draw_indexed.instance_count;2209state->info.view_mask = subpass->view_mask;2210state->info.increment_draw_id = true;22112212if (state->info.primitive_restart)2213state->info.restart_index = util_prim_restart_index_from_size(state->info.index_size);2214/* avoid calculating multiple times if cmdbuf is submitted again */2215if (cmd->u.draw_indexed.calc_start) {2216for (unsigned i = 0; i < cmd->u.draw_indexed.draw_count; i++)2217cmd->u.draw_indexed.draws[i].start = (state->index_offset / state->index_size) + cmd->u.draw_indexed.draws[i].start;2218cmd->u.draw_indexed.calc_start = false;2219}2220state->info.index_bias_varies = cmd->u.draw_indexed.vertex_offset_changes;2221state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, cmd->u.draw_indexed.draws, cmd->u.draw_indexed.draw_count);2222}22232224static void handle_draw_indirect(struct lvp_cmd_buffer_entry *cmd,2225struct rendering_state *state, bool indexed)2226{2227const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];2228struct pipe_draw_start_count_bias draw = {0};2229if (indexed) {2230state->info.index_bounds_valid = false;2231state->info.index_size = state->index_size;2232state->info.index.resource = state->index_buffer;2233state->info.max_index = ~0;2234} else2235state->info.index_size = 0;2236state->indirect_info.offset = cmd->u.draw_indirect.offset;2237state->indirect_info.stride = cmd->u.draw_indirect.stride;2238state->indirect_info.draw_count = cmd->u.draw_indirect.draw_count;2239state->indirect_info.buffer = cmd->u.draw_indirect.buffer->bo;2240state->info.view_mask = subpass->view_mask;22412242state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);2243}22442245static void handle_index_buffer(struct lvp_cmd_buffer_entry *cmd,2246struct rendering_state *state)2247{2248struct lvp_cmd_bind_index_buffer *ib = &cmd->u.index_buffer;2249switch (ib->index_type) {2250case VK_INDEX_TYPE_UINT8_EXT:2251state->index_size = 1;2252break;2253case VK_INDEX_TYPE_UINT16:2254state->index_size = 2;2255break;2256case VK_INDEX_TYPE_UINT32:2257state->index_size = 4;2258break;2259default:2260break;2261}2262state->index_offset = ib->offset;2263if (ib->buffer)2264state->index_buffer = ib->buffer->bo;2265else2266state->index_buffer = NULL;22672268state->ib_dirty = true;2269}22702271static void handle_dispatch(struct lvp_cmd_buffer_entry *cmd,2272struct rendering_state *state)2273{2274state->dispatch_info.grid[0] = cmd->u.dispatch.x;2275state->dispatch_info.grid[1] = cmd->u.dispatch.y;2276state->dispatch_info.grid[2] = cmd->u.dispatch.z;2277state->dispatch_info.grid_base[0] = cmd->u.dispatch.base_x;2278state->dispatch_info.grid_base[1] = cmd->u.dispatch.base_y;2279state->dispatch_info.grid_base[2] = cmd->u.dispatch.base_z;2280state->dispatch_info.indirect = NULL;2281state->pctx->launch_grid(state->pctx, &state->dispatch_info);2282}22832284static void handle_dispatch_indirect(struct lvp_cmd_buffer_entry *cmd,2285struct rendering_state *state)2286{2287state->dispatch_info.indirect = cmd->u.dispatch_indirect.buffer->bo;2288state->dispatch_info.indirect_offset = cmd->u.dispatch_indirect.offset;2289state->pctx->launch_grid(state->pctx, &state->dispatch_info);2290}22912292static void handle_push_constants(struct lvp_cmd_buffer_entry *cmd,2293struct rendering_state *state)2294{2295memcpy(state->push_constants + cmd->u.push_constants.offset, cmd->u.push_constants.val, cmd->u.push_constants.size);22962297state->pc_buffer[PIPE_SHADER_VERTEX].buffer_size = 128 * 4;2298state->pc_buffer[PIPE_SHADER_VERTEX].buffer_offset = 0;2299state->pc_buffer[PIPE_SHADER_VERTEX].user_buffer = state->push_constants;2300state->pcbuf_dirty[PIPE_SHADER_VERTEX] = true;2301state->pc_buffer[PIPE_SHADER_FRAGMENT].buffer_size = 128 * 4;2302state->pc_buffer[PIPE_SHADER_FRAGMENT].buffer_offset = 0;2303state->pc_buffer[PIPE_SHADER_FRAGMENT].user_buffer = state->push_constants;2304state->pcbuf_dirty[PIPE_SHADER_FRAGMENT] = true;2305state->pc_buffer[PIPE_SHADER_GEOMETRY].buffer_size = 128 * 4;2306state->pc_buffer[PIPE_SHADER_GEOMETRY].buffer_offset = 0;2307state->pc_buffer[PIPE_SHADER_GEOMETRY].user_buffer = state->push_constants;2308state->pcbuf_dirty[PIPE_SHADER_GEOMETRY] = true;2309state->pc_buffer[PIPE_SHADER_TESS_CTRL].buffer_size = 128 * 4;2310state->pc_buffer[PIPE_SHADER_TESS_CTRL].buffer_offset = 0;2311state->pc_buffer[PIPE_SHADER_TESS_CTRL].user_buffer = state->push_constants;2312state->pcbuf_dirty[PIPE_SHADER_TESS_CTRL] = true;2313state->pc_buffer[PIPE_SHADER_TESS_EVAL].buffer_size = 128 * 4;2314state->pc_buffer[PIPE_SHADER_TESS_EVAL].buffer_offset = 0;2315state->pc_buffer[PIPE_SHADER_TESS_EVAL].user_buffer = state->push_constants;2316state->pcbuf_dirty[PIPE_SHADER_TESS_EVAL] = true;2317state->pc_buffer[PIPE_SHADER_COMPUTE].buffer_size = 128 * 4;2318state->pc_buffer[PIPE_SHADER_COMPUTE].buffer_offset = 0;2319state->pc_buffer[PIPE_SHADER_COMPUTE].user_buffer = state->push_constants;2320state->pcbuf_dirty[PIPE_SHADER_COMPUTE] = true;2321}23222323static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,2324struct rendering_state *state);23252326static void handle_execute_commands(struct lvp_cmd_buffer_entry *cmd,2327struct rendering_state *state)2328{2329for (unsigned i = 0; i < cmd->u.execute_commands.command_buffer_count; i++) {2330struct lvp_cmd_buffer *secondary_buf = cmd->u.execute_commands.cmd_buffers[i];2331lvp_execute_cmd_buffer(secondary_buf, state);2332}2333}23342335static void handle_event_set(struct lvp_cmd_buffer_entry *cmd,2336struct rendering_state *state)2337{2338struct lvp_event *event = cmd->u.event_set.event;23392340if (cmd->u.event_set.flush)2341state->pctx->flush(state->pctx, NULL, 0);2342event->event_storage = (cmd->u.event_set.value == true) ? 1 : 0;2343}23442345static void handle_wait_events(struct lvp_cmd_buffer_entry *cmd,2346struct rendering_state *state)2347{2348for (unsigned i = 0; i < cmd->u.wait_events.event_count; i++) {2349struct lvp_event *event = cmd->u.wait_events.events[i];23502351while (event->event_storage != true);2352}2353}23542355static void handle_pipeline_barrier(struct lvp_cmd_buffer_entry *cmd,2356struct rendering_state *state)2357{2358/* why hello nail, I'm a hammer. - TODO */2359state->pctx->flush(state->pctx, NULL, 0);2360}23612362static void maybe_emit_state_for_begin_query(struct lvp_cmd_buffer_entry *cmd,2363struct rendering_state *state)2364{2365struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;2366struct lvp_query_pool *pool = qcmd->pool;23672368if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS &&2369pool->pipeline_stats & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT)2370emit_compute_state(state);2371emit_state(state);2372}23732374static void handle_begin_query(struct lvp_cmd_buffer_entry *cmd,2375struct rendering_state *state)2376{2377struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;2378struct lvp_query_pool *pool = qcmd->pool;23792380if (!pool->queries[qcmd->query]) {2381enum pipe_query_type qtype = pool->base_type;2382if (qtype == PIPE_QUERY_OCCLUSION_COUNTER && !qcmd->precise)2383qtype = PIPE_QUERY_OCCLUSION_PREDICATE;2384pool->queries[qcmd->query] = state->pctx->create_query(state->pctx,2385qtype, qcmd->index);2386}23872388state->pctx->begin_query(state->pctx, pool->queries[qcmd->query]);2389}23902391static void handle_end_query(struct lvp_cmd_buffer_entry *cmd,2392struct rendering_state *state)2393{2394struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;2395struct lvp_query_pool *pool = qcmd->pool;2396assert(pool->queries[qcmd->query]);23972398state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);2399}24002401static void handle_reset_query_pool(struct lvp_cmd_buffer_entry *cmd,2402struct rendering_state *state)2403{2404struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;2405struct lvp_query_pool *pool = qcmd->pool;2406for (unsigned i = qcmd->query; i < qcmd->query + qcmd->index; i++) {2407if (pool->queries[i]) {2408state->pctx->destroy_query(state->pctx, pool->queries[i]);2409pool->queries[i] = NULL;2410}2411}2412}24132414static void handle_write_timestamp(struct lvp_cmd_buffer_entry *cmd,2415struct rendering_state *state)2416{2417struct lvp_cmd_query_cmd *qcmd = &cmd->u.query;2418struct lvp_query_pool *pool = qcmd->pool;2419if (!pool->queries[qcmd->query]) {2420pool->queries[qcmd->query] = state->pctx->create_query(state->pctx,2421PIPE_QUERY_TIMESTAMP, 0);2422}24232424if (qcmd->flush)2425state->pctx->flush(state->pctx, NULL, 0);2426state->pctx->end_query(state->pctx, pool->queries[qcmd->query]);24272428}24292430static void handle_copy_query_pool_results(struct lvp_cmd_buffer_entry *cmd,2431struct rendering_state *state)2432{2433struct lvp_cmd_copy_query_pool_results *copycmd = &cmd->u.copy_query_pool_results;2434struct lvp_query_pool *pool = copycmd->pool;24352436for (unsigned i = copycmd->first_query; i < copycmd->first_query + copycmd->query_count; i++) {2437unsigned offset = copycmd->dst_offset + copycmd->dst->offset + (copycmd->stride * (i - copycmd->first_query));2438if (pool->queries[i]) {2439if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT)2440state->pctx->get_query_result_resource(state->pctx,2441pool->queries[i],2442copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,2443copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,2444-1,2445copycmd->dst->bo,2446offset + (copycmd->flags & VK_QUERY_RESULT_64_BIT ? 8 : 4));2447if (pool->type == VK_QUERY_TYPE_PIPELINE_STATISTICS) {2448unsigned num_results = 0;2449unsigned result_size = copycmd->flags & VK_QUERY_RESULT_64_BIT ? 8 : 4;2450u_foreach_bit(bit, pool->pipeline_stats)2451state->pctx->get_query_result_resource(state->pctx,2452pool->queries[i],2453copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,2454copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,2455bit,2456copycmd->dst->bo,2457offset + num_results++ * result_size);2458} else {2459state->pctx->get_query_result_resource(state->pctx,2460pool->queries[i],2461copycmd->flags & VK_QUERY_RESULT_WAIT_BIT,2462copycmd->flags & VK_QUERY_RESULT_64_BIT ? PIPE_QUERY_TYPE_U64 : PIPE_QUERY_TYPE_U32,24630,2464copycmd->dst->bo,2465offset);2466}2467} else {2468/* if no queries emitted yet, just reset the buffer to 0 so avail is reported correctly */2469if (copycmd->flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {2470struct pipe_transfer *src_t;2471uint32_t *map;24722473struct pipe_box box = {0};2474box.x = offset;2475box.width = copycmd->stride;2476box.height = 1;2477box.depth = 1;2478map = state->pctx->buffer_map(state->pctx,2479copycmd->dst->bo, 0, PIPE_MAP_READ, &box,2480&src_t);24812482memset(map, 0, box.width);2483state->pctx->buffer_unmap(state->pctx, src_t);2484}2485}2486}2487}24882489static void pack_clear_color(enum pipe_format pformat, VkClearColorValue *in_val, uint32_t col_val[4])2490{2491const struct util_format_description *desc = util_format_description(pformat);2492col_val[0] = col_val[1] = col_val[2] = col_val[3] = 0;2493for (unsigned c = 0; c < 4; c++) {2494if (desc->swizzle[c] >= 4)2495continue;2496const struct util_format_channel_description *channel = &desc->channel[desc->swizzle[c]];2497if (channel->size == 32) {2498col_val[c] = in_val->uint32[c];2499continue;2500}2501if (channel->pure_integer) {2502uint64_t v = in_val->uint32[c] & ((1u << channel->size) - 1);2503switch (channel->size) {2504case 2:2505case 8:2506case 10:2507col_val[0] |= (v << channel->shift);2508break;2509case 16:2510col_val[c / 2] |= (v << (16 * (c % 2)));2511break;2512}2513} else {2514util_pack_color(in_val->float32, pformat, (union util_color *)col_val);2515break;2516}2517}2518}25192520static void handle_clear_color_image(struct lvp_cmd_buffer_entry *cmd,2521struct rendering_state *state)2522{2523struct lvp_image *image = cmd->u.clear_color_image.image;2524uint32_t col_val[4];2525pack_clear_color(image->bo->format, &cmd->u.clear_color_image.clear_val, col_val);2526for (unsigned i = 0; i < cmd->u.clear_color_image.range_count; i++) {2527VkImageSubresourceRange *range = &cmd->u.clear_color_image.ranges[i];2528struct pipe_box box;2529box.x = 0;2530box.y = 0;2531box.z = 0;25322533uint32_t level_count = lvp_get_levelCount(image, range);2534for (unsigned j = range->baseMipLevel; j < range->baseMipLevel + level_count; j++) {2535box.width = u_minify(image->bo->width0, j);2536box.height = u_minify(image->bo->height0, j);2537box.depth = 1;2538if (image->bo->target == PIPE_TEXTURE_3D)2539box.depth = u_minify(image->bo->depth0, j);2540else if (image->bo->target == PIPE_TEXTURE_1D_ARRAY) {2541box.y = range->baseArrayLayer;2542box.height = lvp_get_layerCount(image, range);2543box.depth = 1;2544} else {2545box.z = range->baseArrayLayer;2546box.depth = lvp_get_layerCount(image, range);2547}25482549state->pctx->clear_texture(state->pctx, image->bo,2550j, &box, (void *)col_val);2551}2552}2553}25542555static void handle_clear_ds_image(struct lvp_cmd_buffer_entry *cmd,2556struct rendering_state *state)2557{2558struct lvp_image *image = cmd->u.clear_ds_image.image;2559for (unsigned i = 0; i < cmd->u.clear_ds_image.range_count; i++) {2560VkImageSubresourceRange *range = &cmd->u.clear_ds_image.ranges[i];2561uint32_t ds_clear_flags = 0;2562if (range->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)2563ds_clear_flags |= PIPE_CLEAR_DEPTH;2564if (range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)2565ds_clear_flags |= PIPE_CLEAR_STENCIL;25662567uint32_t level_count = lvp_get_levelCount(image, range);2568for (unsigned j = 0; j < level_count; j++) {2569struct pipe_surface *surf;2570unsigned width, height;25712572width = u_minify(image->bo->width0, range->baseMipLevel + j);2573height = u_minify(image->bo->height0, range->baseMipLevel + j);25742575surf = create_img_surface_bo(state, range,2576image->bo, image->bo->format,2577width, height,25780, lvp_get_layerCount(image, range) - 1, j);25792580state->pctx->clear_depth_stencil(state->pctx,2581surf,2582ds_clear_flags,2583cmd->u.clear_ds_image.clear_val.depth,2584cmd->u.clear_ds_image.clear_val.stencil,25850, 0,2586width, height, true);2587state->pctx->surface_destroy(state->pctx, surf);2588}2589}2590}25912592static void handle_clear_attachments(struct lvp_cmd_buffer_entry *cmd,2593struct rendering_state *state)2594{2595for (uint32_t a = 0; a < cmd->u.clear_attachments.attachment_count; a++) {2596VkClearAttachment *att = &cmd->u.clear_attachments.attachments[a];2597const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];2598struct lvp_image_view *imgv;25992600if (att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {2601struct lvp_subpass_attachment *color_att = &subpass->color_attachments[att->colorAttachment];2602if (!color_att || color_att->attachment == VK_ATTACHMENT_UNUSED)2603continue;2604imgv = get_attachment(state, color_att->attachment);2605} else {2606struct lvp_subpass_attachment *ds_att = subpass->depth_stencil_attachment;2607if (!ds_att || ds_att->attachment == VK_ATTACHMENT_UNUSED)2608continue;2609imgv = get_attachment(state, ds_att->attachment);2610}2611union pipe_color_union col_val;2612double dclear_val = 0;2613uint32_t sclear_val = 0;2614uint32_t ds_clear_flags = 0;2615if (att->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) {2616ds_clear_flags |= PIPE_CLEAR_DEPTH;2617dclear_val = att->clearValue.depthStencil.depth;2618}2619if (att->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {2620ds_clear_flags |= PIPE_CLEAR_STENCIL;2621sclear_val = att->clearValue.depthStencil.stencil;2622}2623if (att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {2624for (unsigned i = 0; i < 4; i++)2625col_val.ui[i] = att->clearValue.color.uint32[i];2626}26272628for (uint32_t r = 0; r < cmd->u.clear_attachments.rect_count; r++) {26292630VkClearRect *rect = &cmd->u.clear_attachments.rects[r];2631if (subpass->view_mask) {2632u_foreach_bit(i, subpass->view_mask)2633clear_attachment_layers(state, imgv, &rect->rect,2634i, 1,2635ds_clear_flags, dclear_val, sclear_val,2636&col_val);2637} else2638clear_attachment_layers(state, imgv, &rect->rect,2639rect->baseArrayLayer, rect->layerCount,2640ds_clear_flags, dclear_val, sclear_val,2641&col_val);2642}2643}2644}26452646static void handle_resolve_image(struct lvp_cmd_buffer_entry *cmd,2647struct rendering_state *state)2648{2649int i;2650struct lvp_cmd_resolve_image *resolvecmd = &cmd->u.resolve_image;2651struct pipe_blit_info info;26522653memset(&info, 0, sizeof(info));26542655state->pctx->flush(state->pctx, NULL, 0);2656info.src.resource = resolvecmd->src->bo;2657info.dst.resource = resolvecmd->dst->bo;2658info.src.format = resolvecmd->src->bo->format;2659info.dst.format = resolvecmd->dst->bo->format;2660info.mask = util_format_is_depth_or_stencil(info.src.format) ? PIPE_MASK_ZS : PIPE_MASK_RGBA;2661info.filter = PIPE_TEX_FILTER_NEAREST;2662for (i = 0; i < resolvecmd->region_count; i++) {2663int srcX0, srcY0;2664unsigned dstX0, dstY0;26652666srcX0 = resolvecmd->regions[i].srcOffset.x;2667srcY0 = resolvecmd->regions[i].srcOffset.y;26682669dstX0 = resolvecmd->regions[i].dstOffset.x;2670dstY0 = resolvecmd->regions[i].dstOffset.y;26712672info.dst.box.x = dstX0;2673info.dst.box.y = dstY0;2674info.src.box.x = srcX0;2675info.src.box.y = srcY0;26762677info.dst.box.width = resolvecmd->regions[i].extent.width;2678info.src.box.width = resolvecmd->regions[i].extent.width;2679info.dst.box.height = resolvecmd->regions[i].extent.height;2680info.src.box.height = resolvecmd->regions[i].extent.height;26812682info.dst.box.depth = resolvecmd->regions[i].dstSubresource.layerCount;2683info.src.box.depth = resolvecmd->regions[i].srcSubresource.layerCount;26842685info.src.level = resolvecmd->regions[i].srcSubresource.mipLevel;2686info.src.box.z = resolvecmd->regions[i].srcOffset.z + resolvecmd->regions[i].srcSubresource.baseArrayLayer;26872688info.dst.level = resolvecmd->regions[i].dstSubresource.mipLevel;2689info.dst.box.z = resolvecmd->regions[i].dstOffset.z + resolvecmd->regions[i].dstSubresource.baseArrayLayer;26902691state->pctx->blit(state->pctx, &info);2692}2693}26942695static void handle_draw_indirect_count(struct lvp_cmd_buffer_entry *cmd,2696struct rendering_state *state, bool indexed)2697{2698const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];2699struct pipe_draw_start_count_bias draw = {0};2700if (indexed) {2701state->info.index_bounds_valid = false;2702state->info.index_size = state->index_size;2703state->info.index.resource = state->index_buffer;2704state->info.max_index = ~0;2705} else2706state->info.index_size = 0;2707state->indirect_info.offset = cmd->u.draw_indirect_count.offset;2708state->indirect_info.stride = cmd->u.draw_indirect_count.stride;2709state->indirect_info.draw_count = cmd->u.draw_indirect_count.max_draw_count;2710state->indirect_info.buffer = cmd->u.draw_indirect_count.buffer->bo;2711state->indirect_info.indirect_draw_count_offset = cmd->u.draw_indirect_count.count_buffer_offset;2712state->indirect_info.indirect_draw_count = cmd->u.draw_indirect_count.count_buffer->bo;2713state->info.view_mask = subpass->view_mask;27142715state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);2716}27172718static void handle_compute_push_descriptor_set(struct lvp_cmd_buffer_entry *cmd,2719struct dyn_info *dyn_info,2720struct rendering_state *state)2721{2722struct lvp_cmd_push_descriptor_set *pds = &cmd->u.push_descriptor_set;2723struct lvp_descriptor_set_layout *layout = pds->layout->set[pds->set].layout;27242725if (!(layout->shader_stages & VK_SHADER_STAGE_COMPUTE_BIT))2726return;2727for (unsigned i = 0; i < pds->set; i++) {2728increment_dyn_info(dyn_info, pds->layout->set[i].layout, false);2729}2730unsigned info_idx = 0;2731for (unsigned i = 0; i < pds->descriptor_write_count; i++) {2732struct lvp_write_descriptor *desc = &pds->descriptors[i];2733struct lvp_descriptor_set_binding_layout *binding = &layout->binding[desc->dst_binding];27342735if (!binding->valid)2736continue;27372738for (unsigned j = 0; j < desc->descriptor_count; j++) {2739union lvp_descriptor_info *info = &pds->infos[info_idx + j];27402741handle_descriptor(state, dyn_info, binding,2742MESA_SHADER_COMPUTE, PIPE_SHADER_COMPUTE,2743j, desc->descriptor_type,2744info);2745}2746info_idx += desc->descriptor_count;2747}2748}27492750static void handle_push_descriptor_set(struct lvp_cmd_buffer_entry *cmd,2751struct rendering_state *state)2752{2753struct lvp_cmd_push_descriptor_set *pds = &cmd->u.push_descriptor_set;2754struct lvp_descriptor_set_layout *layout = pds->layout->set[pds->set].layout;2755struct dyn_info dyn_info;27562757memset(&dyn_info.stage, 0, sizeof(dyn_info.stage));2758dyn_info.dyn_index = 0;2759if (pds->bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {2760handle_compute_push_descriptor_set(cmd, &dyn_info, state);2761}27622763for (unsigned i = 0; i < pds->set; i++) {2764increment_dyn_info(&dyn_info, pds->layout->set[i].layout, false);2765}27662767unsigned info_idx = 0;2768for (unsigned i = 0; i < pds->descriptor_write_count; i++) {2769struct lvp_write_descriptor *desc = &pds->descriptors[i];2770struct lvp_descriptor_set_binding_layout *binding = &layout->binding[desc->dst_binding];27712772if (!binding->valid)2773continue;27742775for (unsigned j = 0; j < desc->descriptor_count; j++) {2776union lvp_descriptor_info *info = &pds->infos[info_idx + j];27772778if (layout->shader_stages & VK_SHADER_STAGE_VERTEX_BIT)2779handle_descriptor(state, &dyn_info, binding,2780MESA_SHADER_VERTEX, PIPE_SHADER_VERTEX,2781j, desc->descriptor_type,2782info);2783if (layout->shader_stages & VK_SHADER_STAGE_FRAGMENT_BIT)2784handle_descriptor(state, &dyn_info, binding,2785MESA_SHADER_FRAGMENT, PIPE_SHADER_FRAGMENT,2786j, desc->descriptor_type,2787info);2788if (layout->shader_stages & VK_SHADER_STAGE_GEOMETRY_BIT)2789handle_descriptor(state, &dyn_info, binding,2790MESA_SHADER_GEOMETRY, PIPE_SHADER_GEOMETRY,2791j, desc->descriptor_type,2792info);2793if (layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)2794handle_descriptor(state, &dyn_info, binding,2795MESA_SHADER_TESS_CTRL, PIPE_SHADER_TESS_CTRL,2796j, desc->descriptor_type,2797info);2798if (layout->shader_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)2799handle_descriptor(state, &dyn_info, binding,2800MESA_SHADER_TESS_EVAL, PIPE_SHADER_TESS_EVAL,2801j, desc->descriptor_type,2802info);2803}2804info_idx += desc->descriptor_count;2805}2806}28072808static void handle_bind_transform_feedback_buffers(struct lvp_cmd_buffer_entry *cmd,2809struct rendering_state *state)2810{2811struct lvp_cmd_bind_transform_feedback_buffers *btfb = &cmd->u.bind_transform_feedback_buffers;28122813for (unsigned i = 0; i < btfb->binding_count; i++) {2814int idx = i + btfb->first_binding;2815if (state->so_targets[idx])2816state->pctx->stream_output_target_destroy(state->pctx, state->so_targets[idx]);28172818state->so_targets[idx] = state->pctx->create_stream_output_target(state->pctx,2819btfb->buffers[i]->bo,2820btfb->offsets[i],2821btfb->sizes[i]);2822}2823state->num_so_targets = btfb->first_binding + btfb->binding_count;2824}28252826static void handle_begin_transform_feedback(struct lvp_cmd_buffer_entry *cmd,2827struct rendering_state *state)2828{2829struct lvp_cmd_begin_transform_feedback *btf = &cmd->u.begin_transform_feedback;2830uint32_t offsets[4];28312832memset(offsets, 0, sizeof(uint32_t)*4);28332834for (unsigned i = 0; i < btf->counter_buffer_count; i++) {2835if (!btf->counter_buffers[i])2836continue;28372838pipe_buffer_read(state->pctx,2839btf->counter_buffers[i]->bo,2840btf->counter_buffer_offsets[i],28414,2842&offsets[i]);2843}2844state->pctx->set_stream_output_targets(state->pctx, state->num_so_targets,2845state->so_targets, offsets);2846}28472848static void handle_end_transform_feedback(struct lvp_cmd_buffer_entry *cmd,2849struct rendering_state *state)2850{2851struct lvp_cmd_end_transform_feedback *etf = &cmd->u.end_transform_feedback;28522853if (etf->counter_buffer_count) {2854for (unsigned i = 0; i < etf->counter_buffer_count; i++) {2855if (!etf->counter_buffers[i])2856continue;28572858uint32_t offset;2859offset = state->pctx->stream_output_target_offset(state->so_targets[i]);28602861pipe_buffer_write(state->pctx,2862etf->counter_buffers[i]->bo,2863etf->counter_buffer_offsets[i],28644,2865&offset);2866}2867}2868state->pctx->set_stream_output_targets(state->pctx, 0, NULL, NULL);2869}28702871static void handle_draw_indirect_byte_count(struct lvp_cmd_buffer_entry *cmd,2872struct rendering_state *state)2873{2874struct lvp_cmd_draw_indirect_byte_count *dibc = &cmd->u.draw_indirect_byte_count;2875const struct lvp_subpass *subpass = &state->pass->subpasses[state->subpass];2876struct pipe_draw_start_count_bias draw = {0};28772878pipe_buffer_read(state->pctx,2879dibc->counter_buffer->bo,2880dibc->counter_buffer->offset + dibc->counter_buffer_offset,28814, &draw.count);28822883state->info.start_instance = cmd->u.draw_indirect_byte_count.first_instance;2884state->info.instance_count = cmd->u.draw_indirect_byte_count.instance_count;2885state->info.index_size = 0;28862887draw.count /= cmd->u.draw_indirect_byte_count.vertex_stride;2888state->info.view_mask = subpass->view_mask;2889state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1);2890}28912892static void handle_begin_conditional_rendering(struct lvp_cmd_buffer_entry *cmd,2893struct rendering_state *state)2894{2895struct lvp_cmd_begin_conditional_rendering *bcr = &cmd->u.begin_conditional_rendering;2896state->pctx->render_condition_mem(state->pctx,2897bcr->buffer->bo,2898bcr->buffer->offset + bcr->offset,2899bcr->inverted);2900}29012902static void handle_end_conditional_rendering(struct rendering_state *state)2903{2904state->pctx->render_condition_mem(state->pctx, NULL, 0, false);2905}29062907static void handle_set_vertex_input(struct lvp_cmd_buffer_entry *cmd,2908struct rendering_state *state)2909{2910const struct lvp_cmd_set_vertex_input *vertex_input = &cmd->u.set_vertex_input;2911const struct VkVertexInputBindingDescription2EXT *bindings = (void*)vertex_input->data;2912const struct VkVertexInputAttributeDescription2EXT *attrs = (void*)(vertex_input->data +2913vertex_input->binding_count *2914sizeof(struct VkVertexInputBindingDescription2EXT));2915int max_location = -1;2916for (unsigned i = 0; i < vertex_input->attr_count; i++) {2917const struct VkVertexInputBindingDescription2EXT *binding = &bindings[attrs[i].binding];2918unsigned location = attrs[i].location;2919state->velem.velems[location].src_offset = attrs[i].offset;2920state->velem.velems[location].vertex_buffer_index = attrs[i].binding;2921state->velem.velems[location].src_format = lvp_vk_format_to_pipe_format(attrs[i].format);2922state->vb[attrs[i].binding].stride = binding->stride;29232924switch (binding->inputRate) {2925case VK_VERTEX_INPUT_RATE_VERTEX:2926state->velem.velems[location].instance_divisor = 0;2927break;2928case VK_VERTEX_INPUT_RATE_INSTANCE:2929state->velem.velems[location].instance_divisor = binding->divisor;2930break;2931default:2932assert(0);2933break;2934}29352936if ((int)location > max_location)2937max_location = location;2938}2939state->velem.count = max_location + 1;2940state->vb_dirty = true;2941state->ve_dirty = true;2942}29432944static void handle_set_cull_mode(struct lvp_cmd_buffer_entry *cmd,2945struct rendering_state *state)2946{2947state->rs_state.cull_face = vk_cull_to_pipe(cmd->u.set_cull_mode.cull_mode);2948state->rs_dirty = true;2949}29502951static void handle_set_front_face(struct lvp_cmd_buffer_entry *cmd,2952struct rendering_state *state)2953{2954state->rs_state.front_ccw = (cmd->u.set_front_face.front_face == VK_FRONT_FACE_COUNTER_CLOCKWISE);2955state->rs_dirty = true;2956}29572958static void handle_set_primitive_topology(struct lvp_cmd_buffer_entry *cmd,2959struct rendering_state *state)2960{2961state->info.mode = vk_conv_topology(cmd->u.set_primitive_topology.prim);2962state->rs_dirty = true;2963}296429652966static void handle_set_depth_test_enable(struct lvp_cmd_buffer_entry *cmd,2967struct rendering_state *state)2968{2969state->dsa_dirty |= state->dsa_state.depth_enabled != cmd->u.set_depth_test_enable.depth_test_enable;2970state->dsa_state.depth_enabled = cmd->u.set_depth_test_enable.depth_test_enable;2971}29722973static void handle_set_depth_write_enable(struct lvp_cmd_buffer_entry *cmd,2974struct rendering_state *state)2975{2976state->dsa_dirty |= state->dsa_state.depth_writemask != cmd->u.set_depth_write_enable.depth_write_enable;2977state->dsa_state.depth_writemask = cmd->u.set_depth_write_enable.depth_write_enable;2978}29792980static void handle_set_depth_compare_op(struct lvp_cmd_buffer_entry *cmd,2981struct rendering_state *state)2982{2983state->dsa_dirty |= state->dsa_state.depth_func != cmd->u.set_depth_compare_op.depth_op;2984state->dsa_state.depth_func = cmd->u.set_depth_compare_op.depth_op;2985}29862987static void handle_set_depth_bounds_test_enable(struct lvp_cmd_buffer_entry *cmd,2988struct rendering_state *state)2989{2990state->dsa_dirty |= state->dsa_state.depth_bounds_test != cmd->u.set_depth_bounds_test_enable.depth_bounds_test_enable;2991state->dsa_state.depth_bounds_test = cmd->u.set_depth_bounds_test_enable.depth_bounds_test_enable;2992}29932994static void handle_set_stencil_test_enable(struct lvp_cmd_buffer_entry *cmd,2995struct rendering_state *state)2996{2997state->dsa_dirty |= state->dsa_state.stencil[0].enabled != cmd->u.set_stencil_test_enable.stencil_test_enable ||2998state->dsa_state.stencil[1].enabled != cmd->u.set_stencil_test_enable.stencil_test_enable;2999state->dsa_state.stencil[0].enabled = cmd->u.set_stencil_test_enable.stencil_test_enable;3000state->dsa_state.stencil[1].enabled = cmd->u.set_stencil_test_enable.stencil_test_enable;3001}30023003static void handle_set_stencil_op(struct lvp_cmd_buffer_entry *cmd,3004struct rendering_state *state)3005{3006if (cmd->u.set_stencil_op.face_mask & VK_STENCIL_FACE_FRONT_BIT) {3007state->dsa_state.stencil[0].func = cmd->u.set_stencil_op.compare_op;3008state->dsa_state.stencil[0].fail_op = vk_conv_stencil_op(cmd->u.set_stencil_op.fail_op);3009state->dsa_state.stencil[0].zpass_op = vk_conv_stencil_op(cmd->u.set_stencil_op.pass_op);3010state->dsa_state.stencil[0].zfail_op = vk_conv_stencil_op(cmd->u.set_stencil_op.depth_fail_op);3011}30123013if (cmd->u.set_stencil_op.face_mask & VK_STENCIL_FACE_BACK_BIT) {3014state->dsa_state.stencil[1].func = cmd->u.set_stencil_op.compare_op;3015state->dsa_state.stencil[1].fail_op = vk_conv_stencil_op(cmd->u.set_stencil_op.fail_op);3016state->dsa_state.stencil[1].zpass_op = vk_conv_stencil_op(cmd->u.set_stencil_op.pass_op);3017state->dsa_state.stencil[1].zfail_op = vk_conv_stencil_op(cmd->u.set_stencil_op.depth_fail_op);3018}3019state->dsa_dirty = true;3020}30213022static void handle_set_line_stipple(struct lvp_cmd_buffer_entry *cmd,3023struct rendering_state *state)3024{3025state->rs_state.line_stipple_factor = cmd->u.set_line_stipple.line_stipple_factor - 1;3026state->rs_state.line_stipple_pattern = cmd->u.set_line_stipple.line_stipple_pattern;3027state->rs_dirty = true;3028}30293030static void handle_set_depth_bias_enable(struct lvp_cmd_buffer_entry *cmd,3031struct rendering_state *state)3032{3033state->rs_dirty |= state->depth_bias.enabled != cmd->u.set_depth_bias_enable.enable;3034state->depth_bias.enabled = cmd->u.set_depth_bias_enable.enable;3035}30363037static void handle_set_logic_op(struct lvp_cmd_buffer_entry *cmd,3038struct rendering_state *state)3039{3040unsigned op = vk_conv_logic_op(cmd->u.set_logic_op.op);3041state->rs_dirty |= state->blend_state.logicop_func != op;3042state->blend_state.logicop_func = op;3043}30443045static void handle_set_patch_control_points(struct lvp_cmd_buffer_entry *cmd,3046struct rendering_state *state)3047{3048state->info.vertices_per_patch = cmd->u.set_patch_control_points.vertices_per_patch;3049}30503051static void handle_set_primitive_restart_enable(struct lvp_cmd_buffer_entry *cmd,3052struct rendering_state *state)3053{3054state->info.primitive_restart = cmd->u.set_primitive_restart_enable.enable;3055}30563057static void handle_set_rasterizer_discard_enable(struct lvp_cmd_buffer_entry *cmd,3058struct rendering_state *state)3059{3060state->rs_dirty |= state->rs_state.rasterizer_discard != cmd->u.set_rasterizer_discard_enable.enable;3061state->rs_state.rasterizer_discard = cmd->u.set_rasterizer_discard_enable.enable;3062}30633064static void lvp_execute_cmd_buffer(struct lvp_cmd_buffer *cmd_buffer,3065struct rendering_state *state)3066{3067struct lvp_cmd_buffer_entry *cmd;3068bool first = true;3069bool did_flush = false;30703071LIST_FOR_EACH_ENTRY(cmd, &cmd_buffer->cmds, cmd_link) {3072switch (cmd->cmd_type) {3073case LVP_CMD_BIND_PIPELINE:3074handle_pipeline(cmd, state);3075break;3076case LVP_CMD_SET_VIEWPORT:3077handle_set_viewport(cmd, state);3078break;3079case LVP_CMD_SET_SCISSOR:3080handle_set_scissor(cmd, state);3081break;3082case LVP_CMD_SET_LINE_WIDTH:3083handle_set_line_width(cmd, state);3084break;3085case LVP_CMD_SET_DEPTH_BIAS:3086handle_set_depth_bias(cmd, state);3087break;3088case LVP_CMD_SET_BLEND_CONSTANTS:3089handle_set_blend_constants(cmd, state);3090break;3091case LVP_CMD_SET_DEPTH_BOUNDS:3092handle_set_depth_bounds(cmd, state);3093break;3094case LVP_CMD_SET_STENCIL_COMPARE_MASK:3095handle_set_stencil_compare_mask(cmd, state);3096break;3097case LVP_CMD_SET_STENCIL_WRITE_MASK:3098handle_set_stencil_write_mask(cmd, state);3099break;3100case LVP_CMD_SET_STENCIL_REFERENCE:3101handle_set_stencil_reference(cmd, state);3102break;3103case LVP_CMD_BIND_DESCRIPTOR_SETS:3104handle_descriptor_sets(cmd, state);3105break;3106case LVP_CMD_BIND_INDEX_BUFFER:3107handle_index_buffer(cmd, state);3108break;3109case LVP_CMD_BIND_VERTEX_BUFFERS:3110handle_vertex_buffers(cmd, state);3111break;3112case LVP_CMD_DRAW:3113emit_state(state);3114handle_draw(cmd, state);3115break;3116case LVP_CMD_DRAW_INDEXED:3117emit_state(state);3118handle_draw_indexed(cmd, state);3119break;3120case LVP_CMD_DRAW_INDIRECT:3121emit_state(state);3122handle_draw_indirect(cmd, state, false);3123break;3124case LVP_CMD_DRAW_INDEXED_INDIRECT:3125emit_state(state);3126handle_draw_indirect(cmd, state, true);3127break;3128case LVP_CMD_DISPATCH:3129emit_compute_state(state);3130handle_dispatch(cmd, state);3131break;3132case LVP_CMD_DISPATCH_INDIRECT:3133emit_compute_state(state);3134handle_dispatch_indirect(cmd, state);3135break;3136case LVP_CMD_COPY_BUFFER:3137handle_copy_buffer(cmd, state);3138break;3139case LVP_CMD_COPY_IMAGE:3140handle_copy_image(cmd, state);3141break;3142case LVP_CMD_BLIT_IMAGE:3143handle_blit_image(cmd, state);3144break;3145case LVP_CMD_COPY_BUFFER_TO_IMAGE:3146handle_copy_buffer_to_image(cmd, state);3147break;3148case LVP_CMD_COPY_IMAGE_TO_BUFFER:3149handle_copy_image_to_buffer(cmd, state);3150break;3151case LVP_CMD_UPDATE_BUFFER:3152handle_update_buffer(cmd, state);3153break;3154case LVP_CMD_FILL_BUFFER:3155handle_fill_buffer(cmd, state);3156break;3157case LVP_CMD_CLEAR_COLOR_IMAGE:3158handle_clear_color_image(cmd, state);3159break;3160case LVP_CMD_CLEAR_DEPTH_STENCIL_IMAGE:3161handle_clear_ds_image(cmd, state);3162break;3163case LVP_CMD_CLEAR_ATTACHMENTS:3164handle_clear_attachments(cmd, state);3165break;3166case LVP_CMD_RESOLVE_IMAGE:3167handle_resolve_image(cmd, state);3168break;3169case LVP_CMD_SET_EVENT:3170case LVP_CMD_RESET_EVENT:3171handle_event_set(cmd, state);3172break;3173case LVP_CMD_WAIT_EVENTS:3174handle_wait_events(cmd, state);3175break;3176case LVP_CMD_PIPELINE_BARRIER:3177/* skip flushes since every cmdbuf does a flush3178after iterating its cmds and so this is redundant3179*/3180if (first || did_flush || cmd->cmd_link.next == &cmd_buffer->cmds)3181continue;3182handle_pipeline_barrier(cmd, state);3183did_flush = true;3184continue;3185case LVP_CMD_BEGIN_QUERY:3186maybe_emit_state_for_begin_query(cmd, state);3187handle_begin_query(cmd, state);3188break;3189case LVP_CMD_END_QUERY:3190handle_end_query(cmd, state);3191break;3192case LVP_CMD_RESET_QUERY_POOL:3193handle_reset_query_pool(cmd, state);3194break;3195case LVP_CMD_WRITE_TIMESTAMP:3196handle_write_timestamp(cmd, state);3197break;3198case LVP_CMD_COPY_QUERY_POOL_RESULTS:3199handle_copy_query_pool_results(cmd, state);3200break;3201case LVP_CMD_PUSH_CONSTANTS:3202handle_push_constants(cmd, state);3203break;3204case LVP_CMD_BEGIN_RENDER_PASS:3205handle_begin_render_pass(cmd, state);3206break;3207case LVP_CMD_NEXT_SUBPASS:3208handle_next_subpass(cmd, state);3209break;3210case LVP_CMD_END_RENDER_PASS:3211handle_end_render_pass(cmd, state);3212break;3213case LVP_CMD_EXECUTE_COMMANDS:3214handle_execute_commands(cmd, state);3215break;3216case LVP_CMD_DRAW_INDIRECT_COUNT:3217emit_state(state);3218handle_draw_indirect_count(cmd, state, false);3219break;3220case LVP_CMD_DRAW_INDEXED_INDIRECT_COUNT:3221emit_state(state);3222handle_draw_indirect_count(cmd, state, true);3223break;3224case LVP_CMD_PUSH_DESCRIPTOR_SET:3225handle_push_descriptor_set(cmd, state);3226break;3227case LVP_CMD_BIND_TRANSFORM_FEEDBACK_BUFFERS:3228handle_bind_transform_feedback_buffers(cmd, state);3229break;3230case LVP_CMD_BEGIN_TRANSFORM_FEEDBACK:3231handle_begin_transform_feedback(cmd, state);3232break;3233case LVP_CMD_END_TRANSFORM_FEEDBACK:3234handle_end_transform_feedback(cmd, state);3235break;3236case LVP_CMD_DRAW_INDIRECT_BYTE_COUNT:3237emit_state(state);3238handle_draw_indirect_byte_count(cmd, state);3239break;3240case LVP_CMD_BEGIN_CONDITIONAL_RENDERING:3241handle_begin_conditional_rendering(cmd, state);3242break;3243case LVP_CMD_END_CONDITIONAL_RENDERING:3244handle_end_conditional_rendering(state);3245break;3246case LVP_CMD_SET_VERTEX_INPUT:3247handle_set_vertex_input(cmd, state);3248break;3249case LVP_CMD_SET_CULL_MODE:3250handle_set_cull_mode(cmd, state);3251break;3252case LVP_CMD_SET_FRONT_FACE:3253handle_set_front_face(cmd, state);3254break;3255case LVP_CMD_SET_PRIMITIVE_TOPOLOGY:3256handle_set_primitive_topology(cmd, state);3257break;3258case LVP_CMD_SET_DEPTH_TEST_ENABLE:3259handle_set_depth_test_enable(cmd, state);3260break;3261case LVP_CMD_SET_DEPTH_WRITE_ENABLE:3262handle_set_depth_write_enable(cmd, state);3263break;3264case LVP_CMD_SET_DEPTH_COMPARE_OP:3265handle_set_depth_compare_op(cmd, state);3266break;3267case LVP_CMD_SET_DEPTH_BOUNDS_TEST_ENABLE:3268handle_set_depth_bounds_test_enable(cmd, state);3269break;3270case LVP_CMD_SET_STENCIL_TEST_ENABLE:3271handle_set_stencil_test_enable(cmd, state);3272break;3273case LVP_CMD_SET_STENCIL_OP:3274handle_set_stencil_op(cmd, state);3275break;3276case LVP_CMD_SET_LINE_STIPPLE:3277handle_set_line_stipple(cmd, state);3278break;3279case LVP_CMD_SET_DEPTH_BIAS_ENABLE:3280handle_set_depth_bias_enable(cmd, state);3281break;3282case LVP_CMD_SET_LOGIC_OP:3283handle_set_logic_op(cmd, state);3284break;3285case LVP_CMD_SET_PATCH_CONTROL_POINTS:3286handle_set_patch_control_points(cmd, state);3287break;3288case LVP_CMD_SET_PRIMITIVE_RESTART_ENABLE:3289handle_set_primitive_restart_enable(cmd, state);3290break;3291case LVP_CMD_SET_RASTERIZER_DISCARD_ENABLE:3292handle_set_rasterizer_discard_enable(cmd, state);3293break;3294}3295first = false;3296did_flush = false;3297}3298}32993300VkResult lvp_execute_cmds(struct lvp_device *device,3301struct lvp_queue *queue,3302struct lvp_cmd_buffer *cmd_buffer)3303{3304struct rendering_state state;3305memset(&state, 0, sizeof(state));3306state.pctx = queue->ctx;3307state.cso = queue->cso;3308state.blend_dirty = true;3309state.dsa_dirty = true;3310state.rs_dirty = true;3311state.vp_dirty = true;3312for (enum pipe_shader_type s = PIPE_SHADER_VERTEX; s < PIPE_SHADER_TYPES; s++) {3313for (unsigned i = 0; i < PIPE_MAX_SAMPLERS; i++)3314state.cso_ss_ptr[s][i] = &state.ss[s][i];3315}3316/* create a gallium context */3317lvp_execute_cmd_buffer(cmd_buffer, &state);33183319state.start_vb = -1;3320state.num_vb = 0;3321cso_unbind_context(queue->cso);3322for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {3323if (state.so_targets[i]) {3324state.pctx->stream_output_target_destroy(state.pctx, state.so_targets[i]);3325}3326}33273328free(state.pending_clear_aspects);3329free(state.cleared_views);3330return VK_SUCCESS;3331}333233333334